Preload next image during slideshow (#1847)
## Description When viewing images in a slideshow, this PR enqueues the next image so it will likely be cached and ready to display when the slideshow advances. This works for both automatic and manual scrolling as well as advancing next or previous images. ### Related issues Closes #1835 ### Testing Emulator with large photos ## Screenshots N/A ## AI or LLM usage None
This commit is contained in:
parent
22a949bc76
commit
4e53cbaa7f
1 changed files with 41 additions and 4 deletions
|
|
@ -6,6 +6,9 @@ import androidx.compose.runtime.Stable
|
|||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import androidx.media3.common.Player
|
||||
import coil3.imageLoader
|
||||
import coil3.request.ImageRequest
|
||||
import coil3.size.Size
|
||||
import com.github.damontecres.wholphin.data.ChosenStreams
|
||||
import com.github.damontecres.wholphin.data.PlaybackEffectDao
|
||||
import com.github.damontecres.wholphin.data.ServerRepository
|
||||
|
|
@ -172,7 +175,7 @@ class SlideshowViewModel
|
|||
val size = state.value.items.size
|
||||
val newPosition = state.value.position + 1
|
||||
return if (newPosition < size) {
|
||||
updatePosition(newPosition)
|
||||
updatePosition(newPosition, true)
|
||||
true
|
||||
} else {
|
||||
false
|
||||
|
|
@ -182,14 +185,23 @@ class SlideshowViewModel
|
|||
fun previousImage(): Boolean {
|
||||
val newPosition = state.value.position - 1
|
||||
return if (newPosition >= 0) {
|
||||
updatePosition(newPosition)
|
||||
updatePosition(newPosition, false)
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
fun updatePosition(position: Int): Job? =
|
||||
/**
|
||||
* Update image state to the specified position
|
||||
*
|
||||
* @param position the index to use
|
||||
* @param isNext whether moving to the next or previous image for prefetching purposes
|
||||
*/
|
||||
fun updatePosition(
|
||||
position: Int,
|
||||
isNext: Boolean = true,
|
||||
): Job? =
|
||||
(state.value.items as? ApiRequestPager<*>)?.let { pager ->
|
||||
viewModelScope.launchIO {
|
||||
try {
|
||||
|
|
@ -286,6 +298,31 @@ class SlideshowViewModel
|
|||
)
|
||||
}
|
||||
}
|
||||
try {
|
||||
// If there is a next/previous image, fetch it into the image cache
|
||||
val nextIndex = position + if (isNext) 1 else -1
|
||||
if (nextIndex in pager.indices) {
|
||||
pager.getBlocking(nextIndex)?.let { nextImage ->
|
||||
if (nextImage.data.mediaType == MediaType.PHOTO) {
|
||||
val url = api.libraryApi.getDownloadUrl(nextImage.id)
|
||||
val request =
|
||||
ImageRequest
|
||||
.Builder(context)
|
||||
.data(url)
|
||||
.size(Size.ORIGINAL)
|
||||
.build()
|
||||
context.imageLoader.enqueue(request)
|
||||
Timber.v(
|
||||
"Prefetching index=%s, id=%s",
|
||||
nextIndex,
|
||||
nextImage.id,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (ex: Exception) {
|
||||
Timber.e(ex, "Error preloading image")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -339,7 +376,7 @@ class SlideshowViewModel
|
|||
fun pulseSlideshow() = pulseSlideshow(slideshowDelay)
|
||||
|
||||
fun pulseSlideshow(milliseconds: Long) {
|
||||
Timber.v("pulseSlideshow $milliseconds")
|
||||
// Timber.v("pulseSlideshow $milliseconds")
|
||||
slideshowJob?.cancel()
|
||||
slideshowJob =
|
||||
viewModelScope
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue