Compare commits
	
		
			3 Commits
		
	
	
		
			v125010111
			...
			ce255b23cd
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| ce255b23cd | |||
| 3b3a575dae | |||
| 
						 | 
					7bcf4574b4 | 
@@ -1,3 +1,10 @@
 | 
			
		||||
**v125010111
 | 
			
		||||
 | 
			
		||||
- Debug trying to fix context issues. (#174)
 | 
			
		||||
- Changelog for v125010031
 | 
			
		||||
 | 
			
		||||
--------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
**v125010031
 | 
			
		||||
 | 
			
		||||
- Merge pull request 'Bump dependencies' (#173) from upgarde into master
 | 
			
		||||
 
 | 
			
		||||
@@ -317,50 +317,44 @@ class HomeActivity :
 | 
			
		||||
 | 
			
		||||
    private fun reloadLayoutManager() {
 | 
			
		||||
        val currentManager = binding.recyclerView.layoutManager
 | 
			
		||||
        val layoutManager: RecyclerView.LayoutManager
 | 
			
		||||
 | 
			
		||||
        // This will only update the layout manager if settings changed
 | 
			
		||||
        fun gridLayoutManager() {
 | 
			
		||||
            val layoutManager =
 | 
			
		||||
                GridLayoutManager(
 | 
			
		||||
                    this,
 | 
			
		||||
                    calculateNoOfColumns(),
 | 
			
		||||
                )
 | 
			
		||||
            binding.recyclerView.layoutManager = layoutManager
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        fun staggererdGridLayoutManager() {
 | 
			
		||||
            var layoutManager =
 | 
			
		||||
                StaggeredGridLayoutManager(
 | 
			
		||||
                    calculateNoOfColumns(),
 | 
			
		||||
                    StaggeredGridLayoutManager.VERTICAL,
 | 
			
		||||
                )
 | 
			
		||||
            layoutManager.gapStrategy =
 | 
			
		||||
                StaggeredGridLayoutManager.GAP_HANDLING_MOVE_ITEMS_BETWEEN_SPANS
 | 
			
		||||
            binding.recyclerView.layoutManager = layoutManager
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        when (currentManager) {
 | 
			
		||||
            is StaggeredGridLayoutManager ->
 | 
			
		||||
                if (!appSettingsService.isCardViewEnabled()) {
 | 
			
		||||
                    layoutManager =
 | 
			
		||||
                        GridLayoutManager(
 | 
			
		||||
                            this,
 | 
			
		||||
                            calculateNoOfColumns(),
 | 
			
		||||
                        )
 | 
			
		||||
                    binding.recyclerView.layoutManager = layoutManager
 | 
			
		||||
                    gridLayoutManager()
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
            is GridLayoutManager ->
 | 
			
		||||
                if (appSettingsService.isCardViewEnabled()) {
 | 
			
		||||
                    layoutManager =
 | 
			
		||||
                        StaggeredGridLayoutManager(
 | 
			
		||||
                            calculateNoOfColumns(),
 | 
			
		||||
                            StaggeredGridLayoutManager.VERTICAL,
 | 
			
		||||
                        )
 | 
			
		||||
                    layoutManager.gapStrategy =
 | 
			
		||||
                        StaggeredGridLayoutManager.GAP_HANDLING_MOVE_ITEMS_BETWEEN_SPANS
 | 
			
		||||
                    binding.recyclerView.layoutManager = layoutManager
 | 
			
		||||
                    staggererdGridLayoutManager()
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
            else ->
 | 
			
		||||
                if (currentManager == null) {
 | 
			
		||||
                    if (!appSettingsService.isCardViewEnabled()) {
 | 
			
		||||
                        layoutManager =
 | 
			
		||||
                            GridLayoutManager(
 | 
			
		||||
                                this,
 | 
			
		||||
                                calculateNoOfColumns(),
 | 
			
		||||
                            )
 | 
			
		||||
                        binding.recyclerView.layoutManager = layoutManager
 | 
			
		||||
                        gridLayoutManager()
 | 
			
		||||
                    } else {
 | 
			
		||||
                        layoutManager =
 | 
			
		||||
                            StaggeredGridLayoutManager(
 | 
			
		||||
                                calculateNoOfColumns(),
 | 
			
		||||
                                StaggeredGridLayoutManager.VERTICAL,
 | 
			
		||||
                            )
 | 
			
		||||
                        layoutManager.gapStrategy =
 | 
			
		||||
                            StaggeredGridLayoutManager.GAP_HANDLING_MOVE_ITEMS_BETWEEN_SPANS
 | 
			
		||||
                        binding.recyclerView.layoutManager = layoutManager
 | 
			
		||||
                        staggererdGridLayoutManager()
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
        }
 | 
			
		||||
@@ -485,8 +479,8 @@ class HomeActivity :
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private fun handleListResult(appendResults: Boolean = false) {
 | 
			
		||||
        val oldManager = binding.recyclerView.layoutManager
 | 
			
		||||
        if (appendResults) {
 | 
			
		||||
            val oldManager = binding.recyclerView.layoutManager
 | 
			
		||||
            firstVisible =
 | 
			
		||||
                when (oldManager) {
 | 
			
		||||
                    is StaggeredGridLayoutManager ->
 | 
			
		||||
@@ -499,7 +493,13 @@ class HomeActivity :
 | 
			
		||||
                }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (recyclerAdapter == null) {
 | 
			
		||||
        @Suppress("detekt:ComplexCondition")
 | 
			
		||||
        if (recyclerAdapter == null ||
 | 
			
		||||
            (
 | 
			
		||||
                (recyclerAdapter is ItemListAdapter && appSettingsService.isCardViewEnabled()) ||
 | 
			
		||||
                    (recyclerAdapter is ItemCardAdapter && !appSettingsService.isCardViewEnabled())
 | 
			
		||||
            )
 | 
			
		||||
        ) {
 | 
			
		||||
            if (appSettingsService.isCardViewEnabled()) {
 | 
			
		||||
                recyclerAdapter =
 | 
			
		||||
                    ItemCardAdapter(
 | 
			
		||||
 
 | 
			
		||||
@@ -118,13 +118,13 @@ class ItemCardAdapter(
 | 
			
		||||
                binding.itemImage.setImageDrawable(null)
 | 
			
		||||
            } else {
 | 
			
		||||
                binding.itemImage.visibility = View.VISIBLE
 | 
			
		||||
                c.bitmapCenterCrop(itm.getThumbnail(repository.baseUrl), binding.itemImage)
 | 
			
		||||
                c.bitmapCenterCrop(itm.getThumbnail(repository.baseUrl), binding.itemImage, appSettingsService)
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (itm.getIcon(repository.baseUrl).isEmpty()) {
 | 
			
		||||
                binding.sourceImage.setBackgroundAndText(itm.sourcetitle.getHtmlDecoded())
 | 
			
		||||
            } else {
 | 
			
		||||
                c.circularDrawable(itm.getIcon(repository.baseUrl), binding.sourceImage)
 | 
			
		||||
                c.circularDrawable(itm.getIcon(repository.baseUrl), binding.sourceImage, appSettingsService)
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -65,10 +65,10 @@ class ItemListAdapter(
 | 
			
		||||
                if (itm.getIcon(repository.baseUrl).isEmpty()) {
 | 
			
		||||
                    binding.itemImage.setBackgroundAndText(itm.sourcetitle.getHtmlDecoded())
 | 
			
		||||
                } else {
 | 
			
		||||
                    c.circularDrawable(itm.getIcon(repository.baseUrl), binding.itemImage)
 | 
			
		||||
                    c.circularDrawable(itm.getIcon(repository.baseUrl), binding.itemImage, appSettingsService)
 | 
			
		||||
                }
 | 
			
		||||
            } else {
 | 
			
		||||
                c.circularDrawable(itm.getThumbnail(repository.baseUrl), binding.itemImage)
 | 
			
		||||
                c.circularDrawable(itm.getThumbnail(repository.baseUrl), binding.itemImage, appSettingsService)
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -16,6 +16,7 @@ import bou.amine.apps.readerforselfossv2.android.databinding.SourceListItemBindi
 | 
			
		||||
import bou.amine.apps.readerforselfossv2.android.utils.glide.circularDrawable
 | 
			
		||||
import bou.amine.apps.readerforselfossv2.model.SelfossModel
 | 
			
		||||
import bou.amine.apps.readerforselfossv2.repository.Repository
 | 
			
		||||
import bou.amine.apps.readerforselfossv2.service.AppSettingsService
 | 
			
		||||
import bou.amine.apps.readerforselfossv2.utils.getHtmlDecoded
 | 
			
		||||
import bou.amine.apps.readerforselfossv2.utils.getIcon
 | 
			
		||||
import kotlinx.coroutines.CoroutineScope
 | 
			
		||||
@@ -36,6 +37,7 @@ class SourcesListAdapter(
 | 
			
		||||
 | 
			
		||||
    override val di: DI by closestDI(app)
 | 
			
		||||
    private val repository: Repository by instance()
 | 
			
		||||
    private val appSettingsService: AppSettingsService by instance()
 | 
			
		||||
 | 
			
		||||
    override fun onCreateViewHolder(
 | 
			
		||||
        parent: ViewGroup,
 | 
			
		||||
@@ -82,7 +84,7 @@ class SourcesListAdapter(
 | 
			
		||||
        if (itm.getIcon(repository.baseUrl).isEmpty()) {
 | 
			
		||||
            binding.itemImage.setBackgroundAndText(itm.title.getHtmlDecoded())
 | 
			
		||||
        } else {
 | 
			
		||||
            c.circularDrawable(itm.getIcon(repository.baseUrl), binding.itemImage)
 | 
			
		||||
            c.circularDrawable(itm.getIcon(repository.baseUrl), binding.itemImage, appSettingsService)
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (!itm.error.isNullOrBlank()) {
 | 
			
		||||
 
 | 
			
		||||
@@ -63,7 +63,7 @@ class LoadingWorker(
 | 
			
		||||
                        handleNewItemsNotification(apiItems, notificationManager)
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                apiItems.map { it.preloadImages(context) }
 | 
			
		||||
                apiItems.map { it.preloadImages(context, appSettingsService) }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return Result.success()
 | 
			
		||||
 
 | 
			
		||||
@@ -32,7 +32,9 @@ import bou.amine.apps.readerforselfossv2.android.model.ParecelableItem
 | 
			
		||||
import bou.amine.apps.readerforselfossv2.android.model.toModel
 | 
			
		||||
import bou.amine.apps.readerforselfossv2.android.model.toParcelable
 | 
			
		||||
import bou.amine.apps.readerforselfossv2.android.utils.acra.sendSilentlyWithAcraWithName
 | 
			
		||||
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.openItemUrlInBrowserAsNewTask
 | 
			
		||||
import bou.amine.apps.readerforselfossv2.android.utils.openUrlInBrowser
 | 
			
		||||
@@ -46,9 +48,6 @@ import bou.amine.apps.readerforselfossv2.utils.getHtmlDecoded
 | 
			
		||||
import bou.amine.apps.readerforselfossv2.utils.getImages
 | 
			
		||||
import bou.amine.apps.readerforselfossv2.utils.getThumbnail
 | 
			
		||||
import bou.amine.apps.readerforselfossv2.utils.isEmptyOrNullOrNullString
 | 
			
		||||
import com.bumptech.glide.Glide
 | 
			
		||||
import com.bumptech.glide.load.engine.DiskCacheStrategy
 | 
			
		||||
import com.bumptech.glide.request.RequestOptions
 | 
			
		||||
import com.github.rubensousa.floatingtoolbar.FloatingToolbar
 | 
			
		||||
import com.google.android.material.floatingactionbutton.FloatingActionButton
 | 
			
		||||
import kotlinx.coroutines.CoroutineScope
 | 
			
		||||
@@ -65,6 +64,8 @@ import java.util.Locale
 | 
			
		||||
import java.util.concurrent.ExecutionException
 | 
			
		||||
 | 
			
		||||
private const val IMAGE_JPG = "image/jpg"
 | 
			
		||||
private const val IMAGE_PNG = "image/png"
 | 
			
		||||
private const val IMAGE_WEBP = "image/webp"
 | 
			
		||||
 | 
			
		||||
private const val WHITE_COLOR_HEX = 0xFFFFFF
 | 
			
		||||
 | 
			
		||||
@@ -208,12 +209,7 @@ class ArticleFragment :
 | 
			
		||||
 | 
			
		||||
            if (!contentImage.isEmptyOrNullOrNullString() && context != null) {
 | 
			
		||||
                binding.imageView.visibility = View.VISIBLE
 | 
			
		||||
                Glide
 | 
			
		||||
                    .with(requireContext())
 | 
			
		||||
                    .asBitmap()
 | 
			
		||||
                    .load(contentImage)
 | 
			
		||||
                    .apply(RequestOptions.fitCenterTransform())
 | 
			
		||||
                    .into(binding.imageView)
 | 
			
		||||
                requireContext().bitmapFitCenter(contentImage, binding.imageView, appSettingsService)
 | 
			
		||||
            } else {
 | 
			
		||||
                binding.imageView.visibility = View.GONE
 | 
			
		||||
            }
 | 
			
		||||
@@ -327,13 +323,7 @@ class ArticleFragment :
 | 
			
		||||
    private fun handleLeadImage(leadImageUrl: String?) {
 | 
			
		||||
        if (!leadImageUrl.isNullOrEmpty() && context != null) {
 | 
			
		||||
            binding.imageView.visibility = View.VISIBLE
 | 
			
		||||
            Glide
 | 
			
		||||
                .with(requireContext())
 | 
			
		||||
                .asBitmap()
 | 
			
		||||
                .load(
 | 
			
		||||
                    leadImageUrl,
 | 
			
		||||
                ).apply(RequestOptions.fitCenterTransform())
 | 
			
		||||
                .into(binding.imageView)
 | 
			
		||||
            requireContext().bitmapFitCenter(leadImageUrl, binding.imageView, appSettingsService)
 | 
			
		||||
        } else {
 | 
			
		||||
            binding.imageView.visibility = View.GONE
 | 
			
		||||
        }
 | 
			
		||||
@@ -357,78 +347,37 @@ class ArticleFragment :
 | 
			
		||||
                        false
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                @Suppress("detekt:LongMethod", "detekt:SwallowedException")
 | 
			
		||||
                @Suppress("detekt:SwallowedException", "detekt:ReturnCount")
 | 
			
		||||
                @Deprecated("Deprecated in Java")
 | 
			
		||||
                override fun shouldInterceptRequest(
 | 
			
		||||
                    view: WebView,
 | 
			
		||||
                    url: String,
 | 
			
		||||
                ): WebResourceResponse? {
 | 
			
		||||
                    val glideOptions = RequestOptions.diskCacheStrategyOf(DiskCacheStrategy.ALL)
 | 
			
		||||
                    var glideResource: WebResourceResponse? = null
 | 
			
		||||
                    if (url.lowercase(Locale.US).contains(".jpg") ||
 | 
			
		||||
                        url
 | 
			
		||||
                            .lowercase(Locale.US)
 | 
			
		||||
                            .contains(".jpeg")
 | 
			
		||||
                    ) {
 | 
			
		||||
                        try {
 | 
			
		||||
                            val image =
 | 
			
		||||
                                Glide
 | 
			
		||||
                                    .with(view)
 | 
			
		||||
                                    .asBitmap()
 | 
			
		||||
                                    .apply(glideOptions)
 | 
			
		||||
                                    .load(url)
 | 
			
		||||
                                    .submit()
 | 
			
		||||
                                    .get()
 | 
			
		||||
                            glideResource =
 | 
			
		||||
                                WebResourceResponse(
 | 
			
		||||
                                    IMAGE_JPG,
 | 
			
		||||
                                    "UTF-8",
 | 
			
		||||
                                    getBitmapInputStream(image, Bitmap.CompressFormat.JPEG),
 | 
			
		||||
                                )
 | 
			
		||||
                        } catch (e: ExecutionException) {
 | 
			
		||||
                            // Do nothing
 | 
			
		||||
                    val (mime: String?, compression: Bitmap.CompressFormat) =
 | 
			
		||||
                        if (url
 | 
			
		||||
                                .lowercase(Locale.US)
 | 
			
		||||
                                .contains(".jpg") ||
 | 
			
		||||
                            url.lowercase(Locale.US).contains(".jpeg")
 | 
			
		||||
                        ) {
 | 
			
		||||
                            Pair(IMAGE_JPG, Bitmap.CompressFormat.JPEG)
 | 
			
		||||
                        } else if (url.lowercase(Locale.US).contains(".png")) {
 | 
			
		||||
                            Pair(IMAGE_PNG, Bitmap.CompressFormat.PNG)
 | 
			
		||||
                        } else if (url.lowercase(Locale.US).contains(".webp")) {
 | 
			
		||||
                            Pair(IMAGE_WEBP, Bitmap.CompressFormat.WEBP)
 | 
			
		||||
                        } else {
 | 
			
		||||
                            return super.shouldInterceptRequest(view, url)
 | 
			
		||||
                        }
 | 
			
		||||
                    } else if (url.lowercase(Locale.US).contains(".png")) {
 | 
			
		||||
                        try {
 | 
			
		||||
                            val image =
 | 
			
		||||
                                Glide
 | 
			
		||||
                                    .with(view)
 | 
			
		||||
                                    .asBitmap()
 | 
			
		||||
                                    .apply(glideOptions)
 | 
			
		||||
                                    .load(url)
 | 
			
		||||
                                    .submit()
 | 
			
		||||
                                    .get()
 | 
			
		||||
                            glideResource =
 | 
			
		||||
                                WebResourceResponse(
 | 
			
		||||
                                    IMAGE_JPG,
 | 
			
		||||
                                    "UTF-8",
 | 
			
		||||
                                    getBitmapInputStream(image, Bitmap.CompressFormat.PNG),
 | 
			
		||||
                                )
 | 
			
		||||
                        } catch (e: ExecutionException) {
 | 
			
		||||
                            // Do nothing
 | 
			
		||||
                        }
 | 
			
		||||
                    } else if (url.lowercase(Locale.US).contains(".webp")) {
 | 
			
		||||
                        try {
 | 
			
		||||
                            val image =
 | 
			
		||||
                                Glide
 | 
			
		||||
                                    .with(view)
 | 
			
		||||
                                    .asBitmap()
 | 
			
		||||
                                    .apply(glideOptions)
 | 
			
		||||
                                    .load(url)
 | 
			
		||||
                                    .submit()
 | 
			
		||||
                                    .get()
 | 
			
		||||
                            glideResource =
 | 
			
		||||
                                WebResourceResponse(
 | 
			
		||||
                                    IMAGE_JPG,
 | 
			
		||||
                                    "UTF-8",
 | 
			
		||||
                                    getBitmapInputStream(image, Bitmap.CompressFormat.WEBP),
 | 
			
		||||
                                )
 | 
			
		||||
                        } catch (e: ExecutionException) {
 | 
			
		||||
                            // Do nothing
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    return glideResource ?: super.shouldInterceptRequest(view, url)
 | 
			
		||||
                    try {
 | 
			
		||||
                        val image = view.getGlideImageForResource(url, appSettingsService)
 | 
			
		||||
                        return WebResourceResponse(
 | 
			
		||||
                            mime,
 | 
			
		||||
                            "UTF-8",
 | 
			
		||||
                            getBitmapInputStream(image, compression),
 | 
			
		||||
                        )
 | 
			
		||||
                    } catch (e: ExecutionException) {
 | 
			
		||||
                        return super.shouldInterceptRequest(view, url)
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -16,11 +16,12 @@ import bou.amine.apps.readerforselfossv2.android.HomeActivity
 | 
			
		||||
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.repository.Repository
 | 
			
		||||
import bou.amine.apps.readerforselfossv2.service.AppSettingsService
 | 
			
		||||
import bou.amine.apps.readerforselfossv2.utils.getColorHexCode
 | 
			
		||||
import bou.amine.apps.readerforselfossv2.utils.getHtmlDecoded
 | 
			
		||||
import bou.amine.apps.readerforselfossv2.utils.getIcon
 | 
			
		||||
import com.bumptech.glide.Glide
 | 
			
		||||
import com.bumptech.glide.request.target.ViewTarget
 | 
			
		||||
import com.bumptech.glide.request.transition.Transition
 | 
			
		||||
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
 | 
			
		||||
@@ -41,6 +42,7 @@ class FilterSheetFragment :
 | 
			
		||||
    private lateinit var binding: FilterFragmentBinding
 | 
			
		||||
    override val di: DI by closestDI()
 | 
			
		||||
    private val repository: Repository by instance()
 | 
			
		||||
    private val appSettingsService: AppSettingsService by instance()
 | 
			
		||||
 | 
			
		||||
    private var selectedChip: Chip? = null
 | 
			
		||||
 | 
			
		||||
@@ -84,23 +86,22 @@ class FilterSheetFragment :
 | 
			
		||||
            val c = Chip(context)
 | 
			
		||||
            c.ellipsize = TextUtils.TruncateAt.END
 | 
			
		||||
 | 
			
		||||
            Glide
 | 
			
		||||
                .with(context)
 | 
			
		||||
                .load(source.getIcon(repository.baseUrl))
 | 
			
		||||
                .into(
 | 
			
		||||
                    object : ViewTarget<Chip?, Drawable?>(c) {
 | 
			
		||||
                        override fun onResourceReady(
 | 
			
		||||
                            resource: Drawable,
 | 
			
		||||
                            transition: Transition<in Drawable?>?,
 | 
			
		||||
                        ) {
 | 
			
		||||
                            try {
 | 
			
		||||
                                c.chipIcon = resource
 | 
			
		||||
                            } catch (e: Exception) {
 | 
			
		||||
                                e.sendSilentlyWithAcraWithName("sources > onResourceReady")
 | 
			
		||||
                            }
 | 
			
		||||
            context.imageIntoViewTarget(
 | 
			
		||||
                source.getIcon(repository.baseUrl),
 | 
			
		||||
                object : ViewTarget<Chip?, Drawable?>(c) {
 | 
			
		||||
                    override fun onResourceReady(
 | 
			
		||||
                        resource: Drawable,
 | 
			
		||||
                        transition: Transition<in Drawable?>?,
 | 
			
		||||
                    ) {
 | 
			
		||||
                        try {
 | 
			
		||||
                            c.chipIcon = resource
 | 
			
		||||
                        } catch (e: Exception) {
 | 
			
		||||
                            e.sendSilentlyWithAcraWithName("sources > onResourceReady")
 | 
			
		||||
                        }
 | 
			
		||||
                    },
 | 
			
		||||
                )
 | 
			
		||||
                    }
 | 
			
		||||
                },
 | 
			
		||||
                appSettingsService,
 | 
			
		||||
            )
 | 
			
		||||
 | 
			
		||||
            c.text = source.title.getHtmlDecoded()
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -6,13 +6,19 @@ import android.view.View
 | 
			
		||||
import android.view.ViewGroup
 | 
			
		||||
import androidx.fragment.app.Fragment
 | 
			
		||||
import bou.amine.apps.readerforselfossv2.android.databinding.FragmentImageBinding
 | 
			
		||||
import com.bumptech.glide.Glide
 | 
			
		||||
import com.bumptech.glide.load.engine.DiskCacheStrategy
 | 
			
		||||
import com.bumptech.glide.request.RequestOptions
 | 
			
		||||
import bou.amine.apps.readerforselfossv2.android.utils.glide.bitmapWithCache
 | 
			
		||||
import bou.amine.apps.readerforselfossv2.service.AppSettingsService
 | 
			
		||||
import org.kodein.di.DI
 | 
			
		||||
import org.kodein.di.DIAware
 | 
			
		||||
import org.kodein.di.android.x.closestDI
 | 
			
		||||
import org.kodein.di.instance
 | 
			
		||||
 | 
			
		||||
class ImageFragment : Fragment() {
 | 
			
		||||
class ImageFragment :
 | 
			
		||||
    Fragment(),
 | 
			
		||||
    DIAware {
 | 
			
		||||
    override val di: DI by closestDI()
 | 
			
		||||
    private val appSettingsService: AppSettingsService by instance()
 | 
			
		||||
    private lateinit var imageUrl: String
 | 
			
		||||
    private val glideOptions = RequestOptions.diskCacheStrategyOf(DiskCacheStrategy.ALL)
 | 
			
		||||
    private var _binding: FragmentImageBinding? = null
 | 
			
		||||
    val binding get() = _binding
 | 
			
		||||
 | 
			
		||||
@@ -31,12 +37,7 @@ class ImageFragment : Fragment() {
 | 
			
		||||
        val view = binding?.root
 | 
			
		||||
 | 
			
		||||
        binding!!.photoView.visibility = View.VISIBLE
 | 
			
		||||
        Glide
 | 
			
		||||
            .with(requireActivity())
 | 
			
		||||
            .asBitmap()
 | 
			
		||||
            .apply(glideOptions)
 | 
			
		||||
            .load(imageUrl)
 | 
			
		||||
            .into(binding!!.photoView)
 | 
			
		||||
        requireActivity().bitmapWithCache(imageUrl, binding!!.photoView, appSettingsService)
 | 
			
		||||
 | 
			
		||||
        return view
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -3,28 +3,21 @@ package bou.amine.apps.readerforselfossv2.android.model
 | 
			
		||||
import android.content.Context
 | 
			
		||||
import android.webkit.URLUtil
 | 
			
		||||
import bou.amine.apps.readerforselfossv2.android.utils.acra.sendSilentlyWithAcraWithName
 | 
			
		||||
import bou.amine.apps.readerforselfossv2.android.utils.glide.preloadImage
 | 
			
		||||
import bou.amine.apps.readerforselfossv2.model.SelfossModel
 | 
			
		||||
import bou.amine.apps.readerforselfossv2.service.AppSettingsService
 | 
			
		||||
import bou.amine.apps.readerforselfossv2.utils.getImages
 | 
			
		||||
import com.bumptech.glide.Glide
 | 
			
		||||
import com.bumptech.glide.load.engine.DiskCacheStrategy
 | 
			
		||||
import com.bumptech.glide.request.RequestOptions
 | 
			
		||||
 | 
			
		||||
private const val PRELOAD_IMAGE_TIMEOUT = 10000
 | 
			
		||||
 | 
			
		||||
fun SelfossModel.Item.preloadImages(context: Context): Boolean {
 | 
			
		||||
fun SelfossModel.Item.preloadImages(
 | 
			
		||||
    context: Context,
 | 
			
		||||
    appSettingsService: AppSettingsService,
 | 
			
		||||
): Boolean {
 | 
			
		||||
    val imageUrls = this.getImages()
 | 
			
		||||
 | 
			
		||||
    val glideOptions = RequestOptions.diskCacheStrategyOf(DiskCacheStrategy.ALL).timeout(PRELOAD_IMAGE_TIMEOUT)
 | 
			
		||||
 | 
			
		||||
    try {
 | 
			
		||||
        for (url in imageUrls) {
 | 
			
		||||
            if (URLUtil.isValidUrl(url)) {
 | 
			
		||||
                Glide
 | 
			
		||||
                    .with(context)
 | 
			
		||||
                    .asBitmap()
 | 
			
		||||
                    .apply(glideOptions)
 | 
			
		||||
                    .load(url)
 | 
			
		||||
                    .submit()
 | 
			
		||||
                context.preloadImage(url, appSettingsService)
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    } catch (e: Error) {
 | 
			
		||||
 
 | 
			
		||||
@@ -2,33 +2,119 @@ package bou.amine.apps.readerforselfossv2.android.utils.glide
 | 
			
		||||
 | 
			
		||||
import android.content.Context
 | 
			
		||||
import android.graphics.Bitmap
 | 
			
		||||
import android.graphics.drawable.Drawable
 | 
			
		||||
import android.webkit.WebView
 | 
			
		||||
import android.widget.ImageView
 | 
			
		||||
import bou.amine.apps.readerforselfossv2.android.utils.CircleImageView
 | 
			
		||||
import bou.amine.apps.readerforselfossv2.service.AppSettingsService
 | 
			
		||||
import com.bumptech.glide.Glide
 | 
			
		||||
import com.bumptech.glide.load.engine.DiskCacheStrategy
 | 
			
		||||
import com.bumptech.glide.load.model.GlideUrl
 | 
			
		||||
import com.bumptech.glide.load.model.LazyHeaders
 | 
			
		||||
import com.bumptech.glide.request.RequestOptions
 | 
			
		||||
import com.bumptech.glide.request.target.ViewTarget
 | 
			
		||||
import com.google.android.material.chip.Chip
 | 
			
		||||
import java.io.ByteArrayInputStream
 | 
			
		||||
import java.io.ByteArrayOutputStream
 | 
			
		||||
import java.io.InputStream
 | 
			
		||||
import kotlin.io.encoding.Base64
 | 
			
		||||
import kotlin.io.encoding.ExperimentalEncodingApi
 | 
			
		||||
 | 
			
		||||
private const val PRELOAD_IMAGE_TIMEOUT = 10000
 | 
			
		||||
 | 
			
		||||
@OptIn(ExperimentalEncodingApi::class)
 | 
			
		||||
fun String.toGlideUrl(appSettingsService: AppSettingsService): GlideUrl {
 | 
			
		||||
    if (appSettingsService.getBasicUserName().isNotEmpty()) {
 | 
			
		||||
        val authString = "${appSettingsService.getBasicUserName()}:${appSettingsService.getBasicPassword()}"
 | 
			
		||||
        val authBuf = Base64.encode(authString.toByteArray(Charsets.UTF_8))
 | 
			
		||||
 | 
			
		||||
        return GlideUrl(
 | 
			
		||||
            this,
 | 
			
		||||
            LazyHeaders
 | 
			
		||||
                .Builder()
 | 
			
		||||
                .addHeader("Authorization", "Basic $authBuf")
 | 
			
		||||
                .build(),
 | 
			
		||||
        )
 | 
			
		||||
    } else {
 | 
			
		||||
        return GlideUrl(
 | 
			
		||||
            this,
 | 
			
		||||
        )
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fun WebView.getGlideImageForResource(
 | 
			
		||||
    url: String,
 | 
			
		||||
    appSettingsService: AppSettingsService,
 | 
			
		||||
) = Glide
 | 
			
		||||
    .with(this)
 | 
			
		||||
    .asBitmap()
 | 
			
		||||
    .apply(RequestOptions.diskCacheStrategyOf(DiskCacheStrategy.ALL))
 | 
			
		||||
    .load(url.toGlideUrl(appSettingsService))
 | 
			
		||||
    .submit()
 | 
			
		||||
    .get()
 | 
			
		||||
 | 
			
		||||
fun Context.preloadImage(
 | 
			
		||||
    url: String,
 | 
			
		||||
    appSettingsService: AppSettingsService,
 | 
			
		||||
) = Glide
 | 
			
		||||
    .with(this)
 | 
			
		||||
    .asBitmap()
 | 
			
		||||
    .apply(RequestOptions.diskCacheStrategyOf(DiskCacheStrategy.ALL).timeout(PRELOAD_IMAGE_TIMEOUT))
 | 
			
		||||
    .load(url.toGlideUrl(appSettingsService))
 | 
			
		||||
    .submit()
 | 
			
		||||
 | 
			
		||||
fun Context.imageIntoViewTarget(
 | 
			
		||||
    url: String,
 | 
			
		||||
    target: ViewTarget<Chip?, Drawable?>,
 | 
			
		||||
    appSettingsService: AppSettingsService,
 | 
			
		||||
) = Glide
 | 
			
		||||
    .with(this)
 | 
			
		||||
    .load(url.toGlideUrl(appSettingsService))
 | 
			
		||||
    .into(target)
 | 
			
		||||
 | 
			
		||||
fun Context.bitmapWithCache(
 | 
			
		||||
    url: String,
 | 
			
		||||
    iv: ImageView,
 | 
			
		||||
    appSettingsService: AppSettingsService,
 | 
			
		||||
) = Glide
 | 
			
		||||
    .with(this)
 | 
			
		||||
    .asBitmap()
 | 
			
		||||
    .apply(RequestOptions.diskCacheStrategyOf(DiskCacheStrategy.ALL))
 | 
			
		||||
    .load(url.toGlideUrl(appSettingsService))
 | 
			
		||||
    .into(iv)
 | 
			
		||||
 | 
			
		||||
fun Context.bitmapCenterCrop(
 | 
			
		||||
    url: String,
 | 
			
		||||
    iv: ImageView,
 | 
			
		||||
    appSettingsService: AppSettingsService,
 | 
			
		||||
) = Glide
 | 
			
		||||
    .with(this)
 | 
			
		||||
    .asBitmap()
 | 
			
		||||
    .load(url)
 | 
			
		||||
    .load(url.toGlideUrl(appSettingsService))
 | 
			
		||||
    .apply(RequestOptions.centerCropTransform())
 | 
			
		||||
    .into(iv)
 | 
			
		||||
 | 
			
		||||
fun Context.bitmapFitCenter(
 | 
			
		||||
    url: String,
 | 
			
		||||
    iv: ImageView,
 | 
			
		||||
    appSettingsService: AppSettingsService,
 | 
			
		||||
) = Glide
 | 
			
		||||
    .with(this)
 | 
			
		||||
    .asBitmap()
 | 
			
		||||
    .load(url.toGlideUrl(appSettingsService))
 | 
			
		||||
    .apply(RequestOptions.fitCenterTransform())
 | 
			
		||||
    .into(iv)
 | 
			
		||||
 | 
			
		||||
fun Context.circularDrawable(
 | 
			
		||||
    url: String,
 | 
			
		||||
    view: CircleImageView,
 | 
			
		||||
    appSettingsService: AppSettingsService,
 | 
			
		||||
) {
 | 
			
		||||
    view.textView.text = ""
 | 
			
		||||
 | 
			
		||||
    Glide
 | 
			
		||||
        .with(this)
 | 
			
		||||
        .load(url)
 | 
			
		||||
        .load(url.toGlideUrl(appSettingsService))
 | 
			
		||||
        .into(view.imageView)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,4 @@
 | 
			
		||||
**v125010111**
 | 
			
		||||
 | 
			
		||||
- Debug trying to fix context issues. (#174)
 | 
			
		||||
- Changelog for v125010031
 | 
			
		||||
		Reference in New Issue
	
	Block a user