bugfix: No browser, no link.

This commit is contained in:
Amine Bouabdallaoui 2024-12-30 13:51:14 +01:00
parent 27c1bba146
commit 162a350a8f
5 changed files with 66 additions and 45 deletions

View File

@ -1,7 +1,6 @@
package bou.amine.apps.readerforselfossv2.android
import android.content.Intent
import android.net.Uri
import android.os.Bundle
import android.view.Menu
import android.view.MenuItem
@ -32,6 +31,7 @@ import bou.amine.apps.readerforselfossv2.android.settings.SettingsActivity
import bou.amine.apps.readerforselfossv2.android.testing.CountingIdlingResourceSingleton
import bou.amine.apps.readerforselfossv2.android.utils.bottombar.maybeShow
import bou.amine.apps.readerforselfossv2.android.utils.bottombar.removeBadge
import bou.amine.apps.readerforselfossv2.android.utils.openUrlInBrowser
import bou.amine.apps.readerforselfossv2.model.SelfossModel
import bou.amine.apps.readerforselfossv2.repository.Repository
import bou.amine.apps.readerforselfossv2.service.AppSettingsService
@ -589,9 +589,7 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener, DIAwar
override fun onOptionsItemSelected(item: MenuItem): Boolean {
when (item.itemId) {
R.id.issue_tracker -> {
val browserIntent =
Intent(Intent.ACTION_VIEW, Uri.parse(AppSettingsService.trackerUrl))
startActivity(browserIntent)
baseContext.openUrlInBrowser(AppSettingsService.trackerUrl)
return true
}

View File

@ -12,7 +12,7 @@ import bou.amine.apps.readerforselfossv2.android.sendSilentlyWithAcraWithName
import bou.amine.apps.readerforselfossv2.android.utils.LinkOnTouchListener
import bou.amine.apps.readerforselfossv2.android.utils.glide.bitmapCenterCrop
import bou.amine.apps.readerforselfossv2.android.utils.glide.circularDrawable
import bou.amine.apps.readerforselfossv2.android.utils.openInBrowserAsNewTask
import bou.amine.apps.readerforselfossv2.android.utils.openItemUrlInBrowserAsNewTask
import bou.amine.apps.readerforselfossv2.android.utils.shareLink
import bou.amine.apps.readerforselfossv2.model.SelfossModel
import bou.amine.apps.readerforselfossv2.repository.Repository
@ -71,7 +71,7 @@ class ItemCardAdapter(
}
binding.browserBtn.setOnClickListener {
c.openInBrowserAsNewTask(items[position])
c.openItemUrlInBrowserAsNewTask(items[position])
}
}
@ -126,4 +126,4 @@ class ItemCardAdapter(
}
inner class ViewHolder(val binding: CardItemBinding) : RecyclerView.ViewHolder(binding.root)
}
}

View File

@ -1,16 +1,20 @@
package bou.amine.apps.readerforselfossv2.android.fragments
import android.content.ActivityNotFoundException
import android.content.Intent
import android.content.res.ColorStateList
import android.content.res.TypedArray
import android.graphics.Bitmap
import android.graphics.Typeface
import android.graphics.drawable.ColorDrawable
import android.net.Uri
import android.os.Bundle
import android.util.TypedValue
import android.view.*
import android.view.GestureDetector
import android.view.InflateException
import android.view.LayoutInflater
import android.view.MenuItem
import android.view.MotionEvent
import android.view.View
import android.view.ViewGroup
import android.webkit.WebResourceResponse
import android.webkit.WebSettings
import android.webkit.WebView
@ -28,7 +32,8 @@ import bou.amine.apps.readerforselfossv2.android.model.toParcelable
import bou.amine.apps.readerforselfossv2.android.sendSilentlyWithAcraWithName
import bou.amine.apps.readerforselfossv2.android.utils.glide.getBitmapInputStream
import bou.amine.apps.readerforselfossv2.android.utils.isUrlValid
import bou.amine.apps.readerforselfossv2.android.utils.openInBrowserAsNewTask
import bou.amine.apps.readerforselfossv2.android.utils.openItemUrlInBrowserAsNewTask
import bou.amine.apps.readerforselfossv2.android.utils.openUrlInBrowser
import bou.amine.apps.readerforselfossv2.android.utils.shareLink
import bou.amine.apps.readerforselfossv2.model.MercuryModel
import bou.amine.apps.readerforselfossv2.model.SelfossModel
@ -53,7 +58,7 @@ import org.kodein.di.android.x.closestDI
import org.kodein.di.instance
import java.net.MalformedURLException
import java.net.URL
import java.util.*
import java.util.Locale
import java.util.concurrent.ExecutionException
private const val IMAGE_JPG = "image/jpg"
@ -211,7 +216,7 @@ class ArticleFragment : Fragment(), DIAware {
override fun onItemClick(item: MenuItem) {
when (item.itemId) {
R.id.share_action -> requireActivity().shareLink(url, contentTitle)
R.id.open_action -> requireActivity().openInBrowserAsNewTask(this@ArticleFragment.item)
R.id.open_action -> requireActivity().openItemUrlInBrowserAsNewTask(this@ArticleFragment.item)
R.id.unread_action ->
if (context != null) {
if (this@ArticleFragment.item.unread) {
@ -236,6 +241,7 @@ class ArticleFragment : Fragment(), DIAware {
).show()
}
}
else -> Unit
}
}
@ -288,7 +294,7 @@ class ArticleFragment : Fragment(), DIAware {
contentText = data.content.orEmpty()
htmlToWebview()
handleLeadImage(data?.lead_image_url)
handleLeadImage(data.lead_image_url)
binding.nestedScrollView.scrollTo(0, 0)
binding.progressBar.visibility = View.GONE
@ -320,11 +326,7 @@ class ArticleFragment : Fragment(), DIAware {
url: String,
): Boolean {
return if (context != null && url.isUrlValid() && binding.webcontent.hitTestResult.type != WebView.HitTestResult.SRC_IMAGE_ANCHOR_TYPE) {
try {
requireContext().startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(url)))
} catch (e: ActivityNotFoundException) {
e.sendSilentlyWithAcraWithName("activityNotFound > $url")
}
requireContext().openUrlInBrowser(url)
true
} else {
false
@ -343,7 +345,8 @@ class ArticleFragment : Fragment(), DIAware {
) {
try {
val image =
Glide.with(view).asBitmap().apply(glideOptions).load(url).submit().get()
Glide.with(view).asBitmap().apply(glideOptions).load(url).submit()
.get()
return WebResourceResponse(
IMAGE_JPG,
"UTF-8",
@ -355,7 +358,8 @@ class ArticleFragment : Fragment(), DIAware {
} else if (url.lowercase(Locale.US).contains(".png")) {
try {
val image =
Glide.with(view).asBitmap().apply(glideOptions).load(url).submit().get()
Glide.with(view).asBitmap().apply(glideOptions).load(url).submit()
.get()
return WebResourceResponse(
IMAGE_JPG,
"UTF-8",
@ -367,7 +371,8 @@ class ArticleFragment : Fragment(), DIAware {
} else if (url.lowercase(Locale.US).contains(".webp")) {
try {
val image =
Glide.with(view).asBitmap().apply(glideOptions).load(url).submit().get()
Glide.with(view).asBitmap().apply(glideOptions).load(url).submit()
.get()
return WebResourceResponse(
IMAGE_JPG,
"UTF-8",
@ -545,7 +550,7 @@ class ArticleFragment : Fragment(), DIAware {
private fun openInBrowserAfterFailing() {
binding.progressBar.visibility = View.GONE
if (context != null) {
requireContext().openInBrowserAsNewTask(this@ArticleFragment.item)
requireContext().openItemUrlInBrowserAsNewTask(this@ArticleFragment.item)
} else {
Exception("openInBrowserAfterFailing context is null").sendSilentlyWithAcraWithName("openInBrowserAfterFailing > $context")
}
@ -565,9 +570,9 @@ class ArticleFragment : Fragment(), DIAware {
fun performClick(): Boolean {
if (allImages != null && (
binding.webcontent.hitTestResult.type == WebView.HitTestResult.IMAGE_TYPE ||
binding.webcontent.hitTestResult.type == WebView.HitTestResult.SRC_IMAGE_ANCHOR_TYPE
)
binding.webcontent.hitTestResult.type == WebView.HitTestResult.IMAGE_TYPE ||
binding.webcontent.hitTestResult.type == WebView.HitTestResult.SRC_IMAGE_ANCHOR_TYPE
)
) {
val position: Int = allImages.indexOf(binding.webcontent.hitTestResult.extra)
@ -579,4 +584,4 @@ class ArticleFragment : Fragment(), DIAware {
}
return false
}
}
}

View File

@ -1,7 +1,5 @@
package bou.amine.apps.readerforselfossv2.android.settings
import android.content.Intent
import android.net.Uri
import android.os.Bundle
import android.text.Editable
import android.text.InputFilter
@ -17,6 +15,7 @@ import androidx.preference.PreferenceFragmentCompat
import bou.amine.apps.readerforselfossv2.android.R
import bou.amine.apps.readerforselfossv2.android.databinding.ActivitySettingsBinding
import bou.amine.apps.readerforselfossv2.android.sendSilentlyWithAcraWithName
import bou.amine.apps.readerforselfossv2.android.utils.openUrlInBrowser
import bou.amine.apps.readerforselfossv2.service.AppSettingsService
import com.mikepenz.aboutlibraries.LibsBuilder
import org.kodein.di.DIAware
@ -237,9 +236,8 @@ class SettingsActivity :
}
class LinksPreferenceFragment : PreferenceFragmentCompat() {
private fun openUrl(uri: Uri?) {
val browserIntent = Intent(Intent.ACTION_VIEW, uri)
startActivity(browserIntent)
private fun openUrl(url: String) {
context?.openUrlInBrowser(url)
}
override fun onCreatePreferences(
@ -250,19 +248,19 @@ class SettingsActivity :
preferenceManager.findPreference<Preference>("trackerLink")?.onPreferenceClickListener =
Preference.OnPreferenceClickListener {
openUrl(Uri.parse(AppSettingsService.trackerUrl))
openUrl(AppSettingsService.trackerUrl)
true
}
preferenceManager.findPreference<Preference>("sourceLink")?.onPreferenceClickListener =
Preference.OnPreferenceClickListener {
openUrl(Uri.parse(AppSettingsService.sourceUrl))
openUrl(AppSettingsService.sourceUrl)
false
}
preferenceManager.findPreference<Preference>("translation")?.onPreferenceClickListener =
Preference.OnPreferenceClickListener {
openUrl(Uri.parse(AppSettingsService.translationUrl))
openUrl(AppSettingsService.translationUrl)
false
}
}
@ -276,4 +274,4 @@ class SettingsActivity :
setPreferencesFromResource(R.xml.pref_experimental, rootKey)
}
}
}
}

View File

@ -1,6 +1,7 @@
package bou.amine.apps.readerforselfossv2.android.utils
import android.app.Activity
import android.content.ActivityNotFoundException
import android.content.Context
import android.content.Intent
import android.net.Uri
@ -17,6 +18,7 @@ import bou.amine.apps.readerforselfossv2.model.SelfossModel
import bou.amine.apps.readerforselfossv2.utils.toStringUriWithHttp
import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
fun Context.openItemUrl(
currentItem: Int,
linkDecoded: String,
@ -35,15 +37,13 @@ fun Context.openItemUrl(
intent.putExtra("currentItem", currentItem)
app.startActivity(intent)
} else {
val intent = Intent(Intent.ACTION_VIEW)
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
intent.data = Uri.parse(linkDecoded.toStringUriWithHttp())
startActivity(intent)
this.openUrlInBrowserAsNewTask(linkDecoded)
}
}
}
fun String.isUrlValid(): Boolean = this.toHttpUrlOrNull() != null && Patterns.WEB_URL.matcher(this).matches()
fun String.isUrlValid(): Boolean =
this.toHttpUrlOrNull() != null && Patterns.WEB_URL.matcher(this).matches()
fun String.isBaseUrlInvalid(): Boolean {
val baseUrl = this.toHttpUrlOrNull()
@ -56,11 +56,31 @@ fun String.isBaseUrlInvalid(): Boolean {
return !(Patterns.WEB_URL.matcher(this).matches() && existsAndEndsWithSlash)
}
fun Context.openInBrowserAsNewTask(i: SelfossModel.Item) {
fun Context.openItemUrlInBrowserAsNewTask(i: SelfossModel.Item) {
this.openUrlInBrowserAsNewTask(i.getLinkDecoded().toStringUriWithHttp())
}
fun Context.openUrlInBrowserAsNewTask(url: String) {
val intent = Intent(Intent.ACTION_VIEW)
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
intent.data = Uri.parse(i.getLinkDecoded().toStringUriWithHttp())
startActivity(intent)
intent.data = Uri.parse(url)
this.mayBeStartActivity(intent)
}
fun Context.openUrlInBrowser(url: String) {
val intent = Intent(Intent.ACTION_VIEW)
intent.data = Uri.parse(url)
this.mayBeStartActivity(intent)
}
fun Context.mayBeStartActivity(intent: Intent) {
try {
this.startActivity(intent)
} catch (e: ActivityNotFoundException) {
Toast.makeText(this, getString(R.string.no_browser), Toast.LENGTH_SHORT).show()
}
}
class LinkOnTouchListener : View.OnTouchListener {
@ -102,4 +122,4 @@ class LinkOnTouchListener : View.OnTouchListener {
}
return ret
}
}
}