fix ./ relative url linking, add inline image feature

This commit is contained in:
Jonathan Fisher 2020-11-12 23:04:15 +00:00
parent e4669d9592
commit e5a26ce3a2
9 changed files with 46 additions and 25 deletions

View File

@ -9,6 +9,6 @@ class Ariane: Application() {
const val GEMINI_USER_SEARCH_BASE = "gemini://gus.guru/search?"
const val GEMINI_BACKLINK_BASE = "gemini://gus.guru/backlinks?"
const val FEATURE_INLINE_IMAGES = false
const val FEATURE_INLINE_IMAGES = true
}
}

View File

@ -22,8 +22,7 @@ const val GEMINI_SCHEME = "gemini"
*
*/
class GeminiDatasource(
private val context: Context
): Datasource {
private val context: Context): Datasource {
private val prefs = PreferenceManager.getDefaultSharedPreferences(context)
private var last: URI? = null
@ -65,10 +64,15 @@ class GeminiDatasource(
URI.create("gemini:$address")
}
address.startsWith("/") -> {
//internal navigation
//internal navigation/relative link
val internalNav = "gemini://${last?.host}$address"
URI.create(internalNav)
}
address.startsWith("./") -> {
//internal navigation/relative link - with dot
val internalNav = "gemini://${last?.host}${address.substring(1)}"
URI.create(internalNav)
}
!address.contains("://") -> {
//looks like a relative link
val lastAddress = last.toString()

View File

@ -1,12 +1,9 @@
package oppen.ariane.ui
import android.content.ActivityNotFoundException
import android.content.Context
import android.content.Intent
import android.content.SharedPreferences
import android.media.MediaPlayer
import android.net.Uri
import android.os.Build
import android.os.Bundle
import android.view.inputmethod.EditorInfo
import androidx.activity.viewModels
@ -35,7 +32,6 @@ import oppen.ariane.ui.modals_menus.about.AboutDialog
import oppen.ariane.ui.modals_menus.history.HistoryDialog
import oppen.ariane.ui.modals_menus.input.InputDialog
import oppen.ariane.ui.modals_menus.overflow.OverflowPopup
import oppen.ariane.ui.modals_menus.set_home.SetHomeDialog
import oppen.ariane.ui.settings.SettingsActivity
import oppen.hideKeyboard
import oppen.visibleRetainingSpace
@ -63,7 +59,15 @@ class GemActivity : AppCompatActivity() {
LinkPopup.show(view, uri){ menuId ->
when (menuId) {
R.id.link_menu_load_image -> {
adapter.loadImage(position)
loadingView(true)
model.requestInlineImage(uri){ imageUri ->
imageUri?.let{
runOnUiThread {
loadingView(false)
adapter.loadImage(position, imageUri)
}
}
}
}
R.id.link_menu_copy -> {
Intent().apply {

View File

@ -1,5 +1,6 @@
package oppen.ariane.ui
import android.net.Uri
import androidx.lifecycle.ViewModel
import oppen.ariane.Ariane
import oppen.ariane.io.gemini.Datasource
@ -42,6 +43,15 @@ class GemViewModel: ViewModel() {
}
}
fun requestInlineImage(uri: URI, onImageReady: (cacheUri: Uri?) -> Unit){
gemini.request(uri){ state ->
when (state) {
is GemState.ResponseImage -> onImageReady(state.cacheUri)
else -> onState(state)
}
}
}
fun canGoBack(): Boolean = history.size > 1
@ExperimentalStdlibApi

View File

@ -1,6 +1,7 @@
package oppen.ariane.ui
import android.annotation.SuppressLint
import android.net.Uri
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
@ -15,8 +16,7 @@ import java.net.URI
class GemtextAdapter(val onLink: (adapter: GemtextAdapter, link: URI, longTap: Boolean, adapterPosition: Int, view: View?) -> Unit): RecyclerView.Adapter<GemtextAdapter.ViewHolder>() {
var lines = mutableListOf<String>()
var imageIndexes = arrayListOf<Int>()
var inlineImages = HashMap<Int, Uri>()
private val typeText = 0
private val typeH1 = 1
@ -39,6 +39,7 @@ class GemtextAdapter(val onLink: (adapter: GemtextAdapter, link: URI, longTap: B
}
fun render(lines: List<String>){
this.inlineImages.clear()
this.lines.clear()
this.lines.addAll(lines)
notifyDataSetChanged()
@ -114,6 +115,7 @@ class GemtextAdapter(val onLink: (adapter: GemtextAdapter, link: URI, longTap: B
val uri = getUri(lines[holder.adapterPosition])
println("User click link: $uri")
onLink(this, uri, false, holder.adapterPosition, null)
}
holder.itemView.gemtext_text_link.setOnLongClickListener {view ->
val uri = getUri(lines[holder.adapterPosition])
@ -122,12 +124,10 @@ class GemtextAdapter(val onLink: (adapter: GemtextAdapter, link: URI, longTap: B
true
}
if(imageIndexes.contains(holder.adapterPosition)){
if(inlineImages.containsKey(position)){
holder.itemView.gemtext_inline_image.visible(true)
//todo - need to download the image...
}
holder.itemView.gemtext_inline_image.setImageURI(inlineImages[position])
}
}
}
}
@ -145,8 +145,8 @@ class GemtextAdapter(val onLink: (adapter: GemtextAdapter, link: URI, longTap: B
return null
}
fun loadImage(position: Int){
imageIndexes.add(position)
fun loadImage(position: Int, cacheUri: Uri){
inlineImages[position] = cacheUri
notifyItemChanged(position)
}
}

View File

@ -16,10 +16,10 @@ object LinkPopup {
val inflater: MenuInflater = popup.menuInflater
val path = uri.toString().toLowerCase()
if(Ariane.Companion.FEATURE_INLINE_IMAGES &&
path.endsWith(".png") ||
if(Ariane.FEATURE_INLINE_IMAGES &&
(path.endsWith(".png") ||
path.endsWith(".jpg") ||
path.endsWith(".jpeg")){
path.endsWith(".jpeg"))){
inflater.inflate(R.menu.image_link_menu, popup.menu)
}else{
inflater.inflate(R.menu.link_menu, popup.menu)

View File

@ -51,7 +51,7 @@ object OverflowPopup {
* Converts the given MenuItem's title into a Spannable containing both its icon and title.
*/
private fun insertMenuItemIcon(context: Context, menuItem: MenuItem) {
var icon: Drawable = menuItem.icon
val icon: Drawable = menuItem.icon
val iconSize = context.resources.getDimensionPixelSize(R.dimen.menu_item_icon_size)
icon.setBounds(0, 0, iconSize, iconSize)
icon.setTint(Color.WHITE)

View File

@ -19,6 +19,10 @@
android:id="@+id/gemtext_inline_image"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/screen_margin"
android:layout_marginRight="@dimen/screen_margin"
android:layout_marginTop="@dimen/default_margin"
android:visibility="gone"
android:adjustViewBounds="true"
android:layout_below="@+id/gemtext_text_link"/>
</RelativeLayout>

View File

@ -3,15 +3,14 @@
<string name="gemini_protocol">gemini://</string>
<string name="main_input_hint">Enter gemini:// address</string>
<string name="main_input_search_hint">Enter search term</string>
<string name="copy_address">Copy address</string>
<string name="load_image">Load image</string>
<string name="copy_address">Share address</string>
<string name="load_image">Display inline</string>
<string name="about">About</string>
<string name="address_copied_to_clipboard">Address copied to clipboard</string>
<string name="gemini_address">Gemini address</string>
<string name="share">Share</string>
<string name="set_home">Set Home</string>
<string name="settings">Settings</string>
<string name="home_icon_attribution">Home icon by Icongeek26 on FlatIcon.com</string>
<string name="about_body">Ariane: Gemini protocol client from Öppenlab</string>
<string name="gnu_link">GPL v3</string>
<string name="copyright">Copyright © 2020 Öppenlab</string>