diff --git a/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/fragments/ArticleFragment.kt b/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/fragments/ArticleFragment.kt index 1672abf..6b1276a 100644 --- a/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/fragments/ArticleFragment.kt +++ b/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/fragments/ArticleFragment.kt @@ -33,6 +33,7 @@ import bou.amine.apps.readerforselfossv2.android.utils.glide.bitmapFitCenter import bou.amine.apps.readerforselfossv2.android.utils.glide.getBitmapInputStream import bou.amine.apps.readerforselfossv2.android.utils.glide.getGlideImageForResource import bou.amine.apps.readerforselfossv2.android.utils.isUrlValid +import bou.amine.apps.readerforselfossv2.android.utils.maybeIfContext import bou.amine.apps.readerforselfossv2.android.utils.openItemUrlInBrowserAsNewTask import bou.amine.apps.readerforselfossv2.android.utils.openUrlInBrowserAsNewTask import bou.amine.apps.readerforselfossv2.android.utils.shareLink @@ -117,8 +118,8 @@ class ArticleFragment : e.sendSilentlyWithAcra() } - colorOnSurface = requireContext().getColorFromAttr(R.attr.colorOnSurface) - colorSurface = requireContext().getColorFromAttr(R.attr.colorSurface) + colorOnSurface = getColorFromAttr(R.attr.colorOnSurface) + colorSurface = getColorFromAttr(R.attr.colorSurface) contentText = item.content contentTitle = item.title.getHtmlDecoded() @@ -147,11 +148,11 @@ class ArticleFragment : handleContent() } catch (e: InflateException) { e.sendSilentlyWithAcraWithName("webview not available") - try { + maybeIfContext { AlertDialog - .Builder(requireContext()) - .setMessage(requireContext().getString(R.string.webview_dialog_issue_message)) - .setTitle(requireContext().getString(R.string.webview_dialog_issue_title)) + .Builder(it) + .setMessage(it.getString(R.string.webview_dialog_issue_message)) + .setTitle(it.getString(R.string.webview_dialog_issue_title)) .setPositiveButton( android.R.string.ok, ) { _, _ -> @@ -159,8 +160,6 @@ class ArticleFragment : requireActivity().finish() }.create() .show() - } catch (e: IllegalStateException) { - e.sendSilentlyWithAcraWithName("OnCreate context required is null") } } @@ -182,7 +181,7 @@ class ArticleFragment : if (!contentImage.isEmptyOrNullOrNullString() && context != null) { binding.imageView.visibility = View.VISIBLE - requireContext().bitmapFitCenter(contentImage, binding.imageView, appSettingsService) + maybeIfContext { it.bitmapFitCenter(contentImage, binding.imageView, appSettingsService) } } else { binding.imageView.visibility = View.GONE } @@ -194,7 +193,7 @@ class ArticleFragment : fab.mainFabClosedIconColor = colorOnSurface fab.mainFabOpenedIconColor = colorOnSurface - handleFloatingToolbarActionItems() + maybeIfContext { context -> handleFloatingToolbarActionItems(context) } fab.setOnActionSelectedListener { actionItem -> when (actionItem.id) { @@ -207,12 +206,14 @@ class ArticleFragment : repository.markAsRead(this@ArticleFragment.item) } this@ArticleFragment.item.unread = false - Toast - .makeText( - requireContext(), - R.string.marked_as_read, - Toast.LENGTH_LONG, - ).show() + maybeIfContext { + Toast + .makeText( + it, + R.string.marked_as_read, + Toast.LENGTH_LONG, + ).show() + } } else { CoroutineScope(Dispatchers.IO).launch { repository.unmarkAsRead(this@ArticleFragment.item) @@ -235,14 +236,14 @@ class ArticleFragment : } } - private fun handleFloatingToolbarActionItems() { + private fun handleFloatingToolbarActionItems(c: Context) { fab.addHomeMadeActionItem( R.id.share_action, resources.getDrawable(R.drawable.ic_share_white_24dp), R.string.reader_action_share, colorOnSurface, colorSurface, - requireContext(), + c, ) fab.addHomeMadeActionItem( R.id.open_action, @@ -250,7 +251,7 @@ class ArticleFragment : R.string.reader_action_open, colorOnSurface, colorSurface, - requireContext(), + c, ) fab.addHomeMadeActionItem( R.id.unread_action, @@ -258,7 +259,7 @@ class ArticleFragment : R.string.unmark, colorOnSurface, colorSurface, - requireContext(), + c, ) } @@ -311,9 +312,11 @@ class ArticleFragment : } private fun handleLeadImage(leadImageUrl: String?) { - if (!leadImageUrl.isNullOrEmpty() && context != null) { + if (!leadImageUrl.isNullOrEmpty()) { binding.imageView.visibility = View.VISIBLE - requireContext().bitmapFitCenter(leadImageUrl, binding.imageView, appSettingsService) + maybeIfContext { + it.bitmapFitCenter(leadImageUrl, binding.imageView, appSettingsService) + } } else { binding.imageView.visibility = View.GONE } @@ -327,11 +330,10 @@ class ArticleFragment : view: WebView?, url: String, ): Boolean = - if (context != null && - url.isUrlValid() && + if (url.isUrlValid() && binding.webcontent.hitTestResult.type != WebView.HitTestResult.SRC_IMAGE_ANCHOR_TYPE ) { - requireContext().openUrlInBrowserAsNewTask(url) + maybeIfContext { it.openUrlInBrowserAsNewTask(url) } true } else { false @@ -374,23 +376,14 @@ class ArticleFragment : @Suppress("detekt:LongMethod", "detekt:ImplicitDefaultLocale") private fun htmlToWebview() { - val context: Context - try { - context = requireContext() - } catch (e: IllegalStateException) { - e.sendSilentlyWithAcraWithName("Webview context required is null") - return - } - - try { + maybeIfContext { val attrs: IntArray = intArrayOf(android.R.attr.fontFamily) - val a: TypedArray = context.obtainStyledAttributes(resId, attrs) + val a: TypedArray = it.obtainStyledAttributes(resId, attrs) binding.webcontent.settings.standardFontFamily = a.getString(0) - binding.webcontent.visibility = View.VISIBLE - } catch (e: IllegalStateException) { - e.sendSilentlyWithAcraWithName("Context issue when setting attributes, but context wasn't null before") + "" } + binding.webcontent.visibility = View.VISIBLE val colorSurfaceString = String.format( @@ -483,7 +476,7 @@ class ArticleFragment : | color: ${ String.format( "#%06X", - WHITE_COLOR_HEX and context.resources.getColor(R.color.colorAccent), + WHITE_COLOR_HEX and (maybeIfContext { it.resources.getColor(R.color.colorAccent) } as Int), ) } !important; | } @@ -540,10 +533,8 @@ class ArticleFragment : private fun openInBrowserAfterFailing() { binding.progressBar.visibility = View.GONE - try { - requireContext().openItemUrlInBrowserAsNewTask(this@ArticleFragment.item) - } catch (e: IllegalStateException) { - e.sendSilentlyWithAcraWithName("After failing context required is null") + maybeIfContext { + it.openItemUrlInBrowserAsNewTask(this@ArticleFragment.item) } } diff --git a/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/fragments/FilterSheetFragment.kt b/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/fragments/FilterSheetFragment.kt index 067affb..477a6aa 100644 --- a/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/fragments/FilterSheetFragment.kt +++ b/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/fragments/FilterSheetFragment.kt @@ -1,6 +1,5 @@ package bou.amine.apps.readerforselfossv2.android.fragments -import android.content.Context import android.graphics.Color import android.graphics.drawable.Drawable import android.graphics.drawable.GradientDrawable @@ -17,6 +16,7 @@ import bou.amine.apps.readerforselfossv2.android.R import bou.amine.apps.readerforselfossv2.android.databinding.FilterFragmentBinding import bou.amine.apps.readerforselfossv2.android.utils.acra.sendSilentlyWithAcraWithName import bou.amine.apps.readerforselfossv2.android.utils.glide.imageIntoViewTarget +import bou.amine.apps.readerforselfossv2.android.utils.maybeIfContext import bou.amine.apps.readerforselfossv2.repository.Repository import bou.amine.apps.readerforselfossv2.service.AppSettingsService import bou.amine.apps.readerforselfossv2.utils.getColorHexCode @@ -60,8 +60,8 @@ class FilterSheetFragment : try { CoroutineScope(Dispatchers.Main).launch { - handleTagChips(requireContext()) - handleSourceChips(requireContext()) + handleTagChips() + handleSourceChips() binding.progressBar2.visibility = GONE binding.filterView.visibility = VISIBLE @@ -79,29 +79,31 @@ class FilterSheetFragment : return binding.root } - private suspend fun handleSourceChips(context: Context) { + private suspend fun handleSourceChips() { val sourceGroup = binding.sourcesGroup repository.getSourcesDetailsOrStats().forEachIndexed { _, source -> val c = Chip(context) c.ellipsize = TextUtils.TruncateAt.END - context.imageIntoViewTarget( - source.getIcon(repository.baseUrl), - object : ViewTarget(c) { - override fun onResourceReady( - resource: Drawable, - transition: Transition?, - ) { - try { - c.chipIcon = resource - } catch (e: Exception) { - e.sendSilentlyWithAcraWithName("sources > onResourceReady") + maybeIfContext { + it.imageIntoViewTarget( + source.getIcon(repository.baseUrl), + object : ViewTarget(c) { + override fun onResourceReady( + resource: Drawable, + transition: Transition?, + ) { + try { + c.chipIcon = resource + } catch (e: Exception) { + e.sendSilentlyWithAcraWithName("sources > onResourceReady") + } } - } - }, - appSettingsService, - ) + }, + appSettingsService, + ) + } c.text = source.title.getHtmlDecoded() @@ -137,7 +139,7 @@ class FilterSheetFragment : } } - private suspend fun handleTagChips(context: Context) { + private suspend fun handleTagChips() { val tagGroup = binding.tagsGroup val tags = repository.getTags() diff --git a/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/utils/AppUtils.kt b/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/utils/AppUtils.kt index 4f7bfce..77d0311 100644 --- a/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/utils/AppUtils.kt +++ b/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/utils/AppUtils.kt @@ -5,6 +5,7 @@ import android.content.Intent import android.util.TypedValue import androidx.annotation.AttrRes import androidx.annotation.ColorInt +import androidx.fragment.app.Fragment import bou.amine.apps.readerforselfossv2.android.R import bou.amine.apps.readerforselfossv2.android.utils.acra.sendSilentlyWithAcraWithName import bou.amine.apps.readerforselfossv2.utils.toStringUriWithHttp @@ -29,15 +30,30 @@ fun Context.shareLink( } @ColorInt -fun Context.getColorFromAttr( +fun Fragment.getColorFromAttr( @AttrRes attrColor: Int, resolveRefs: Boolean = true, ): Int { val typedValue = TypedValue() - try { - this.theme.resolveAttribute(attrColor, typedValue, resolveRefs) - } catch (e: Throwable) { - e.sendSilentlyWithAcraWithName("ColorFromAttr") - } + maybeIfContextWithLog { this.requireContext().theme.resolveAttribute(attrColor, typedValue, resolveRefs) } return typedValue.data } + +@Suppress("detekt:SwallowedException") +fun Fragment.maybeIfContext(fn: (Context) -> Any): Any? { + try { + return fn(this.requireContext()) + } catch (e: Exception) { + // Do nothing + return null + } +} + +fun Fragment.maybeIfContextWithLog(fn: (Context) -> Any): Any? { + try { + return fn(this.requireContext()) + } catch (e: Exception) { + e.sendSilentlyWithAcraWithName("Fragment context issue...") + return null + } +} diff --git a/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/utils/glide/GlideUtils.kt b/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/utils/glide/GlideUtils.kt index 8e4009d..e1dc7e8 100644 --- a/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/utils/glide/GlideUtils.kt +++ b/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/utils/glide/GlideUtils.kt @@ -23,6 +23,7 @@ import kotlin.io.encoding.ExperimentalEncodingApi private const val PRELOAD_IMAGE_TIMEOUT = 10000 +@Suppress("detekt:ReturnCount") @OptIn(ExperimentalEncodingApi::class) fun String.toGlideUrl(appSettingsService: AppSettingsService): Any { // GlideUrl Or String if (this.isEmptyOrNullOrNullString()) {