diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/player/PlayerGeneratorViewModel.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/player/PlayerGeneratorViewModel.kt index 42659f8d..3179cb9f 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/player/PlayerGeneratorViewModel.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/player/PlayerGeneratorViewModel.kt @@ -7,6 +7,7 @@ import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.lagradost.cloudstream3.mvvm.Resource import com.lagradost.cloudstream3.mvvm.launchSafe +import com.lagradost.cloudstream3.mvvm.logError import com.lagradost.cloudstream3.mvvm.normalSafeApiCall import com.lagradost.cloudstream3.mvvm.safeApiCall import com.lagradost.cloudstream3.ui.result.ResultEpisode @@ -15,6 +16,7 @@ import com.lagradost.cloudstream3.utils.EpisodeSkip import com.lagradost.cloudstream3.utils.ExtractorLink import com.lagradost.cloudstream3.utils.ExtractorUri import kotlinx.coroutines.Job +import kotlinx.coroutines.launch class PlayerGeneratorViewModel : ViewModel() { companion object { @@ -38,6 +40,11 @@ class PlayerGeneratorViewModel : ViewModel() { private val _currentSubtitleYear = MutableLiveData(null) val currentSubtitleYear: LiveData = _currentSubtitleYear + /** + * Save the Episode ID to prevent starting multiple link loading Jobs when preloading links. + */ + private var currentLoadingEpisodeId: Int? = null + fun setSubtitleYear(year: Int?) { _currentSubtitleYear.postValue(year) } @@ -72,18 +79,32 @@ class PlayerGeneratorViewModel : ViewModel() { } fun preLoadNextLinks() { + val id = getId() + // Do not preload if already loading + if (id == currentLoadingEpisodeId) return + Log.i(TAG, "preLoadNextLinks") currentJob?.cancel() - currentJob = viewModelScope.launchSafe { - if (generator?.hasCache == true && generator?.hasNext() == true) { - safeApiCall { - generator?.generateLinks( - type = LoadType.InApp, - clearCache = false, - callback = {}, - subtitleCallback = {}, - offset = 1 - ) + currentLoadingEpisodeId = id + + currentJob = viewModelScope.launch { + try { + if (generator?.hasCache == true && generator?.hasNext() == true) { + safeApiCall { + generator?.generateLinks( + type = LoadType.InApp, + clearCache = false, + callback = {}, + subtitleCallback = {}, + offset = 1 + ) + } + } + } catch (t: Throwable) { + logError(t) + } finally { + if (currentLoadingEpisodeId == id) { + currentLoadingEpisodeId = null } } } @@ -162,14 +183,14 @@ class PlayerGeneratorViewModel : ViewModel() { // load more data _loadingLinks.postValue(Resource.Loading()) val loadingState = safeApiCall { - generator?.generateLinks(type = type,clearCache = clearCache, callback = { + generator?.generateLinks(type = type, clearCache = clearCache, callback = { currentLinks.add(it) // Clone to prevent ConcurrentModificationException normalSafeApiCall { // Extra normalSafeApiCall since .toSet() iterates. _currentLinks.postValue(currentLinks.toSet()) } - }, subtitleCallback = { + }, subtitleCallback = { currentSubs.add(it) normalSafeApiCall { _currentSubs.postValue(currentSubs.toSet())