diff --git a/app/src/main/java/oppen/Extensions.kt b/app/src/main/java/oppen/Extensions.kt index 8fce839..e9c68b6 100644 --- a/app/src/main/java/oppen/Extensions.kt +++ b/app/src/main/java/oppen/Extensions.kt @@ -1,5 +1,6 @@ package oppen +import android.annotation.SuppressLint import android.content.Context import android.os.CountDownTimer import android.view.View @@ -27,6 +28,14 @@ fun String.toURI(): URI { return URI.create(this) } +@SuppressLint("DefaultLocale") +fun String.endsWithImage(): Boolean{ + return this.toLowerCase().endsWith(".png") || + this.toLowerCase().endsWith(".jpg") || + this.toLowerCase().endsWith(".jpeg") || + this.toLowerCase().endsWith(".gif") +} + fun delay(ms: Long, action: () -> Unit){ object : CountDownTimer(ms, ms/2) { override fun onTick(millisUntilFinished: Long) {} diff --git a/app/src/main/java/oppen/ariane/Ariane.kt b/app/src/main/java/oppen/ariane/Ariane.kt index 4041339..77819c1 100644 --- a/app/src/main/java/oppen/ariane/Ariane.kt +++ b/app/src/main/java/oppen/ariane/Ariane.kt @@ -8,7 +8,5 @@ class Ariane: Application() { const val DEFAULT_HOME_CAPSULE = "gemini://gemini.circumlunar.space/~oppen/index.gmi" const val GEMINI_USER_SEARCH_BASE = "gemini://gus.guru/search?" const val GEMINI_BACKLINK_BASE = "gemini://gus.guru/backlinks?" - - const val FEATURE_INLINE_IMAGES = true } } \ No newline at end of file diff --git a/app/src/main/java/oppen/ariane/ui/GemtextAdapter.kt b/app/src/main/java/oppen/ariane/ui/GemtextAdapter.kt index 2ba8e1e..7f0e2ad 100644 --- a/app/src/main/java/oppen/ariane/ui/GemtextAdapter.kt +++ b/app/src/main/java/oppen/ariane/ui/GemtextAdapter.kt @@ -10,6 +10,7 @@ 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.ariane.R +import oppen.endsWithImage import oppen.visible import java.net.URI @@ -23,9 +24,10 @@ class GemtextAdapter(val onLink: (adapter: GemtextAdapter, link: URI, longTap: B private val typeH2 = 2 private val typeH3 = 3 private val typeListItem = 4 - private val typeLink = 5 - private val typeCodeBlock = 6 - private val typeQuote = 7 + private val typeImageLink = 5 + private val typeLink = 6 + private val typeCodeBlock = 7 + private val typeQuote = 8 sealed class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView){ class Text(itemView: View): ViewHolder(itemView) @@ -33,6 +35,7 @@ class GemtextAdapter(val onLink: (adapter: GemtextAdapter, link: URI, longTap: B class H2(itemView: View): ViewHolder(itemView) class H3(itemView: View): ViewHolder(itemView) class ListItem(itemView: View): ViewHolder(itemView) + class ImageLinkLink(itemView: View): ViewHolder(itemView) class Link(itemView: View): ViewHolder(itemView) class Code(itemView: View): ViewHolder(itemView) class Quote(itemView: View): ViewHolder(itemView) @@ -52,6 +55,7 @@ class GemtextAdapter(val onLink: (adapter: GemtextAdapter, link: URI, longTap: B 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)) + typeImageLink -> ViewHolder.Link(LayoutInflater.from(parent.context).inflate(R.layout.gemtext_image_link, 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)) @@ -67,6 +71,7 @@ class GemtextAdapter(val onLink: (adapter: GemtextAdapter, link: URI, longTap: B line.startsWith("##") -> typeH2 line.startsWith("#") -> typeH1 line.startsWith("*") -> typeListItem + line.startsWith("=>") && line.endsWithImage() -> typeImageLink line.startsWith("=>") -> typeLink line.startsWith(">") -> typeQuote else -> typeText @@ -113,13 +118,36 @@ class GemtextAdapter(val onLink: (adapter: GemtextAdapter, link: URI, longTap: B 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") + println("User clicked link: $uri") onLink(this, uri, false, holder.adapterPosition, null) } holder.itemView.gemtext_text_link.setOnLongClickListener {view -> val uri = getUri(lines[holder.adapterPosition]) - println("User click link: $uri") + println("User long-clicked link: $uri") + onLink(this, uri, true, holder.adapterPosition, view) + true + } + } + is ViewHolder.ImageLinkLink -> { + //todo - extract, largely duplicate of above + 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 clicked link: $uri") + onLink(this, uri, false, holder.adapterPosition, null) + + } + holder.itemView.gemtext_text_link.setOnLongClickListener {view -> + val uri = getUri(lines[holder.adapterPosition]) + println("User long-clicked link: $uri") onLink(this, uri, true, holder.adapterPosition, view) true } @@ -127,6 +155,8 @@ class GemtextAdapter(val onLink: (adapter: GemtextAdapter, link: URI, longTap: B if(inlineImages.containsKey(position)){ holder.itemView.gemtext_inline_image.visible(true) holder.itemView.gemtext_inline_image.setImageURI(inlineImages[position]) + }else{ + holder.itemView.gemtext_inline_image.visible(false) } } } diff --git a/app/src/main/java/oppen/ariane/ui/modals_menus/LinkPopup.kt b/app/src/main/java/oppen/ariane/ui/modals_menus/LinkPopup.kt index cccc32e..6f6ae1a 100644 --- a/app/src/main/java/oppen/ariane/ui/modals_menus/LinkPopup.kt +++ b/app/src/main/java/oppen/ariane/ui/modals_menus/LinkPopup.kt @@ -3,32 +3,28 @@ package oppen.ariane.ui.modals_menus import android.view.MenuInflater import android.view.View import androidx.appcompat.widget.PopupMenu -import oppen.ariane.Ariane import oppen.ariane.R +import oppen.endsWithImage import java.net.URI - object LinkPopup { fun show(view: View?, uri: URI, onMenuOption: (menuId: Int) -> Unit){ if(view != null) { + val popup = PopupMenu(view.context, view) val inflater: MenuInflater = popup.menuInflater - val path = uri.toString().toLowerCase() - if(Ariane.FEATURE_INLINE_IMAGES && - (path.endsWith(".png") || - path.endsWith(".jpg") || - path.endsWith(".jpeg"))){ - inflater.inflate(R.menu.image_link_menu, popup.menu) - }else{ - inflater.inflate(R.menu.link_menu, popup.menu) + when { + uri.toString().endsWithImage() -> inflater.inflate(R.menu.image_link_menu, popup.menu) + else -> inflater.inflate(R.menu.link_menu, popup.menu) } popup.setOnMenuItemClickListener { menuItem -> onMenuOption(menuItem.itemId) true } + popup.show() } } diff --git a/app/src/main/res/layout/gemtext_image_link.xml b/app/src/main/res/layout/gemtext_image_link.xml new file mode 100644 index 0000000..30782ad --- /dev/null +++ b/app/src/main/res/layout/gemtext_image_link.xml @@ -0,0 +1,28 @@ + + + + + + \ No newline at end of file