mirror of
https://github.com/libre-tube/LibreTube.git
synced 2025-04-29 16:30:31 +05:30
Fixed #2670 : Timestamp click behaviour in the description.
This commit is contained in:
parent
0ee5753e91
commit
6d322bf9f7
@ -76,7 +76,6 @@ import com.github.libretube.ui.dialogs.AddToPlaylistDialog
|
|||||||
import com.github.libretube.ui.dialogs.DownloadDialog
|
import com.github.libretube.ui.dialogs.DownloadDialog
|
||||||
import com.github.libretube.ui.dialogs.ShareDialog
|
import com.github.libretube.ui.dialogs.ShareDialog
|
||||||
import com.github.libretube.ui.extensions.setAspectRatio
|
import com.github.libretube.ui.extensions.setAspectRatio
|
||||||
import com.github.libretube.ui.extensions.setFormattedHtml
|
|
||||||
import com.github.libretube.ui.extensions.setupSubscriptionButton
|
import com.github.libretube.ui.extensions.setupSubscriptionButton
|
||||||
import com.github.libretube.ui.interfaces.OnlinePlayerOptions
|
import com.github.libretube.ui.interfaces.OnlinePlayerOptions
|
||||||
import com.github.libretube.ui.models.CommentsViewModel
|
import com.github.libretube.ui.models.CommentsViewModel
|
||||||
@ -84,7 +83,19 @@ import com.github.libretube.ui.models.PlayerViewModel
|
|||||||
import com.github.libretube.ui.sheets.BaseBottomSheet
|
import com.github.libretube.ui.sheets.BaseBottomSheet
|
||||||
import com.github.libretube.ui.sheets.CommentsSheet
|
import com.github.libretube.ui.sheets.CommentsSheet
|
||||||
import com.github.libretube.ui.sheets.PlayingQueueSheet
|
import com.github.libretube.ui.sheets.PlayingQueueSheet
|
||||||
import com.github.libretube.util.*
|
import com.github.libretube.util.BackgroundHelper
|
||||||
|
import com.github.libretube.util.DashHelper
|
||||||
|
import com.github.libretube.util.DataSaverMode
|
||||||
|
import com.github.libretube.util.HtmlParser
|
||||||
|
import com.github.libretube.util.ImageHelper
|
||||||
|
import com.github.libretube.util.LinkHandler
|
||||||
|
import com.github.libretube.util.NavigationHelper
|
||||||
|
import com.github.libretube.util.NowPlayingNotification
|
||||||
|
import com.github.libretube.util.PlayerHelper
|
||||||
|
import com.github.libretube.util.PlayingQueue
|
||||||
|
import com.github.libretube.util.PreferenceHelper
|
||||||
|
import com.github.libretube.util.SeekbarPreviewListener
|
||||||
|
import com.github.libretube.util.TextUtils
|
||||||
import com.google.android.exoplayer2.C
|
import com.google.android.exoplayer2.C
|
||||||
import com.google.android.exoplayer2.DefaultLoadControl
|
import com.google.android.exoplayer2.DefaultLoadControl
|
||||||
import com.google.android.exoplayer2.ExoPlayer
|
import com.google.android.exoplayer2.ExoPlayer
|
||||||
@ -1026,7 +1037,11 @@ class PlayerFragment : BaseFragment(), OnlinePlayerOptions {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setupDescription(descTextView: TextView, description: String, exoPlayer: ExoPlayer) {
|
private fun setupDescription(
|
||||||
|
descTextView: TextView,
|
||||||
|
description: String,
|
||||||
|
exoPlayer: ExoPlayer
|
||||||
|
) {
|
||||||
// detect whether the description is html formatted
|
// detect whether the description is html formatted
|
||||||
if (description.contains("<") && description.contains(">")) {
|
if (description.contains("<") && description.contains(">")) {
|
||||||
descTextView.movementMethod = LinkMovementMethod.getInstance()
|
descTextView.movementMethod = LinkMovementMethod.getInstance()
|
||||||
@ -1065,7 +1080,6 @@ class PlayerFragment : BaseFragment(), OnlinePlayerOptions {
|
|||||||
val intent = Intent(Intent.ACTION_VIEW, Uri.parse(link))
|
val intent = Intent(Intent.ACTION_VIEW, Uri.parse(link))
|
||||||
startActivity(intent)
|
startActivity(intent)
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// not a youtube link
|
// not a youtube link
|
||||||
// handle normally
|
// handle normally
|
||||||
|
@ -4,10 +4,15 @@ import android.text.Editable
|
|||||||
import android.text.Html
|
import android.text.Html
|
||||||
import android.text.Spanned
|
import android.text.Spanned
|
||||||
import androidx.core.text.HtmlCompat
|
import androidx.core.text.HtmlCompat
|
||||||
import org.xml.sax.*
|
import org.xml.sax.Attributes
|
||||||
import java.util.*
|
import org.xml.sax.ContentHandler
|
||||||
|
import org.xml.sax.Locator
|
||||||
|
import org.xml.sax.SAXException
|
||||||
|
import org.xml.sax.XMLReader
|
||||||
|
|
||||||
class HtmlParser private constructor(private val handler: TagHandler) : Html.TagHandler, ContentHandler {
|
class HtmlParser private constructor(private val handler: TagHandler) :
|
||||||
|
Html.TagHandler,
|
||||||
|
ContentHandler {
|
||||||
private val tagStatus = ArrayDeque<Boolean>()
|
private val tagStatus = ArrayDeque<Boolean>()
|
||||||
private var wrapped: ContentHandler? = null
|
private var wrapped: ContentHandler? = null
|
||||||
private var text: Editable? = null
|
private var text: Editable? = null
|
||||||
@ -27,7 +32,13 @@ class HtmlParser private constructor(private val handler: TagHandler) : Html.Tag
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Throws(SAXException::class) override fun startElement(uri: String, localName: String, qName: String, attributes: Attributes) {
|
@Throws(SAXException::class)
|
||||||
|
override fun startElement(
|
||||||
|
uri: String,
|
||||||
|
localName: String,
|
||||||
|
qName: String,
|
||||||
|
attributes: Attributes
|
||||||
|
) {
|
||||||
val isHandled = handler.handleTag(true, localName, text, attributes)
|
val isHandled = handler.handleTag(true, localName, text, attributes)
|
||||||
tagStatus.addLast(isHandled)
|
tagStatus.addLast(isHandled)
|
||||||
if (!isHandled) {
|
if (!isHandled) {
|
||||||
@ -35,7 +46,8 @@ class HtmlParser private constructor(private val handler: TagHandler) : Html.Tag
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Throws(SAXException::class) override fun endElement(uri: String, localName: String, qName: String) {
|
@Throws(SAXException::class)
|
||||||
|
override fun endElement(uri: String, localName: String, qName: String) {
|
||||||
if (!tagStatus.removeLast()) {
|
if (!tagStatus.removeLast()) {
|
||||||
wrapped?.endElement(uri, localName, qName)
|
wrapped?.endElement(uri, localName, qName)
|
||||||
}
|
}
|
||||||
@ -46,47 +58,65 @@ class HtmlParser private constructor(private val handler: TagHandler) : Html.Tag
|
|||||||
wrapped?.setDocumentLocator(locator)
|
wrapped?.setDocumentLocator(locator)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Throws(SAXException::class) override fun startDocument() {
|
@Throws(SAXException::class)
|
||||||
|
override fun startDocument() {
|
||||||
wrapped?.startDocument()
|
wrapped?.startDocument()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Throws(SAXException::class) override fun endDocument() {
|
@Throws(SAXException::class)
|
||||||
|
override fun endDocument() {
|
||||||
wrapped?.endDocument()
|
wrapped?.endDocument()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Throws(SAXException::class) override fun startPrefixMapping(prefix: String, uri: String) {
|
@Throws(SAXException::class)
|
||||||
|
override fun startPrefixMapping(prefix: String, uri: String) {
|
||||||
wrapped?.startPrefixMapping(prefix, uri)
|
wrapped?.startPrefixMapping(prefix, uri)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Throws(SAXException::class) override fun endPrefixMapping(prefix: String) {
|
@Throws(SAXException::class)
|
||||||
|
override fun endPrefixMapping(prefix: String) {
|
||||||
wrapped?.endPrefixMapping(prefix)
|
wrapped?.endPrefixMapping(prefix)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Throws(SAXException::class) override fun characters(ch: CharArray, start: Int, length: Int) {
|
@Throws(SAXException::class)
|
||||||
|
override fun characters(ch: CharArray, start: Int, length: Int) {
|
||||||
wrapped?.characters(ch, start, length)
|
wrapped?.characters(ch, start, length)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Throws(SAXException::class) override fun ignorableWhitespace(ch: CharArray, start: Int, length: Int) {
|
@Throws(SAXException::class)
|
||||||
|
override fun ignorableWhitespace(ch: CharArray, start: Int, length: Int) {
|
||||||
wrapped?.ignorableWhitespace(ch, start, length)
|
wrapped?.ignorableWhitespace(ch, start, length)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Throws(SAXException::class) override fun processingInstruction(target: String, data: String) {
|
@Throws(SAXException::class)
|
||||||
|
override fun processingInstruction(target: String, data: String) {
|
||||||
wrapped?.processingInstruction(target, data)
|
wrapped?.processingInstruction(target, data)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Throws(SAXException::class) override fun skippedEntity(name: String) {
|
@Throws(SAXException::class)
|
||||||
|
override fun skippedEntity(name: String) {
|
||||||
wrapped?.skippedEntity(name)
|
wrapped?.skippedEntity(name)
|
||||||
}
|
}
|
||||||
|
|
||||||
interface TagHandler {
|
interface TagHandler {
|
||||||
fun handleTag(opening: Boolean, tag: String?, output: Editable?, attributes: Attributes?): Boolean
|
fun handleTag(
|
||||||
|
opening: Boolean,
|
||||||
|
tag: String?,
|
||||||
|
output: Editable?,
|
||||||
|
attributes: Attributes?
|
||||||
|
): Boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
fun createSpannedText(html: String, handler: TagHandler): Spanned {
|
fun createSpannedText(html: String, handler: TagHandler): Spanned {
|
||||||
// add a tag at the start that is not handled by default,
|
// add a tag at the start that is not handled by default,
|
||||||
// allowing custom tag handler to replace xmlReader contentHandler
|
// allowing custom tag handler to replace xmlReader contentHandler
|
||||||
return HtmlCompat.fromHtml(html, HtmlCompat.FROM_HTML_MODE_LEGACY, null, HtmlParser(handler))
|
return HtmlCompat.fromHtml(
|
||||||
|
html,
|
||||||
|
HtmlCompat.FROM_HTML_MODE_LEGACY,
|
||||||
|
null,
|
||||||
|
HtmlParser(handler)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@JvmStatic fun getValue(attributes: Attributes, name: String): String? {
|
@JvmStatic fun getValue(attributes: Attributes, name: String): String? {
|
||||||
|
@ -4,7 +4,6 @@ import android.text.Editable
|
|||||||
import android.text.Spanned
|
import android.text.Spanned
|
||||||
import android.text.TextPaint
|
import android.text.TextPaint
|
||||||
import android.text.style.ClickableSpan
|
import android.text.style.ClickableSpan
|
||||||
import android.util.Log
|
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import com.github.libretube.util.HtmlParser.Companion.getValue
|
import com.github.libretube.util.HtmlParser.Companion.getValue
|
||||||
import org.xml.sax.Attributes
|
import org.xml.sax.Attributes
|
||||||
@ -12,7 +11,12 @@ import org.xml.sax.Attributes
|
|||||||
class LinkHandler(private val clickCallback: ((String) -> Unit)?) : HtmlParser.TagHandler {
|
class LinkHandler(private val clickCallback: ((String) -> Unit)?) : HtmlParser.TagHandler {
|
||||||
private var linkTagStartIndex = -1
|
private var linkTagStartIndex = -1
|
||||||
private var link: String? = null
|
private var link: String? = null
|
||||||
override fun handleTag(opening: Boolean, tag: String?, output: Editable?, attributes: Attributes?): Boolean {
|
override fun handleTag(
|
||||||
|
opening: Boolean,
|
||||||
|
tag: String?,
|
||||||
|
output: Editable?,
|
||||||
|
attributes: Attributes?
|
||||||
|
): Boolean {
|
||||||
if (output != null) {
|
if (output != null) {
|
||||||
if ("a" == tag) {
|
if ("a" == tag) {
|
||||||
if (opening && attributes != null) {
|
if (opening && attributes != null) {
|
||||||
@ -29,7 +33,8 @@ class LinkHandler(private val clickCallback: ((String) -> Unit)?) : HtmlParser.T
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun setLinkSpans(output: Editable, start: Int, end: Int, link: String?) {
|
private fun setLinkSpans(output: Editable, start: Int, end: Int, link: String?) {
|
||||||
output.setSpan(object : ClickableSpan() {
|
output.setSpan(
|
||||||
|
object : ClickableSpan() {
|
||||||
override fun onClick(widget: View) {
|
override fun onClick(widget: View) {
|
||||||
if (clickCallback != null && link != null) {
|
if (clickCallback != null && link != null) {
|
||||||
clickCallback.invoke(link)
|
clickCallback.invoke(link)
|
||||||
@ -40,6 +45,10 @@ class LinkHandler(private val clickCallback: ((String) -> Unit)?) : HtmlParser.T
|
|||||||
super.updateDrawState(ds)
|
super.updateDrawState(ds)
|
||||||
ds.isUnderlineText = false
|
ds.isUnderlineText = false
|
||||||
}
|
}
|
||||||
}, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
|
},
|
||||||
|
start,
|
||||||
|
end,
|
||||||
|
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user