Switch markdown library

Fixes #1215
Fixes #904
Fixes #476
This commit is contained in:
Phillip Thelen 2019-10-28 17:45:25 +01:00
parent a7311de300
commit 81a6a0c0a6
17 changed files with 95 additions and 86 deletions

View file

@ -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 {

View file

@ -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)

View file

@ -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

View file

@ -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) }

View file

@ -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")
}
}
})

View file

@ -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")

View file

@ -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() {

View file

@ -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()
}

View file

@ -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 {

View file

@ -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()
}

View file

@ -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 {

View file

@ -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)
}

View file

@ -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()

View file

@ -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

View file

@ -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
}
}

View file

@ -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) }
}

View file

@ -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