mirror of
https://gitlab.futo.org/videostreaming/grayjay.git
synced 2025-04-20 03:24:50 +00:00
Loop support, Improve add to queue behavior, home retry, fix history search pager, defaults progressbar
This commit is contained in:
parent
58da91eae8
commit
b284176072
13 changed files with 123 additions and 7 deletions
|
@ -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)
|
||||
|
|
|
@ -168,7 +168,7 @@ abstract class ContentFeedView<TFragment> : FeedView<TFragment, IPlatformContent
|
|||
protected open fun onContentClicked(content: IPlatformContent, time: Long) {
|
||||
if(content is IPlatformVideo) {
|
||||
if (StatePlayer.instance.hasQueue) {
|
||||
StatePlayer.instance.addToQueue(content)
|
||||
StatePlayer.instance.insertToQueue(content, true);
|
||||
} else {
|
||||
if (Settings.instance.playback.shouldResumePreview(time))
|
||||
fragment.navigate<VideoDetailFragment>(content.withTimestamp(time)).maximizeVideoDetail();
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
|
|
@ -100,7 +100,7 @@ class StateHistory {
|
|||
return _historyDBStore.getObjectPager();
|
||||
}
|
||||
fun getHistorySearchPager(query: String): IPager<HistoryVideo> {
|
||||
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];
|
||||
|
|
|
@ -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<Pair<IPlatformClient, Deferred<IPager<IPlatformContent>?>>> = 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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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);
|
||||
|
|
9
app/src/main/res/drawable/ic_loop.xml
Normal file
9
app/src/main/res/drawable/ic_loop.xml
Normal file
|
@ -0,0 +1,9 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="960"
|
||||
android:viewportHeight="960">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M292.31,840L160,707.69L292.31,575.39L320.61,604.15L237.08,687.69L692.31,687.69L692.31,527.69L732.31,527.69L732.31,727.69L237.08,727.69L320.61,811.23L292.31,840ZM227.69,432.31L227.69,232.31L722.92,232.31L639.39,148.77L667.69,120L800,252.31L667.69,384.61L639.39,355.85L722.92,272.31L267.69,272.31L267.69,432.31L227.69,432.31Z"/>
|
||||
</vector>
|
9
app/src/main/res/drawable/ic_loop_active.xml
Normal file
9
app/src/main/res/drawable/ic_loop_active.xml
Normal file
|
@ -0,0 +1,9 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="960"
|
||||
android:viewportHeight="960">
|
||||
<path
|
||||
android:fillColor="@color/colorPrimary"
|
||||
android:pathData="M292.31,840L160,707.69L292.31,575.39L320.61,604.15L237.08,687.69L692.31,687.69L692.31,527.69L732.31,527.69L732.31,727.69L237.08,727.69L320.61,811.23L292.31,840ZM227.69,432.31L227.69,232.31L722.92,232.31L639.39,148.77L667.69,120L800,252.31L667.69,384.61L639.39,355.85L722.92,272.31L267.69,272.31L267.69,432.31L227.69,432.31Z"/>
|
||||
</vector>
|
|
@ -45,6 +45,14 @@
|
|||
android:clickable="true"
|
||||
android:padding="12dp"
|
||||
app:srcCompat="@drawable/ic_screen_lock_rotation" />
|
||||
<ImageButton
|
||||
android:id="@+id/exo_loop"
|
||||
android:layout_width="50dp"
|
||||
android:layout_height="50dp"
|
||||
android:scaleType="fitCenter"
|
||||
android:clickable="true"
|
||||
android:padding="12dp"
|
||||
app:srcCompat="@drawable/ic_loop" />
|
||||
<ImageButton
|
||||
android:id="@+id/exo_settings"
|
||||
android:layout_width="50dp"
|
||||
|
|
|
@ -73,6 +73,14 @@
|
|||
android:clickable="true"
|
||||
android:padding="12dp"
|
||||
app:srcCompat="@drawable/ic_screen_lock_rotation" />
|
||||
<ImageButton
|
||||
android:id="@+id/exo_loop"
|
||||
android:layout_width="50dp"
|
||||
android:layout_height="50dp"
|
||||
android:scaleType="fitCenter"
|
||||
android:clickable="true"
|
||||
android:padding="12dp"
|
||||
app:srcCompat="@drawable/ic_loop" />
|
||||
<ImageButton
|
||||
android:id="@+id/exo_settings"
|
||||
android:layout_width="50dp"
|
||||
|
|
|
@ -54,6 +54,15 @@
|
|||
android:clickable="true"
|
||||
android:padding="12dp"
|
||||
app:srcCompat="@drawable/ic_cast" />
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/button_loop"
|
||||
android:layout_width="50dp"
|
||||
android:layout_height="50dp"
|
||||
android:scaleType="fitCenter"
|
||||
android:clickable="true"
|
||||
android:padding="12dp"
|
||||
app:srcCompat="@drawable/ic_loop" />
|
||||
<ImageButton
|
||||
android:id="@+id/button_settings"
|
||||
android:layout_width="50dp"
|
||||
|
|
Loading…
Add table
Reference in a new issue