From 705eef901173c8515a51f1554232702a576d037e Mon Sep 17 00:00:00 2001 From: Docile-Alligator <25734209+Docile-Alligator@users.noreply.github.com> Date: Sun, 10 Mar 2024 22:28:59 -0400 Subject: Submit text post with embedded images. --- .../activities/PostTextActivity.java | 5 +++ .../infinityforreddit/markdown/MarkdownUtils.java | 18 +++++++++++ .../markdown/RichTextJSONConverter.java | 1 + .../infinityforreddit/post/SubmitPost.java | 22 +++++++------ .../services/SubmitPostService.java | 37 +++++++++++++++++++--- .../infinityforreddit/utils/APIUtils.java | 1 + app/src/main/res/values/strings.xml | 1 + 7 files changed, 72 insertions(+), 13 deletions(-) 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 2c968e68..7a164f67 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/PostTextActivity.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/PostTextActivity.java @@ -576,6 +576,11 @@ public class PostTextActivity extends BaseActivity implements FlairBottomSheetFr intent.putExtra(SubmitPostService.EXTRA_SUBREDDIT_NAME, subredditName); intent.putExtra(SubmitPostService.EXTRA_TITLE, titleEditText.getText().toString()); intent.putExtra(SubmitPostService.EXTRA_CONTENT, contentEditText.getText().toString()); + if (!uploadedImages.isEmpty()) { + intent.putExtra(SubmitPostService.EXTRA_IS_RICHTEXT_JSON, true); + intent.putExtra(SubmitPostService.EXTRA_UPLOADED_IMAGES, uploadedImages); + } + intent.putExtra(SubmitPostService.EXTRA_KIND, APIUtils.KIND_SELF); intent.putExtra(SubmitPostService.EXTRA_FLAIR, flair); intent.putExtra(SubmitPostService.EXTRA_IS_SPOILER, isSpoiler); diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/markdown/MarkdownUtils.java b/app/src/main/java/ml/docilealligator/infinityforreddit/markdown/MarkdownUtils.java index b9b906fd..b7eacc61 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/markdown/MarkdownUtils.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/markdown/MarkdownUtils.java @@ -57,6 +57,24 @@ public class MarkdownUtils { .build(); } + @NonNull + public static Markwon createPostSubmissionRedditMarkwon(@NonNull Context context, + @NonNull UploadedImagePlugin uploadedImagePlugin) { + return Markwon.builder(context) + .usePlugin(MarkwonInlineParserPlugin.create(plugin -> { + plugin.excludeInlineProcessor(HtmlInlineProcessor.class); + plugin.excludeInlineProcessor(BangInlineProcessor.class); + })) + .usePlugin(SuperscriptPlugin.create()) + .usePlugin(SpoilerParserPlugin.create(0, 0)) + .usePlugin(RedditHeadingPlugin.create()) + .usePlugin(StrikethroughPlugin.create()) + .usePlugin(LinkifyPlugin.create(Linkify.WEB_URLS)) + .usePlugin(uploadedImagePlugin) + .usePlugin(TableEntryPlugin.create(context)) + .build(); + } + @NonNull public static Markwon createDescriptionMarkwon(Context context, MarkwonPlugin miscPlugin, EvenBetterLinkMovementMethod.OnLinkLongClickListener onLinkLongClickListener) { 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 96ae272e..eba78e07 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/markdown/RichTextJSONConverter.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/markdown/RichTextJSONConverter.java @@ -547,6 +547,7 @@ public class RichTextJSONConverter implements Visitor { throw new RuntimeException(e); } } else if (customBlock instanceof UploadedImageBlock) { + //Nothing is allowed inside this block. try { JSONObject nodeJSON = new JSONObject(); nodeJSON.put(TYPE, IMAGE_E); diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/post/SubmitPost.java b/app/src/main/java/ml/docilealligator/infinityforreddit/post/SubmitPost.java index f5bcb248..30c92824 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/post/SubmitPost.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/post/SubmitPost.java @@ -32,10 +32,10 @@ public class SubmitPost { public static void submitTextOrLinkPost(Executor executor, Handler handler, Retrofit oauthRetrofit, String accessToken, String subredditName, String title, String content, Flair flair, boolean isSpoiler, boolean isNSFW, - boolean receivePostReplyNotifications, String kind, + boolean receivePostReplyNotifications, boolean isRichTextJSON, String kind, SubmitPostListener submitPostListener) { submitPost(executor, handler, oauthRetrofit, accessToken, subredditName, title, content, - flair, isSpoiler, isNSFW, receivePostReplyNotifications, kind, null, submitPostListener); + flair, isSpoiler, isNSFW, receivePostReplyNotifications, isRichTextJSON, kind, null, submitPostListener); } public static void submitImagePost(Executor executor, Handler handler, Retrofit oauthRetrofit, Retrofit uploadMediaRetrofit, @@ -47,7 +47,7 @@ public class SubmitPost { if (imageUrlOrError != null && !imageUrlOrError.startsWith("Error: ")) { submitPost(executor, handler, oauthRetrofit, accessToken, subredditName, title, imageUrlOrError, flair, isSpoiler, isNSFW, - receivePostReplyNotifications, APIUtils.KIND_IMAGE, null, submitPostListener); + receivePostReplyNotifications, false, APIUtils.KIND_IMAGE, null, submitPostListener); } else { submitPostListener.submitFailed(imageUrlOrError); } @@ -98,12 +98,12 @@ public class SubmitPost { if (fileType.equals("gif")) { submitPost(executor, handler, oauthRetrofit, accessToken, subredditName, title, url, flair, isSpoiler, isNSFW, - receivePostReplyNotifications, APIUtils.KIND_VIDEOGIF, imageUrlOrError, + receivePostReplyNotifications, false, APIUtils.KIND_VIDEOGIF, imageUrlOrError, submitPostListener); } else { submitPost(executor, handler, oauthRetrofit, accessToken, subredditName, title, url, flair, isSpoiler, isNSFW, - receivePostReplyNotifications, APIUtils.KIND_VIDEO, imageUrlOrError, + receivePostReplyNotifications, false, APIUtils.KIND_VIDEO, imageUrlOrError, submitPostListener); } } else { @@ -127,14 +127,14 @@ public class SubmitPost { boolean receivePostReplyNotifications, String kind, SubmitPostListener submitPostListener) { submitPost(executor, handler, oauthRetrofit, accessToken, subredditName, title, crosspostFullname, - flair, isSpoiler, isNSFW, receivePostReplyNotifications, kind, null, submitPostListener); + flair, isSpoiler, isNSFW, receivePostReplyNotifications, false, kind, null, submitPostListener); } private static void submitPost(Executor executor, Handler handler, Retrofit oauthRetrofit, String accessToken, String subredditName, String title, String content, Flair flair, boolean isSpoiler, boolean isNSFW, - boolean receivePostReplyNotifications, String kind, - @Nullable String posterUrl, SubmitPostListener submitPostListener) { + boolean receivePostReplyNotifications, boolean isRichTextJSON, + String kind, @Nullable String posterUrl, SubmitPostListener submitPostListener) { RedditAPI api = oauthRetrofit.create(RedditAPI.class); Map params = new HashMap<>(); @@ -144,7 +144,11 @@ public class SubmitPost { params.put(APIUtils.KIND_KEY, kind); switch (kind) { case APIUtils.KIND_SELF: - params.put(APIUtils.TEXT_KEY, content); + if (isRichTextJSON) { + params.put(APIUtils.RICHTEXT_JSON_KEY, content); + } else { + params.put(APIUtils.TEXT_KEY, content); + } break; case APIUtils.KIND_LINK: case APIUtils.KIND_IMAGE: 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 06415a6b..8b958171 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/services/SubmitPostService.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/services/SubmitPostService.java @@ -33,6 +33,9 @@ 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; @@ -41,11 +44,14 @@ 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; import ml.docilealligator.infinityforreddit.R; import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; +import ml.docilealligator.infinityforreddit.UploadedImage; import ml.docilealligator.infinityforreddit.account.Account; import ml.docilealligator.infinityforreddit.apis.RedditAPI; import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; @@ -55,6 +61,9 @@ 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; @@ -70,6 +79,8 @@ public class SubmitPostService extends Service { public static final String EXTRA_SUBREDDIT_NAME = "ESN"; public static final String EXTRA_TITLE = "ET"; public static final String EXTRA_CONTENT = "EC"; + public static final String EXTRA_IS_RICHTEXT_JSON = "EIRJ"; + public static final String EXTRA_UPLOADED_IMAGES = "EUI"; public static final String EXTRA_REDDIT_GALLERY_PAYLOAD = "ERGP"; public static final String EXTRA_POLL_PAYLOAD = "EPP"; public static final String EXTRA_KIND = "EK"; @@ -146,10 +157,28 @@ public class SubmitPostService extends Service { .build(); if (postType == EXTRA_POST_TEXT_OR_LINK) { - String content = bundle.getString(EXTRA_CONTENT); + String content = bundle.getString(EXTRA_CONTENT, ""); + boolean isRichTextJSON = bundle.getBoolean(EXTRA_IS_RICHTEXT_JSON); String kind = bundle.getString(EXTRA_KIND); + if (isRichTextJSON) { + List uploadedImages = bundle.getParcelableArrayList(EXTRA_UPLOADED_IMAGES); + Map 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(); + } catch (JSONException e) { + handler.post(() -> EventBus.getDefault().post(new SubmitTextOrLinkPostEvent(false, null, getString(R.string.convert_to_richtext_json_failed)))); + return; + } + } submitTextOrLinkPost(newAuthenticatorOauthRetrofit, account, subredditName, title, content, flair, isSpoiler, isNSFW, - receivePostReplyNotifications, kind); + receivePostReplyNotifications, isRichTextJSON, kind); } else if (postType == EXTRA_POST_TYPE_CROSSPOST) { String content = bundle.getString(EXTRA_CONTENT); submitCrosspost(mExecutor, handler, newAuthenticatorOauthRetrofit, account, subredditName, title, content, @@ -234,10 +263,10 @@ public class SubmitPostService extends Service { private void submitTextOrLinkPost(Retrofit newAuthenticatorOauthRetrofit, Account selectedAccount, String subredditName, String title, String content, Flair flair, boolean isSpoiler, boolean isNSFW, boolean receivePostReplyNotifications, - String kind) { + boolean isRichtextJSON, String kind) { SubmitPost.submitTextOrLinkPost(mExecutor, handler, newAuthenticatorOauthRetrofit, selectedAccount.getAccessToken(), subredditName, title, content, flair, isSpoiler, - isNSFW, receivePostReplyNotifications, kind, new SubmitPost.SubmitPostListener() { + isNSFW, receivePostReplyNotifications, isRichtextJSON, kind, new SubmitPost.SubmitPostListener() { @Override public void submitSuccessful(Post post) { handler.post(() -> EventBus.getDefault().post(new SubmitTextOrLinkPostEvent(true, post, null))); diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/utils/APIUtils.java b/app/src/main/java/ml/docilealligator/infinityforreddit/utils/APIUtils.java index 87ec827e..2e2cb3fa 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/utils/APIUtils.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/utils/APIUtils.java @@ -85,6 +85,7 @@ public class APIUtils { public static final String KIND_VIDEO = "video"; public static final String KIND_VIDEOGIF = "videogif"; public static final String KIND_CROSSPOST = "crosspost"; + public static final String RICHTEXT_JSON_KEY = "richtext_json"; public static final String FILEPATH_KEY = "filepath"; public static final String MIMETYPE_KEY = "mimetype"; diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 49d8971f..41614640 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -207,6 +207,7 @@ Error processing image Error processing video A good poll needs two or more options! + Could not process markdown Download Started. Check the notification for progress. -- cgit v1.2.3