Add webview fallback for TV

This commit is contained in:
Blatzar 2022-08-16 01:24:19 +02:00
parent 309c2b828c
commit ef165ad4cb
8 changed files with 149 additions and 37 deletions

View file

@ -3,6 +3,7 @@ package com.lagradost.cloudstream3
import android.app.Application import android.app.Application
import android.content.Context import android.content.Context
import android.widget.Toast import android.widget.Toast
import androidx.fragment.app.Fragment
import com.google.auto.service.AutoService import com.google.auto.service.AutoService
import com.lagradost.cloudstream3.mvvm.normalSafeApiCall import com.lagradost.cloudstream3.mvvm.normalSafeApiCall
import com.lagradost.cloudstream3.mvvm.suspendSafeApiCall import com.lagradost.cloudstream3.mvvm.suspendSafeApiCall
@ -135,8 +136,11 @@ class AcraApplication : Application() {
context?.removeKey(path) context?.removeKey(path)
} }
fun openBrowser(url: String) { /**
context?.openBrowser(url) * If fallbackWebview is true and a fragment is supplied then it will open a webview with the url if the browser fails.
* */
fun openBrowser(url: String, fallbackWebview: Boolean = false, fragment: Fragment? = null) {
context?.openBrowser(url, fallbackWebview, fragment)
} }
} }
} }

View file

@ -82,11 +82,9 @@ import java.io.File
import kotlin.concurrent.thread import kotlin.concurrent.thread
import kotlin.reflect.KClass import kotlin.reflect.KClass
import com.lagradost.cloudstream3.plugins.PluginManager import com.lagradost.cloudstream3.plugins.PluginManager
import com.lagradost.cloudstream3.plugins.RepositoryManager
import com.lagradost.cloudstream3.syncproviders.AccountManager.Companion.appStringRepo import com.lagradost.cloudstream3.syncproviders.AccountManager.Companion.appStringRepo
import com.lagradost.cloudstream3.ui.settings.extensions.RepositoryData
import com.lagradost.cloudstream3.ui.setup.SetupFragmentExtensions import com.lagradost.cloudstream3.ui.setup.SetupFragmentExtensions
import com.lagradost.cloudstream3.utils.Coroutines.main import com.lagradost.cloudstream3.utils.AppUtils.loadRepository
import com.lagradost.cloudstream3.utils.Event import com.lagradost.cloudstream3.utils.Event
@ -332,26 +330,6 @@ class MainActivity : AppCompatActivity(), ColorPickerDialogListener {
super.onNewIntent(intent) super.onNewIntent(intent)
} }
private fun loadRepo(url: String) {
ioSafe {
val repo = RepositoryManager.parseRepository(url) ?: return@ioSafe
RepositoryManager.addRepository(
RepositoryData(
repo.name,
url
)
)
main {
showToast(
this@MainActivity,
getString(R.string.player_loaded_subtitles, repo.name),
Toast.LENGTH_LONG
)
}
afterRepositoryLoadedEvent.invoke(true)
}
}
private fun handleAppIntent(intent: Intent?) { private fun handleAppIntent(intent: Intent?) {
if (intent == null) return if (intent == null) return
val str = intent.dataString val str = intent.dataString
@ -360,7 +338,7 @@ class MainActivity : AppCompatActivity(), ColorPickerDialogListener {
if (str.startsWith("https://cs.repo")) { if (str.startsWith("https://cs.repo")) {
val realUrl = "https://" + str.substringAfter("?") val realUrl = "https://" + str.substringAfter("?")
println("Repository url: $realUrl") println("Repository url: $realUrl")
loadRepo(realUrl) loadRepository(realUrl)
} else if (str.contains(appString)) { } else if (str.contains(appString)) {
for (api in OAuth2Apis) { for (api in OAuth2Apis) {
if (str.contains("/${api.redirectUrl}")) { if (str.contains("/${api.redirectUrl}")) {
@ -392,7 +370,7 @@ class MainActivity : AppCompatActivity(), ColorPickerDialogListener {
} }
} else if (str.contains(appStringRepo)) { } else if (str.contains(appStringRepo)) {
val url = str.replaceFirst(appStringRepo, "https") val url = str.replaceFirst(appStringRepo, "https")
loadRepo(url) loadRepository(url)
} else { } else {
if (str.startsWith(DOWNLOAD_NAVIGATE_TO)) { if (str.startsWith(DOWNLOAD_NAVIGATE_TO)) {
this.navigate(R.id.navigation_downloads) this.navigate(R.id.navigation_downloads)

View file

@ -0,0 +1,62 @@
package com.lagradost.cloudstream3.ui
import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.webkit.WebResourceRequest
import android.webkit.WebView
import android.webkit.WebViewClient
import androidx.navigation.fragment.findNavController
import com.lagradost.cloudstream3.R
import com.lagradost.cloudstream3.USER_AGENT
import com.lagradost.cloudstream3.utils.AppUtils.loadRepository
import kotlinx.android.synthetic.main.fragment_webview.*
class WebviewFragment : Fragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val url = arguments?.getString(WEBVIEW_URL) ?: "".also {
findNavController().popBackStack()
}
web_view.webViewClient = object : WebViewClient() {
override fun shouldOverrideUrlLoading(
view: WebView?,
request: WebResourceRequest?
): Boolean {
val requestUrl = request?.url.toString()
if (requestUrl.startsWith("https://cs.repo")) {
val realUrl = "https://" + requestUrl.substringAfter("?")
println("Repository url: $realUrl :::: $requestUrl")
activity?.loadRepository(realUrl)
findNavController().popBackStack()
return true
}
return super.shouldOverrideUrlLoading(view, request)
}
}
web_view.settings.javaScriptEnabled = true
web_view.settings.domStorageEnabled = true
web_view.settings.userAgentString = USER_AGENT
web_view.loadUrl(url)
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_webview, container, false)
}
companion object {
private const val WEBVIEW_URL = "webview_url"
fun newInstance(webViewUrl: String) =
Bundle().apply {
putString(WEBVIEW_URL, webViewUrl)
}
}
}

View file

@ -119,10 +119,12 @@ class ExtensionsFragment : Fragment() {
} }
list_repositories?.setOnClickListener { list_repositories?.setOnClickListener {
openBrowser(PUBLIC_REPOSITORIES_LIST) // Open webview on tv if browser fails
val isTv = it.context.isTvSettings()
openBrowser(PUBLIC_REPOSITORIES_LIST, isTv, this)
// Set clipboard on TV because the browser might not exist or work properly // Set clipboard on TV because the browser might not exist or work properly
if (it.context.isTvSettings()) { if (isTv) {
val serviceClipboard = val serviceClipboard =
(activity?.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager?) (activity?.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager?)
?: return@setOnClickListener ?: return@setOnClickListener
@ -189,7 +191,9 @@ class ExtensionsFragment : Fragment() {
} }
dialog.list_repositories?.setOnClickListener { dialog.list_repositories?.setOnClickListener {
openBrowser(PUBLIC_REPOSITORIES_LIST) // Open webview on tv if browser fails
val isTv = it.context.isTvSettings()
openBrowser(PUBLIC_REPOSITORIES_LIST, isTv, this)
} }
// dialog.text2?.text = provider.name // dialog.text2?.text = provider.name

View file

@ -12,6 +12,7 @@ import com.lagradost.cloudstream3.MainActivity.Companion.afterRepositoryLoadedEv
import com.lagradost.cloudstream3.R import com.lagradost.cloudstream3.R
import com.lagradost.cloudstream3.plugins.RepositoryManager import com.lagradost.cloudstream3.plugins.RepositoryManager
import com.lagradost.cloudstream3.plugins.RepositoryManager.PREBUILT_REPOSITORIES import com.lagradost.cloudstream3.plugins.RepositoryManager.PREBUILT_REPOSITORIES
import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.isTvSettings
import com.lagradost.cloudstream3.ui.settings.extensions.PUBLIC_REPOSITORIES_LIST import com.lagradost.cloudstream3.ui.settings.extensions.PUBLIC_REPOSITORIES_LIST
import com.lagradost.cloudstream3.ui.settings.extensions.PluginsViewModel import com.lagradost.cloudstream3.ui.settings.extensions.PluginsViewModel
import com.lagradost.cloudstream3.ui.settings.extensions.RepoAdapter import com.lagradost.cloudstream3.ui.settings.extensions.RepoAdapter
@ -65,7 +66,9 @@ class SetupFragmentExtensions : Fragment() {
}).apply { updateList(repositories) } }).apply { updateList(repositories) }
} else { } else {
list_repositories?.setOnClickListener { list_repositories?.setOnClickListener {
openBrowser(PUBLIC_REPOSITORIES_LIST) // Open webview on tv if browser fails
val isTv = it.context.isTvSettings()
openBrowser(PUBLIC_REPOSITORIES_LIST, isTv, this)
} }
} }
} }
@ -87,7 +90,6 @@ class SetupFragmentExtensions : Fragment() {
next_btt?.setOnClickListener { next_btt?.setOnClickListener {
// Continue setup // Continue setup
println("ISSETUP $isSetup")
if (isSetup) if (isSetup)
findNavController().navigate(R.id.action_navigation_setup_extensions_to_navigation_setup_provider_languages) findNavController().navigate(R.id.action_navigation_setup_extensions_to_navigation_setup_provider_languages)
else else

View file

@ -20,12 +20,15 @@ import android.os.ParcelFileDescriptor
import android.provider.MediaStore import android.provider.MediaStore
import android.text.Spanned import android.text.Spanned
import android.util.Log import android.util.Log
import android.widget.Toast
import androidx.annotation.RequiresApi import androidx.annotation.RequiresApi
import androidx.annotation.WorkerThread import androidx.annotation.WorkerThread
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import androidx.core.text.HtmlCompat import androidx.core.text.HtmlCompat
import androidx.core.text.toSpanned import androidx.core.text.toSpanned
import androidx.fragment.app.Fragment
import androidx.navigation.fragment.findNavController
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import androidx.tvprovider.media.tv.PreviewChannelHelper import androidx.tvprovider.media.tv.PreviewChannelHelper
@ -38,16 +41,20 @@ import com.google.android.gms.cast.framework.CastState
import com.google.android.gms.common.ConnectionResult import com.google.android.gms.common.ConnectionResult
import com.google.android.gms.common.GoogleApiAvailability import com.google.android.gms.common.GoogleApiAvailability
import com.google.android.gms.common.wrappers.Wrappers import com.google.android.gms.common.wrappers.Wrappers
import com.lagradost.cloudstream3.CommonActivity.showToast
import com.lagradost.cloudstream3.MainActivity.Companion.afterRepositoryLoadedEvent
import com.lagradost.cloudstream3.R import com.lagradost.cloudstream3.R
import com.lagradost.cloudstream3.SearchResponse import com.lagradost.cloudstream3.SearchResponse
import com.lagradost.cloudstream3.isMovieType import com.lagradost.cloudstream3.isMovieType
import com.lagradost.cloudstream3.mapper import com.lagradost.cloudstream3.mapper
import com.lagradost.cloudstream3.mvvm.logError import com.lagradost.cloudstream3.mvvm.logError
import com.lagradost.cloudstream3.plugins.RepositoryManager
import com.lagradost.cloudstream3.ui.WebviewFragment
import com.lagradost.cloudstream3.ui.result.ResultFragment import com.lagradost.cloudstream3.ui.result.ResultFragment
import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.isTrueTvSettings import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.isTrueTvSettings
import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.isTvSettings import com.lagradost.cloudstream3.ui.settings.extensions.RepositoryData
import com.lagradost.cloudstream3.utils.AppUtils.loadResult
import com.lagradost.cloudstream3.utils.Coroutines.ioSafe import com.lagradost.cloudstream3.utils.Coroutines.ioSafe
import com.lagradost.cloudstream3.utils.Coroutines.main
import com.lagradost.cloudstream3.utils.FillerEpisodeCheck.toClassDir import com.lagradost.cloudstream3.utils.FillerEpisodeCheck.toClassDir
import com.lagradost.cloudstream3.utils.JsUnpacker.Companion.load import com.lagradost.cloudstream3.utils.JsUnpacker.Companion.load
import com.lagradost.cloudstream3.utils.UIHelper.navigate import com.lagradost.cloudstream3.utils.UIHelper.navigate
@ -232,8 +239,35 @@ object AppUtils {
) )
} }
} }
fun Activity.loadRepository(url: String) {
ioSafe {
val repo = RepositoryManager.parseRepository(url) ?: return@ioSafe
RepositoryManager.addRepository(
RepositoryData(
repo.name,
url
)
)
main {
showToast(
this@loadRepository,
getString(R.string.player_loaded_subtitles, repo.name),
Toast.LENGTH_LONG
)
}
afterRepositoryLoadedEvent.invoke(true)
}
}
fun Context.openBrowser(url: String) {
/**
* If fallbackWebview is true and a fragment is supplied then it will open a webview with the url if the browser fails.
* */
fun Context.openBrowser(
url: String,
fallbackWebview: Boolean = false,
fragment: Fragment? = null
) {
try { try {
val intent = Intent(Intent.ACTION_VIEW) val intent = Intent(Intent.ACTION_VIEW)
intent.data = Uri.parse(url) intent.data = Uri.parse(url)
@ -241,6 +275,15 @@ object AppUtils {
ContextCompat.startActivity(this, intent, null) ContextCompat.startActivity(this, intent, null)
} catch (e: Exception) { } catch (e: Exception) {
logError(e) logError(e)
if (fallbackWebview) {
try {
fragment
?.findNavController()
?.navigate(R.id.navigation_webview, WebviewFragment.newInstance(url))
} catch (e: Exception) {
logError(e)
}
}
} }
} }

View file

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<WebView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/web_view"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.WebviewFragment">
</WebView>

View file

@ -194,6 +194,16 @@
app:popExitAnim="@anim/exit_anim" app:popExitAnim="@anim/exit_anim"
tools:layout="@layout/fragment_plugins" /> tools:layout="@layout/fragment_plugins" />
<fragment
android:id="@+id/navigation_webview"
android:name="com.lagradost.cloudstream3.ui.WebviewFragment"
android:label="@string/title_settings"
app:enterAnim="@anim/enter_anim"
app:exitAnim="@anim/exit_anim"
app:popEnterAnim="@anim/enter_anim"
app:popExitAnim="@anim/exit_anim"
tools:layout="@layout/fragment_webview" />
<fragment <fragment
android:id="@+id/navigation_settings_lang" android:id="@+id/navigation_settings_lang"
android:name="com.lagradost.cloudstream3.ui.settings.SettingsLang" android:name="com.lagradost.cloudstream3.ui.settings.SettingsLang"