diff --git a/app/src/main/java/com/futo/platformplayer/Settings.kt b/app/src/main/java/com/futo/platformplayer/Settings.kt index 68bdb887..d9fa52fb 100644 --- a/app/src/main/java/com/futo/platformplayer/Settings.kt +++ b/app/src/main/java/com/futo/platformplayer/Settings.kt @@ -181,7 +181,7 @@ class Settings : FragmentedStorageFileJson() { @FormField(R.string.progress_bar, FieldForm.TOGGLE, R.string.progress_bar_description, 6) - var progressBar: Boolean = false; + var progressBar: Boolean = true; @FormField(R.string.clear_hidden, FieldForm.BUTTON, R.string.clear_hidden_description, 8) @@ -212,7 +212,7 @@ class Settings : FragmentedStorageFileJson() { var previewFeedItems: Boolean = true; @FormField(R.string.progress_bar, FieldForm.TOGGLE, R.string.progress_bar_description, 6) - var progressBar: Boolean = false; + var progressBar: Boolean = true; fun getSearchFeedStyle(): FeedStyle { @@ -230,7 +230,7 @@ class Settings : FragmentedStorageFileJson() { class ChannelSettings { @FormField(R.string.progress_bar, FieldForm.TOGGLE, R.string.progress_bar_description, 6) - var progressBar: Boolean = false; + var progressBar: Boolean = true; } @FormField(R.string.subscriptions, "group", R.string.configure_how_your_subscriptions_works_and_feels, 4) @@ -252,7 +252,7 @@ class Settings : FragmentedStorageFileJson() { var previewFeedItems: Boolean = true; @FormField(R.string.progress_bar, FieldForm.TOGGLE, R.string.progress_bar_description, 6) - var progressBar: Boolean = false; + var progressBar: Boolean = true; @FormField(R.string.fetch_on_app_boot, FieldForm.TOGGLE, R.string.shortly_after_opening_the_app_start_fetching_subscriptions, 7) @Serializable(with = FlexibleBooleanSerializer::class) diff --git a/app/src/main/java/com/futo/platformplayer/fragment/mainactivity/main/ContentFeedView.kt b/app/src/main/java/com/futo/platformplayer/fragment/mainactivity/main/ContentFeedView.kt index 2986eb20..246f665f 100644 --- a/app/src/main/java/com/futo/platformplayer/fragment/mainactivity/main/ContentFeedView.kt +++ b/app/src/main/java/com/futo/platformplayer/fragment/mainactivity/main/ContentFeedView.kt @@ -168,7 +168,7 @@ abstract class ContentFeedView : FeedView(content.withTimestamp(time)).maximizeVideoDetail(); diff --git a/app/src/main/java/com/futo/platformplayer/fragment/mainactivity/main/HistoryFragment.kt b/app/src/main/java/com/futo/platformplayer/fragment/mainactivity/main/HistoryFragment.kt index 9cd9ffd8..3a5cdc50 100644 --- a/app/src/main/java/com/futo/platformplayer/fragment/mainactivity/main/HistoryFragment.kt +++ b/app/src/main/java/com/futo/platformplayer/fragment/mainactivity/main/HistoryFragment.kt @@ -18,6 +18,7 @@ import com.futo.platformplayer.* import com.futo.platformplayer.api.media.models.contents.IPlatformContent import com.futo.platformplayer.api.media.structures.IAsyncPager import com.futo.platformplayer.api.media.structures.IPager +import com.futo.platformplayer.api.media.structures.PlatformContentPager import com.futo.platformplayer.constructs.TaskHandler import com.futo.platformplayer.logging.Logger import com.futo.platformplayer.models.HistoryVideo @@ -181,6 +182,7 @@ class HistoryFragment : MainFragment() { val query = _editSearch.text.toString(); if (_editSearch.text.isNotEmpty()) { setPager(StateHistory.instance.getHistorySearchPager(query)); + //setPager(StateHistory.instance.getHistorySearchPager(query)); } else { setPager(StateHistory.instance.getHistoryPager()); } diff --git a/app/src/main/java/com/futo/platformplayer/states/StateHistory.kt b/app/src/main/java/com/futo/platformplayer/states/StateHistory.kt index b60e22be..b1151d0c 100644 --- a/app/src/main/java/com/futo/platformplayer/states/StateHistory.kt +++ b/app/src/main/java/com/futo/platformplayer/states/StateHistory.kt @@ -100,7 +100,7 @@ class StateHistory { return _historyDBStore.getObjectPager(); } fun getHistorySearchPager(query: String): IPager { - return _historyDBStore.queryLikeObjectPager(DBHistory.Index::url, "%${query}%", 10); + return _historyDBStore.queryLikeObjectPager(DBHistory.Index::name, "%${query}%", 10); } fun getHistoryIndexByUrl(url: String): DBHistory.Index? { return historyIndex[url]; diff --git a/app/src/main/java/com/futo/platformplayer/states/StatePlatform.kt b/app/src/main/java/com/futo/platformplayer/states/StatePlatform.kt index 71e178fd..12afe523 100644 --- a/app/src/main/java/com/futo/platformplayer/states/StatePlatform.kt +++ b/app/src/main/java/com/futo/platformplayer/states/StatePlatform.kt @@ -40,6 +40,7 @@ import com.futo.platformplayer.models.ImageVariable import com.futo.platformplayer.stores.* import kotlinx.coroutines.* import okhttp3.internal.concat +import java.lang.Thread.sleep import java.time.OffsetDateTime import kotlin.reflect.jvm.internal.impl.builtins.jvm.JavaToKotlinClassMap.PlatformMutabilityMapping import kotlin.streams.asSequence @@ -405,7 +406,12 @@ class StatePlatform { val deferred: List?>>> = clients.map { return@map Pair(it, scope.async(Dispatchers.IO) { try { - val searchResult = it.fromPool(_pagerClientPool).getHome(); + var searchResult = it.fromPool(_pagerClientPool).getHome(); + if(searchResult.getResults().size == 0) { + Logger.i(TAG, "No home results, retrying"); + sleep(500); + searchResult = it.fromPool(_pagerClientPool).getHome(); + } return@async searchResult; } catch(ex: Throwable) { Logger.e(TAG, "getHomeRefresh", ex); diff --git a/app/src/main/java/com/futo/platformplayer/states/StatePlayer.kt b/app/src/main/java/com/futo/platformplayer/states/StatePlayer.kt index 54991ed3..84dc3150 100644 --- a/app/src/main/java/com/futo/platformplayer/states/StatePlayer.kt +++ b/app/src/main/java/com/futo/platformplayer/states/StatePlayer.kt @@ -37,6 +37,7 @@ class StatePlayer { //Video Status var rotationLock : Boolean = false; + var loopVideo : Boolean = false; val isPlaying: Boolean get() = _exoplayer?.player?.playWhenReady ?: false; @@ -286,6 +287,31 @@ class StatePlayer { } onQueueChanged.emit(true); } + fun insertToQueue(video: IPlatformVideo, playNow: Boolean = false) { + synchronized(_queue) { + if(_queue.isEmpty()) { + setQueueType(TYPE_QUEUE); + currentVideo?.let { + _queue.add(it); + } + } + if(_queue.isEmpty()) + _queue.add(video); + else + _queue.add(_queuePosition.coerceAtLeast(0).coerceAtMost(_queue.size - 1), video); + + if (queueShuffle) { + addToShuffledQueue(video); + } + + if (_queuePosition < 0) { + _queuePosition = 0; + } + } + onQueueChanged.emit(true); + if(playNow) + setQueuePosition(video); + } fun setQueuePosition(video: IPlatformVideo) { synchronized(_queue) { if (getCurrentQueueItem() == video) { @@ -348,6 +374,8 @@ class StatePlayer { } fun getNextQueueItem() : IPlatformVideo? { + if(loopVideo) + return currentVideo; synchronized(_queue) { val shuffledQueue = _queueShuffled; val queue = if (queueShuffle && shuffledQueue != null) { @@ -375,6 +403,8 @@ class StatePlayer { } }; fun nextQueueItem(withoutRemoval: Boolean = false) : IPlatformVideo? { + if(loopVideo) + return currentVideo; synchronized(_queue) { if (_queue.isEmpty()) return null; diff --git a/app/src/main/java/com/futo/platformplayer/views/casting/CastView.kt b/app/src/main/java/com/futo/platformplayer/views/casting/CastView.kt index 5045f59d..86e762b0 100644 --- a/app/src/main/java/com/futo/platformplayer/views/casting/CastView.kt +++ b/app/src/main/java/com/futo/platformplayer/views/casting/CastView.kt @@ -26,6 +26,7 @@ class CastView : ConstraintLayout { private val _thumbnail: ImageView; private val _buttonMinimize: ImageButton; private val _buttonSettings: ImageButton; + private val _buttonLoop: ImageButton; private val _buttonPlay: ImageButton; private val _buttonPause: ImageButton; private val _buttonCast: CastButton; @@ -49,6 +50,7 @@ class CastView : ConstraintLayout { _thumbnail = findViewById(R.id.image_thumbnail); _buttonMinimize = findViewById(R.id.button_minimize); _buttonSettings = findViewById(R.id.button_settings); + _buttonLoop = findViewById(R.id.button_loop); _buttonPlay = findViewById(R.id.button_play); _buttonPause = findViewById(R.id.button_pause); _buttonCast = findViewById(R.id.button_cast); @@ -65,6 +67,12 @@ class CastView : ConstraintLayout { StateCasting.instance.videoSeekTo(d.expectedCurrentTime + it / 1000); }; + _buttonLoop.setOnClickListener { + StatePlayer.instance.loopVideo = !StatePlayer.instance.loopVideo; + _buttonLoop.setImageResource(if(StatePlayer.instance.loopVideo) R.drawable.ic_loop_active else R.drawable.ic_loop); + } + _buttonLoop.setImageResource(if(StatePlayer.instance.loopVideo) R.drawable.ic_loop_active else R.drawable.ic_loop); + _timeBar.addListener(object : OnScrubListener { override fun onScrubStart(timeBar: TimeBar, position: Long) { StateCasting.instance.videoSeekTo(position.toDouble()); diff --git a/app/src/main/java/com/futo/platformplayer/views/video/FutoVideoPlayer.kt b/app/src/main/java/com/futo/platformplayer/views/video/FutoVideoPlayer.kt index 3b1c9430..65ad8377 100644 --- a/app/src/main/java/com/futo/platformplayer/views/video/FutoVideoPlayer.kt +++ b/app/src/main/java/com/futo/platformplayer/views/video/FutoVideoPlayer.kt @@ -68,6 +68,7 @@ class FutoVideoPlayer : FutoVideoPlayerBase { private val _control_videosettings: ImageButton; private val _control_minimize: ImageButton; private val _control_rotate_lock: ImageButton; + private val _control_loop: ImageButton; private val _control_cast: ImageButton; private val _control_play: ImageButton; private val _control_chapter: TextView; @@ -77,6 +78,7 @@ class FutoVideoPlayer : FutoVideoPlayerBase { private val _control_videosettings_fullscreen: ImageButton; private val _control_minimize_fullscreen: ImageButton; private val _control_rotate_lock_fullscreen: ImageButton; + private val _control_loop_fullscreen: ImageButton; private val _control_cast_fullscreen: ImageButton; private val _control_play_fullscreen: ImageButton; private val _time_bar_fullscreen: TimeBar; @@ -128,6 +130,7 @@ class FutoVideoPlayer : FutoVideoPlayerBase { _control_videosettings = videoControls.findViewById(R.id.exo_settings); _control_minimize = videoControls.findViewById(R.id.exo_minimize); _control_rotate_lock = videoControls.findViewById(R.id.exo_rotate_lock); + _control_loop = videoControls.findViewById(R.id.exo_loop); _control_cast = videoControls.findViewById(R.id.exo_cast); _control_play = videoControls.findViewById(com.google.android.exoplayer2.ui.R.id.exo_play); _time_bar = videoControls.findViewById(com.google.android.exoplayer2.ui.R.id.exo_progress); @@ -138,6 +141,7 @@ class FutoVideoPlayer : FutoVideoPlayerBase { _control_minimize_fullscreen = _videoControls_fullscreen.findViewById(R.id.exo_minimize); _control_videosettings_fullscreen = _videoControls_fullscreen.findViewById(R.id.exo_settings); _control_rotate_lock_fullscreen = _videoControls_fullscreen.findViewById(R.id.exo_rotate_lock); + _control_loop_fullscreen = videoControls.findViewById(R.id.exo_loop); _control_cast_fullscreen = _videoControls_fullscreen.findViewById(R.id.exo_cast); _control_play_fullscreen = videoControls.findViewById(com.google.android.exoplayer2.ui.R.id.exo_play); _control_chapter_fullscreen = _videoControls_fullscreen.findViewById(R.id.text_chapter_current); @@ -244,6 +248,16 @@ class FutoVideoPlayer : FutoVideoPlayerBase { UIDialogs.showCastingDialog(context); }; + + _control_loop.setOnClickListener { + StatePlayer.instance.loopVideo = !StatePlayer.instance.loopVideo; + updateLoopVideoUI(); + } + _control_loop_fullscreen.setOnClickListener { + StatePlayer.instance.loopVideo = !StatePlayer.instance.loopVideo; + updateLoopVideoUI(); + } + _control_minimize_fullscreen.setOnClickListener { onMinimize.emit(this); }; @@ -273,6 +287,8 @@ class FutoVideoPlayer : FutoVideoPlayerBase { } } + updateLoopVideoUI(); + if(!isInEditMode) { gestureControl.hideControls(); } @@ -555,6 +571,17 @@ class FutoVideoPlayer : FutoVideoPlayerBase { _control_rotate_lock.setImageResource(R.drawable.ic_screen_lock_rotation); } } + fun updateLoopVideoUI() { + if(StatePlayer.instance.loopVideo) { + _control_loop.setImageResource(R.drawable.ic_loop_active); + _control_loop_fullscreen.setImageResource(R.drawable.ic_loop_active); + } + else { + _control_loop.setImageResource(R.drawable.ic_loop); + _control_loop_fullscreen.setImageResource(R.drawable.ic_loop); + } + } + fun setGestureSoundFactor(soundFactor: Float) { gestureControl.setSoundFactor(soundFactor); diff --git a/app/src/main/res/drawable/ic_loop.xml b/app/src/main/res/drawable/ic_loop.xml new file mode 100644 index 00000000..89ab5549 --- /dev/null +++ b/app/src/main/res/drawable/ic_loop.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_loop_active.xml b/app/src/main/res/drawable/ic_loop_active.xml new file mode 100644 index 00000000..c3e1cab1 --- /dev/null +++ b/app/src/main/res/drawable/ic_loop_active.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/layout/video_player_ui.xml b/app/src/main/res/layout/video_player_ui.xml index 7a318f12..7298aaca 100644 --- a/app/src/main/res/layout/video_player_ui.xml +++ b/app/src/main/res/layout/video_player_ui.xml @@ -45,6 +45,14 @@ android:clickable="true" android:padding="12dp" app:srcCompat="@drawable/ic_screen_lock_rotation" /> + + + +