2020-12-26 12:10:54 +01:00
|
|
|
package com.h.pixeldroid.posts
|
|
|
|
|
|
|
|
import android.content.Context
|
|
|
|
import android.os.Build
|
|
|
|
import android.text.Html
|
|
|
|
import android.text.SpannableStringBuilder
|
|
|
|
import android.text.Spanned
|
|
|
|
import android.text.style.ClickableSpan
|
|
|
|
import android.text.style.URLSpan
|
|
|
|
import android.util.Log
|
|
|
|
import android.view.View
|
|
|
|
import android.widget.TextView
|
|
|
|
import android.widget.Toast
|
|
|
|
import androidx.core.text.toSpanned
|
2020-12-29 22:14:32 +01:00
|
|
|
import androidx.lifecycle.LifecycleCoroutineScope
|
2020-12-26 12:10:54 +01:00
|
|
|
import com.h.pixeldroid.R
|
|
|
|
import com.h.pixeldroid.utils.api.PixelfedAPI
|
2020-12-29 22:14:32 +01:00
|
|
|
import com.h.pixeldroid.utils.api.objects.Account.Companion.openAccountFromId
|
2020-12-26 12:10:54 +01:00
|
|
|
import com.h.pixeldroid.utils.api.objects.Mention
|
2021-04-19 11:43:14 +02:00
|
|
|
import com.h.pixeldroid.utils.db.AppDatabase
|
|
|
|
import com.h.pixeldroid.utils.di.PixelfedAPIHolder
|
2020-12-26 12:10:54 +01:00
|
|
|
import java.net.URI
|
|
|
|
import java.net.URISyntaxException
|
|
|
|
import java.text.ParseException
|
|
|
|
import java.util.*
|
|
|
|
|
|
|
|
fun fromHtml(html: String): Spanned {
|
|
|
|
val result: Spanned = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
|
|
|
Html.fromHtml(html, Html.FROM_HTML_MODE_LEGACY)
|
|
|
|
} else {
|
|
|
|
@Suppress("DEPRECATION")
|
|
|
|
Html.fromHtml(html)
|
|
|
|
}
|
|
|
|
return result.trim().toSpanned()
|
|
|
|
}
|
|
|
|
|
|
|
|
fun getDomain(urlString: String?): String {
|
|
|
|
val uri: URI
|
|
|
|
try {
|
|
|
|
uri = URI(urlString!!)
|
|
|
|
} catch (e: URISyntaxException) {
|
|
|
|
return ""
|
|
|
|
}
|
|
|
|
val host: String = uri.host
|
|
|
|
return if (host.startsWith("www.")) {
|
|
|
|
host.substring(4)
|
|
|
|
} else {
|
|
|
|
host
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fun parseHTMLText(
|
2021-04-19 11:43:14 +02:00
|
|
|
text: String,
|
|
|
|
mentions: List<Mention>?,
|
|
|
|
apiHolder: PixelfedAPIHolder,
|
|
|
|
context: Context,
|
|
|
|
lifecycleScope: LifecycleCoroutineScope,
|
|
|
|
db: AppDatabase
|
2020-12-26 12:10:54 +01:00
|
|
|
) : Spanned {
|
|
|
|
//Convert text to spannable
|
|
|
|
val content = fromHtml(text)
|
|
|
|
|
|
|
|
//Retrive all links that should be made clickable
|
|
|
|
val builder = SpannableStringBuilder(content)
|
|
|
|
val urlSpans = content.getSpans(0, content.length, URLSpan::class.java)
|
|
|
|
|
|
|
|
for(span in urlSpans) {
|
|
|
|
val start = builder.getSpanStart(span)
|
|
|
|
val end = builder.getSpanEnd(span)
|
|
|
|
val flags = builder.getSpanFlags(span)
|
|
|
|
val text = builder.subSequence(start, end)
|
|
|
|
var customSpan: ClickableSpan? = null
|
|
|
|
|
|
|
|
//Handle hashtags
|
|
|
|
if (text[0] == '#') {
|
|
|
|
val tag = text.subSequence(1, text.length).toString()
|
|
|
|
customSpan = object : ClickableSpanNoUnderline() {
|
|
|
|
override fun onClick(widget: View) {
|
|
|
|
Toast.makeText(context, tag, Toast.LENGTH_SHORT).show()
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//Handle mentions
|
|
|
|
if(text[0] == '@' && !mentions.isNullOrEmpty()) {
|
|
|
|
val accountUsername = text.subSequence(1, text.length).toString()
|
|
|
|
var id: String? = null
|
|
|
|
|
|
|
|
//Go through all mentions stored in the status
|
|
|
|
for (mention in mentions) {
|
|
|
|
if (mention.username.equals(accountUsername, ignoreCase = true)
|
|
|
|
) {
|
|
|
|
id = mention.id
|
|
|
|
|
|
|
|
//Mentions can be of users in other domains
|
|
|
|
if (mention.url.contains(getDomain(span.url))) {
|
|
|
|
break
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//Check that we found a user for the given mention
|
|
|
|
if (id != null) {
|
|
|
|
val accountId: String = id
|
|
|
|
customSpan = object : ClickableSpanNoUnderline() {
|
|
|
|
override fun onClick(widget: View) {
|
|
|
|
Log.e("MENTION", "CLICKED")
|
|
|
|
//Retrieve the account for the given profile
|
2020-12-29 22:14:32 +01:00
|
|
|
lifecycleScope.launchWhenCreated {
|
2021-04-19 11:43:14 +02:00
|
|
|
val api: PixelfedAPI = apiHolder.api ?: apiHolder.setDomainToCurrentUser(db)
|
2021-04-18 23:43:47 +02:00
|
|
|
openAccountFromId(accountId, api, context)
|
2020-12-29 22:14:32 +01:00
|
|
|
}
|
2020-12-26 12:10:54 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
builder.removeSpan(span)
|
|
|
|
builder.setSpan(customSpan, start, end, flags)
|
|
|
|
|
|
|
|
// Add zero-width space after links in end of line to fix its too large hitbox.
|
|
|
|
if (end >= builder.length || builder.subSequence(end, end + 1).toString() == "\n") {
|
|
|
|
builder.insert(end, "\u200B")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return builder
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fun setTextViewFromISO8601(date: Date, textView: TextView, absoluteTime: Boolean, context: Context) {
|
|
|
|
val now = Date().time
|
|
|
|
|
|
|
|
try {
|
|
|
|
val then = date.time
|
|
|
|
val formattedDate = android.text.format.DateUtils
|
|
|
|
.getRelativeTimeSpanString(then, now,
|
|
|
|
android.text.format.DateUtils.SECOND_IN_MILLIS,
|
|
|
|
android.text.format.DateUtils.FORMAT_ABBREV_RELATIVE)
|
|
|
|
|
|
|
|
textView.text = if(absoluteTime) context.getString(R.string.posted_on).format(date)
|
|
|
|
else "$formattedDate"
|
|
|
|
|
|
|
|
} catch (e: ParseException) {
|
|
|
|
e.printStackTrace()
|
|
|
|
}
|
|
|
|
}
|