Merge branch 'master' of gitlab.futo.org:videostreaming/grayjay

This commit is contained in:
Koen 2024-01-15 18:07:08 +01:00
commit 5cc8488d94
5 changed files with 86 additions and 8 deletions

View file

@ -22,15 +22,17 @@ class BrowserFragment : MainFragment() {
override val hasBottomBar: Boolean get() = true; override val hasBottomBar: Boolean get() = true;
private var _webview: WebView? = null; private var _webview: WebView? = null;
private val _webviewWithoutHandling = object: WebViewClient() {
override fun shouldOverrideUrlLoading(view: WebView?, request: WebResourceRequest?): Boolean {
return false;
}
};
override fun onCreateMainView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View { override fun onCreateMainView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
val view = inflater.inflate(R.layout.fragment_browser, container, false); val view = inflater.inflate(R.layout.fragment_browser, container, false);
_webview = view.findViewById<WebView?>(R.id.webview).apply { _webview = view.findViewById<WebView?>(R.id.webview).apply {
this.webViewClient = object: WebViewClient() { this.webViewClient = _webviewWithoutHandling;
override fun shouldOverrideUrlLoading(view: WebView?, request: WebResourceRequest?): Boolean {
return false;
}
};
this.settings.javaScriptEnabled = true; this.settings.javaScriptEnabled = true;
CookieManager.getInstance().setAcceptCookie(true); CookieManager.getInstance().setAcceptCookie(true);
this.settings.domStorageEnabled = true; this.settings.domStorageEnabled = true;
@ -41,8 +43,26 @@ class BrowserFragment : MainFragment() {
override fun onShownWithView(parameter: Any?, isBack: Boolean) { override fun onShownWithView(parameter: Any?, isBack: Boolean) {
super.onShownWithView(parameter, isBack) super.onShownWithView(parameter, isBack)
if(parameter is String) if(parameter is String) {
_webview?.webViewClient = _webviewWithoutHandling;
_webview?.loadUrl(parameter); _webview?.loadUrl(parameter);
}
else if(parameter is NavigateOptions) {
if(parameter.urlHandlers != null && parameter.urlHandlers.isNotEmpty())
_webview?.webViewClient = object: WebViewClient() {
override fun shouldOverrideUrlLoading(view: WebView?, request: WebResourceRequest?): Boolean {
val schema = request?.url?.scheme;
if(schema != null && parameter.urlHandlers.containsKey(schema)) {
parameter.urlHandlers[schema]?.invoke(request);
return true;
}
return false;
}
};
else
_webview?.webViewClient = _webviewWithoutHandling;
_webview?.loadUrl(parameter.url);
}
else else
_webview?.loadUrl("about:blank"); _webview?.loadUrl("about:blank");
} }
@ -59,4 +79,9 @@ class BrowserFragment : MainFragment() {
companion object { companion object {
fun newInstance() = BrowserFragment().apply {} fun newInstance() = BrowserFragment().apply {}
} }
class NavigateOptions(
val url: String,
val urlHandlers: Map<String, (WebResourceRequest)->Unit>? = null
)
} }

View file

@ -8,6 +8,7 @@ import android.view.ViewGroup
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import com.futo.platformplayer.* import com.futo.platformplayer.*
import com.futo.platformplayer.activities.MainActivity
import com.futo.platformplayer.api.media.models.contents.IPlatformContent import com.futo.platformplayer.api.media.models.contents.IPlatformContent
import com.futo.platformplayer.api.media.platforms.js.JSClient import com.futo.platformplayer.api.media.platforms.js.JSClient
import com.futo.platformplayer.api.media.structures.EmptyPager import com.futo.platformplayer.api.media.structures.EmptyPager
@ -17,15 +18,20 @@ import com.futo.platformplayer.engine.exceptions.ScriptCaptchaRequiredException
import com.futo.platformplayer.engine.exceptions.ScriptExecutionException import com.futo.platformplayer.engine.exceptions.ScriptExecutionException
import com.futo.platformplayer.engine.exceptions.ScriptImplementationException import com.futo.platformplayer.engine.exceptions.ScriptImplementationException
import com.futo.platformplayer.logging.Logger import com.futo.platformplayer.logging.Logger
import com.futo.platformplayer.models.SearchType
import com.futo.platformplayer.states.AnnouncementType import com.futo.platformplayer.states.AnnouncementType
import com.futo.platformplayer.states.StateAnnouncement import com.futo.platformplayer.states.StateAnnouncement
import com.futo.platformplayer.states.StateApp
import com.futo.platformplayer.states.StateMeta import com.futo.platformplayer.states.StateMeta
import com.futo.platformplayer.states.StatePlatform import com.futo.platformplayer.states.StatePlatform
import com.futo.platformplayer.states.StateSubscriptions
import com.futo.platformplayer.views.FeedStyle import com.futo.platformplayer.views.FeedStyle
import com.futo.platformplayer.views.NoResultsView
import com.futo.platformplayer.views.adapters.ContentPreviewViewHolder import com.futo.platformplayer.views.adapters.ContentPreviewViewHolder
import com.futo.platformplayer.views.adapters.InsertedViewAdapterWithLoader import com.futo.platformplayer.views.adapters.InsertedViewAdapterWithLoader
import com.futo.platformplayer.views.adapters.InsertedViewHolder import com.futo.platformplayer.views.adapters.InsertedViewHolder
import com.futo.platformplayer.views.announcements.AnnouncementView import com.futo.platformplayer.views.announcements.AnnouncementView
import com.futo.platformplayer.views.buttons.BigButton
import java.time.OffsetDateTime import java.time.OffsetDateTime
import java.util.UUID import java.util.UUID
@ -147,6 +153,34 @@ class HomeFragment : MainFragment() {
finishRefreshLayoutLoader(); finishRefreshLayoutLoader();
} }
override fun getEmptyPagerView(): View? {
val dp10 = 10.dp(resources);
val dp30 = 30.dp(resources);
if(!StatePlatform.instance.getEnabledClients().isEmpty())
//Initial setup
return NoResultsView(context, "You have no Sources", "Enable or install some sources", R.drawable.ic_sources,
listOf(BigButton(context, "Browse Online Sources", "View official sources online", R.drawable.ic_explore) {
fragment.navigate<BrowserFragment>(BrowserFragment.NavigateOptions("https://plugins.grayjay.app/", mapOf(
Pair("grayjay") { req ->
StateApp.instance.contextOrNull?.let {
if(it is MainActivity) {
it.handleUrlAll(req.url.toString());
}
};
}
)));
}.withMargin(dp10, dp30).withBackground(R.drawable.background_big_primary))
);
else
return NoResultsView(context, "Nothing to see here", "The enabled sources do not have any results.", R.drawable.ic_help,
listOf(BigButton(context, "Sources", "Go to the sources tab", R.drawable.ic_creators) {
fragment.navigate<SourcesFragment>();
}.withMargin(dp10, dp30))
);
return null;
}
override fun reload() { override fun reload() {
loadResults(); loadResults();
} }
@ -161,13 +195,15 @@ class HomeFragment : MainFragment() {
} }
private fun loadedResult(pager : IPager<IPlatformContent>) { private fun loadedResult(pager : IPager<IPlatformContent>) {
if (pager is EmptyPager<IPlatformContent>) { if (pager is EmptyPager<IPlatformContent>) {
StateAnnouncement.instance.registerAnnouncement(UUID.randomUUID().toString(), context.getString(R.string.no_home_available), context.getString(R.string.no_home_page_is_available_please_check_if_you_are_connected_to_the_internet_and_refresh), AnnouncementType.SESSION); //StateAnnouncement.instance.registerAnnouncement(UUID.randomUUID().toString(), context.getString(R.string.no_home_available), context.getString(R.string.no_home_page_is_available_please_check_if_you_are_connected_to_the_internet_and_refresh), AnnouncementType.SESSION);
} }
Logger.i(TAG, "Got new home pager ${pager}"); Logger.i(TAG, "Got new home pager ${pager}");
finishRefreshLayoutLoader(); finishRefreshLayoutLoader();
setLoading(false); setLoading(false);
setPager(pager); setPager(pager);
if(pager.getResults().isEmpty() && !pager.hasMorePages())
setEmptyPager(true);
} }
} }

View file

@ -126,7 +126,7 @@ abstract class SubscriptionsTaskFetchAlgorithm(
val pager = MultiChronoContentPager(groupedPagers, allowFailure, 15); val pager = MultiChronoContentPager(groupedPagers, allowFailure, 15);
pager.initialize(); pager.initialize();
return Result(DedupContentPager(pager), exs); return Result(DedupContentPager(pager, StatePlatform.instance.getEnabledClients().map { it.id }), exs);
} }
fun executeSubscriptionTasks(tasks: List<SubscriptionTask>, failedPlugins: MutableList<String>, cachedChannels: MutableList<String>): List<ForkJoinTask<SubscriptionTaskResult>> { fun executeSubscriptionTasks(tasks: List<SubscriptionTask>, failedPlugins: MutableList<String>, cachedChannels: MutableList<String>): List<ForkJoinTask<SubscriptionTaskResult>> {

View file

@ -629,6 +629,10 @@ class FutoVideoPlayer : FutoVideoPlayerBase {
} }
} }
override fun onIsPlayingChanged(playing: Boolean) {
super.onIsPlayingChanged(playing)
updatePlayPause();
}
override fun onPlaybackStateChanged(playbackState: Int) { override fun onPlaybackStateChanged(playbackState: Int) {
Logger.v(TAG, "onPlaybackStateChanged $playbackState"); Logger.v(TAG, "onPlaybackStateChanged $playbackState");
updatePlayPause() updatePlayPause()

View file

@ -100,6 +100,16 @@ abstract class FutoVideoPlayerBase : RelativeLayout {
private var _toResume = false; private var _toResume = false;
private val _playerEventListener = object: Player.Listener { private val _playerEventListener = object: Player.Listener {
override fun onPlaybackSuppressionReasonChanged(playbackSuppressionReason: Int) {
super.onPlaybackSuppressionReasonChanged(playbackSuppressionReason)
}
override fun onIsPlayingChanged(isPlaying: Boolean) {
super.onIsPlayingChanged(isPlaying);
this@FutoVideoPlayerBase.onIsPlayingChanged(isPlaying);
updatePlaying();
}
//TODO: Figure out why this is deprecated, and what the alternative is. //TODO: Figure out why this is deprecated, and what the alternative is.
override fun onPlaybackStateChanged(playbackState: Int) { override fun onPlaybackStateChanged(playbackState: Int) {
super.onPlaybackStateChanged(playbackState) super.onPlaybackStateChanged(playbackState)
@ -616,6 +626,9 @@ abstract class FutoVideoPlayerBase : RelativeLayout {
} }
protected open fun onSourceChanged(videoSource: IVideoSource?, audioSource: IAudioSource? = null, resume: Boolean = true) { } protected open fun onSourceChanged(videoSource: IVideoSource?, audioSource: IAudioSource? = null, resume: Boolean = true) { }
protected open fun onIsPlayingChanged(playing: Boolean) {
}
protected open fun onPlaybackStateChanged(playbackState: Int) { protected open fun onPlaybackStateChanged(playbackState: Int) {
if (_shouldPlaybackRestartOnConnectivity && playbackState == ExoPlayer.STATE_READY) { if (_shouldPlaybackRestartOnConnectivity && playbackState == ExoPlayer.STATE_READY) {
Logger.i(TAG, "_shouldPlaybackRestartOnConnectivity=false"); Logger.i(TAG, "_shouldPlaybackRestartOnConnectivity=false");