Better markdown handling

This commit fixes some of the issues with markdown rendering:
- Switch to Textview instead of RecyclerView to render Markdown
- Import Spoiler renderer from Jebora
- Import Script renderer from Jebora
- Clean out markwon plugins that were specific to reddit

Closes #130 #172 #217 and #273
This commit is contained in:
Bazsalanszky 2024-08-09 12:45:15 +02:00
parent c1c8d99de2
commit 767e75b798
13 changed files with 235 additions and 64 deletions

View File

@ -245,6 +245,7 @@ dependencies {
implementation "io.noties.markwon:simple-ext:$markwonVersion" implementation "io.noties.markwon:simple-ext:$markwonVersion"
implementation "io.noties.markwon:inline-parser:$markwonVersion" implementation "io.noties.markwon:inline-parser:$markwonVersion"
implementation "io.noties.markwon:image-glide:$markwonVersion" implementation "io.noties.markwon:image-glide:$markwonVersion"
implementation "io.noties.markwon:html:$markwonVersion"
implementation 'com.atlassian.commonmark:commonmark-ext-gfm-tables:0.14.0' implementation 'com.atlassian.commonmark:commonmark-ext-gfm-tables:0.14.0'
implementation 'me.saket:better-link-movement-method:2.2.0' implementation 'me.saket:better-link-movement-method:2.2.0'

View File

@ -681,10 +681,7 @@ public class PostDetailRecyclerViewAdapter extends RecyclerView.Adapter<Recycler
if (mPost.getSelfText() != null && !mPost.getSelfText().equals("")) { if (mPost.getSelfText() != null && !mPost.getSelfText().equals("")) {
((PostDetailBaseViewHolder) holder).contentMarkdownView.setVisibility(View.VISIBLE); ((PostDetailBaseViewHolder) holder).contentMarkdownView.setVisibility(View.VISIBLE);
((PostDetailBaseViewHolder) holder).contentMarkdownView.setAdapter(mMarkwonAdapter); mPostDetailMarkwon.setMarkdown(((PostDetailBaseViewHolder) holder).contentMarkdownView,mPost.getSelfText());
mMarkwonAdapter.setMarkdown(mPostDetailMarkwon, mPost.getSelfText());
// noinspection NotifyDataSetChanged
mMarkwonAdapter.notifyDataSetChanged();
} }
if (holder instanceof PostDetailBaseVideoAutoplayViewHolder) { if (holder instanceof PostDetailBaseVideoAutoplayViewHolder) {
@ -1216,7 +1213,7 @@ public class PostDetailRecyclerViewAdapter extends RecyclerView.Adapter<Recycler
CustomTextView flairTextView; CustomTextView flairTextView;
TextView awardsTextView; TextView awardsTextView;
TextView upvoteRatioTextView; TextView upvoteRatioTextView;
RecyclerView contentMarkdownView; TextView contentMarkdownView;
ConstraintLayout bottomConstraintLayout; ConstraintLayout bottomConstraintLayout;
MaterialButton upvoteButton; MaterialButton upvoteButton;
TextView scoreTextView; TextView scoreTextView;
@ -1248,7 +1245,7 @@ public class PostDetailRecyclerViewAdapter extends RecyclerView.Adapter<Recycler
CustomTextView flairTextView, CustomTextView flairTextView,
TextView awardsTextView, TextView awardsTextView,
TextView upvoteRatioTextView, TextView upvoteRatioTextView,
RecyclerView contentMarkdownView, TextView contentMarkdownView,
ConstraintLayout bottomConstraintLayout, ConstraintLayout bottomConstraintLayout,
MaterialButton upvoteButton, MaterialButton upvoteButton,
TextView scoreTextView, TextView scoreTextView,
@ -1344,7 +1341,7 @@ public class PostDetailRecyclerViewAdapter extends RecyclerView.Adapter<Recycler
mActivity.startActivity(intent); mActivity.startActivity(intent);
}); });
contentMarkdownView.setLayoutManager(new SwipeLockLinearLayoutManager(mActivity, new SwipeLockInterface() { /*contentMarkdownView.setLayoutManager(new SwipeLockLinearLayoutManager(mActivity, new SwipeLockInterface() {
@Override @Override
public void lockSwipe() { public void lockSwipe() {
((ViewPostDetailActivity) mActivity).lockSwipeRightToGoBack(); ((ViewPostDetailActivity) mActivity).lockSwipeRightToGoBack();
@ -1354,7 +1351,7 @@ public class PostDetailRecyclerViewAdapter extends RecyclerView.Adapter<Recycler
public void unlockSwipe() { public void unlockSwipe() {
((ViewPostDetailActivity) mActivity).unlockSwipeRightToGoBack(); ((ViewPostDetailActivity) mActivity).unlockSwipeRightToGoBack();
} }
})); }));*/
upvoteButton.setOnClickListener(view -> { upvoteButton.setOnClickListener(view -> {
if (mPost.isArchived()) { if (mPost.isArchived()) {
@ -1827,7 +1824,7 @@ public class PostDetailRecyclerViewAdapter extends RecyclerView.Adapter<Recycler
ImageView pauseButton, ImageView pauseButton,
ImageView playButton, ImageView playButton,
DefaultTimeBar progressBar, DefaultTimeBar progressBar,
RecyclerView contentMarkdownView, TextView contentMarkdownView,
ConstraintLayout bottomConstraintLayout, ConstraintLayout bottomConstraintLayout,
MaterialButton upvoteButton, MaterialButton upvoteButton,
TextView scoreTextView, TextView scoreTextView,

View File

@ -18,6 +18,8 @@ import eu.toldi.infinityforlemmy.customviews.CustomMarkwonAdapter;
import io.noties.markwon.Markwon; import io.noties.markwon.Markwon;
import io.noties.markwon.MarkwonPlugin; import io.noties.markwon.MarkwonPlugin;
import io.noties.markwon.ext.strikethrough.StrikethroughPlugin; import io.noties.markwon.ext.strikethrough.StrikethroughPlugin;
import io.noties.markwon.ext.tables.TablePlugin;
import io.noties.markwon.html.HtmlPlugin;
import io.noties.markwon.image.glide.GlideImagesPlugin; import io.noties.markwon.image.glide.GlideImagesPlugin;
import io.noties.markwon.inlineparser.BangInlineProcessor; import io.noties.markwon.inlineparser.BangInlineProcessor;
import io.noties.markwon.inlineparser.HtmlInlineProcessor; import io.noties.markwon.inlineparser.HtmlInlineProcessor;
@ -44,35 +46,27 @@ public class MarkdownUtils {
Markwon result; Markwon result;
if (dataSaverEnabled) { if (dataSaverEnabled) {
result = Markwon.builder(context) result = Markwon.builder(context)
.usePlugin(MarkwonInlineParserPlugin.create(plugin -> {
plugin.excludeInlineProcessor(HtmlInlineProcessor.class);
}))
.usePlugin(miscPlugin) .usePlugin(miscPlugin)
.usePlugin(SuperscriptPlugin.create()) .usePlugin(new ScriptRewriteSupportPlugin())
.usePlugin(SpoilerParserPlugin.create(markdownColor, spoilerBackgroundColor)) .usePlugin(new MarkwonSpoilerPlugin(true))
.usePlugin(RedditHeadingPlugin.create()) .usePlugin(HtmlPlugin.create())
.usePlugin(StrikethroughPlugin.create()) .usePlugin(StrikethroughPlugin.create())
.usePlugin(MovementMethodPlugin.create(new SpoilerAwareMovementMethod() .usePlugin(TablePlugin.create(context))
.setOnLinkLongClickListener(onLinkLongClickListener)))
.usePlugin(LinkifyPlugin.create(Linkify.WEB_URLS)) .usePlugin(LinkifyPlugin.create(Linkify.WEB_URLS))
.usePlugin(TableEntryPlugin.create(context))
.usePlugin(new MarkwonLemmyLinkPlugin()) .usePlugin(new MarkwonLemmyLinkPlugin())
.build(); .build();
} else { } else {
result = Markwon.builder(context) result = Markwon.builder(context)
.usePlugin(GlideImagesPlugin.create(new GlideMarkdownLoader(mGlide))) .usePlugin(GlideImagesPlugin.create(new GlideMarkdownLoader(mGlide)))
.usePlugin(MarkwonInlineParserPlugin.create(plugin -> {
plugin.excludeInlineProcessor(HtmlInlineProcessor.class);
}))
.usePlugin(miscPlugin) .usePlugin(miscPlugin)
.usePlugin(SuperscriptPlugin.create()) .usePlugin(new ScriptRewriteSupportPlugin())
.usePlugin(SpoilerParserPlugin.create(markdownColor, spoilerBackgroundColor)) .usePlugin(new MarkwonSpoilerPlugin(true))
.usePlugin(RedditHeadingPlugin.create()) .usePlugin(HtmlPlugin.create())
.usePlugin(StrikethroughPlugin.create()) .usePlugin(StrikethroughPlugin.create())
.usePlugin(MovementMethodPlugin.create(new SpoilerAwareMovementMethod() .usePlugin(MovementMethodPlugin.create(new SpoilerAwareMovementMethod()
.setOnLinkLongClickListener(onLinkLongClickListener))) .setOnLinkLongClickListener(onLinkLongClickListener)))
.usePlugin(LinkifyPlugin.create(Linkify.WEB_URLS)) .usePlugin(LinkifyPlugin.create(Linkify.WEB_URLS))
.usePlugin(TableEntryPlugin.create(context)) .usePlugin(TablePlugin.create(context))
.usePlugin(ClickableGlideImagesPlugin.create(context)) .usePlugin(ClickableGlideImagesPlugin.create(context))
.usePlugin(new MarkwonLemmyLinkPlugin()) .usePlugin(new MarkwonLemmyLinkPlugin())
.build(); .build();
@ -87,32 +81,27 @@ public class MarkdownUtils {
Markwon result; Markwon result;
if (dataSaverEnabled) { if (dataSaverEnabled) {
result = Markwon.builder(context) result = Markwon.builder(context)
.usePlugin(MarkwonInlineParserPlugin.create(plugin -> {
plugin.excludeInlineProcessor(HtmlInlineProcessor.class);
}))
.usePlugin(miscPlugin) .usePlugin(miscPlugin)
.usePlugin(SuperscriptPlugin.create()) .usePlugin(new ScriptRewriteSupportPlugin())
.usePlugin(RedditHeadingPlugin.create()) .usePlugin(new MarkwonSpoilerPlugin(true))
.usePlugin(HtmlPlugin.create())
.usePlugin(StrikethroughPlugin.create()) .usePlugin(StrikethroughPlugin.create())
.usePlugin(MovementMethodPlugin.create(new SpoilerAwareMovementMethod() .usePlugin(MovementMethodPlugin.create(new SpoilerAwareMovementMethod()
.setOnLinkLongClickListener(onLinkLongClickListener))) .setOnLinkLongClickListener(onLinkLongClickListener)))
.usePlugin(LinkifyPlugin.create(Linkify.WEB_URLS)) .usePlugin(LinkifyPlugin.create(Linkify.WEB_URLS))
.usePlugin(TableEntryPlugin.create(context)) .usePlugin(TablePlugin.create(context))
.usePlugin(new MarkwonLemmyLinkPlugin()) .usePlugin(new MarkwonLemmyLinkPlugin())
.build(); .build();
} else { } else {
result = Markwon.builder(context) result = Markwon.builder(context)
.usePlugin(MarkwonInlineParserPlugin.create(plugin -> {
plugin.excludeInlineProcessor(HtmlInlineProcessor.class);
}))
.usePlugin(miscPlugin) .usePlugin(miscPlugin)
.usePlugin(SuperscriptPlugin.create()) .usePlugin(new ScriptRewriteSupportPlugin())
.usePlugin(RedditHeadingPlugin.create()) .usePlugin(new MarkwonSpoilerPlugin(true))
.usePlugin(StrikethroughPlugin.create()) .usePlugin(HtmlPlugin.create())
.usePlugin(MovementMethodPlugin.create(new SpoilerAwareMovementMethod() .usePlugin(MovementMethodPlugin.create(new SpoilerAwareMovementMethod()
.setOnLinkLongClickListener(onLinkLongClickListener))) .setOnLinkLongClickListener(onLinkLongClickListener)))
.usePlugin(LinkifyPlugin.create(Linkify.WEB_URLS)) .usePlugin(LinkifyPlugin.create(Linkify.WEB_URLS))
.usePlugin(TableEntryPlugin.create(context)) .usePlugin(TablePlugin.create(context))
.usePlugin(GlideImagesPlugin.create(context.getApplicationContext())) .usePlugin(GlideImagesPlugin.create(context.getApplicationContext()))
.usePlugin(new MarkwonLemmyLinkPlugin()) .usePlugin(new MarkwonLemmyLinkPlugin())
.build(); .build();

View File

@ -0,0 +1,158 @@
package eu.toldi.infinityforlemmy.markdown
import android.text.SpannableStringBuilder
import android.text.Spanned
import android.text.TextPaint
import android.text.style.ClickableSpan
import android.util.Log
import android.view.View
import android.widget.TextView
import io.noties.markwon.AbstractMarkwonPlugin
import io.noties.markwon.MarkwonPlugin
import io.noties.markwon.MarkwonVisitor
import io.noties.markwon.core.CorePlugin
import io.noties.markwon.image.AsyncDrawableScheduler
// Source copied from https://github.com/LemmyNet/jerboa/blob/main/app/src/main/java/com/jerboa/util/markwon/MarkwonSpoilerPlugin.kt
data class SpoilerTitleSpan(
val title: CharSequence,
)
class SpoilerCloseSpan
class MarkwonSpoilerPlugin(
val enableInteraction: Boolean,
) : AbstractMarkwonPlugin() {
override fun configure(registry: MarkwonPlugin.Registry) {
registry.require(CorePlugin::class.java) {
it.addOnTextAddedListener(
SpoilerTextAddedListener(),
)
}
}
private class SpoilerTextAddedListener : CorePlugin.OnTextAddedListener {
override fun onTextAdded(
visitor: MarkwonVisitor,
text: String,
start: Int,
) {
val spoilerTitleRegex = Regex("(:::\\s+spoiler\\s+)(.*)")
// Find all spoiler "start" lines
val spoilerTitles = spoilerTitleRegex.findAll(text)
for (match in spoilerTitles) {
val spoilerTitle = match.groups[2]!!.value
visitor.builder().setSpan(
SpoilerTitleSpan(spoilerTitle),
start,
start + match.groups[2]!!.range.last,
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE,
)
}
val spoilerCloseRegex = Regex("^(?!.*spoiler).*:::")
// Find all spoiler "end" lines
val spoilerCloses = spoilerCloseRegex.findAll(text)
for (match in spoilerCloses) {
visitor
.builder()
.setSpan(SpoilerCloseSpan(), start, start + 3, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
}
}
}
override fun afterSetText(textView: TextView) {
try {
val spanned = SpannableStringBuilder(textView.text)
val spoilerTitleSpans =
spanned.getSpans(0, spanned.length, SpoilerTitleSpan::class.java)
val spoilerCloseSpans =
spanned.getSpans(0, spanned.length, SpoilerCloseSpan::class.java)
spoilerTitleSpans.sortBy { spanned.getSpanStart(it) }
spoilerCloseSpans.sortBy { spanned.getSpanStart(it) }
spoilerTitleSpans.forEachIndexed { index, spoilerTitleSpan ->
val spoilerStart = spanned.getSpanStart(spoilerTitleSpan)
var spoilerEnd = spanned.length
if (index < spoilerCloseSpans.size) {
val spoilerCloseSpan = spoilerCloseSpans[index]
spoilerEnd = spanned.getSpanEnd(spoilerCloseSpan)
}
var open = false
// The space at the end is necessary for the lengths to be the same
// This reduces complexity as else it would need complex logic to determine the replacement length
val getSpoilerTitle = { openParam: Boolean ->
if (openParam) "${spoilerTitleSpan.title}\n" else "${spoilerTitleSpan.title}\u200B"
}
val spoilerTitle = getSpoilerTitle(false)
val spoilerContent =
spanned.subSequence(
spanned.getSpanEnd(spoilerTitleSpan) + 1,
spoilerEnd - 3,
) as SpannableStringBuilder
// Remove spoiler content from span
spanned.replace(spoilerStart, spoilerEnd, spoilerTitle)
// Set span block title
spanned.setSpan(
spoilerTitle,
spoilerStart,
spoilerStart + spoilerTitle.length,
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE,
)
val wrapper =
object : ClickableSpan() {
override fun onClick(p0: View) {
if (enableInteraction) {
textView.cancelPendingInputEvents()
open = !open
val spoilerStartCurrent = spanned.getSpanStart(spoilerTitle)
spanned.replace(
spoilerStartCurrent,
spoilerStartCurrent + spoilerTitle.length,
getSpoilerTitle(open),
)
if (open) {
spanned.insert(spoilerStartCurrent + spoilerTitle.length, spoilerContent)
} else {
spanned.replace(
spoilerStartCurrent + spoilerTitle.length,
spoilerStartCurrent + spoilerTitle.length + spoilerContent.length,
"",
)
}
textView.text = spanned
AsyncDrawableScheduler.schedule(textView)
}
}
override fun updateDrawState(ds: TextPaint) {
}
}
// Set spoiler block type as ClickableSpan
spanned.setSpan(
wrapper,
spoilerStart,
spoilerStart + spoilerTitle.length,
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE,
)
textView.text = spanned
}
} catch (e: Exception) {
Log.w("jerboa", "Failed to parse spoiler tag. Format incorrect")
}
}
}

View File

@ -0,0 +1,26 @@
package eu.toldi.infinityforlemmy.markdown
import io.noties.markwon.AbstractMarkwonPlugin
// Source copied from https://github.com/LemmyNet/jerboa/blob/main/app/src/main/java/com/jerboa/util/markwon/ScriptRewriteSupportPlugin.kt
class ScriptRewriteSupportPlugin : AbstractMarkwonPlugin() {
override fun processMarkdown(markdown: String): String =
super.processMarkdown(
if (markdown.contains("^") || markdown.contains("~")) {
rewriteLemmyScriptToMarkwonScript(markdown)
} else { // Fast path: if there are no markdown characters, we don't need to do anything
markdown
},
)
companion object {
val SUPERSCRIPT_RGX = Regex("""\^([^\n^]+)\^""")
val SUBSCRIPT_RGX = Regex("""(?<!~)~([^\n~]+)~""")
fun rewriteLemmyScriptToMarkwonScript(text: String): String =
text
.replace(SUPERSCRIPT_RGX, "<sup>$1</sup>")
.replace(SUBSCRIPT_RGX, "<sub>$1</sub>")
}
}

View File

@ -256,13 +256,13 @@
android:src="@drawable/ic_link" android:src="@drawable/ic_link"
android:visibility="gone" /> android:visibility="gone" />
<androidx.recyclerview.widget.RecyclerView <TextView
android:id="@+id/content_markdown_view_item_post_detail_gallery" android:id="@+id/content_markdown_view_item_post_detail_gallery"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_marginTop="8dp" android:layout_marginTop="8dp"
android:layout_marginStart="8dp" android:layout_marginStart="16dp"
android:layout_marginEnd="8dp" android:layout_marginEnd="16dp"
android:visibility="gone" android:visibility="gone"
android:nestedScrollingEnabled="false" /> android:nestedScrollingEnabled="false" />

View File

@ -262,13 +262,13 @@
</RelativeLayout> </RelativeLayout>
<androidx.recyclerview.widget.RecyclerView <TextView
android:id="@+id/content_markdown_view_item_post_detail_image_and_gif_autoplay" android:id="@+id/content_markdown_view_item_post_detail_image_and_gif_autoplay"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_marginTop="8dp" android:layout_marginTop="8dp"
android:layout_marginStart="8dp" android:layout_marginStart="16dp"
android:layout_marginEnd="8dp" android:layout_marginEnd="16dp"
android:visibility="gone" android:visibility="gone"
android:nestedScrollingEnabled="false" /> android:nestedScrollingEnabled="false" />

View File

@ -271,13 +271,13 @@
</RelativeLayout> </RelativeLayout>
<androidx.recyclerview.widget.RecyclerView <TextView
android:id="@+id/content_markdown_view_item_post_detail_link" android:id="@+id/content_markdown_view_item_post_detail_link"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_marginTop="8dp" android:layout_marginTop="8dp"
android:layout_marginStart="8dp" android:layout_marginStart="16dp"
android:layout_marginEnd="8dp" android:layout_marginEnd="16dp"
android:visibility="gone" android:visibility="gone"
android:nestedScrollingEnabled="false" /> android:nestedScrollingEnabled="false" />

View File

@ -106,17 +106,17 @@
android:focusable="true" android:focusable="true"
android:longClickable="true" /> android:longClickable="true" />
<androidx.recyclerview.widget.RecyclerView <TextView
android:id="@+id/content_markdown_view_item_post_detail_no_preview" android:id="@+id/content_markdown_view_item_post_detail_no_preview"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_marginTop="8dp" android:layout_marginTop="8dp"
android:layout_marginStart="8dp" android:layout_marginStart="16dp"
android:layout_marginEnd="8dp" android:layout_marginEnd="16dp"
android:visibility="gone" android:visibility="gone"
android:nestedScrollingEnabled="false" > android:nestedScrollingEnabled="false" >
</androidx.recyclerview.widget.RecyclerView> </TextView>
<androidx.constraintlayout.widget.ConstraintLayout <androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent" android:layout_width="match_parent"

View File

@ -106,17 +106,17 @@
android:textIsSelectable="true" android:textIsSelectable="true"
android:textSize="?attr/title_font_18" /> android:textSize="?attr/title_font_18" />
<androidx.recyclerview.widget.RecyclerView <TextView
android:id="@+id/content_markdown_view_item_post_detail_text" android:id="@+id/content_markdown_view_item_post_detail_text"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_marginTop="8dp" android:layout_marginTop="8dp"
android:layout_marginStart="8dp" android:layout_marginStart="16dp"
android:layout_marginEnd="8dp" android:layout_marginEnd="16dp"
android:visibility="gone" android:visibility="gone"
android:nestedScrollingEnabled="false" > android:nestedScrollingEnabled="false" >
</androidx.recyclerview.widget.RecyclerView> </TextView>
<androidx.constraintlayout.widget.ConstraintLayout <androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent" android:layout_width="match_parent"

View File

@ -274,13 +274,13 @@
</RelativeLayout> </RelativeLayout>
<androidx.recyclerview.widget.RecyclerView <TextView
android:id="@+id/content_markdown_view_item_post_detail_video_and_gif_preview" android:id="@+id/content_markdown_view_item_post_detail_video_and_gif_preview"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_marginTop="8dp" android:layout_marginTop="8dp"
android:layout_marginStart="8dp" android:layout_marginStart="16dp"
android:layout_marginEnd="8dp" android:layout_marginEnd="16dp"
android:visibility="gone" android:visibility="gone"
android:nestedScrollingEnabled="false" /> android:nestedScrollingEnabled="false" />

View File

@ -255,13 +255,13 @@
</com.google.android.exoplayer2.ui.AspectRatioFrameLayout> </com.google.android.exoplayer2.ui.AspectRatioFrameLayout>
<androidx.recyclerview.widget.RecyclerView <TextView
android:id="@+id/content_markdown_view_item_post_detail_video_autoplay" android:id="@+id/content_markdown_view_item_post_detail_video_autoplay"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_marginTop="8dp" android:layout_marginTop="8dp"
android:layout_marginStart="8dp" android:layout_marginStart="16dp"
android:layout_marginEnd="8dp" android:layout_marginEnd="16dp"
android:visibility="gone" android:visibility="gone"
android:nestedScrollingEnabled="false" /> android:nestedScrollingEnabled="false" />

View File

@ -258,13 +258,13 @@
</com.google.android.exoplayer2.ui.AspectRatioFrameLayout> </com.google.android.exoplayer2.ui.AspectRatioFrameLayout>
<androidx.recyclerview.widget.RecyclerView <TextView
android:id="@+id/content_markdown_view_item_post_detail_video_autoplay" android:id="@+id/content_markdown_view_item_post_detail_video_autoplay"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_marginTop="8dp" android:layout_marginTop="8dp"
android:layout_marginStart="8dp" android:layout_marginStart="16dp"
android:layout_marginEnd="8dp" android:layout_marginEnd="16dp"
android:visibility="gone" android:visibility="gone"
android:nestedScrollingEnabled="false" /> android:nestedScrollingEnabled="false" />