mirror of https://git.sr.ht/~oppen/ariane
137 lines
6.0 KiB
Kotlin
137 lines
6.0 KiB
Kotlin
package oppen.gem.ui
|
|
|
|
import android.annotation.SuppressLint
|
|
import android.view.LayoutInflater
|
|
import android.view.View
|
|
import android.view.ViewGroup
|
|
import androidx.recyclerview.widget.RecyclerView
|
|
import kotlinx.android.synthetic.main.gemtext_code_block.view.*
|
|
import kotlinx.android.synthetic.main.gemtext_link.view.*
|
|
import kotlinx.android.synthetic.main.gemtext_text.view.gemtext_text_textview
|
|
import oppen.gem.R
|
|
import java.net.URI
|
|
|
|
class GemtextAdapter(val onLink: (link: URI, longTap: Boolean, view: View?) -> Unit): RecyclerView.Adapter<GemtextAdapter.ViewHolder>() {
|
|
|
|
var lines = mutableListOf<String>()
|
|
|
|
private val typeText = 0
|
|
private val typeH1 = 1
|
|
private val typeH2 = 2
|
|
private val typeH3 = 3
|
|
private val typeListItem = 4
|
|
private val typeLink = 5
|
|
private val typeCodeBlock = 6
|
|
private val typeQuote = 7
|
|
|
|
sealed class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView){
|
|
class Text(itemView: View): ViewHolder(itemView)
|
|
class H1(itemView: View): ViewHolder(itemView)
|
|
class H2(itemView: View): ViewHolder(itemView)
|
|
class H3(itemView: View): ViewHolder(itemView)
|
|
class ListItem(itemView: View): ViewHolder(itemView)
|
|
class Link(itemView: View): ViewHolder(itemView)
|
|
class Code(itemView: View): ViewHolder(itemView)
|
|
class Quote(itemView: View): ViewHolder(itemView)
|
|
}
|
|
|
|
fun render(lines: List<String>){
|
|
this.lines.clear()
|
|
this.lines.addAll(lines)
|
|
notifyDataSetChanged()
|
|
}
|
|
|
|
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
|
|
return when(viewType){
|
|
typeText -> ViewHolder.Text(LayoutInflater.from(parent.context).inflate(R.layout.gemtext_text, parent, false))
|
|
typeH1 -> ViewHolder.H1(LayoutInflater.from(parent.context).inflate(R.layout.gemtext_h1, parent, false))
|
|
typeH2 -> ViewHolder.H2(LayoutInflater.from(parent.context).inflate(R.layout.gemtext_h2, parent, false))
|
|
typeH3 -> ViewHolder.H3(LayoutInflater.from(parent.context).inflate(R.layout.gemtext_h3, parent, false))
|
|
typeListItem -> ViewHolder.ListItem(LayoutInflater.from(parent.context).inflate(R.layout.gemtext_text, parent, false))
|
|
typeLink -> ViewHolder.Link(LayoutInflater.from(parent.context).inflate(R.layout.gemtext_link, parent, false))
|
|
typeCodeBlock-> ViewHolder.Code(LayoutInflater.from(parent.context).inflate(R.layout.gemtext_code_block, parent, false))
|
|
typeQuote -> ViewHolder.Quote(LayoutInflater.from(parent.context).inflate(R.layout.gemtext_quote, parent, false))
|
|
else -> ViewHolder.Text(LayoutInflater.from(parent.context).inflate(R.layout.gemtext_text, parent, false))
|
|
}
|
|
}
|
|
|
|
override fun getItemViewType(position: Int): Int {
|
|
val line = lines[position]
|
|
return when {
|
|
line.startsWith("```") -> typeCodeBlock
|
|
line.startsWith("###") -> typeH3
|
|
line.startsWith("##") -> typeH2
|
|
line.startsWith("#") -> typeH1
|
|
line.startsWith("*") -> typeListItem
|
|
line.startsWith("=>") -> typeLink
|
|
line.startsWith(">") -> typeQuote
|
|
else -> typeText
|
|
}
|
|
}
|
|
|
|
override fun getItemCount(): Int = lines.size
|
|
|
|
@SuppressLint("SetTextI18n")
|
|
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
|
val line = lines[position]
|
|
|
|
when(holder){
|
|
is ViewHolder.Text -> holder.itemView.gemtext_text_textview.text = line
|
|
is ViewHolder.Code-> holder.itemView.gemtext_text_monospace_textview.text = line.substring(3)
|
|
is ViewHolder.Quote-> holder.itemView.gemtext_text_monospace_textview.text = line.substring(1).trim()
|
|
is ViewHolder.H1 -> {
|
|
when {
|
|
line.length > 2 -> holder.itemView.gemtext_text_textview.text = line.substring(2).trim()
|
|
else -> holder.itemView.gemtext_text_textview.text = ""
|
|
}
|
|
}
|
|
is ViewHolder.H2 -> {
|
|
when {
|
|
line.length > 3 -> holder.itemView.gemtext_text_textview.text = line.substring(3).trim()
|
|
else -> holder.itemView.gemtext_text_textview.text = ""
|
|
}
|
|
}
|
|
is ViewHolder.H3 -> {
|
|
when {
|
|
line.length > 4 -> holder.itemView.gemtext_text_textview.text = line.substring(4).trim()
|
|
else -> holder.itemView.gemtext_text_textview.text = ""
|
|
}
|
|
}
|
|
is ViewHolder.ListItem -> holder.itemView.gemtext_text_textview.text = "• ${line.substring(1)}".trim()
|
|
is ViewHolder.Link -> {
|
|
val linkParts = line.substring(2).trim().split("\\s+".toRegex(), 2)
|
|
var linkName = linkParts[0]
|
|
if(linkParts.size > 1) {
|
|
linkName = linkParts[1]
|
|
}
|
|
val displayText = linkName
|
|
holder.itemView.gemtext_text_link.text = displayText
|
|
holder.itemView.gemtext_text_link.paint.isUnderlineText = true
|
|
holder.itemView.gemtext_text_link.setOnClickListener {
|
|
val uri = getUri(lines[holder.adapterPosition])
|
|
println("User click link: $uri")
|
|
onLink(uri, false, null)
|
|
}
|
|
holder.itemView.gemtext_text_link.setOnLongClickListener {view ->
|
|
val uri = getUri(lines[holder.adapterPosition])
|
|
println("User click link: $uri")
|
|
onLink(uri, true, view)
|
|
true
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private fun getUri(linkLine: String): URI{
|
|
val linkParts = linkLine.substring(2).trim().split("\\s+".toRegex(), 2)
|
|
return URI.create(linkParts.first())
|
|
}
|
|
|
|
fun inferTitle(): String? {
|
|
lines.forEach { line ->
|
|
if(line.startsWith("#")) return line.replace("#", "").trim()
|
|
}
|
|
|
|
return null
|
|
}
|
|
} |