diff --git a/app/app/src/main/java/com/github/livingwithhippos/unchained/data/repository/UnrestrictRepository.kt b/app/app/src/main/java/com/github/livingwithhippos/unchained/data/repository/UnrestrictRepository.kt index 0bcf8851..49cb12ab 100644 --- a/app/app/src/main/java/com/github/livingwithhippos/unchained/data/repository/UnrestrictRepository.kt +++ b/app/app/src/main/java/com/github/livingwithhippos/unchained/data/repository/UnrestrictRepository.kt @@ -1,5 +1,7 @@ package com.github.livingwithhippos.unchained.data.repository +import android.os.SystemClock +import android.util.LruCache import com.github.livingwithhippos.unchained.data.local.ProtoStore import com.github.livingwithhippos.unchained.data.model.DownloadItem import com.github.livingwithhippos.unchained.data.model.UnchainedNetworkException @@ -16,12 +18,28 @@ class UnrestrictRepository constructor(protoStore: ProtoStore, private val unrestrictApiHelper: UnrestrictApiHelper) : BaseRepository(protoStore) { + private val unrestrictedLinkCache = + LruCache( + UNRESTRICTED_LINK_CACHE_MAX_ENTRIES + ) + suspend fun getEitherUnrestrictedLink( link: String, password: String? = null, remote: Int? = null, ): EitherResult { val token = getToken() + val cacheKey = + UnrestrictedLinkCacheKey( + token = token, + link = link, + password = password, + remote = remote, + ) + + getCachedUnrestrictedLink(cacheKey)?.let { + return EitherResult.Success(it) + } val linkResponse = eitherApiResult( @@ -36,9 +54,17 @@ constructor(protoStore: ProtoStore, private val unrestrictApiHelper: UnrestrictA errorMessage = "Error Fetching Unrestricted Link Info", ) + if (linkResponse is EitherResult.Success) { + cacheUnrestrictedLink(cacheKey, linkResponse.success) + } + return linkResponse } + fun clearUnrestrictedLinkCache() { + synchronized(unrestrictedLinkCache) { unrestrictedLinkCache.evictAll() } + } + suspend fun getUnrestrictedLinkList( linksList: List, password: String? = null, @@ -110,4 +136,46 @@ constructor(protoStore: ProtoStore, private val unrestrictApiHelper: UnrestrictA return containerResponse } + + private fun cacheUnrestrictedLink(key: UnrestrictedLinkCacheKey, item: DownloadItem) { + synchronized(unrestrictedLinkCache) { + unrestrictedLinkCache.put( + key, + CachedUnrestrictedLink( + item = item, + createdAtElapsedRealtime = SystemClock.elapsedRealtime(), + ), + ) + } + } + + private fun getCachedUnrestrictedLink(key: UnrestrictedLinkCacheKey): DownloadItem? = + synchronized(unrestrictedLinkCache) { + val cachedLink = unrestrictedLinkCache.get(key) ?: return@synchronized null + val cacheAge = SystemClock.elapsedRealtime() - cachedLink.createdAtElapsedRealtime + + if (cacheAge <= UNRESTRICTED_LINK_CACHE_TTL_MS) { + cachedLink.item + } else { + unrestrictedLinkCache.remove(key) + null + } + } + + private data class UnrestrictedLinkCacheKey( + val token: String, + val link: String, + val password: String?, + val remote: Int?, + ) + + private data class CachedUnrestrictedLink( + val item: DownloadItem, + val createdAtElapsedRealtime: Long, + ) + + companion object { + private const val UNRESTRICTED_LINK_CACHE_MAX_ENTRIES = 5000 + private const val UNRESTRICTED_LINK_CACHE_TTL_MS = 2 * 60 * 60 * 1000L + } } diff --git a/app/app/src/main/java/com/github/livingwithhippos/unchained/folderlist/view/FolderListFragment.kt b/app/app/src/main/java/com/github/livingwithhippos/unchained/folderlist/view/FolderListFragment.kt index a33e68c5..32719e32 100644 --- a/app/app/src/main/java/com/github/livingwithhippos/unchained/folderlist/view/FolderListFragment.kt +++ b/app/app/src/main/java/com/github/livingwithhippos/unchained/folderlist/view/FolderListFragment.kt @@ -236,15 +236,7 @@ class FolderListFragment : UnchainedFragment(), DownloadListListener { // observe the list loading status viewModel.folderLiveData.observe(viewLifecycleOwner) { - it.getContentIfNotHandled()?.let { _ -> - updateList(adapter) - // scroll only if the results are still coming in - if (viewModel.getScrollingAllowed()) { - lifecycleScope.launch { - binding.rvFolderList.delayedScrolling(requireContext(), delay = 500) - } - } - } + it.getContentIfNotHandled()?.let { _ -> updateList(adapter) } } // observe errors diff --git a/app/app/src/main/java/com/github/livingwithhippos/unchained/folderlist/viewmodel/FolderListViewModel.kt b/app/app/src/main/java/com/github/livingwithhippos/unchained/folderlist/viewmodel/FolderListViewModel.kt index d2e45395..0e1721bf 100644 --- a/app/app/src/main/java/com/github/livingwithhippos/unchained/folderlist/viewmodel/FolderListViewModel.kt +++ b/app/app/src/main/java/com/github/livingwithhippos/unchained/folderlist/viewmodel/FolderListViewModel.kt @@ -74,7 +74,7 @@ constructor( } is EitherResult.Success -> { hitList.add(file.success) - folderLiveData.postEvent(hitList) + folderLiveData.postEvent(hitList.toList()) setRetrievedLinks(hitList.size) progressLiveData.postValue((index + 1) * 100 / links.size) }