Fixes to connectivity loss playback restart and fixes to added ensureEnoughContentVisible.

This commit is contained in:
Koen 2023-12-01 15:01:41 +01:00
commit 23d1085755
3 changed files with 43 additions and 25 deletions

View file

@ -390,7 +390,7 @@ class Settings : FragmentedStorageFileJson() {
@DropdownFieldOptionsId(R.array.restart_playback_after_loss)
var restartPlaybackAfterLoss: Int = 1;
@FormField(R.string.restart_after_connectivity_loss, FieldForm.DROPDOWN, R.string.restart_playback_when_gaining_connectivity_after_a_loss, 11)
@FormField(R.string.restart_after_connectivity_loss, FieldForm.DROPDOWN, R.string.restart_playback_when_gaining_connectivity_after_a_loss, 12)
@DropdownFieldOptionsId(R.array.restart_playback_after_loss)
var restartPlaybackAfterConnectivityLoss: Int = 1;
}

View file

@ -13,7 +13,6 @@ import androidx.recyclerview.widget.RecyclerView.LayoutManager
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
import com.futo.platformplayer.*
import com.futo.platformplayer.api.media.IPlatformClient
import com.futo.platformplayer.api.media.models.contents.IPlatformContent
import com.futo.platformplayer.api.media.platforms.js.models.JSPager
import com.futo.platformplayer.api.media.structures.*
import com.futo.platformplayer.constructs.Event1
@ -21,7 +20,6 @@ import com.futo.platformplayer.constructs.TaskHandler
import com.futo.platformplayer.engine.exceptions.PluginException
import com.futo.platformplayer.logging.Logger
import com.futo.platformplayer.views.FeedStyle
import com.futo.platformplayer.views.adapters.ContentPreviewViewHolder
import com.futo.platformplayer.views.others.ProgressBar
import com.futo.platformplayer.views.others.TagsView
import com.futo.platformplayer.views.adapters.InsertedViewAdapterWithLoader
@ -64,6 +62,7 @@ abstract class FeedView<TFragment, TResult, TConverted, TPager, TViewHolder> : L
val fragment: TFragment;
private val _scrollListener: RecyclerView.OnScrollListener;
private var _automaticNextPageCounter = 0;
constructor(fragment: TFragment, inflater: LayoutInflater, cachedRecyclerData: RecyclerData<InsertedViewAdapterWithLoader<TViewHolder>, LinearLayoutManager, TPager, TResult, TConverted, InsertedViewHolder<TViewHolder>>? = null) : super(inflater.context) {
this.fragment = fragment;
@ -122,7 +121,6 @@ abstract class FeedView<TFragment, TResult, TConverted, TPager, TViewHolder> : L
_toolbarContentView = findViewById(R.id.container_toolbar_content);
var filteredNextPageCounter = 0;
_nextPageHandler = TaskHandler<TPager, List<TResult>>({fragment.lifecycleScope}, {
if (it is IAsyncPager<*>)
it.nextPageAsync();
@ -142,15 +140,8 @@ abstract class FeedView<TFragment, TResult, TConverted, TPager, TViewHolder> : L
val filteredResults = filterResults(it);
recyclerData.results.addAll(filteredResults);
recyclerData.resultsUnfiltered.addAll(it);
if(filteredResults.isEmpty()) {
filteredNextPageCounter++
if(filteredNextPageCounter <= 4)
loadNextPage()
}
else {
filteredNextPageCounter = 0;
recyclerData.adapter.notifyItemRangeInserted(recyclerData.adapter.childToParentPosition(posBefore), filteredResults.size);
}
recyclerData.adapter.notifyItemRangeInserted(recyclerData.adapter.childToParentPosition(posBefore), filteredResults.size);
ensureEnoughContentVisible(filteredResults)
}.exception<Throwable> {
Logger.w(TAG, "Failed to load next page.", it);
UIDialogs.showGeneralRetryErrorDialog(context, context.getString(R.string.failed_to_load_next_page), it, {
@ -170,8 +161,10 @@ abstract class FeedView<TFragment, TResult, TConverted, TPager, TViewHolder> : L
val visibleItemCount = _recyclerResults.childCount;
val firstVisibleItem = recyclerData.layoutManager.findFirstVisibleItemPosition();
//Logger.i(TAG, "onScrolled loadNextPage visibleItemCount=$visibleItemCount firstVisibleItem=$visibleItemCount")
if (!_loading && firstVisibleItem + visibleItemCount + visibleThreshold >= recyclerData.results.size && firstVisibleItem > 0) {
//Logger.i(TAG, "loadNextPage(): firstVisibleItem=$firstVisibleItem visibleItemCount=$visibleItemCount visibleThreshold=$visibleThreshold _results.size=${_results.size}")
//Logger.i(TAG, "onScrolled loadNextPage(): firstVisibleItem=$firstVisibleItem visibleItemCount=$visibleItemCount visibleThreshold=$visibleThreshold recyclerData.results.size=${recyclerData.results.size}")
loadNextPage();
}
}
@ -180,6 +173,33 @@ abstract class FeedView<TFragment, TResult, TConverted, TPager, TViewHolder> : L
_recyclerResults.addOnScrollListener(_scrollListener);
}
private fun ensureEnoughContentVisible(filteredResults: List<TConverted>) {
val canScroll = if (recyclerData.results.isEmpty()) false else {
val layoutManager = recyclerData.layoutManager
val firstVisibleItemPosition = layoutManager.findFirstVisibleItemPosition()
if (firstVisibleItemPosition != RecyclerView.NO_POSITION) {
val firstVisibleView = layoutManager.findViewByPosition(firstVisibleItemPosition)
val itemHeight = firstVisibleView?.height ?: 0
val occupiedSpace = recyclerData.results.size * itemHeight
val recyclerViewHeight = _recyclerResults.height
Logger.i(TAG, "ensureEnoughContentVisible loadNextPage occupiedSpace=$occupiedSpace recyclerViewHeight=$recyclerViewHeight")
occupiedSpace >= recyclerViewHeight
} else {
false
}
}
Logger.i(TAG, "ensureEnoughContentVisible loadNextPage canScroll=$canScroll _automaticNextPageCounter=$_automaticNextPageCounter")
if (!canScroll || filteredResults.isEmpty()) {
_automaticNextPageCounter++
if(_automaticNextPageCounter <= 4)
loadNextPage()
} else {
_automaticNextPageCounter = 0;
}
}
protected fun setTextCentered(text: String?) {
_textCentered.text = text;
}
@ -369,6 +389,7 @@ abstract class FeedView<TFragment, TResult, TConverted, TPager, TViewHolder> : L
recyclerData.resultsUnfiltered.addAll(toAdd);
recyclerData.adapter.notifyDataSetChanged();
recyclerData.loadedFeedStyle = feedStyle;
ensureEnoughContentVisible(filteredResults)
}
private fun detachPagerEvents() {

View file

@ -156,22 +156,21 @@ abstract class FutoVideoPlayerBase : RelativeLayout {
val dur = duration;
var shouldRestartPlayback = false
if (_shouldPlaybackRestartOnConnectivity && abs(pos - dur) > 2000) {
if (Settings.instance.playback.restartPlaybackAfterLoss == 1) {
if (Settings.instance.playback.restartPlaybackAfterConnectivityLoss == 1) {
val lossTime_ms = _connectivityLossTime_ms
if (lossTime_ms != null && System.currentTimeMillis() - lossTime_ms < 1000 * 30) {
shouldRestartPlayback = true
}
} else if (Settings.instance.playback.restartPlaybackAfterLoss == 2) {
} else if (Settings.instance.playback.restartPlaybackAfterConnectivityLoss == 2) {
val lossTime_ms = _connectivityLossTime_ms
if (lossTime_ms != null && System.currentTimeMillis() - lossTime_ms < 1000 * 10) {
shouldRestartPlayback = true
}
} else if (Settings.instance.playback.restartPlaybackAfterLoss == 3) {
} else if (Settings.instance.playback.restartPlaybackAfterConnectivityLoss == 3) {
shouldRestartPlayback = true
}
}
if (shouldRestartPlayback) {
Logger.i(TAG, "Playback ended due to connection loss, resuming playback since connection is restored.");
exoPlayer?.player?.playWhenReady = true;
@ -529,13 +528,13 @@ abstract class FutoVideoPlayerBase : RelativeLayout {
PlaybackException.ERROR_CODE_IO_BAD_HTTP_STATUS -> {
onDatasourceError.emit(error);
}
PlaybackException.ERROR_CODE_IO_CLEARTEXT_NOT_PERMITTED,
PlaybackException.ERROR_CODE_IO_FILE_NOT_FOUND,
PlaybackException.ERROR_CODE_IO_INVALID_HTTP_CONTENT_TYPE,
//PlaybackException.ERROR_CODE_IO_CLEARTEXT_NOT_PERMITTED,
//PlaybackException.ERROR_CODE_IO_FILE_NOT_FOUND,
//PlaybackException.ERROR_CODE_IO_INVALID_HTTP_CONTENT_TYPE,
PlaybackException.ERROR_CODE_IO_NETWORK_CONNECTION_FAILED,
PlaybackException.ERROR_CODE_IO_NETWORK_CONNECTION_TIMEOUT,
PlaybackException.ERROR_CODE_IO_NO_PERMISSION,
PlaybackException.ERROR_CODE_IO_READ_POSITION_OUT_OF_RANGE,
//PlaybackException.ERROR_CODE_IO_NO_PERMISSION,
//PlaybackException.ERROR_CODE_IO_READ_POSITION_OUT_OF_RANGE,
PlaybackException.ERROR_CODE_IO_UNSPECIFIED -> {
Logger.i(TAG, "IO error, set _shouldPlaybackRestartOnConnectivity=true");
_shouldPlaybackRestartOnConnectivity = true;
@ -557,8 +556,6 @@ abstract class FutoVideoPlayerBase : RelativeLayout {
Logger.i(TAG, "_shouldPlaybackRestartOnConnectivity=false");
_shouldPlaybackRestartOnConnectivity = false;
}
}
companion object {