diff options
author | Docile-Alligator <25734209+Docile-Alligator@users.noreply.github.com> | 2024-03-11 20:33:58 +0000 |
---|---|---|
committer | Docile-Alligator <25734209+Docile-Alligator@users.noreply.github.com> | 2024-03-11 20:33:58 +0000 |
commit | 21b1e3f51232e56c1e4e112ec222cf7a924c1ddc (patch) | |
tree | 6213946a173e61b0adfc3e07a7203cc9281b86c3 /app/src | |
parent | 705eef901173c8515a51f1554232702a576d037e (diff) | |
download | infinity-for-reddit-21b1e3f51232e56c1e4e112ec222cf7a924c1ddc.tar infinity-for-reddit-21b1e3f51232e56c1e4e112ec222cf7a924c1ddc.tar.gz infinity-for-reddit-21b1e3f51232e56c1e4e112ec222cf7a924c1ddc.tar.bz2 infinity-for-reddit-21b1e3f51232e56c1e4e112ec222cf7a924c1ddc.tar.lz infinity-for-reddit-21b1e3f51232e56c1e4e112ec222cf7a924c1ddc.tar.xz infinity-for-reddit-21b1e3f51232e56c1e4e112ec222cf7a924c1ddc.tar.zst infinity-for-reddit-21b1e3f51232e56c1e4e112ec222cf7a924c1ddc.zip |
Submit comment with up to one embedded image.
Diffstat (limited to 'app/src')
12 files changed, 131 insertions, 74 deletions
diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/CommentActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/CommentActivity.java index 806a3ec2..a0ef1052 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/CommentActivity.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/CommentActivity.java @@ -282,24 +282,25 @@ public class CommentActivity extends BaseActivity implements UploadImageEnabledA } MarkdownBottomBarRecyclerViewAdapter adapter = new MarkdownBottomBarRecyclerViewAdapter( - mCustomThemeWrapper, new MarkdownBottomBarRecyclerViewAdapter.ItemClickListener() { - @Override - public void onClick(int item) { - MarkdownBottomBarRecyclerViewAdapter.bindEditTextWithItemClickListener( - CommentActivity.this, binding.commentCommentEditText, item); - } + mCustomThemeWrapper, true, + new MarkdownBottomBarRecyclerViewAdapter.ItemClickListener() { + @Override + public void onClick(int item) { + MarkdownBottomBarRecyclerViewAdapter.bindEditTextWithItemClickListener( + CommentActivity.this, binding.commentCommentEditText, item); + } - @Override - public void onUploadImage() { - Utils.hideKeyboard(CommentActivity.this); - UploadedImagesBottomSheetFragment fragment = new UploadedImagesBottomSheetFragment(); - Bundle arguments = new Bundle(); - arguments.putParcelableArrayList(UploadedImagesBottomSheetFragment.EXTRA_UPLOADED_IMAGES, - uploadedImages); - fragment.setArguments(arguments); - fragment.show(getSupportFragmentManager(), fragment.getTag()); - } - }); + @Override + public void onUploadImage() { + Utils.hideKeyboard(CommentActivity.this); + UploadedImagesBottomSheetFragment fragment = new UploadedImagesBottomSheetFragment(); + Bundle arguments = new Bundle(); + arguments.putParcelableArrayList(UploadedImagesBottomSheetFragment.EXTRA_UPLOADED_IMAGES, + uploadedImages); + fragment.setArguments(arguments); + fragment.show(getSupportFragmentManager(), fragment.getTag()); + } + }); binding.commentMarkdownBottomBarRecyclerView.setLayoutManager(new LinearLayoutManagerBugFixed(this, LinearLayoutManagerBugFixed.HORIZONTAL, false)); @@ -436,8 +437,8 @@ public class CommentActivity extends BaseActivity implements UploadImageEnabledA .connectionPool(new ConnectionPool(0, 1, TimeUnit.NANOSECONDS)) .build()) .build(); - SendComment.sendComment(mExecutor, new Handler(), binding.commentCommentEditText.getText().toString(), - parentFullname, parentDepth, newAuthenticatorOauthRetrofit, selectedAccount, + SendComment.sendComment(this, mExecutor, new Handler(), binding.commentCommentEditText.getText().toString(), + parentFullname, parentDepth, uploadedImages, newAuthenticatorOauthRetrofit, selectedAccount, new SendComment.SendCommentListener() { @Override public void sendCommentSuccess(Comment comment) { @@ -466,7 +467,7 @@ public class CommentActivity extends BaseActivity implements UploadImageEnabledA item.getIcon().setAlpha(255); } - if (errorMessage == null || !errorMessage.equals("")) { + if (errorMessage == null || errorMessage.isEmpty()) { Snackbar.make(binding.commentCoordinatorLayout, R.string.send_comment_failed, Snackbar.LENGTH_SHORT).show(); } else { Snackbar.make(binding.commentCoordinatorLayout, errorMessage, Snackbar.LENGTH_SHORT).show(); diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/PostTextActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/PostTextActivity.java index 7a164f67..da03b3fb 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/PostTextActivity.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/PostTextActivity.java @@ -369,24 +369,25 @@ public class PostTextActivity extends BaseActivity implements FlairBottomSheetFr }); MarkdownBottomBarRecyclerViewAdapter adapter = new MarkdownBottomBarRecyclerViewAdapter( - mCustomThemeWrapper, new MarkdownBottomBarRecyclerViewAdapter.ItemClickListener() { - @Override - public void onClick(int item) { - MarkdownBottomBarRecyclerViewAdapter.bindEditTextWithItemClickListener( - PostTextActivity.this, contentEditText, item); - } - - @Override - public void onUploadImage() { - Utils.hideKeyboard(PostTextActivity.this); - UploadedImagesBottomSheetFragment fragment = new UploadedImagesBottomSheetFragment(); - Bundle arguments = new Bundle(); - arguments.putParcelableArrayList(UploadedImagesBottomSheetFragment.EXTRA_UPLOADED_IMAGES, - uploadedImages); - fragment.setArguments(arguments); - fragment.show(getSupportFragmentManager(), fragment.getTag()); - } - }); + mCustomThemeWrapper, true, + new MarkdownBottomBarRecyclerViewAdapter.ItemClickListener() { + @Override + public void onClick(int item) { + MarkdownBottomBarRecyclerViewAdapter.bindEditTextWithItemClickListener( + PostTextActivity.this, contentEditText, item); + } + + @Override + public void onUploadImage() { + Utils.hideKeyboard(PostTextActivity.this); + UploadedImagesBottomSheetFragment fragment = new UploadedImagesBottomSheetFragment(); + Bundle arguments = new Bundle(); + arguments.putParcelableArrayList(UploadedImagesBottomSheetFragment.EXTRA_UPLOADED_IMAGES, + uploadedImages); + fragment.setArguments(arguments); + fragment.show(getSupportFragmentManager(), fragment.getTag()); + } + }); markdownBottomBarRecyclerView.setLayoutManager(new LinearLayoutManagerBugFixed(this, LinearLayoutManager.HORIZONTAL, false)); diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/MarkdownBottomBarRecyclerViewAdapter.java b/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/MarkdownBottomBarRecyclerViewAdapter.java index 8faf9607..11720b1b 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/MarkdownBottomBarRecyclerViewAdapter.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/MarkdownBottomBarRecyclerViewAdapter.java @@ -31,9 +31,10 @@ public class MarkdownBottomBarRecyclerViewAdapter extends RecyclerView.Adapter<R public static final int CODE_BLOCK = 9; public static final int UPLOAD_IMAGE = 10; - private static final int ITEM_COUNT = 11; + private static final int ITEM_COUNT = 10; private final CustomThemeWrapper customThemeWrapper; + private final boolean canUploadImage; private final ItemClickListener itemClickListener; public interface ItemClickListener { @@ -43,7 +44,14 @@ public class MarkdownBottomBarRecyclerViewAdapter extends RecyclerView.Adapter<R public MarkdownBottomBarRecyclerViewAdapter(CustomThemeWrapper customThemeWrapper, ItemClickListener itemClickListener) { + this(customThemeWrapper, false, itemClickListener); + } + + public MarkdownBottomBarRecyclerViewAdapter(CustomThemeWrapper customThemeWrapper, + boolean canUploadImage, + ItemClickListener itemClickListener) { this.customThemeWrapper = customThemeWrapper; + this.canUploadImage = canUploadImage; this.itemClickListener = itemClickListener; } @@ -96,7 +104,7 @@ public class MarkdownBottomBarRecyclerViewAdapter extends RecyclerView.Adapter<R @Override public int getItemCount() { - return ITEM_COUNT; + return canUploadImage ? ITEM_COUNT + 1 : ITEM_COUNT; } public static void bindEditTextWithItemClickListener(Activity activity, EditText commentEditText, int item) { diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/comment/SendComment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/comment/SendComment.java index 1206279f..18d6c0a0 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/comment/SendComment.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/comment/SendComment.java @@ -1,16 +1,23 @@ package ml.docilealligator.infinityforreddit.comment; +import android.content.Context; import android.os.Handler; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import org.json.JSONException; + import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.concurrent.Executor; +import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.UploadedImage; import ml.docilealligator.infinityforreddit.account.Account; import ml.docilealligator.infinityforreddit.apis.RedditAPI; +import ml.docilealligator.infinityforreddit.markdown.RichTextJSONConverter; import ml.docilealligator.infinityforreddit.utils.APIUtils; import retrofit2.Call; import retrofit2.Callback; @@ -18,15 +25,26 @@ import retrofit2.Response; import retrofit2.Retrofit; public class SendComment { - public static void sendComment(Executor executor, Handler handler, String commentMarkdown, - String thingFullname, int parentDepth, + public static void sendComment(Context context, Executor executor, Handler handler, + String commentMarkdown, String thingFullname, int parentDepth, + List<UploadedImage> uploadedImages, Retrofit newAuthenticatorOauthRetrofit, Account account, SendCommentListener sendCommentListener) { Map<String, String> headers = APIUtils.getOAuthHeader(account.getAccessToken()); Map<String, String> params = new HashMap<>(); params.put(APIUtils.API_TYPE_KEY, "json"); params.put(APIUtils.RETURN_RTJSON_KEY, "true"); - params.put(APIUtils.TEXT_KEY, commentMarkdown); + if (!uploadedImages.isEmpty()) { + try { + params.put(APIUtils.RICHTEXT_JSON_KEY, new RichTextJSONConverter().constructRichTextJSON(context, commentMarkdown, uploadedImages)); + params.put(APIUtils.TEXT_KEY, ""); + } catch (JSONException e) { + sendCommentListener.sendCommentFailed(context.getString(R.string.convert_to_richtext_json_failed)); + return; + } + } else { + params.put(APIUtils.TEXT_KEY, commentMarkdown); + } params.put(APIUtils.THING_ID_KEY, thingFullname); newAuthenticatorOauthRetrofit.create(RedditAPI.class).sendCommentOrReplyToMessage(headers, params).enqueue(new Callback<String>() { diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/ViewPostDetailFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/ViewPostDetailFragment.java index 615f411c..4bfe129b 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/ViewPostDetailFragment.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/ViewPostDetailFragment.java @@ -1064,11 +1064,15 @@ public class ViewPostDetailFragment extends Fragment implements FragmentCommunic } return true; } else if (itemId == R.id.action_edit_view_post_detail_fragment) { - Intent editPostIntent = new Intent(activity, EditPostActivity.class); - editPostIntent.putExtra(EditPostActivity.EXTRA_FULLNAME, mPost.getFullName()); - editPostIntent.putExtra(EditPostActivity.EXTRA_TITLE, mPost.getTitle()); - editPostIntent.putExtra(EditPostActivity.EXTRA_CONTENT, mPost.getSelfText()); - startActivityForResult(editPostIntent, EDIT_POST_REQUEST_CODE); + if (mPost.getMediaMetadataMap() == null) { + Intent editPostIntent = new Intent(activity, EditPostActivity.class); + editPostIntent.putExtra(EditPostActivity.EXTRA_FULLNAME, mPost.getFullName()); + editPostIntent.putExtra(EditPostActivity.EXTRA_TITLE, mPost.getTitle()); + editPostIntent.putExtra(EditPostActivity.EXTRA_CONTENT, mPost.getSelfText()); + startActivityForResult(editPostIntent, EDIT_POST_REQUEST_CODE); + } else { + Toast.makeText(activity, R.string.cannot_edit_post_with_images, Toast.LENGTH_LONG).show(); + } return true; } else if (itemId == R.id.action_delete_view_post_detail_fragment) { new MaterialAlertDialogBuilder(activity, R.style.MaterialAlertDialogTheme) diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/markdown/CustomMarkwonAdapter.java b/app/src/main/java/ml/docilealligator/infinityforreddit/markdown/CustomMarkwonAdapter.java index d3cd46a3..530b5dc4 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/markdown/CustomMarkwonAdapter.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/markdown/CustomMarkwonAdapter.java @@ -1,5 +1,6 @@ package ml.docilealligator.infinityforreddit.markdown; +import android.util.Log; import android.util.SparseArray; import android.view.LayoutInflater; import android.view.View; @@ -15,6 +16,8 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import org.commonmark.node.Node; +import org.json.JSONException; +import org.json.JSONObject; import java.util.Collections; import java.util.List; @@ -89,12 +92,12 @@ public class CustomMarkwonAdapter extends MarkwonAdapter { public void setParsedMarkdown(@NonNull Markwon markwon, @NonNull List<Node> nodes) { // clear all entries before applying - /*try { + try { JSONObject object = new RichTextJSONConverter().constructRichTextJSON(nodes); Log.i("asdf", "s" + object); } catch (JSONException e) { throw new RuntimeException(e); - }*/ + } defaultEntry.clear(); diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/markdown/RichTextJSONConverter.java b/app/src/main/java/ml/docilealligator/infinityforreddit/markdown/RichTextJSONConverter.java index eba78e07..6ff044b5 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/markdown/RichTextJSONConverter.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/markdown/RichTextJSONConverter.java @@ -1,5 +1,7 @@ package ml.docilealligator.infinityforreddit.markdown; +import android.content.Context; + import androidx.annotation.Nullable; import org.commonmark.ext.gfm.strikethrough.Strikethrough; @@ -43,6 +45,10 @@ import java.util.List; import java.util.Map; import java.util.Stack; +import io.noties.markwon.Markwon; +import io.noties.markwon.MarkwonReducer; +import ml.docilealligator.infinityforreddit.UploadedImage; + public class RichTextJSONConverter implements Visitor { private static final int BOLD = 1; private static final int ITALICS = 2; @@ -101,6 +107,25 @@ public class RichTextJSONConverter implements Visitor { contentArrayStack.push(document); } + public String constructRichTextJSON(Context context, String markdown, + List<UploadedImage> uploadedImages) throws JSONException { + UploadedImagePlugin uploadedImagePlugin = new UploadedImagePlugin(); + uploadedImagePlugin.setUploadedImages(uploadedImages); + Markwon markwon = MarkdownUtils.createPostSubmissionRedditMarkwon( + context, uploadedImagePlugin); + + List<Node> nodes = MarkwonReducer.directChildren().reduce(markwon.parse(markdown)); + + JSONObject richText = new JSONObject(); + + for (Node n : nodes) { + n.accept(this); + } + + richText.put(DOCUMENT, document); + return richText.toString(); + } + public JSONObject constructRichTextJSON(List<Node> nodes) throws JSONException { JSONObject richText = new JSONObject(); @@ -565,9 +590,9 @@ public class RichTextJSONConverter implements Visitor { public void visit(CustomNode customNode) { if (customNode instanceof Superscript) { /* - Superscript can still has inline spans, thus checking children's next node until the end. - Superscript must use ^(), not ^ right now. - */ + Superscript can still has inline spans, thus checking children's next node until the end. + Superscript must use ^(), not ^ right now. + */ Node child = customNode.getFirstChild(); while (child != null) { JSONArray format = getFormatArray(customNode); diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/markdown/UploadedImageBlockParser.java b/app/src/main/java/ml/docilealligator/infinityforreddit/markdown/UploadedImageBlockParser.java index 26c50627..ca9c0904 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/markdown/UploadedImageBlockParser.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/markdown/UploadedImageBlockParser.java @@ -10,6 +10,8 @@ import org.commonmark.parser.block.BlockStart; import org.commonmark.parser.block.MatchedBlockParser; import org.commonmark.parser.block.ParserState; +import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -63,8 +65,15 @@ public class UploadedImageBlockParser extends AbstractBlockParser { return BlockStart.none(); } - public void setUploadedImageMap(@Nullable Map<String, UploadedImage> uploadedImageMap) { - this.uploadedImageMap = uploadedImageMap; + public void setUploadedImages(@Nullable List<UploadedImage> uploadedImages) { + if (uploadedImages == null) { + return; + } + + uploadedImageMap = new HashMap<>(); + for (UploadedImage u : uploadedImages) { + uploadedImageMap.put(u.imageUrlOrKey, u); + } } } } diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/markdown/UploadedImagePlugin.java b/app/src/main/java/ml/docilealligator/infinityforreddit/markdown/UploadedImagePlugin.java index bde869d1..64645a84 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/markdown/UploadedImagePlugin.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/markdown/UploadedImagePlugin.java @@ -4,7 +4,7 @@ import androidx.annotation.NonNull; import org.commonmark.parser.Parser; -import java.util.Map; +import java.util.List; import io.noties.markwon.AbstractMarkwonPlugin; import ml.docilealligator.infinityforreddit.UploadedImage; @@ -27,7 +27,7 @@ public class UploadedImagePlugin extends AbstractMarkwonPlugin { builder.customBlockParserFactory(factory); } - public void setUploadedImageMap(Map<String, UploadedImage> uploadedImageMap) { - factory.setUploadedImageMap(uploadedImageMap); + public void setUploadedImages(List<UploadedImage> uploadedImages) { + factory.setUploadedImages(uploadedImages); } } diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/post/Post.java b/app/src/main/java/ml/docilealligator/infinityforreddit/post/Post.java index 52c1bf22..b204c97d 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/post/Post.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/post/Post.java @@ -581,11 +581,12 @@ public class Post implements Parcelable { this.previews = previews; } + @Nullable public Map<String, MediaMetadata> getMediaMetadataMap() { return mediaMetadataMap; } - public void setMediaMetadataMap(Map<String, MediaMetadata> mediaMetadataMap) { + public void setMediaMetadataMap(@Nullable Map<String, MediaMetadata> mediaMetadataMap) { this.mediaMetadataMap = mediaMetadataMap; } diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/services/SubmitPostService.java b/app/src/main/java/ml/docilealligator/infinityforreddit/services/SubmitPostService.java index 8b958171..851c8b6b 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/services/SubmitPostService.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/services/SubmitPostService.java @@ -33,9 +33,7 @@ import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; -import java.util.HashMap; import java.util.List; -import java.util.Map; import java.util.Random; import java.util.concurrent.ExecutionException; import java.util.concurrent.Executor; @@ -44,8 +42,6 @@ import java.util.concurrent.TimeUnit; import javax.inject.Inject; import javax.inject.Named; -import io.noties.markwon.Markwon; -import io.noties.markwon.MarkwonReducer; import ml.docilealligator.infinityforreddit.AnyAccountAccessTokenAuthenticator; import ml.docilealligator.infinityforreddit.Flair; import ml.docilealligator.infinityforreddit.Infinity; @@ -61,9 +57,7 @@ import ml.docilealligator.infinityforreddit.events.SubmitImagePostEvent; import ml.docilealligator.infinityforreddit.events.SubmitPollPostEvent; import ml.docilealligator.infinityforreddit.events.SubmitTextOrLinkPostEvent; import ml.docilealligator.infinityforreddit.events.SubmitVideoOrGifPostEvent; -import ml.docilealligator.infinityforreddit.markdown.MarkdownUtils; import ml.docilealligator.infinityforreddit.markdown.RichTextJSONConverter; -import ml.docilealligator.infinityforreddit.markdown.UploadedImagePlugin; import ml.docilealligator.infinityforreddit.post.Post; import ml.docilealligator.infinityforreddit.post.SubmitPost; import ml.docilealligator.infinityforreddit.utils.APIUtils; @@ -162,16 +156,8 @@ public class SubmitPostService extends Service { String kind = bundle.getString(EXTRA_KIND); if (isRichTextJSON) { List<UploadedImage> uploadedImages = bundle.getParcelableArrayList(EXTRA_UPLOADED_IMAGES); - Map<String, UploadedImage> uploadedImageMap = new HashMap<>(); - for (UploadedImage u : uploadedImages) { - uploadedImageMap.put(u.imageUrlOrKey, u); - } - UploadedImagePlugin uploadedImagePlugin = new UploadedImagePlugin(); - uploadedImagePlugin.setUploadedImageMap(uploadedImageMap); - Markwon markwon = MarkdownUtils.createPostSubmissionRedditMarkwon( - SubmitPostService.this, uploadedImagePlugin); try { - content = new RichTextJSONConverter().constructRichTextJSON(MarkwonReducer.directChildren().reduce(markwon.parse(content))).toString(); + content = new RichTextJSONConverter().constructRichTextJSON(SubmitPostService.this, content, uploadedImages); } catch (JSONException e) { handler.post(() -> EventBus.getDefault().post(new SubmitTextOrLinkPostEvent(false, null, getString(R.string.convert_to_richtext_json_failed)))); return; diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 41614640..8eba62d7 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1368,5 +1368,6 @@ <string name="i_understand">I understand</string> <string name="add_to_comment_filter">Add to Comment Filter</string> + <string name="cannot_edit_post_with_images">Editing posts with images is not allowed.</string> </resources> |