cloudstream/app/src/main/java/com/lagradost/cloudstream3/MainActivity.kt

800 lines
31 KiB
Kotlin
Raw Normal View History

2021-04-30 17:20:15 +00:00
package com.lagradost.cloudstream3
2021-07-17 21:36:50 +00:00
import android.content.ComponentName
2021-07-04 00:59:51 +00:00
import android.content.Intent
2021-07-19 13:19:47 +00:00
import android.content.res.ColorStateList
2021-09-03 09:13:34 +00:00
import android.content.res.Configuration
2021-04-30 17:20:15 +00:00
import android.os.Bundle
2022-04-03 15:00:50 +00:00
import android.util.Log
2022-01-07 19:27:25 +00:00
import android.view.KeyEvent
2022-03-03 11:26:26 +00:00
import android.view.Menu
import android.view.MenuItem
2022-01-07 19:27:25 +00:00
import android.view.WindowManager
2022-03-03 11:26:26 +00:00
import androidx.annotation.IdRes
2021-04-30 17:20:15 +00:00
import androidx.appcompat.app.AppCompatActivity
2021-09-20 21:11:36 +00:00
import androidx.core.view.isVisible
2022-03-03 11:26:26 +00:00
import androidx.navigation.NavController
2021-12-12 02:33:17 +00:00
import androidx.navigation.NavDestination
2022-03-03 11:26:26 +00:00
import androidx.navigation.NavDestination.Companion.hierarchy
import androidx.navigation.NavGraph.Companion.findStartDestination
import androidx.navigation.NavOptions
2022-04-22 18:53:58 +00:00
import androidx.navigation.fragment.NavHostFragment
2021-09-20 21:11:36 +00:00
import androidx.navigation.ui.setupWithNavController
2021-08-30 21:42:58 +00:00
import androidx.preference.PreferenceManager
import com.fasterxml.jackson.databind.DeserializationFeature
import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
import com.google.android.gms.cast.framework.*
import com.google.android.material.navigationrail.NavigationRailView
2021-08-06 20:55:11 +00:00
import com.jaredrummler.android.colorpicker.ColorPickerDialogListener
2022-03-16 15:29:11 +00:00
import com.lagradost.cloudstream3.APIHolder.allProviders
import com.lagradost.cloudstream3.APIHolder.apis
2021-09-12 14:10:22 +00:00
import com.lagradost.cloudstream3.APIHolder.getApiDubstatusSettings
2022-06-02 22:51:41 +00:00
import com.lagradost.cloudstream3.APIHolder.initAll
import com.lagradost.cloudstream3.APIHolder.updateHasTrailers
2022-01-07 19:27:25 +00:00
import com.lagradost.cloudstream3.CommonActivity.loadThemes
import com.lagradost.cloudstream3.CommonActivity.onColorSelectedEvent
import com.lagradost.cloudstream3.CommonActivity.onDialogDismissedEvent
import com.lagradost.cloudstream3.CommonActivity.onUserLeaveHint
2022-04-03 15:00:50 +00:00
import com.lagradost.cloudstream3.CommonActivity.showToast
2022-01-07 19:27:25 +00:00
import com.lagradost.cloudstream3.CommonActivity.updateLocale
2021-09-12 15:57:07 +00:00
import com.lagradost.cloudstream3.mvvm.logError
2022-07-30 01:24:07 +00:00
import com.lagradost.cloudstream3.mvvm.normalSafeApiCall
import com.lagradost.cloudstream3.network.initClient
2021-07-08 19:39:49 +00:00
import com.lagradost.cloudstream3.receivers.VideoDownloadRestartReceiver
import com.lagradost.cloudstream3.syncproviders.AccountManager.Companion.OAuth2Apis
import com.lagradost.cloudstream3.syncproviders.AccountManager.Companion.accountManagers
import com.lagradost.cloudstream3.syncproviders.AccountManager.Companion.appString
import com.lagradost.cloudstream3.syncproviders.AccountManager.Companion.inAppAuths
2021-09-12 14:10:22 +00:00
import com.lagradost.cloudstream3.ui.APIRepository
import com.lagradost.cloudstream3.ui.download.DOWNLOAD_NAVIGATE_TO
2022-01-18 14:10:01 +00:00
import com.lagradost.cloudstream3.ui.result.ResultFragment
import com.lagradost.cloudstream3.ui.search.SearchResultBuilder
import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.isEmulatorSettings
2021-10-30 18:14:12 +00:00
import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.isTvSettings
2022-06-16 22:07:07 +00:00
import com.lagradost.cloudstream3.ui.settings.SettingsGeneral
2022-07-30 01:24:07 +00:00
import com.lagradost.cloudstream3.ui.setup.HAS_DONE_SETUP_KEY
import com.lagradost.cloudstream3.utils.AppUtils.isCastApiAvailable
2022-01-07 19:27:25 +00:00
import com.lagradost.cloudstream3.utils.AppUtils.loadCache
import com.lagradost.cloudstream3.utils.AppUtils.loadResult
2022-03-16 15:29:11 +00:00
import com.lagradost.cloudstream3.utils.AppUtils.tryParseJson
2022-03-04 15:39:56 +00:00
import com.lagradost.cloudstream3.utils.BackupUtils.setUpBackup
2022-04-03 15:00:50 +00:00
import com.lagradost.cloudstream3.utils.Coroutines.ioSafe
2022-03-16 15:29:11 +00:00
import com.lagradost.cloudstream3.utils.Coroutines.main
2022-07-30 01:24:07 +00:00
import com.lagradost.cloudstream3.utils.DataStore
2021-07-17 15:56:26 +00:00
import com.lagradost.cloudstream3.utils.DataStore.getKey
2021-07-17 21:36:50 +00:00
import com.lagradost.cloudstream3.utils.DataStore.removeKey
2022-03-16 15:29:11 +00:00
import com.lagradost.cloudstream3.utils.DataStore.setKey
2022-05-02 21:32:28 +00:00
import com.lagradost.cloudstream3.utils.DataStoreHelper.migrateResumeWatching
2021-07-17 21:36:50 +00:00
import com.lagradost.cloudstream3.utils.DataStoreHelper.setViewPos
2022-06-16 17:47:48 +00:00
import com.lagradost.cloudstream3.utils.IOnBackPressed
import com.lagradost.cloudstream3.utils.InAppUpdater.Companion.runAutoUpdate
import com.lagradost.cloudstream3.utils.UIHelper.changeStatusBarState
import com.lagradost.cloudstream3.utils.UIHelper.checkWrite
2022-02-05 01:05:13 +00:00
import com.lagradost.cloudstream3.utils.UIHelper.colorFromAttribute
import com.lagradost.cloudstream3.utils.UIHelper.getResourceColor
2021-11-12 16:55:54 +00:00
import com.lagradost.cloudstream3.utils.UIHelper.hideKeyboard
2021-09-23 10:50:10 +00:00
import com.lagradost.cloudstream3.utils.UIHelper.navigate
import com.lagradost.cloudstream3.utils.UIHelper.requestRW
2022-06-16 22:07:07 +00:00
import com.lagradost.cloudstream3.utils.USER_PROVIDER_API
import com.lagradost.nicehttp.Requests
import com.lagradost.nicehttp.ResponseParser
import kotlinx.android.synthetic.main.activity_main.*
2022-02-04 20:49:35 +00:00
import kotlinx.android.synthetic.main.fragment_result_swipe.*
2022-03-16 15:29:11 +00:00
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.withContext
2022-06-17 17:25:41 +00:00
import org.schabi.newpipe.extractor.NewPipe
2022-01-07 19:27:25 +00:00
import java.io.File
import kotlin.concurrent.thread
import kotlin.reflect.KClass
2021-04-30 17:20:15 +00:00
2021-07-17 21:36:50 +00:00
const val VLC_PACKAGE = "org.videolan.vlc"
const val VLC_INTENT_ACTION_RESULT = "org.videolan.vlc.player.result"
val VLC_COMPONENT: ComponentName =
ComponentName(VLC_PACKAGE, "org.videolan.vlc.gui.video.VideoPlayerActivity")
const val VLC_REQUEST_CODE = 42
const val VLC_FROM_START = -1
const val VLC_FROM_PROGRESS = -2
const val VLC_EXTRA_POSITION_OUT = "extra_position"
const val VLC_EXTRA_DURATION_OUT = "extra_duration"
const val VLC_LAST_ID_KEY = "vlc_last_open_id"
2022-01-07 19:27:25 +00:00
// Short name for requests client to make it nicer to use
var app = Requests(responseParser = object : ResponseParser {
val mapper: ObjectMapper = jacksonObjectMapper().configure(
DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES,
false
)
override fun <T : Any> parse(text: String, kClass: KClass<T>): T {
return mapper.readValue(text, kClass.java)
}
override fun <T : Any> parseSafe(text: String, kClass: KClass<T>): T? {
return try {
mapper.readValue(text, kClass.java)
} catch (e: Exception) {
null
}
}
override fun writeValueAsString(obj: Any): String {
return mapper.writeValueAsString(obj)
}
}).apply {
2022-05-07 11:18:22 +00:00
defaultHeaders = mapOf("user-agent" to USER_AGENT)
}
2021-06-14 16:58:43 +00:00
2021-08-06 20:55:11 +00:00
class MainActivity : AppCompatActivity(), ColorPickerDialogListener {
2022-04-03 15:00:50 +00:00
companion object {
const val TAG = "MAINACT"
}
2021-08-06 20:55:11 +00:00
override fun onColorSelected(dialogId: Int, color: Int) {
onColorSelectedEvent.invoke(Pair(dialogId, color))
}
override fun onDialogDismissed(dialogId: Int) {
onDialogDismissedEvent.invoke(dialogId)
}
2021-06-10 23:00:22 +00:00
2021-09-03 09:13:34 +00:00
override fun onConfigurationChanged(newConfig: Configuration) {
super.onConfigurationChanged(newConfig)
updateLocale() // android fucks me by chaining lang when rotating the phone
2022-04-22 18:53:58 +00:00
val navHostFragment =
supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as NavHostFragment
2022-04-22 18:53:58 +00:00
navHostFragment.navController.currentDestination?.let { updateNavBar(it) }
2021-12-12 02:33:17 +00:00
}
2022-01-07 19:27:25 +00:00
private fun updateNavBar(destination: NavDestination) {
2021-12-12 02:33:17 +00:00
this.hideKeyboard()
// Fucks up anime info layout since that has its own layout
cast_mini_controller_holder?.isVisible =
!listOf(R.id.navigation_results, R.id.navigation_player).contains(destination.id)
val isNavVisible = listOf(
R.id.navigation_home,
R.id.navigation_search,
R.id.navigation_downloads,
R.id.navigation_settings,
2022-05-15 18:38:32 +00:00
R.id.navigation_download_child,
R.id.navigation_subtitles,
R.id.navigation_chrome_subtitles,
R.id.navigation_settings_player,
R.id.navigation_settings_updates,
R.id.navigation_settings_ui,
R.id.navigation_settings_account,
R.id.navigation_settings_lang,
2022-06-09 13:50:55 +00:00
R.id.navigation_settings_general,
2021-12-12 02:33:17 +00:00
).contains(destination.id)
2022-01-07 19:27:25 +00:00
val landscape = when (resources.configuration.orientation) {
2021-12-12 02:33:17 +00:00
Configuration.ORIENTATION_LANDSCAPE -> {
true
}
Configuration.ORIENTATION_PORTRAIT -> {
false
}
else -> {
false
}
}
nav_view?.isVisible = isNavVisible && !landscape
nav_rail_view?.isVisible = isNavVisible && landscape
2021-09-03 09:13:34 +00:00
}
//private var mCastSession: CastSession? = null
lateinit var mSessionManager: SessionManager
private val mSessionManagerListener: SessionManagerListener<Session> by lazy { SessionManagerListenerImpl() }
private inner class SessionManagerListenerImpl : SessionManagerListener<Session> {
override fun onSessionStarting(session: Session) {
}
override fun onSessionStarted(session: Session, sessionId: String) {
invalidateOptionsMenu()
}
override fun onSessionStartFailed(session: Session, i: Int) {
}
override fun onSessionEnding(session: Session) {
}
override fun onSessionResumed(session: Session, wasSuspended: Boolean) {
invalidateOptionsMenu()
}
override fun onSessionResumeFailed(session: Session, i: Int) {
}
override fun onSessionSuspended(session: Session, i: Int) {
}
override fun onSessionEnded(session: Session, error: Int) {
}
override fun onSessionResuming(session: Session, s: String) {
}
}
override fun onResume() {
super.onResume()
try {
if (isCastApiAvailable()) {
//mCastSession = mSessionManager.currentCastSession
mSessionManager.addSessionManagerListener(mSessionManagerListener)
}
} catch (e: Exception) {
logError(e)
}
}
override fun onPause() {
super.onPause()
try {
if (isCastApiAvailable()) {
mSessionManager.removeSessionManagerListener(mSessionManagerListener)
//mCastSession = null
}
} catch (e: Exception) {
logError(e)
}
}
2021-11-28 12:18:01 +00:00
override fun dispatchKeyEvent(event: KeyEvent?): Boolean {
2022-01-07 19:27:25 +00:00
CommonActivity.dispatchKeyEvent(this, event)?.let {
return it
2021-11-27 18:49:51 +00:00
}
return super.dispatchKeyEvent(event)
}
2021-10-27 14:54:57 +00:00
override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean {
2022-01-07 19:27:25 +00:00
CommonActivity.onKeyDown(this, keyCode, event)
2021-10-30 18:14:12 +00:00
2021-10-27 14:54:57 +00:00
return super.onKeyDown(keyCode, event)
}
2021-05-22 22:25:56 +00:00
2021-06-10 23:00:22 +00:00
override fun onUserLeaveHint() {
super.onUserLeaveHint()
2022-01-07 19:27:25 +00:00
onUserLeaveHint(this)
2021-06-10 23:00:22 +00:00
}
2021-05-22 22:25:56 +00:00
2022-06-16 17:47:48 +00:00
private fun backPressed() {
2022-02-05 01:05:13 +00:00
this.window?.navigationBarColor =
this.colorFromAttribute(R.attr.primaryGrayBackground)
2021-09-02 16:51:13 +00:00
this.updateLocale()
2021-05-18 13:43:32 +00:00
super.onBackPressed()
2021-09-03 09:13:34 +00:00
this.updateLocale()
2021-05-18 13:43:32 +00:00
}
2021-04-30 17:20:15 +00:00
2022-06-16 17:47:48 +00:00
override fun onBackPressed() {
((supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as? NavHostFragment?)?.childFragmentManager?.primaryNavigationFragment as? IOnBackPressed)?.onBackPressed()
?.let { runNormal ->
if (runNormal) backPressed()
} ?: run {
backPressed()
}
}
2021-07-04 00:59:51 +00:00
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
2021-07-17 21:36:50 +00:00
if (VLC_REQUEST_CODE == requestCode) {
if (resultCode == RESULT_OK && data != null) {
val pos: Long =
2022-01-07 19:27:25 +00:00
data.getLongExtra(
VLC_EXTRA_POSITION_OUT,
-1
) //Last position in media when player exited
2021-07-17 21:36:50 +00:00
val dur: Long =
2022-01-07 19:27:25 +00:00
data.getLongExtra(
VLC_EXTRA_DURATION_OUT,
-1
) //Last position in media when player exited
2021-07-17 21:36:50 +00:00
val id = getKey<Int>(VLC_LAST_ID_KEY)
2021-07-18 13:02:30 +00:00
println("SET KEY $id at $pos / $dur")
2021-07-17 21:36:50 +00:00
if (dur > 0 && pos > 0) {
setViewPos(id, pos, dur)
}
removeKey(VLC_LAST_ID_KEY)
2022-01-18 14:10:01 +00:00
ResultFragment.updateUI()
2021-07-17 21:36:50 +00:00
}
}
2021-07-04 00:59:51 +00:00
super.onActivityResult(requestCode, resultCode, data)
}
2021-07-08 17:46:47 +00:00
override fun onDestroy() {
val broadcastIntent = Intent()
broadcastIntent.action = "restart_service"
broadcastIntent.setClass(this, VideoDownloadRestartReceiver::class.java)
this.sendBroadcast(broadcastIntent)
super.onDestroy()
}
override fun onNewIntent(intent: Intent?) {
handleAppIntent(intent)
super.onNewIntent(intent)
}
private fun handleAppIntent(intent: Intent?) {
if (intent == null) return
val str = intent.dataString
2022-01-07 19:27:25 +00:00
loadCache()
if (str != null) {
2021-11-07 22:10:19 +00:00
if (str.contains(appString)) {
for (api in OAuth2Apis) {
if (str.contains("/${api.redirectUrl}")) {
2022-04-03 15:00:50 +00:00
ioSafe {
Log.i(TAG, "handleAppIntent $str")
2022-04-03 21:41:28 +00:00
val isSuccessful = api.handleRedirect(str)
if (isSuccessful) {
2022-04-03 15:00:50 +00:00
Log.i(TAG, "authenticated ${api.name}")
} else {
Log.i(TAG, "failed to authenticate ${api.name}")
}
2022-04-03 21:41:28 +00:00
this.runOnUiThread {
try {
showToast(
this,
getString(if (isSuccessful) R.string.authenticated_user else R.string.authenticated_user_fail).format(
api.name
)
)
} catch (e: Exception) {
logError(e) // format might fail
}
}
2022-04-01 20:05:34 +00:00
}
2021-11-07 22:10:19 +00:00
}
}
} else {
2021-11-07 22:10:19 +00:00
if (str.startsWith(DOWNLOAD_NAVIGATE_TO)) {
this.navigate(R.id.navigation_downloads)
} else {
for (api in apis) {
if (str.startsWith(api.mainUrl)) {
loadResult(str, api.name)
break
}
}
}
}
}
}
2022-03-03 11:26:26 +00:00
private fun NavDestination.matchDestination(@IdRes destId: Int): Boolean =
hierarchy.any { it.id == destId }
private fun onNavDestinationSelected(item: MenuItem, navController: NavController): Boolean {
val builder = NavOptions.Builder().setLaunchSingleTop(true).setRestoreState(true)
.setEnterAnim(R.anim.enter_anim)
.setExitAnim(R.anim.exit_anim)
.setPopEnterAnim(R.anim.pop_enter)
.setPopExitAnim(R.anim.pop_exit)
if (item.order and Menu.CATEGORY_SECONDARY == 0) {
builder.setPopUpTo(
navController.graph.findStartDestination().id,
inclusive = false,
saveState = true
)
}
val options = builder.build()
return try {
navController.navigate(item.itemId, null, options)
navController.currentDestination?.matchDestination(item.itemId) == true
} catch (e: IllegalArgumentException) {
false
}
}
2022-05-26 17:04:39 +00:00
fun test() {
2022-06-17 17:25:41 +00:00
/*thread {
val youtubeLink = "https://www.youtube.com/watch?v=Zxem9rqJ5S0"
val url = YoutubeStreamLinkHandlerFactory.getInstance().fromUrl(youtubeLink)
println("ID:::: ${url.id}")
NewPipe.init(DownloaderTestImpl.getInstance())
val service = ServiceList.YouTube
val s = object : YoutubeStreamExtractor(
service,
url
) {
2022-06-16 01:04:24 +00:00
2022-06-17 17:25:41 +00:00
}
s.fetchPage()
val streams = s.videoStreams
println("STREAMS: ${streams.map { "url = "+ it.url + " extra= " + it.height + "|" + it.isVideoOnly + "\n" }}")
}*/
2022-06-16 01:04:24 +00:00
/*
runBlocking {
val query = """
2022-06-16 17:47:48 +00:00
query {
2022-06-16 01:04:24 +00:00
searchShows(search: "spider", limit: 10) {
id
name
originalName
}
}
"""
val data =
mapOf(
"query" to query,
//"variables" to
// mapOf(
// "name" to name,
// ).toJson()
)
val txt = app.post(
"http://api.anime-skip.com/graphql",
headers = mapOf(
"X-Client-ID" to "",
"Content-Type" to "application/json",
"Accept" to "application/json",
),
json = data
)
println("TEXT: $txt")
}*/
2022-05-26 17:04:39 +00:00
/*runBlocking {
//https://test.api.anime-skip.com/graphiql
val txt = app.get(
"https://api.anime-skip.com/status",
headers = mapOf("X-Client-ID" to "")
)
println("TEXT: $txt")
}*/
}
2021-04-30 17:20:15 +00:00
override fun onCreate(savedInstanceState: Bundle?) {
2021-11-08 18:13:39 +00:00
// init accounts
for (api in accountManagers) {
api.init()
2021-11-08 18:13:39 +00:00
}
2022-03-16 15:29:11 +00:00
ioSafe {
inAppAuths.apmap { api ->
try {
api.initialize()
} catch (e: Exception) {
logError(e)
}
}
}
SearchResultBuilder.updateCache(this)
2022-03-16 19:02:30 +00:00
val settingsManager = PreferenceManager.getDefaultSharedPreferences(this)
val downloadFromGithub = try {
settingsManager.getBoolean(getString(R.string.killswitch_key), true)
} catch (e: Exception) {
logError(e)
false
}
2022-03-16 15:29:11 +00:00
// must give benenes to get beta providers
val hasBenene = try {
val count = settingsManager.getInt(getString(R.string.benene_count), 0)
count > 30
} catch (e: Exception) {
e.printStackTrace()
false
}
try {
getKey<Array<SettingsGeneral.CustomSite>>(USER_PROVIDER_API)?.let { list ->
list.forEach { custom ->
allProviders.firstOrNull { it.javaClass.simpleName == custom.parentJavaClass }
?.let {
allProviders.add(it.javaClass.newInstance().apply {
name = custom.name
lang = custom.lang
mainUrl = custom.url.trimEnd('/')
canBeOverridden = false
})
}
}
}
apis = allProviders
APIHolder.apiMap = null
} catch (e: Exception) {
logError(e)
}
2022-03-16 15:29:11 +00:00
// this pulls the latest data so ppl don't have to update to simply change provider url
if (downloadFromGithub) {
2022-03-16 19:02:30 +00:00
try {
runBlocking {
withContext(Dispatchers.IO) {
try {
val cacheStr: String? = getKey(PROVIDER_STATUS_KEY)
val cache: HashMap<String, ProvidersInfoJson>? =
cacheStr?.let { tryParseJson(cacheStr) }
if (cache != null) {
// if cache is found then spin up a new request, but dont wait
main {
try {
val txt = app.get(PROVIDER_STATUS_URL).text
val newCache =
tryParseJson<HashMap<String, ProvidersInfoJson>>(txt)
setKey(PROVIDER_STATUS_KEY, txt)
MainAPI.overrideData = newCache // update all new providers
2022-06-02 22:51:41 +00:00
initAll()
for (api in apis) { // update current providers
newCache?.get(api.javaClass.simpleName)
?.let { data ->
api.overrideWithNewData(data)
}
2022-03-16 19:02:30 +00:00
}
} catch (e: Exception) {
logError(e)
}
}
cache
} else {
// if it is the first time the user has used the app then wait for a request to update all providers
2022-03-16 15:29:11 +00:00
val txt = app.get(PROVIDER_STATUS_URL).text
setKey(PROVIDER_STATUS_KEY, txt)
2022-03-16 19:02:30 +00:00
val newCache = tryParseJson<HashMap<String, ProvidersInfoJson>>(txt)
newCache
}?.let { providersJsonMap ->
MainAPI.overrideData = providersJsonMap
2022-06-02 22:51:41 +00:00
initAll()
2022-03-16 19:02:30 +00:00
val acceptableProviders =
providersJsonMap.filter { it.value.status == PROVIDER_STATUS_OK || it.value.status == PROVIDER_STATUS_SLOW }
2022-03-16 19:02:30 +00:00
.map { it.key }.toSet()
val restrictedApis =
if (hasBenene) providersJsonMap.filter { it.value.status == PROVIDER_STATUS_BETA_ONLY }
2022-03-16 19:02:30 +00:00
.map { it.key }.toSet() else emptySet()
apis = allProviders.filter { api ->
val name = api.javaClass.simpleName
2022-03-17 11:43:27 +00:00
// if the provider does not exist in the json file, then it is shown by default
!providersJsonMap.containsKey(name) || acceptableProviders.contains(
name
) || restrictedApis.contains(name)
2022-03-16 15:29:11 +00:00
}
}
} catch (e: Exception) {
2022-03-16 19:02:30 +00:00
logError(e)
2022-03-16 15:29:11 +00:00
}
}
}
2022-03-16 19:02:30 +00:00
} catch (e: Exception) {
2022-06-02 22:51:41 +00:00
initAll()
2022-03-16 19:02:30 +00:00
apis = allProviders
e.printStackTrace()
logError(e)
2022-03-16 15:29:11 +00:00
}
2022-03-16 19:02:30 +00:00
} else {
2022-06-02 22:51:41 +00:00
initAll()
2022-03-16 15:29:11 +00:00
apis = allProviders
}
2022-06-16 22:07:07 +00:00
2022-01-07 19:27:25 +00:00
loadThemes(this)
2021-09-02 16:51:13 +00:00
updateLocale()
app.initClient(this)
2021-04-30 17:20:15 +00:00
super.onCreate(savedInstanceState)
try {
if (isCastApiAvailable()) {
mSessionManager = CastContext.getSharedInstance(this).sessionManager
}
} catch (e: Exception) {
logError(e)
}
window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN)
2021-06-29 23:14:48 +00:00
2021-10-30 18:14:12 +00:00
if (isTvSettings()) {
setContentView(R.layout.activity_main_tv)
} else {
setContentView(R.layout.activity_main)
}
changeStatusBarState(isEmulatorSettings())
// val navView: BottomNavigationView = findViewById(R.id.nav_view)
2022-03-04 15:39:56 +00:00
setUpBackup()
2022-01-07 19:27:25 +00:00
CommonActivity.init(this)
val navHostFragment =
supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as NavHostFragment
2022-04-22 18:53:58 +00:00
val navController = navHostFragment.navController
//val navController = findNavController(R.id.nav_host_fragment)
2021-07-19 13:19:47 +00:00
2021-09-20 21:11:36 +00:00
/*navOptions = NavOptions.Builder()
2021-07-19 13:19:47 +00:00
.setLaunchSingleTop(true)
.setEnterAnim(R.anim.nav_enter_anim)
.setExitAnim(R.anim.nav_exit_anim)
.setPopEnterAnim(R.anim.nav_pop_enter)
.setPopExitAnim(R.anim.nav_pop_exit)
.setPopUpTo(navController.graph.startDestination, false)
2021-09-20 21:11:36 +00:00
.build()*/
2021-11-25 17:26:14 +00:00
nav_view?.setupWithNavController(navController)
2022-04-18 18:24:29 +00:00
val nav_rail = findViewById<NavigationRailView?>(R.id.nav_rail_view)
nav_rail?.setupWithNavController(navController)
2022-03-03 11:26:26 +00:00
2022-04-18 18:24:29 +00:00
nav_rail?.setOnItemSelectedListener { item ->
2022-03-03 11:26:26 +00:00
onNavDestinationSelected(
item,
navController
)
}
nav_view?.setOnItemSelectedListener { item ->
onNavDestinationSelected(
item,
navController
)
}
2021-09-20 21:11:36 +00:00
navController.addOnDestinationChangedListener { _, destination, _ ->
2021-12-12 02:33:17 +00:00
updateNavBar(destination)
2021-09-20 21:11:36 +00:00
}
2022-03-03 11:26:26 +00:00
2022-01-07 19:27:25 +00:00
loadCache()
2022-05-26 17:04:39 +00:00
test()
updateHasTrailers()
2021-09-20 21:11:36 +00:00
/*nav_view.setOnNavigationItemSelectedListener { item ->
2021-07-19 13:19:47 +00:00
when (item.itemId) {
R.id.navigation_home -> {
navController.navigate(R.id.navigation_home, null, navOptions)
}
2021-07-19 13:19:47 +00:00
R.id.navigation_search -> {
navController.navigate(R.id.navigation_search, null, navOptions)
}
R.id.navigation_downloads -> {
navController.navigate(R.id.navigation_downloads, null, navOptions)
}
R.id.navigation_settings -> {
navController.navigate(R.id.navigation_settings, null, navOptions)
}
}
true
2021-09-20 21:11:36 +00:00
}*/
2021-07-19 13:19:47 +00:00
val rippleColor = ColorStateList.valueOf(getResourceColor(R.attr.colorPrimary, 0.1f))
2021-11-25 17:26:14 +00:00
nav_view?.itemRippleColor = rippleColor
2022-04-18 18:24:29 +00:00
nav_rail?.itemRippleColor = rippleColor
nav_rail?.itemActiveIndicatorColor = rippleColor
nav_view?.itemActiveIndicatorColor = rippleColor
2021-05-20 21:25:41 +00:00
if (!checkWrite()) {
requestRW()
if (checkWrite()) return
}
2021-06-14 00:00:29 +00:00
CastButtonFactory.setUpMediaRouteButton(this, media_route_button)
2021-06-14 16:58:43 +00:00
2021-07-15 16:45:25 +00:00
// THIS IS CURRENTLY REMOVED BECAUSE HIGHER VERS OF ANDROID NEEDS A NOTIFICATION
//if (!VideoDownloadManager.isMyServiceRunning(this, VideoDownloadKeepAliveService::class.java)) {
// val mYourService = VideoDownloadKeepAliveService()
// val mServiceIntent = Intent(this, mYourService::class.java).putExtra(START_VALUE_KEY, RESTART_ALL_DOWNLOADS_AND_QUEUE)
// this.startService(mServiceIntent)
//}
2021-07-17 15:56:26 +00:00
//settingsManager.getBoolean("disable_automatic_data_downloads", true) &&
2021-07-25 14:25:09 +00:00
// TODO RETURN TO TRUE
/*
2021-07-17 21:36:50 +00:00
if (isUsingMobileData()) {
2021-07-17 15:56:26 +00:00
Toast.makeText(this, "Downloads not resumed on mobile data", Toast.LENGTH_LONG).show()
} else {
val keys = getKeys(VideoDownloadManager.KEY_RESUME_PACKAGES)
val resumePkg = keys.mapNotNull { k -> getKey<VideoDownloadManager.DownloadResumePackage>(k) }
// To remove a bug where this is permanent
removeKeys(VideoDownloadManager.KEY_RESUME_PACKAGES)
for (pkg in resumePkg) { // ADD ALL CURRENT DOWNLOADS
VideoDownloadManager.downloadFromResume(this, pkg, false)
}
2021-07-08 17:46:47 +00:00
2021-07-17 15:56:26 +00:00
// ADD QUEUE
// array needed because List gets cast exception to linkedList for some unknown reason
val resumeQueue =
getKey<Array<VideoDownloadManager.DownloadQueueResumePackage>>(VideoDownloadManager.KEY_RESUME_QUEUE_PACKAGES)
resumeQueue?.sortedBy { it.index }?.forEach {
VideoDownloadManager.downloadFromResume(this, it.pkg)
}
2021-07-25 14:25:09 +00:00
}*/
2021-06-14 00:00:29 +00:00
/*
val castContext = CastContext.getSharedInstance(applicationContext)
fun buildMediaQueueItem(video: String): MediaQueueItem {
// val movieMetadata = MediaMetadata(MediaMetadata.MEDIA_TYPE_PHOTO)
//movieMetadata.putString(MediaMetadata.KEY_TITLE, "CloudStream")
val mediaInfo = MediaInfo.Builder(Uri.parse(video).toString())
.setStreamType(MediaInfo.STREAM_TYPE_NONE)
.setContentType(MimeTypes.IMAGE_JPEG)
// .setMetadata(movieMetadata).build()
.build()
return MediaQueueItem.Builder(mediaInfo).build()
}*/
/*
castContext.addCastStateListener { state ->
if (state == CastState.CONNECTED) {
println("TESTING")
val isCasting = castContext?.sessionManager?.currentCastSession?.remoteMediaClient?.currentItem != null
if(!isCasting) {
val castPlayer = CastPlayer(castContext)
println("LOAD ITEM")
castPlayer.loadItem(buildMediaQueueItem("https://cdn.discordapp.com/attachments/551382684560261121/730169809408622702/ChromecastLogo6.png"),0)
}
}
}*/
/*thread {
createISO()
}*/
2021-08-19 20:05:18 +00:00
2022-04-10 22:00:03 +00:00
if (BuildConfig.DEBUG) {
var providersAndroidManifestString = "Current androidmanifest should be:\n"
for (api in allProviders) {
providersAndroidManifestString += "<data android:scheme=\"https\" android:host=\"${
api.mainUrl.removePrefix(
"https://"
)
}\" android:pathPrefix=\"/\"/>\n"
}
2022-04-10 22:00:03 +00:00
println(providersAndroidManifestString)
}
handleAppIntent(intent)
thread {
runAutoUpdate()
}
2021-08-30 21:42:58 +00:00
2021-09-12 14:10:22 +00:00
APIRepository.dubStatusActive = getApiDubstatusSettings()
2022-01-07 19:27:25 +00:00
try {
// this ensures that no unnecessary space is taken
loadCache()
File(filesDir, "exoplayer").deleteRecursively() // old cache
File(cacheDir, "exoplayer").deleteOnExit() // current cache
} catch (e: Exception) {
logError(e)
}
2022-03-16 15:29:11 +00:00
println("Loaded everything")
2022-05-02 21:32:28 +00:00
ioSafe {
migrateResumeWatching()
}
2022-07-30 01:24:07 +00:00
try {
if (getKey(HAS_DONE_SETUP_KEY, false) != true) {
navController.navigate(R.id.navigation_setup_language)
}
} catch (e: Exception) {
logError(e)
} finally {
setKey(HAS_DONE_SETUP_KEY, true)
}
2021-09-07 19:16:12 +00:00
/*
2022-07-30 01:24:07 +00:00
2021-09-07 19:16:12 +00:00
val relativePath = (Environment.DIRECTORY_DOWNLOADS) + File.separatorChar
val displayName = "output.dex" //""output.dex"
val file = getExternalFilesDir(null)?.absolutePath + File.separatorChar + displayName//"${Environment.getExternalStorageDirectory()}${File.separatorChar}$relativePath$displayName"
println(file)
val realFile = File(file)
println("REAALFILE: ${realFile.exists()} at ${realFile.length()}" )
val src = ExtensionManager.getSourceFromDex(this, "com.example.testdex2.TestClassToDex", File(file))
val output = src?.doMath()
println("MASTER OUTPUT = $output")*/
2021-04-30 17:20:15 +00:00
}
}