mirror of https://git.sr.ht/~oppen/ariane
process text implementation
This commit is contained in:
parent
19bbd1e303
commit
29f1ccc00e
|
@ -10,7 +10,8 @@ A Gemini protocol browser for Android based OS. Formerly called Två, and briefl
|
|||
|
||||
## Releases
|
||||
|
||||
See the project page on Öppenlab.net for latest download: [oppenlab.net/pr/ariane](https://oppenlab.net/pr/ariane/)
|
||||
* See the project page on Öppenlab.net for latest download: [oppenlab.net/pr/ariane](https://oppenlab.net/pr/ariane/)
|
||||
* Install on [Google Play](https://play.google.com/store/apps/details?id=oppen.gemini.ariane)
|
||||
|
||||
## Issue tracker
|
||||
|
||||
|
|
|
@ -60,7 +60,6 @@ dependencies {
|
|||
kapt "androidx.room:room-compiler:$room_version"
|
||||
implementation "androidx.room:room-ktx:$room_version"
|
||||
|
||||
|
||||
testImplementation 'junit:junit:4.13'
|
||||
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
|
||||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
|
||||
|
|
|
@ -18,4 +18,19 @@
|
|||
|
||||
# If you keep the line number information, uncomment this to
|
||||
# hide the original source file name.
|
||||
#-renamesourcefileattribute SourceFile
|
||||
#-renamesourcefileattribute SourceFile
|
||||
|
||||
-keep public class * implements com.bumptech.glide.module.GlideModule
|
||||
-keep class * extends com.bumptech.glide.module.AppGlideModule {
|
||||
<init>(...);
|
||||
}
|
||||
-keep public enum com.bumptech.glide.load.ImageHeaderParser$** {
|
||||
**[] $VALUES;
|
||||
public *;
|
||||
}
|
||||
-keep class com.bumptech.glide.load.data.ParcelFileDescriptorRewinder$InternalRewinder {
|
||||
*** rewind();
|
||||
}
|
||||
|
||||
# for DexGuard only
|
||||
# -keepresourcexmlelements manifest/application/meta-data@value=GlideModule
|
|
@ -14,17 +14,19 @@
|
|||
android:supportsRtl="true"
|
||||
android:theme="@style/AppTheme"
|
||||
android:networkSecurityConfig="@xml/network_security_config">
|
||||
<activity android:name="oppen.ariane.ui.ProcessTextActivity" android:label="Open in Ariane" android:launchMode="singleTop">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.PROCESS_TEXT" />
|
||||
<data android:mimeType="text/plain"/>
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<activity android:name="oppen.ariane.ui.GemActivity"
|
||||
android:label="Open in Ariane">
|
||||
android:launchMode="singleTop">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.PROCESS_TEXT" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<data android:mimeType="text/plain" />
|
||||
</intent-filter>
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
|
|
|
@ -193,7 +193,7 @@ class GeminiDatasource(val context: Context): Datasource {
|
|||
val bufferedReader = BufferedReader(headerInputReader)
|
||||
val headerLine = bufferedReader.readLine()
|
||||
|
||||
println("Tva: header: $headerLine")
|
||||
println("Ariane: response header: $headerLine")
|
||||
|
||||
val header = GeminiResponse.parseHeader(headerLine)
|
||||
|
||||
|
@ -246,8 +246,6 @@ class GeminiDatasource(val context: Context): Datasource {
|
|||
val filenameRegex = Regex("[^A-Za-z0-9]")
|
||||
val cacheFile = File(context.cacheDir, filenameRegex.replace(uri.path, "_"))
|
||||
|
||||
|
||||
|
||||
when {
|
||||
cacheFile.exists() -> {
|
||||
when {
|
||||
|
|
|
@ -55,10 +55,13 @@ class GemActivity : AppCompatActivity() {
|
|||
private val model by viewModels<GemViewModel>()
|
||||
private lateinit var binding: ActivityGemBinding
|
||||
private lateinit var history: HistoryInterface
|
||||
private val adapter = GemtextAdapter { uri, longTap, view ->
|
||||
private val adapter = GemtextAdapter { adapter, uri, longTap, position: Int, view ->
|
||||
if(longTap){
|
||||
LinkPopup.show(view){ menuId ->
|
||||
LinkPopup.show(view, uri){ menuId ->
|
||||
when (menuId) {
|
||||
R.id.link_menu_load_image -> {
|
||||
adapter.loadImage(position)
|
||||
}
|
||||
R.id.link_menu_copy -> {
|
||||
Intent().apply {
|
||||
action = Intent.ACTION_SEND
|
||||
|
@ -219,7 +222,15 @@ class GemActivity : AppCompatActivity() {
|
|||
model.request(address)
|
||||
}
|
||||
|
||||
checkIntentExtras()
|
||||
checkIntentExtras(intent)
|
||||
}
|
||||
|
||||
override fun onNewIntent(intent: Intent?) {
|
||||
super.onNewIntent(intent)
|
||||
|
||||
intent?.let{
|
||||
checkIntentExtras(intent)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -227,39 +238,23 @@ class GemActivity : AppCompatActivity() {
|
|||
* Checks intent to see if Activity was opened to handle selected text
|
||||
*
|
||||
*/
|
||||
private fun checkIntentExtras() {
|
||||
private fun checkIntentExtras(intent: Intent) {
|
||||
|
||||
//First check if there's a uri from a web link or other
|
||||
//Via ProcessTextActivity from selected text in another app
|
||||
if(intent.hasExtra("process_text")){
|
||||
val processText = intent.getStringExtra("process_text")
|
||||
binding.addressEdit.setText(processText)
|
||||
model.request(processText ?: "")
|
||||
return
|
||||
}
|
||||
|
||||
//From clicking a gemini:// address
|
||||
val uri = intent.data
|
||||
if(uri != null){
|
||||
binding.addressEdit.setText(uri.toString())
|
||||
model.request(uri.toString())
|
||||
return
|
||||
}
|
||||
|
||||
//Then check if we've arrived here via some selected text
|
||||
val processText = when {
|
||||
Build.VERSION.SDK_INT >= Build.VERSION_CODES.M &&
|
||||
intent.hasExtra(Intent.EXTRA_PROCESS_TEXT) -> {
|
||||
intent.getCharSequenceExtra(Intent.EXTRA_PROCESS_TEXT).toString()
|
||||
}
|
||||
else -> {
|
||||
null
|
||||
}
|
||||
}
|
||||
processText?.let { text ->
|
||||
if (text.startsWith("gemini://")) {
|
||||
binding.addressEdit.setText(text)
|
||||
model.request(text)
|
||||
} else {
|
||||
Snackbar.make(binding.root, "$text is not a valid Gemini address", Snackbar.LENGTH_SHORT).show()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onNewIntent(intent: Intent?) {
|
||||
super.onNewIntent(intent)
|
||||
intent?.data.toString().let{model.request(it)}
|
||||
}
|
||||
|
||||
private fun showAlert(message: String) = runOnUiThread{
|
||||
|
|
|
@ -9,12 +9,15 @@ 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.visible
|
||||
import java.net.URI
|
||||
|
||||
class GemtextAdapter(val onLink: (link: URI, longTap: Boolean, view: View?) -> Unit): RecyclerView.Adapter<GemtextAdapter.ViewHolder>() {
|
||||
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>()
|
||||
|
||||
private val typeText = 0
|
||||
private val typeH1 = 1
|
||||
private val typeH2 = 2
|
||||
|
@ -110,14 +113,21 @@ class GemtextAdapter(val onLink: (link: URI, longTap: Boolean, view: View?) -> U
|
|||
holder.itemView.gemtext_text_link.setOnClickListener {
|
||||
val uri = getUri(lines[holder.adapterPosition])
|
||||
println("User click link: $uri")
|
||||
onLink(uri, false, null)
|
||||
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")
|
||||
onLink(uri, true, view)
|
||||
onLink(this, uri, true, holder.adapterPosition, view)
|
||||
true
|
||||
}
|
||||
|
||||
if(imageIndexes.contains(holder.adapterPosition)){
|
||||
holder.itemView.gemtext_inline_image.visible(true)
|
||||
|
||||
//todo - need to download the image...
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -134,4 +144,9 @@ class GemtextAdapter(val onLink: (link: URI, longTap: Boolean, view: View?) -> U
|
|||
|
||||
return null
|
||||
}
|
||||
|
||||
fun loadImage(position: Int){
|
||||
imageIndexes.add(position)
|
||||
notifyItemChanged(position)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
package oppen.ariane.ui
|
||||
|
||||
import android.content.Intent
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
|
||||
class ProcessTextActivity: AppCompatActivity() {
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
val processText = when {
|
||||
Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && intent.hasExtra(Intent.EXTRA_PROCESS_TEXT) -> intent.getCharSequenceExtra(Intent.EXTRA_PROCESS_TEXT).toString()
|
||||
else -> null
|
||||
}
|
||||
|
||||
Intent(this, GemActivity::class.java).run {
|
||||
putExtra("process_text", processText)
|
||||
startActivity(this)
|
||||
finish()
|
||||
}
|
||||
}
|
||||
}
|
|
@ -4,15 +4,23 @@ import android.view.MenuInflater
|
|||
import android.view.View
|
||||
import androidx.appcompat.widget.PopupMenu
|
||||
import oppen.ariane.R
|
||||
import java.net.URI
|
||||
|
||||
|
||||
object LinkPopup {
|
||||
|
||||
fun show(view: View?, onMenuOption: (menuId: Int) -> Unit){
|
||||
fun show(view: View?, uri: URI, onMenuOption: (menuId: Int) -> Unit){
|
||||
if(view != null) {
|
||||
val popup = PopupMenu(view.context, view)
|
||||
val inflater: MenuInflater = popup.menuInflater
|
||||
inflater.inflate(R.menu.link_menu, popup.menu)
|
||||
|
||||
val path = uri.toString().toLowerCase()
|
||||
if(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)
|
||||
}
|
||||
|
||||
popup.setOnMenuItemClickListener { menuItem ->
|
||||
onMenuOption(menuItem.itemId)
|
||||
true
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
<RelativeLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content">
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
android:id="@+id/gemtext_text_link"
|
||||
android:textColor="@color/stroke"
|
||||
android:textSize="@dimen/default_text_size"
|
||||
|
@ -10,4 +13,12 @@
|
|||
android:layout_marginLeft="@dimen/screen_margin"
|
||||
android:layout_marginRight="@dimen/screen_margin"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatImageView
|
||||
android:id="@+id/gemtext_inline_image"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:visibility="gone"
|
||||
android:layout_below="@+id/gemtext_text_link"/>
|
||||
</RelativeLayout>
|
|
@ -0,0 +1,7 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:id="@+id/link_menu_load_image"
|
||||
android:title="@string/load_image" />
|
||||
<item android:id="@+id/link_menu_copy"
|
||||
android:title="@string/copy_address" />
|
||||
</menu>
|
|
@ -4,6 +4,7 @@
|
|||
<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="about">About</string>
|
||||
<string name="address_copied_to_clipboard">Address copied to clipboard</string>
|
||||
<string name="gemini_address">Gemini address</string>
|
||||
|
|
Loading…
Reference in New Issue