diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index b870c591..d610fb2f 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -34,7 +34,12 @@
android:theme="@style/AppTheme"
android:usesCleartextTraffic="true"
tools:replace="android:label">
-
+
diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/AppComponent.java b/app/src/main/java/ml/docilealligator/infinityforreddit/AppComponent.java
index 94b55f15..47c27b13 100644
--- a/app/src/main/java/ml/docilealligator/infinityforreddit/AppComponent.java
+++ b/app/src/main/java/ml/docilealligator/infinityforreddit/AppComponent.java
@@ -59,6 +59,7 @@ import ml.docilealligator.infinityforreddit.activities.ViewSubredditDetailActivi
import ml.docilealligator.infinityforreddit.activities.ViewUserDetailActivity;
import ml.docilealligator.infinityforreddit.activities.ViewVideoActivity;
import ml.docilealligator.infinityforreddit.activities.WebViewActivity;
+import ml.docilealligator.infinityforreddit.activities.WikiActivity;
import ml.docilealligator.infinityforreddit.bottomsheetfragments.FlairBottomSheetFragment;
import ml.docilealligator.infinityforreddit.fragments.CommentsListingFragment;
import ml.docilealligator.infinityforreddit.fragments.FollowedUsersListingFragment;
@@ -281,4 +282,6 @@ public interface AppComponent {
void inject(PostGalleryActivity postGalleryActivity);
void inject(TrendingActivity trendingActivity);
+
+ void inject(WikiActivity wikiActivity);
}
diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/FullMarkdownActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/FullMarkdownActivity.java
index 8ed8fa5e..4045826b 100644
--- a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/FullMarkdownActivity.java
+++ b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/FullMarkdownActivity.java
@@ -26,11 +26,12 @@ import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.google.android.material.appbar.AppBarLayout;
-import com.google.android.material.appbar.CollapsingToolbarLayout;
import com.r0adkll.slidr.Slidr;
import com.r0adkll.slidr.model.SlidrInterface;
import org.commonmark.ext.gfm.tables.TableBlock;
+import org.greenrobot.eventbus.EventBus;
+import org.greenrobot.eventbus.Subscribe;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -54,6 +55,7 @@ import ml.docilealligator.infinityforreddit.Infinity;
import ml.docilealligator.infinityforreddit.R;
import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper;
import ml.docilealligator.infinityforreddit.customviews.MarkwonLinearLayoutManager;
+import ml.docilealligator.infinityforreddit.events.SwitchAccountEvent;
import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils;
public class FullMarkdownActivity extends BaseActivity {
@@ -66,8 +68,6 @@ public class FullMarkdownActivity extends BaseActivity {
CoordinatorLayout coordinatorLayout;
@BindView(R.id.appbar_layout_comment_full_markdown_activity)
AppBarLayout appBarLayout;
- @BindView(R.id.collapsing_toolbar_layout_comment_full_markdown_activity)
- CollapsingToolbarLayout collapsingToolbarLayout;
@BindView(R.id.toolbar_comment_full_markdown_activity)
Toolbar toolbar;
@BindView(R.id.content_markdown_view_comment_full_markdown_activity)
@@ -88,6 +88,8 @@ public class FullMarkdownActivity extends BaseActivity {
ButterKnife.bind(this);
+ EventBus.getDefault().register(this);
+
applyCustomTheme();
setSupportActionBar(toolbar);
@@ -115,7 +117,7 @@ public class FullMarkdownActivity extends BaseActivity {
window.setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
}
adjustToolbar(toolbar);
- markdownRecyclerView.setPadding(0, 0, 0, getNavBarHeight());
+ markdownRecyclerView.setPadding(markdownRecyclerView.getPaddingLeft(), 0, markdownRecyclerView.getPaddingRight(), getNavBarHeight());
}
}
@@ -277,4 +279,17 @@ public class FullMarkdownActivity extends BaseActivity {
coordinatorLayout.setBackgroundColor(mCustomThemeWrapper.getBackgroundColor());
applyAppBarLayoutAndToolbarTheme(appBarLayout, toolbar);
}
+
+ @Override
+ protected void onDestroy() {
+ super.onDestroy();
+ EventBus.getDefault().unregister(this);
+ }
+
+ @Subscribe
+ public void onAccountSwitchEvent(SwitchAccountEvent event) {
+ if (!getClass().getName().equals(event.excludeActivityClassName)) {
+ finish();
+ }
+ }
}
\ No newline at end of file
diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/LinkResolverActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/LinkResolverActivity.java
index e0154df2..886f0d45 100644
--- a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/LinkResolverActivity.java
+++ b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/LinkResolverActivity.java
@@ -49,6 +49,7 @@ public class LinkResolverActivity extends AppCompatActivity {
private static final String IMGUR_ALBUM_PATTERN = "/(album|a)/\\w+/?";
private static final String IMGUR_IMAGE_PATTERN = "/\\w+/?";
private static final String RPAN_BROADCAST_PATTERN = "/rpan/r/[\\w-]+/\\w+/?\\w+/?";
+ private static final String WIKI_PATTERN = "/[rR]/[\\w-]+/wiki/?\\w+";
@Inject
@Named("default")
@@ -171,6 +172,10 @@ public class LinkResolverActivity extends AppCompatActivity {
} else {
deepLinkError(uri);
}
+ } else if (path.matches(WIKI_PATTERN)) {
+ Intent intent = new Intent(this, WikiActivity.class);
+ intent.putExtra(WikiActivity.EXTRA_SUBREDDIT_NAME, segments.get(1));
+ startActivity(intent);
} else if (path.matches(SUBREDDIT_PATTERN)) {
Intent intent = new Intent(this, ViewSubredditDetailActivity.class);
intent.putExtra(ViewSubredditDetailActivity.EXTRA_SUBREDDIT_NAME_KEY, path.substring(3));
diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/WikiActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/WikiActivity.java
new file mode 100644
index 00000000..492553dc
--- /dev/null
+++ b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/WikiActivity.java
@@ -0,0 +1,322 @@
+package ml.docilealligator.infinityforreddit.activities;
+
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.graphics.Color;
+import android.net.Uri;
+import android.os.Build;
+import android.os.Bundle;
+import android.text.SpannableStringBuilder;
+import android.text.Spanned;
+import android.text.TextPaint;
+import android.text.style.ClickableSpan;
+import android.text.util.Linkify;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.Window;
+import android.view.WindowManager;
+import android.widget.TextView;
+
+import androidx.annotation.NonNull;
+import androidx.appcompat.widget.Toolbar;
+import androidx.coordinatorlayout.widget.CoordinatorLayout;
+import androidx.recyclerview.widget.LinearLayoutManager;
+import androidx.recyclerview.widget.RecyclerView;
+
+import com.google.android.material.appbar.AppBarLayout;
+import com.r0adkll.slidr.Slidr;
+import com.r0adkll.slidr.model.SlidrInterface;
+
+import org.commonmark.ext.gfm.tables.TableBlock;
+import org.greenrobot.eventbus.EventBus;
+import org.greenrobot.eventbus.Subscribe;
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+
+import butterknife.BindView;
+import butterknife.ButterKnife;
+import io.noties.markwon.AbstractMarkwonPlugin;
+import io.noties.markwon.Markwon;
+import io.noties.markwon.MarkwonConfiguration;
+import io.noties.markwon.core.MarkwonTheme;
+import io.noties.markwon.ext.strikethrough.StrikethroughPlugin;
+import io.noties.markwon.html.HtmlPlugin;
+import io.noties.markwon.linkify.LinkifyPlugin;
+import io.noties.markwon.recycler.MarkwonAdapter;
+import io.noties.markwon.recycler.table.TableEntry;
+import io.noties.markwon.recycler.table.TableEntryPlugin;
+import ml.docilealligator.infinityforreddit.Infinity;
+import ml.docilealligator.infinityforreddit.R;
+import ml.docilealligator.infinityforreddit.apis.RedditAPI;
+import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper;
+import ml.docilealligator.infinityforreddit.customviews.MarkwonLinearLayoutManager;
+import ml.docilealligator.infinityforreddit.events.SwitchAccountEvent;
+import ml.docilealligator.infinityforreddit.utils.JSONUtils;
+import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils;
+import retrofit2.Call;
+import retrofit2.Callback;
+import retrofit2.Response;
+import retrofit2.Retrofit;
+
+public class WikiActivity extends BaseActivity {
+
+ public static final String EXTRA_SUBREDDIT_NAME = "ESN";
+ private static final String WIKI_MARKDOWN_STATE = "WMS";
+
+ @BindView(R.id.coordinator_layout_comment_wiki_activity)
+ CoordinatorLayout coordinatorLayout;
+ @BindView(R.id.appbar_layout_comment_wiki_activity)
+ AppBarLayout appBarLayout;
+ @BindView(R.id.toolbar_comment_wiki_activity)
+ Toolbar toolbar;
+ @BindView(R.id.content_markdown_view_comment_wiki_activity)
+ RecyclerView markdownRecyclerView;
+ @Inject
+ @Named("no_oauth")
+ Retrofit retrofit;
+ @Inject
+ @Named("default")
+ SharedPreferences mSharedPreferences;
+ @Inject
+ CustomThemeWrapper mCustomThemeWrapper;
+ private SlidrInterface mSlidrInterface;
+ private String wikiMarkdown;
+ private Markwon markwon;
+ private MarkwonAdapter markwonAdapter;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ ((Infinity) getApplication()).getAppComponent().inject(this);
+
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_wiki);
+
+ ButterKnife.bind(this);
+
+ EventBus.getDefault().register(this);
+
+ applyCustomTheme();
+
+ setSupportActionBar(toolbar);
+ getSupportActionBar().setDisplayHomeAsUpEnabled(true);
+
+ if (mSharedPreferences.getBoolean(SharedPreferencesUtils.SWIPE_RIGHT_TO_GO_BACK, true)) {
+ mSlidrInterface = Slidr.attach(this);
+ }
+
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
+ Window window = getWindow();
+
+ if (isChangeStatusBarIconColor()) {
+ addOnOffsetChangedListener(appBarLayout);
+ }
+
+ if (isImmersiveInterface()) {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
+ coordinatorLayout.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE |
+ View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN |
+ View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);
+ } else {
+ window.setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
+ }
+ adjustToolbar(toolbar);
+ markdownRecyclerView.setPadding(markdownRecyclerView.getPaddingLeft(), 0, markdownRecyclerView.getPaddingRight(), getNavBarHeight());
+ }
+ }
+
+ int markdownColor = mCustomThemeWrapper.getPrimaryTextColor();
+ int spoilerBackgroundColor = markdownColor | 0xFF000000;
+ int linkColor = mCustomThemeWrapper.getLinkColor();
+ markwon = Markwon.builder(this)
+ .usePlugin(HtmlPlugin.create())
+ .usePlugin(new AbstractMarkwonPlugin() {
+ @NonNull
+ @Override
+ public String processMarkdown(@NonNull String markdown) {
+ StringBuilder markdownStringBuilder = new StringBuilder(markdown);
+ Pattern spoilerPattern = Pattern.compile(">![\\S\\s]*?!<");
+ Matcher matcher = spoilerPattern.matcher(markdownStringBuilder);
+ while (matcher.find()) {
+ markdownStringBuilder.replace(matcher.start(), matcher.start() + 1, ">");
+ }
+ return super.processMarkdown(markdownStringBuilder.toString());
+ }
+
+ @Override
+ public void afterSetText(@NonNull TextView textView) {
+ textView.setHighlightColor(Color.TRANSPARENT);
+ SpannableStringBuilder markdownStringBuilder = new SpannableStringBuilder(textView.getText().toString());
+ Pattern spoilerPattern = Pattern.compile(">![\\S\\s]*?!<");
+ Matcher matcher = spoilerPattern.matcher(markdownStringBuilder);
+ int start = 0;
+ boolean find = false;
+ while (matcher.find(start)) {
+ if (markdownStringBuilder.length() < 4
+ || matcher.start() < 0
+ || matcher.end() > markdownStringBuilder.length()) {
+ break;
+ }
+ find = true;
+ markdownStringBuilder.delete(matcher.end() - 2, matcher.end());
+ markdownStringBuilder.delete(matcher.start(), matcher.start() + 2);
+ ClickableSpan clickableSpan = new ClickableSpan() {
+ private boolean isShowing = false;
+ @Override
+ public void updateDrawState(@NonNull TextPaint ds) {
+ if (isShowing) {
+ super.updateDrawState(ds);
+ ds.setColor(markdownColor);
+ } else {
+ ds.bgColor = spoilerBackgroundColor;
+ ds.setColor(markdownColor);
+ }
+ ds.setUnderlineText(false);
+ }
+
+ @Override
+ public void onClick(@NonNull View view) {
+ isShowing = !isShowing;
+ view.invalidate();
+ }
+ };
+ markdownStringBuilder.setSpan(clickableSpan, matcher.start(), matcher.end() - 4, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
+ start = matcher.end() - 4;
+ }
+ if (find) {
+ textView.setText(markdownStringBuilder);
+ }
+ }
+
+ @Override
+ public void beforeSetText(@NonNull TextView textView, @NonNull Spanned markdown) {
+ textView.setTextColor(markdownColor);
+ }
+
+ @Override
+ public void configureConfiguration(@NonNull MarkwonConfiguration.Builder builder) {
+ builder.linkResolver((view, link) -> {
+ Intent intent = new Intent(WikiActivity.this, LinkResolverActivity.class);
+ Uri uri = Uri.parse(link);
+ intent.setData(uri);
+ startActivity(intent);
+ });
+ }
+
+ @Override
+ public void configureTheme(@NonNull MarkwonTheme.Builder builder) {
+ builder.linkColor(linkColor);
+ }
+ })
+ .usePlugin(StrikethroughPlugin.create())
+ .usePlugin(LinkifyPlugin.create(Linkify.WEB_URLS))
+ .usePlugin(TableEntryPlugin.create(this))
+ .build();
+
+ markwonAdapter = MarkwonAdapter.builder(R.layout.adapter_default_entry, R.id.text)
+ .include(TableBlock.class, TableEntry.create(builder -> builder
+ .tableLayout(R.layout.adapter_table_block, R.id.table_layout)
+ .textLayoutIsRoot(R.layout.view_table_entry_cell)))
+ .build();
+ LinearLayoutManager linearLayoutManager = new MarkwonLinearLayoutManager(this, new MarkwonLinearLayoutManager.HorizontalScrollViewScrolledListener() {
+ @Override
+ public void onScrolledLeft() {
+ if (mSlidrInterface != null) {
+ mSlidrInterface.lock();
+ }
+ }
+
+ @Override
+ public void onScrolledRight() {
+ if (mSlidrInterface != null) {
+ mSlidrInterface.unlock();
+ }
+ }
+ });
+ markdownRecyclerView.setLayoutManager(linearLayoutManager);
+ markdownRecyclerView.setAdapter(markwonAdapter);
+
+ if (savedInstanceState != null) {
+ wikiMarkdown = savedInstanceState.getString(WIKI_MARKDOWN_STATE);
+ }
+
+ if (wikiMarkdown == null) {
+ loadWiki();
+ } else {
+ markwonAdapter.setMarkdown(markwon, wikiMarkdown);
+ markwonAdapter.notifyDataSetChanged();
+ }
+ }
+
+ private void loadWiki() {
+ retrofit.create(RedditAPI.class).getWiki(getIntent().getStringExtra(EXTRA_SUBREDDIT_NAME)).enqueue(new Callback() {
+ @Override
+ public void onResponse(@NonNull Call call, @NonNull Response response) {
+ if (response.isSuccessful()) {
+ try {
+ markwonAdapter.setMarkdown(markwon, new JSONObject(response.body())
+ .getJSONObject(JSONUtils.DATA_KEY).getString(JSONUtils.CONTENT_MD_KEY));
+ markwonAdapter.notifyDataSetChanged();
+ } catch (JSONException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ @Override
+ public void onFailure(@NonNull Call call, @NonNull Throwable t) {
+
+ }
+ });
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(@NonNull MenuItem item) {
+ if (item.getItemId() == android.R.id.home) {
+ finish();
+ return true;
+ }
+
+ return false;
+ }
+
+ @Override
+ protected void onSaveInstanceState(@NonNull Bundle outState) {
+ super.onSaveInstanceState(outState);
+ outState.putString(WIKI_MARKDOWN_STATE, wikiMarkdown);
+ }
+
+ @Override
+ protected void onDestroy() {
+ super.onDestroy();
+ EventBus.getDefault().unregister(this);
+ }
+
+ @Override
+ protected SharedPreferences getDefaultSharedPreferences() {
+ return mSharedPreferences;
+ }
+
+ @Override
+ protected CustomThemeWrapper getCustomThemeWrapper() {
+ return mCustomThemeWrapper;
+ }
+
+ @Override
+ protected void applyCustomTheme() {
+ coordinatorLayout.setBackgroundColor(mCustomThemeWrapper.getBackgroundColor());
+ applyAppBarLayoutAndToolbarTheme(appBarLayout, toolbar);
+ }
+
+ @Subscribe
+ public void onAccountSwitchEvent(SwitchAccountEvent event) {
+ if (!getClass().getName().equals(event.excludeActivityClassName)) {
+ finish();
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/apis/RedditAPI.java b/app/src/main/java/ml/docilealligator/infinityforreddit/apis/RedditAPI.java
index 420b90a2..b7dfba9e 100644
--- a/app/src/main/java/ml/docilealligator/infinityforreddit/apis/RedditAPI.java
+++ b/app/src/main/java/ml/docilealligator/infinityforreddit/apis/RedditAPI.java
@@ -365,4 +365,7 @@ public interface RedditAPI {
@GET("/api/trending_searches_v1.json?withAds=0&raw_json=1&gilding_detail=1")
Call getTrendingSearches(@HeaderMap Map headers);
+
+ @GET("/r/{subredditName}/wiki/index.json?raw_json=1")
+ Call getWiki(@Path("subredditName") String subredditName);
}
diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/utils/JSONUtils.java b/app/src/main/java/ml/docilealligator/infinityforreddit/utils/JSONUtils.java
index 8d68d9fb..b76f198e 100644
--- a/app/src/main/java/ml/docilealligator/infinityforreddit/utils/JSONUtils.java
+++ b/app/src/main/java/ml/docilealligator/infinityforreddit/utils/JSONUtils.java
@@ -170,4 +170,5 @@ public class JSONUtils {
public static final String QUERY_STRING_KEY = "query_string";
public static final String DISPLAY_STRING_KEY = "display_string";
public static final String RESULTS_KEY = "results";
+ public static final String CONTENT_MD_KEY = "content_md";
}
diff --git a/app/src/main/res/layout/activity_comment_full_markdown.xml b/app/src/main/res/layout/activity_comment_full_markdown.xml
index 509ad624..e1f89252 100644
--- a/app/src/main/res/layout/activity_comment_full_markdown.xml
+++ b/app/src/main/res/layout/activity_comment_full_markdown.xml
@@ -14,7 +14,6 @@
android:theme="@style/AppTheme.AppBarOverlay">
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_wiki.xml b/app/src/main/res/layout/activity_wiki.xml
new file mode 100644
index 00000000..0a09d748
--- /dev/null
+++ b/app/src/main/res/layout/activity_wiki.xml
@@ -0,0 +1,43 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index e50763db..e5da66e3 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -42,6 +42,7 @@
RPAN
Gallery Post
Trending
+ Wiki
Open navigation drawer
Close navigation drawer