mirror of
https://github.com/sudoxnym/habitica-android.git
synced 2026-05-20 12:49:02 +00:00
parent
a7311de300
commit
81a6a0c0a6
17 changed files with 95 additions and 86 deletions
|
|
@ -37,8 +37,6 @@ repositories {
|
|||
// Material View Pager
|
||||
maven { url "http://dl.bintray.com/florent37/maven" }
|
||||
|
||||
// Markdown
|
||||
maven { url "https://s3.amazonaws.com/repo.commonsware.com" }
|
||||
|
||||
maven { url "https://jitpack.io" }
|
||||
}
|
||||
|
|
@ -70,7 +68,11 @@ dependencies {
|
|||
// Emojis
|
||||
implementation 'com.github.viirus:emoji-lib:0.0.5'
|
||||
// Markdown
|
||||
implementation 'com.commonsware.cwac:anddown:0.4.0'
|
||||
implementation "io.noties.markwon:core:4.1.2"
|
||||
implementation "io.noties.markwon:ext-strikethrough:4.1.2"
|
||||
implementation "io.noties.markwon:image:4.1.2"
|
||||
implementation "io.noties.markwon:recycler:4.1.2"
|
||||
implementation "io.noties.markwon:html:4.1.2"
|
||||
// About View for all dependent Libraries, we are using
|
||||
implementation('com.mikepenz:aboutlibraries:5.9.4@aar') {
|
||||
transitive = true
|
||||
|
|
@ -115,8 +117,8 @@ dependencies {
|
|||
//Push Notifications
|
||||
implementation 'com.google.firebase:firebase-core:17.2.0'
|
||||
implementation 'com.google.firebase:firebase-messaging:20.0.0'
|
||||
implementation 'com.google.firebase:firebase-config:19.0.2'
|
||||
implementation 'com.google.firebase:firebase-perf:19.0.0'
|
||||
implementation 'com.google.firebase:firebase-config:19.0.3'
|
||||
implementation 'com.google.firebase:firebase-perf:19.0.1'
|
||||
implementation 'com.google.android.gms:play-services-auth:17.0.0'
|
||||
implementation 'io.realm:android-adapters:3.1.0'
|
||||
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
|
||||
|
|
@ -150,7 +152,7 @@ android {
|
|||
resConfigs "en", "bg", "de", "en-rGB", "es", "fr", "hr-rHR", "in", "it", "iw", "ja", "ko", "lt", "nl", "pl", "pt-rBR", "pt-rPT", "ru", "tr", "zh", "zh-rTW"
|
||||
|
||||
versionCode 2274
|
||||
versionName "2.2.1"
|
||||
versionName "2.3"
|
||||
}
|
||||
|
||||
lintOptions {
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@ import com.habitrpg.android.habitica.modules.UserRepositoryModule
|
|||
import com.habitrpg.android.habitica.proxy.CrashlyticsProxy
|
||||
import com.habitrpg.android.habitica.ui.activities.IntroActivity
|
||||
import com.habitrpg.android.habitica.ui.activities.LoginActivity
|
||||
import com.habitrpg.android.habitica.ui.helpers.MarkdownParser
|
||||
import com.habitrpg.android.habitica.ui.views.HabiticaIconsHelper
|
||||
import com.squareup.leakcanary.LeakCanary
|
||||
import com.squareup.leakcanary.RefWatcher
|
||||
|
|
@ -80,6 +81,7 @@ abstract class HabiticaBaseApplication : MultiDexApplication() {
|
|||
refWatcher = LeakCanary.install(this)
|
||||
createBillingAndCheckout()
|
||||
HabiticaIconsHelper.init(this)
|
||||
MarkdownParser.setup(this)
|
||||
|
||||
AppCompatDelegate.setCompatVectorFromResourcesEnabled(true)
|
||||
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ package com.habitrpg.android.habitica.models.tasks
|
|||
|
||||
import android.os.Parcel
|
||||
import android.os.Parcelable
|
||||
import android.text.Spanned
|
||||
import androidx.annotation.StringDef
|
||||
import com.google.gson.annotations.SerializedName
|
||||
import com.habitrpg.android.habitica.R
|
||||
|
|
@ -62,9 +63,9 @@ open class Task : RealmObject, Parcelable {
|
|||
// used for buyable items
|
||||
var specialTag: String? = ""
|
||||
@Ignore
|
||||
var parsedText: CharSequence? = null
|
||||
var parsedText: Spanned? = null
|
||||
@Ignore
|
||||
var parsedNotes: CharSequence? = null
|
||||
var parsedNotes: Spanned? = null
|
||||
|
||||
var isDue: Boolean? = null
|
||||
|
||||
|
|
|
|||
|
|
@ -32,10 +32,10 @@ import com.habitrpg.android.habitica.models.user.Stats
|
|||
import com.habitrpg.android.habitica.ui.AvatarView
|
||||
import com.habitrpg.android.habitica.ui.AvatarWithBarsViewModel
|
||||
import com.habitrpg.android.habitica.ui.adapter.social.AchievementProfileAdapter
|
||||
import com.habitrpg.android.habitica.ui.helpers.MarkdownParser
|
||||
import com.habitrpg.android.habitica.ui.helpers.bindView
|
||||
import com.habitrpg.android.habitica.ui.helpers.dismissKeyboard
|
||||
import com.habitrpg.android.habitica.ui.helpers.loadImage
|
||||
import com.habitrpg.android.habitica.ui.helpers.setMarkdown
|
||||
import com.habitrpg.android.habitica.ui.views.HabiticaSnackbar
|
||||
import com.habitrpg.android.habitica.ui.views.HabiticaSnackbar.SnackbarDisplayType
|
||||
import com.habitrpg.android.habitica.ui.views.dialogs.HabiticaAlertDialog
|
||||
|
|
@ -184,8 +184,8 @@ class FullProfileActivity : BaseActivity() {
|
|||
}
|
||||
|
||||
val blurbText = profile.blurb
|
||||
if (blurbText != null && !blurbText.isEmpty()) {
|
||||
blurbTextView.text = MarkdownParser.parseMarkdown(blurbText)
|
||||
if (blurbText != null && blurbText.isNotEmpty()) {
|
||||
blurbTextView.setMarkdown(blurbText)
|
||||
}
|
||||
|
||||
user.authentication?.timestamps?.createdAt?.let { joinedView.text = dateFormatter.format(it) }
|
||||
|
|
|
|||
|
|
@ -2,9 +2,10 @@ package com.habitrpg.android.habitica.ui.activities
|
|||
|
||||
import android.os.Bundle
|
||||
import android.webkit.WebView
|
||||
import com.commonsware.cwac.anddown.AndDown
|
||||
import com.habitrpg.android.habitica.R
|
||||
import com.habitrpg.android.habitica.components.UserComponent
|
||||
import io.noties.markwon.Markwon
|
||||
import io.noties.markwon.html.HtmlPlugin
|
||||
import kotlinx.android.synthetic.main.activity_prefs.*
|
||||
import okhttp3.*
|
||||
import java.io.BufferedReader
|
||||
|
|
@ -37,8 +38,12 @@ class GuidelinesActivity: BaseActivity() {
|
|||
val text = reader.readText()
|
||||
response.body()?.close()
|
||||
|
||||
val markwon = Markwon.builder(this@GuidelinesActivity)
|
||||
.usePlugin(HtmlPlugin.create())
|
||||
.build()
|
||||
|
||||
findViewById<WebView>(R.id.webview).post {
|
||||
findViewById<WebView>(R.id.webview).loadData(AndDown().markdownToHtml(text), "text/html; charset=utf-8", "utf-8")
|
||||
findViewById<WebView>(R.id.webview).loadData(markwon.toMarkdown(text).toString(), "text/html; charset=utf-8", "utf-8")
|
||||
}
|
||||
}
|
||||
})
|
||||
|
|
|
|||
|
|
@ -13,8 +13,8 @@ import com.habitrpg.android.habitica.api.MaintenanceApiService
|
|||
import com.habitrpg.android.habitica.components.UserComponent
|
||||
import com.habitrpg.android.habitica.data.ApiClient
|
||||
import com.habitrpg.android.habitica.helpers.RxErrorHandler
|
||||
import com.habitrpg.android.habitica.ui.helpers.MarkdownParser
|
||||
import com.habitrpg.android.habitica.ui.helpers.bindView
|
||||
import com.habitrpg.android.habitica.ui.helpers.setMarkdown
|
||||
import com.habitrpg.android.habitica.ui.views.HabiticaEmojiTextView
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.functions.Consumer
|
||||
|
|
@ -48,7 +48,7 @@ class MaintenanceActivity : BaseActivity() {
|
|||
|
||||
@Suppress("DEPRECATION")
|
||||
imageView.setImageURI(data.getString("imageUrl")?.toUri())
|
||||
this.descriptionTextView.text = MarkdownParser.parseMarkdown(data.getString("description"))
|
||||
this.descriptionTextView.setMarkdown(data.getString("description"))
|
||||
this.descriptionTextView.movementMethod = LinkMovementMethod.getInstance()
|
||||
|
||||
isDeprecationNotice = data.getBoolean("deprecationNotice")
|
||||
|
|
|
|||
|
|
@ -23,9 +23,9 @@ import com.habitrpg.android.habitica.data.SocialRepository
|
|||
import com.habitrpg.android.habitica.extensions.getThemeColor
|
||||
import com.habitrpg.android.habitica.helpers.RxErrorHandler
|
||||
import com.habitrpg.android.habitica.models.social.ChatMessage
|
||||
import com.habitrpg.android.habitica.ui.helpers.MarkdownParser
|
||||
import com.habitrpg.android.habitica.ui.helpers.bindView
|
||||
import com.habitrpg.android.habitica.ui.helpers.dismissKeyboard
|
||||
import com.habitrpg.android.habitica.ui.helpers.setMarkdown
|
||||
import io.reactivex.functions.Consumer
|
||||
import javax.inject.Inject
|
||||
|
||||
|
|
@ -71,7 +71,7 @@ class ReportMessageActivity : BaseActivity() {
|
|||
|
||||
contentContainer.setOnTouchListener { _, _ -> true }
|
||||
dismissTouchView.setOnClickListener { finish() }
|
||||
reportExplanationTextView.text = MarkdownParser.parseMarkdown(getString(R.string.report_explanation))
|
||||
reportExplanationTextView.setMarkdown(getString(R.string.report_explanation))
|
||||
|
||||
BottomSheetBehavior.from<View>(bottomSheetView)
|
||||
.setBottomSheetCallback(object : BottomSheetBehavior.BottomSheetCallback() {
|
||||
|
|
|
|||
|
|
@ -12,8 +12,8 @@ import com.habitrpg.android.habitica.helpers.MainNavigationController
|
|||
import com.habitrpg.android.habitica.models.FAQArticle
|
||||
import com.habitrpg.android.habitica.ui.activities.MainActivity
|
||||
import com.habitrpg.android.habitica.ui.fragments.faq.FAQOverviewFragmentDirections
|
||||
import com.habitrpg.android.habitica.ui.helpers.MarkdownParser
|
||||
import com.habitrpg.android.habitica.ui.helpers.bindView
|
||||
import com.habitrpg.android.habitica.ui.helpers.setMarkdown
|
||||
import io.reactivex.BackpressureStrategy
|
||||
import io.reactivex.Flowable
|
||||
import io.reactivex.subjects.PublishSubject
|
||||
|
|
@ -105,7 +105,7 @@ class FAQOverviewRecyclerAdapter : androidx.recyclerview.widget.RecyclerView.Ada
|
|||
|
||||
init {
|
||||
val textView = itemView.findViewById<TextView>(R.id.text_view)
|
||||
textView.text = MarkdownParser.parseMarkdown(itemView.context.getString(R.string.need_help_header_description, "[Habitica Help Guild](https://habitica.com/groups/guild/5481ccf3-5d2d-48a9-a871-70a7380cee5a)"))
|
||||
textView.setMarkdown(itemView.context.getString(R.string.need_help_header_description, "[Habitica Help Guild](https://habitica.com/groups/guild/5481ccf3-5d2d-48a9-a871-70a7380cee5a)"))
|
||||
textView.setOnClickListener { MainNavigationController.navigate(R.id.guildFragment, bundleOf("groupID" to "5481ccf3-5d2d-48a9-a871-70a7380cee5a")) }
|
||||
textView.movementMethod = LinkMovementMethod.getInstance()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,8 +14,8 @@ import com.habitrpg.android.habitica.helpers.MainNavigationController
|
|||
import com.habitrpg.android.habitica.helpers.RxErrorHandler
|
||||
import com.habitrpg.android.habitica.models.social.Group
|
||||
import com.habitrpg.android.habitica.ui.fragments.social.PublicGuildsFragmentDirections
|
||||
import com.habitrpg.android.habitica.ui.helpers.MarkdownParser
|
||||
import com.habitrpg.android.habitica.ui.helpers.bindView
|
||||
import com.habitrpg.android.habitica.ui.helpers.setMarkdown
|
||||
import io.reactivex.functions.Consumer
|
||||
import io.realm.Case
|
||||
import io.realm.OrderedRealmCollection
|
||||
|
|
@ -115,7 +115,7 @@ class PublicGuildsRecyclerViewAdapter(data: OrderedRealmCollection<Group>?, auto
|
|||
fun bind(guild: Group, isInGroup: Boolean) {
|
||||
this.nameTextView.text = guild.name
|
||||
this.memberCountTextView.text = guild.memberCount.toString()
|
||||
this.descriptionTextView.text = MarkdownParser.parseMarkdown(guild.summary)
|
||||
this.descriptionTextView.setMarkdown(guild.summary)
|
||||
if (isInGroup) {
|
||||
this.joinLeaveButton.setText(R.string.leave)
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ import com.habitrpg.android.habitica.ui.activities.GroupFormActivity
|
|||
import com.habitrpg.android.habitica.ui.activities.MainActivity
|
||||
import com.habitrpg.android.habitica.ui.fragments.BaseFragment
|
||||
import com.habitrpg.android.habitica.ui.helpers.DataBindingUtils
|
||||
import com.habitrpg.android.habitica.ui.helpers.MarkdownParser
|
||||
import com.habitrpg.android.habitica.ui.helpers.setMarkdown
|
||||
import com.habitrpg.android.habitica.ui.views.HabiticaSnackbar
|
||||
import io.reactivex.Observable
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
|
|
@ -137,7 +137,7 @@ class GroupInformationFragment : BaseFragment() {
|
|||
groupSummaryView.movementMethod = LinkMovementMethod.getInstance()
|
||||
|
||||
if (configManager.noPartyLinkPartyGuild()) {
|
||||
join_party_description_textview.text = MarkdownParser.parseMarkdown(getString(R.string.join_party_description_guild, "[Party Wanted Guild](https://habitica.com/groups/guild/f2db2a7f-13c5-454d-b3ee-ea1f5089e601)"))
|
||||
join_party_description_textview.setMarkdown(getString(R.string.join_party_description_guild, "[Party Wanted Guild](https://habitica.com/groups/guild/f2db2a7f-13c5-454d-b3ee-ea1f5089e601)"))
|
||||
join_party_description_textview.setOnClickListener {
|
||||
context?.let { FirebaseAnalytics.getInstance(it).logEvent("clicked_party_wanted", null) }
|
||||
MainNavigationController.navigate(R.id.guildFragment, bundleOf("groupID" to "f2db2a7f-13c5-454d-b3ee-ea1f5089e601"))
|
||||
|
|
@ -225,8 +225,8 @@ class GroupInformationFragment : BaseFragment() {
|
|||
groupDescriptionWrapper.visibility = groupItemVisibility
|
||||
|
||||
groupNameView.text = group?.name
|
||||
groupDescriptionView.text = MarkdownParser.parseMarkdown(group?.description)
|
||||
groupSummaryView.text = MarkdownParser.parseMarkdown(group?.summary)
|
||||
groupDescriptionView.setMarkdown(group?.description)
|
||||
groupSummaryView.setMarkdown(group?.summary)
|
||||
gemCountWrapper.visibility = if (group?.balance != null && group.balance > 0) View.VISIBLE else View.GONE
|
||||
gemCountTextView.text = (group?.balance ?: 0 * 4.0).toInt().toString()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,9 +24,9 @@ import com.habitrpg.android.habitica.ui.activities.GroupFormActivity
|
|||
import com.habitrpg.android.habitica.ui.activities.GroupInviteActivity
|
||||
import com.habitrpg.android.habitica.ui.activities.MainActivity
|
||||
import com.habitrpg.android.habitica.ui.fragments.BaseFragment
|
||||
import com.habitrpg.android.habitica.ui.helpers.MarkdownParser
|
||||
import com.habitrpg.android.habitica.ui.helpers.bindView
|
||||
import com.habitrpg.android.habitica.ui.helpers.resetViews
|
||||
import com.habitrpg.android.habitica.ui.helpers.setMarkdown
|
||||
import com.habitrpg.android.habitica.ui.viewmodels.GroupViewModel
|
||||
import com.habitrpg.android.habitica.ui.views.HabiticaIcons
|
||||
import com.habitrpg.android.habitica.ui.views.HabiticaIconsHelper
|
||||
|
|
@ -186,8 +186,8 @@ class GuildDetailFragment : BaseFragment() {
|
|||
guildMembersIconView.setImageBitmap(HabiticaIcons.imageOfGuildCrestMedium((guild?.memberCount ?: 0).toFloat()))
|
||||
guildMembersTextView.text = guild?.memberCount.toString()
|
||||
guildBankTextView.text = guild?.gemCount.toString()
|
||||
guildSummaryView.text = MarkdownParser.parseMarkdown(guild?.summary)
|
||||
guildDescriptionView.text = MarkdownParser.parseMarkdown(guild?.description)
|
||||
guildSummaryView.setMarkdown(guild?.summary)
|
||||
guildDescriptionView.setMarkdown(guild?.description)
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
|
|
|||
|
|
@ -22,10 +22,7 @@ import com.habitrpg.android.habitica.models.members.Member
|
|||
import com.habitrpg.android.habitica.models.social.Group
|
||||
import com.habitrpg.android.habitica.modules.AppModule
|
||||
import com.habitrpg.android.habitica.ui.fragments.BaseMainFragment
|
||||
import com.habitrpg.android.habitica.ui.helpers.DataBindingUtils
|
||||
import com.habitrpg.android.habitica.ui.helpers.MarkdownParser
|
||||
import com.habitrpg.android.habitica.ui.helpers.bindOptionalView
|
||||
import com.habitrpg.android.habitica.ui.helpers.resetViews
|
||||
import com.habitrpg.android.habitica.ui.helpers.*
|
||||
import com.habitrpg.android.habitica.ui.views.dialogs.HabiticaAlertDialog
|
||||
import io.reactivex.functions.Consumer
|
||||
import javax.inject.Inject
|
||||
|
|
@ -152,7 +149,7 @@ class QuestDetailFragment : BaseMainFragment() {
|
|||
return
|
||||
}
|
||||
questTitleView?.text = questContent.text
|
||||
questDescriptionView?.text = MarkdownParser.parseMarkdown(questContent.notes)
|
||||
questDescriptionView?.setMarkdown(questContent.notes)
|
||||
DataBindingUtils.loadImage(questScrollImageView, "inventory_quest_scroll_" + questContent.key)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ import com.habitrpg.android.habitica.ui.activities.FullProfileActivity
|
|||
import com.habitrpg.android.habitica.ui.fragments.BaseMainFragment
|
||||
import com.habitrpg.android.habitica.ui.helpers.MarkdownParser
|
||||
import com.habitrpg.android.habitica.ui.helpers.bindView
|
||||
import com.habitrpg.android.habitica.ui.helpers.setMarkdown
|
||||
import com.habitrpg.android.habitica.ui.views.HabiticaEmojiTextView
|
||||
import com.habitrpg.android.habitica.ui.views.HabiticaIconsHelper
|
||||
import com.habitrpg.android.habitica.ui.views.dialogs.HabiticaAlertDialog
|
||||
|
|
@ -187,7 +188,7 @@ class ChallengeDetailFragment: BaseMainFragment() {
|
|||
private fun set(challenge: Challenge) {
|
||||
this.challenge = challenge
|
||||
challengeName?.text = EmojiParser.parseEmojis(challenge.name)
|
||||
challengeDescription?.text = MarkdownParser.parseMarkdown(challenge.description)
|
||||
challengeDescription?.setMarkdown(challenge.description)
|
||||
challengeLeaderLabel?.username = challenge.leaderName
|
||||
|
||||
gemAmountView?.text = challenge.prize.toString()
|
||||
|
|
|
|||
|
|
@ -120,7 +120,7 @@ class PartyDetailFragment : BaseFragment() {
|
|||
return
|
||||
}
|
||||
titleView?.text = party.name
|
||||
descriptionView?.text = MarkdownParser.parseMarkdown(party.description)
|
||||
descriptionView?.setMarkdown(party.description)
|
||||
|
||||
if (party.quest?.key?.isEmpty() == false) {
|
||||
newQuestButton?.visibility = View.GONE
|
||||
|
|
|
|||
|
|
@ -1,28 +1,38 @@
|
|||
package com.habitrpg.android.habitica.ui.helpers
|
||||
|
||||
import android.graphics.Color
|
||||
import android.text.Html
|
||||
import android.text.Html.FROM_HTML_MODE_LEGACY
|
||||
import android.text.SpannableStringBuilder
|
||||
import android.content.Context
|
||||
import android.text.SpannableString
|
||||
import android.text.Spanned
|
||||
import android.text.style.ForegroundColorSpan
|
||||
import com.commonsware.cwac.anddown.AndDown
|
||||
import android.text.method.LinkMovementMethod
|
||||
import android.widget.TextView
|
||||
import com.habitrpg.android.habitica.helpers.RxErrorHandler
|
||||
import io.noties.markwon.Markwon
|
||||
import io.noties.markwon.ext.strikethrough.StrikethroughPlugin
|
||||
import io.noties.markwon.image.ImagesPlugin
|
||||
import io.noties.markwon.image.file.FileSchemeHandler
|
||||
import io.noties.markwon.image.network.OkHttpNetworkSchemeHandler
|
||||
import io.noties.markwon.movement.MovementMethodPlugin
|
||||
import io.reactivex.Single
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.functions.Consumer
|
||||
import io.reactivex.schedulers.Schedulers
|
||||
import net.pherth.android.emoji_library.EmojiParser
|
||||
import java.util.regex.Pattern
|
||||
|
||||
/**
|
||||
* @author data5tream
|
||||
*/
|
||||
|
||||
object MarkdownParser {
|
||||
|
||||
private val processor = AndDown()
|
||||
internal var markwon: Markwon? = null
|
||||
|
||||
private val regex = Pattern.compile("\\B@[-\\w]+")
|
||||
fun setup(context: Context) {
|
||||
markwon = Markwon.builder(context)
|
||||
.usePlugin(StrikethroughPlugin.create())
|
||||
.usePlugin(ImagesPlugin.create {
|
||||
it.addSchemeHandler(OkHttpNetworkSchemeHandler.create())
|
||||
.addSchemeHandler(FileSchemeHandler.createWithAssets(context.assets))
|
||||
})
|
||||
.usePlugin(MovementMethodPlugin.create(LinkMovementMethod.getInstance()))
|
||||
.build()
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses formatted markdown and returns it as styled CharSequence
|
||||
|
|
@ -30,34 +40,15 @@ object MarkdownParser {
|
|||
* @param input Markdown formatted String
|
||||
* @return Stylized CharSequence
|
||||
*/
|
||||
fun parseMarkdown(input: String?): CharSequence {
|
||||
fun parseMarkdown(input: String?): Spanned {
|
||||
if (input == null) {
|
||||
return ""
|
||||
return SpannableString("")
|
||||
}
|
||||
val output: SpannableStringBuilder = try {
|
||||
val html = processor.markdownToHtml(EmojiParser.parseEmojis(input.trim { it <= ' ' }))
|
||||
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) {
|
||||
Html.fromHtml(html, FROM_HTML_MODE_LEGACY) as? SpannableStringBuilder
|
||||
} else {
|
||||
@Suppress("DEPRECATION")
|
||||
(Html.fromHtml(html) as? SpannableStringBuilder)
|
||||
} ?: SpannableStringBuilder()
|
||||
} catch (e: UnsatisfiedLinkError) {
|
||||
SpannableStringBuilder(input)
|
||||
} catch (e: NoClassDefFoundError) {
|
||||
SpannableStringBuilder(input)
|
||||
}
|
||||
|
||||
val matcher = regex.matcher(output)
|
||||
while (matcher.find()) {
|
||||
val colorSpan = ForegroundColorSpan(Color.parseColor("#9A62FF"))
|
||||
output.setSpan(colorSpan, matcher.start(), matcher.end(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
|
||||
}
|
||||
|
||||
return output.trimEnd('\n')
|
||||
val text = EmojiParser.parseEmojis(input) ?: input
|
||||
return markwon?.toMarkdown(text) ?: SpannableString(text)
|
||||
}
|
||||
|
||||
fun parseMarkdownAsync(input: String?, onSuccess: Consumer<CharSequence>) {
|
||||
fun parseMarkdownAsync(input: String?, onSuccess: Consumer<Spanned>) {
|
||||
Single.just(input ?: "")
|
||||
.map { this.parseMarkdown(it) }
|
||||
.subscribeOn(Schedulers.io())
|
||||
|
|
@ -74,5 +65,17 @@ object MarkdownParser {
|
|||
fun parseCompiled(input: CharSequence): String? {
|
||||
return EmojiParser.convertToCheatCode(input.toString())
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
fun TextView.setMarkdown(input: String?) {
|
||||
MarkdownParser.markwon?.setParsedMarkdown(this, MarkdownParser.parseMarkdown(input))
|
||||
}
|
||||
|
||||
fun TextView.setParsedMarkdown(input: Spanned?) {
|
||||
if (input != null) {
|
||||
MarkdownParser.markwon?.setParsedMarkdown(this, input)
|
||||
} else {
|
||||
text = null
|
||||
}
|
||||
}
|
||||
|
|
@ -7,12 +7,10 @@ import com.habitrpg.android.habitica.R
|
|||
import com.habitrpg.android.habitica.helpers.RxErrorHandler
|
||||
import com.habitrpg.android.habitica.models.responses.TaskDirection
|
||||
import com.habitrpg.android.habitica.models.tasks.Task
|
||||
import com.habitrpg.android.habitica.ui.helpers.MarkdownParser
|
||||
import com.habitrpg.android.habitica.ui.helpers.bindColor
|
||||
import com.habitrpg.android.habitica.ui.helpers.bindOptionalView
|
||||
import com.habitrpg.android.habitica.ui.helpers.bindView
|
||||
import com.habitrpg.android.habitica.ui.helpers.*
|
||||
import com.habitrpg.android.habitica.ui.viewHolders.BindableViewHolder
|
||||
import com.habitrpg.android.habitica.ui.views.EllipsisTextView
|
||||
import io.noties.markwon.utils.NoCopySpannableFactory
|
||||
import io.reactivex.Single
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.functions.Action
|
||||
|
|
@ -73,6 +71,8 @@ abstract class BaseTaskViewHolder constructor(itemView: View, var scoreTaskFunc:
|
|||
itemView.setOnClickListener { onClick(it) }
|
||||
itemView.isClickable = true
|
||||
|
||||
titleTextView.setOnClickListener { onClick(it) }
|
||||
notesTextView?.setOnClickListener { onClick(it) }
|
||||
errorIconView?.setOnClickListener { errorButtonClicked?.run()}
|
||||
|
||||
//Re enable when we find a way to only react when a link is tapped.
|
||||
|
|
@ -115,9 +115,10 @@ abstract class BaseTaskViewHolder constructor(itemView: View, var scoreTaskFunc:
|
|||
|
||||
if (canContainMarkdown()) {
|
||||
if (data.parsedText != null) {
|
||||
titleTextView.text = data.parsedText
|
||||
titleTextView.setParsedMarkdown(data.parsedText)
|
||||
} else {
|
||||
titleTextView.text = data.text
|
||||
titleTextView.setSpannableFactory(NoCopySpannableFactory.getInstance());
|
||||
if (data.text.isNotEmpty()) {
|
||||
Single.just(data.text)
|
||||
.map { MarkdownParser.parseMarkdown(it) }
|
||||
|
|
@ -125,13 +126,14 @@ abstract class BaseTaskViewHolder constructor(itemView: View, var scoreTaskFunc:
|
|||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(Consumer{ parsedText ->
|
||||
data.parsedText = parsedText
|
||||
titleTextView.text = parsedText
|
||||
titleTextView.setParsedMarkdown(parsedText)
|
||||
}, RxErrorHandler.handleEmptyError())
|
||||
}
|
||||
if (data.parsedNotes != null) {
|
||||
notesTextView?.text = data.parsedNotes
|
||||
notesTextView?.setParsedMarkdown(data.parsedText)
|
||||
} else {
|
||||
notesTextView?.text = data.notes
|
||||
notesTextView?.setSpannableFactory(NoCopySpannableFactory.getInstance());
|
||||
data.notes?.let {notes ->
|
||||
if (notes.isEmpty()) {
|
||||
return@let
|
||||
|
|
@ -141,8 +143,8 @@ abstract class BaseTaskViewHolder constructor(itemView: View, var scoreTaskFunc:
|
|||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(Consumer { parsedNotes ->
|
||||
data.parsedNotes = parsedNotes
|
||||
notesTextView?.text = parsedNotes
|
||||
notesTextView?.setParsedMarkdown(parsedNotes)
|
||||
}, RxErrorHandler.handleEmptyError())
|
||||
}
|
||||
}
|
||||
|
|
@ -178,10 +180,6 @@ abstract class BaseTaskViewHolder constructor(itemView: View, var scoreTaskFunc:
|
|||
}
|
||||
|
||||
override fun onClick(v: View) {
|
||||
if (v != itemView || openTaskDisabled) {
|
||||
return
|
||||
}
|
||||
|
||||
task?.let { openTaskFunc(it) }
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -25,8 +25,8 @@ import com.habitrpg.android.habitica.models.inventory.QuestContent
|
|||
import com.habitrpg.android.habitica.models.inventory.QuestProgressCollect
|
||||
import com.habitrpg.android.habitica.models.user.User
|
||||
import com.habitrpg.android.habitica.ui.helpers.DataBindingUtils
|
||||
import com.habitrpg.android.habitica.ui.helpers.MarkdownParser
|
||||
import com.habitrpg.android.habitica.ui.helpers.bindView
|
||||
import com.habitrpg.android.habitica.ui.helpers.setMarkdown
|
||||
import com.habitrpg.android.habitica.ui.views.*
|
||||
import com.habitrpg.android.habitica.ui.views.dialogs.HabiticaAlertDialog
|
||||
import io.reactivex.Observable
|
||||
|
|
@ -165,7 +165,7 @@ class QuestProgressView : LinearLayout {
|
|||
setCollectionViews(collection, quest)
|
||||
}
|
||||
}
|
||||
questDescriptionView.text = MarkdownParser.parseMarkdown(quest.notes)
|
||||
questDescriptionView.setMarkdown(quest.notes)
|
||||
DataBindingUtils.loadImage(questImageView, "quest_"+quest.key, "gif")
|
||||
DataBindingUtils.loadImage(questFlourishesImageView, "quest_"+quest.key+"_flourishes")
|
||||
val lightColor = quest.colors?.lightColor
|
||||
|
|
|
|||
Loading…
Reference in a new issue