Skip to content

Commit

Permalink
Rely solely on recyclerview for lazy loading
Browse files Browse the repository at this point in the history
Closes #136

- Remove manual lazy loading mechanism
- Disable cross fade when loading from cache
  • Loading branch information
naveensingh committed Sep 24, 2024
1 parent 85f5f43 commit ff836d8
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 69 deletions.
82 changes: 16 additions & 66 deletions app/src/main/kotlin/org/fossify/gallery/adapters/MediaAdapter.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@ import android.content.Intent
import android.content.pm.ShortcutInfo
import android.content.pm.ShortcutManager
import android.graphics.drawable.Icon
import android.os.Handler
import android.os.Looper
import android.view.Menu
import android.view.View
import android.view.ViewGroup
Expand Down Expand Up @@ -38,22 +36,16 @@ import org.fossify.gallery.models.ThumbnailSection
class MediaAdapter(
activity: BaseSimpleActivity, var media: ArrayList<ThumbnailItem>, val listener: MediaOperationsListener?, val isAGetIntent: Boolean,
val allowMultiplePicks: Boolean, val path: String, recyclerView: MyRecyclerView, itemClick: (Any) -> Unit
) :
MyRecyclerViewAdapter(activity, recyclerView, itemClick), RecyclerViewFastScroller.OnPopupTextUpdate {
) : MyRecyclerViewAdapter(activity, recyclerView, itemClick), RecyclerViewFastScroller.OnPopupTextUpdate {

private val INSTANT_LOAD_DURATION = 2000L
private val IMAGE_LOAD_DELAY = 100L
private val ITEM_SECTION = 0
private val ITEM_MEDIUM_VIDEO_PORTRAIT = 1
private val ITEM_MEDIUM_PHOTO = 2

private val config = activity.config
private val viewType = config.getFolderViewType(if (config.showAll) SHOW_ALL else path)
private val isListViewType = viewType == VIEW_TYPE_LIST
private var visibleItemPaths = ArrayList<String>()
private var rotatedImagePaths = ArrayList<String>()
private var loadImageInstantly = false
private var delayHandler = Handler(Looper.getMainLooper())
private var currentMediaHash = media.hashCode()
private val hasOTGConnected = activity.hasOTGConnected()

Expand All @@ -69,7 +61,6 @@ class MediaAdapter(

init {
setupDragListener(true)
enableInstantLoad()
}

override fun getActionMenuId() = R.menu.cab_media
Expand Down Expand Up @@ -97,10 +88,6 @@ class MediaAdapter(

override fun onBindViewHolder(holder: MyRecyclerViewAdapter.ViewHolder, position: Int) {
val tmbItem = media.getOrNull(position) ?: return
if (tmbItem is Medium) {
visibleItemPaths.add(tmbItem.path)
}

val allowLongPress = (!isAGetIntent || allowMultiplePicks) && tmbItem is Medium
holder.bindView(tmbItem, tmbItem is Medium, allowLongPress) { itemView, adapterPosition ->
if (tmbItem is Medium) {
Expand Down Expand Up @@ -197,7 +184,6 @@ class MediaAdapter(
super.onViewRecycled(holder)
if (!activity.isDestroyed) {
val itemView = holder.itemView
visibleItemPaths.remove(itemView.allViews.firstOrNull { it.id == R.id.medium_name }?.tag)
val tmb = itemView.allViews.firstOrNull { it.id == R.id.medium_thumbnail }
if (tmb != null) {
Glide.with(activity).clear(tmb)
Expand Down Expand Up @@ -254,15 +240,13 @@ class MediaAdapter(
activity.updateDBMediaPath(firstPath, it)

activity.runOnUiThread {
enableInstantLoad()
listener?.refreshItems()
finishActMode()
}
}
}
} else {
RenameDialog(activity, getSelectedPaths(), true) {
enableInstantLoad()
listener?.refreshItems()
finishActMode()
}
Expand Down Expand Up @@ -572,15 +556,13 @@ class MediaAdapter(
if (thumbnailItems.hashCode() != currentMediaHash) {
currentMediaHash = thumbnailItems.hashCode()
media = thumbnailItems
enableInstantLoad()
notifyDataSetChanged()
finishActMode()
}
}

fun updateDisplayFilenames(displayFilenames: Boolean) {
this.displayFilenames = displayFilenames
enableInstantLoad()
notifyDataSetChanged()
}

Expand All @@ -599,13 +581,6 @@ class MediaAdapter(
notifyDataSetChanged()
}

private fun enableInstantLoad() {
loadImageInstantly = true
delayHandler.postDelayed({
loadImageInstantly = false
}, INSTANT_LOAD_DURATION)
}

private fun setupThumbnail(view: View, medium: Medium) {
val isSelected = selectedKeys.contains(medium.path.hashCode())
bindItem(view, medium).apply {
Expand Down Expand Up @@ -681,46 +656,21 @@ class MediaAdapter(
else -> ROUNDED_CORNERS_NONE
}

if (loadImageInstantly) {
activity.loadImage(
type = medium.type,
path = path,
target = mediumThumbnail,
horizontalScroll = scrollHorizontally,
animateGifs = animateGifs,
cropThumbnails = cropThumbnails,
roundCorners = roundedCorners,
signature = medium.getKey(),
skipMemoryCacheAtPaths = rotatedImagePaths,
onError = {
mediumThumbnail.scaleType = ImageView.ScaleType.CENTER
mediumThumbnail.setImageDrawable(AppCompatResources.getDrawable(activity, R.drawable.ic_vector_warning_colored))
}
)
} else {
mediumThumbnail.setImageDrawable(null)
mediumThumbnail.isHorizontalScrolling = scrollHorizontally
delayHandler.postDelayed({
val isVisible = visibleItemPaths.contains(medium.path)
if (isVisible) {
activity.loadImage(
type = medium.type,
path = path,
target = mediumThumbnail,
horizontalScroll = scrollHorizontally,
animateGifs = animateGifs,
cropThumbnails = cropThumbnails,
roundCorners = roundedCorners,
signature = medium.getKey(),
skipMemoryCacheAtPaths = rotatedImagePaths,
onError = {
mediumThumbnail.scaleType = ImageView.ScaleType.CENTER
mediumThumbnail.setImageDrawable(AppCompatResources.getDrawable(activity, R.drawable.ic_vector_warning_colored))
}
)
}
}, IMAGE_LOAD_DELAY)
}
activity.loadImage(
type = medium.type,
path = path,
target = mediumThumbnail,
horizontalScroll = scrollHorizontally,
animateGifs = animateGifs,
cropThumbnails = cropThumbnails,
roundCorners = roundedCorners,
signature = medium.getKey(),
skipMemoryCacheAtPaths = rotatedImagePaths,
onError = {
mediumThumbnail.scaleType = ImageView.ScaleType.CENTER
mediumThumbnail.setImageDrawable(AppCompatResources.getDrawable(activity, R.drawable.ic_vector_warning_colored))
}
)

if (isListViewType) {
mediumName.setTextColor(textColor)
Expand Down
5 changes: 2 additions & 3 deletions app/src/main/kotlin/org/fossify/gallery/extensions/Context.kt
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ import com.bumptech.glide.load.engine.GlideException
import com.bumptech.glide.load.resource.bitmap.CenterCrop
import com.bumptech.glide.load.resource.bitmap.FitCenter
import com.bumptech.glide.load.resource.bitmap.RoundedCorners
import com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions
import com.bumptech.glide.request.RequestListener
import com.bumptech.glide.request.RequestOptions
import com.bumptech.glide.request.target.Target
Expand Down Expand Up @@ -586,7 +585,7 @@ fun Context.loadImageBase(
.load(path)
.apply(options)
.set(WebpDownsampler.USE_SYSTEM_DECODER, false) // CVE-2023-4863
.transition(DrawableTransitionOptions.withCrossFade(crossFadeDuration))
.transition(getOptionalCrossFadeTransition(crossFadeDuration))

builder = builder.listener(object : RequestListener<Drawable> {
override fun onLoadFailed(e: GlideException?, model: Any?, targetBitmap: Target<Drawable>, isFirstResource: Boolean): Boolean {
Expand Down Expand Up @@ -627,7 +626,7 @@ fun Context.loadSVG(
.listener(SvgSoftwareLayerSetter())
.load(path)
.apply(options)
.transition(DrawableTransitionOptions.withCrossFade(crossFadeDuration))
.transition(getOptionalCrossFadeTransition(crossFadeDuration))

if (roundCorners != ROUNDED_CORNERS_NONE) {
val cornerSize =
Expand Down
19 changes: 19 additions & 0 deletions app/src/main/kotlin/org/fossify/gallery/extensions/Glide.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package org.fossify.gallery.extensions

import com.bumptech.glide.load.DataSource
import com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions
import com.bumptech.glide.request.transition.DrawableCrossFadeFactory
import com.bumptech.glide.request.transition.TransitionFactory

/**
* Cross fade transition option that disabled fading when loading from cache.
*/
fun getOptionalCrossFadeTransition(duration: Int): DrawableTransitionOptions {
return DrawableTransitionOptions.with(
TransitionFactory { dataSource, isFirstResource ->
if (dataSource == DataSource.RESOURCE_DISK_CACHE) return@TransitionFactory null
DrawableCrossFadeFactory.Builder(duration).build().build(dataSource, isFirstResource)
}
)
}

0 comments on commit ff836d8

Please # to comment.