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
2021-09-23 18:08:57 +00:00
import com.google.android.gms.cast.framework.*
2021-11-25 22:36:35 +00:00
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
2021-07-30 01:14:53 +00:00
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
2022-01-07 19:27:25 +00:00
import com.lagradost.cloudstream3.CommonActivity.backEvent
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
2022-04-22 18:53:58 +00:00
import com.lagradost.cloudstream3.movieproviders.NginxProvider
2021-09-12 15:57:07 +00:00
import com.lagradost.cloudstream3.mvvm.logError
2022-05-02 16:58:27 +00:00
import com.lagradost.cloudstream3.network.initClient
2021-07-08 19:39:49 +00:00
import com.lagradost.cloudstream3.receivers.VideoDownloadRestartReceiver
2021-11-12 16:55:54 +00:00
import com.lagradost.cloudstream3.syncproviders.OAuth2API.Companion.OAuth2Apis
import com.lagradost.cloudstream3.syncproviders.OAuth2API.Companion.OAuth2accountApis
import com.lagradost.cloudstream3.syncproviders.OAuth2API.Companion.appString
2021-09-12 14:10:22 +00:00
import com.lagradost.cloudstream3.ui.APIRepository
2021-07-30 01:14:53 +00:00
import com.lagradost.cloudstream3.ui.download.DOWNLOAD_NAVIGATE_TO
2022-01-18 14:10:01 +00:00
import com.lagradost.cloudstream3.ui.result.ResultFragment
2022-05-05 16:16:41 +00:00
import com.lagradost.cloudstream3.ui.search.SearchResultBuilder
2022-02-18 19:54:55 +00:00
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
2021-09-24 22:51:08 +00:00
import com.lagradost.cloudstream3.utils.AppUtils.isCastApiAvailable
2022-01-07 19:27:25 +00:00
import com.lagradost.cloudstream3.utils.AppUtils.loadCache
2021-07-30 01:14:53 +00:00
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
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
2021-08-15 17:38:41 +00:00
import com.lagradost.cloudstream3.utils.InAppUpdater.Companion.runAutoUpdate
2022-02-18 19:54:55 +00:00
import com.lagradost.cloudstream3.utils.UIHelper.changeStatusBarState
2021-08-24 22:19:15 +00:00
import com.lagradost.cloudstream3.utils.UIHelper.checkWrite
2022-02-05 01:05:13 +00:00
import com.lagradost.cloudstream3.utils.UIHelper.colorFromAttribute
2021-08-24 22:19:15 +00:00
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
2021-08-24 22:19:15 +00:00
import com.lagradost.cloudstream3.utils.UIHelper.requestRW
2022-05-02 16:58:27 +00:00
import com.lagradost.nicehttp.Requests
2021-07-30 01:14:53 +00:00
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-01-07 19:27:25 +00:00
import java.io.File
2021-08-15 17:38:41 +00:00
import kotlin.concurrent.thread
2021-04-30 17:20:15 +00:00
2021-08-24 22:19: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
2021-12-05 16:22:30 +00:00
// Short name for requests client to make it nicer to use
2022-05-07 11:18:22 +00:00
var app = Requests ( ) . apply {
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
2022-05-05 16:16:41 +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 _nginx ,
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 ,
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
}
2021-11-25 22:36:35 +00:00
//private var mCastSession: CastSession? = null
2021-09-30 12:16:23 +00:00
lateinit var mSessionManager : SessionManager
private val mSessionManagerListener : SessionManagerListener < Session > by lazy { SessionManagerListenerImpl ( ) }
2021-09-23 18:08:57 +00:00
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 ( )
2021-09-24 22:51:08 +00:00
try {
2021-09-30 12:16:23 +00:00
if ( isCastApiAvailable ( ) ) {
2021-11-25 22:36:35 +00:00
//mCastSession = mSessionManager.currentCastSession
2021-09-24 22:51:08 +00:00
mSessionManager . addSessionManagerListener ( mSessionManagerListener )
}
2021-09-30 12:16:23 +00:00
} catch ( e : Exception ) {
2021-09-24 22:51:08 +00:00
logError ( e )
}
2021-09-23 18:08:57 +00:00
}
override fun onPause ( ) {
super . onPause ( )
2021-09-24 22:51:08 +00:00
try {
2021-09-30 12:16:23 +00:00
if ( isCastApiAvailable ( ) ) {
2021-09-24 22:51:08 +00:00
mSessionManager . removeSessionManagerListener ( mSessionManagerListener )
2021-11-25 22:36:35 +00:00
//mCastSession = null
2021-09-24 22:51:08 +00:00
}
2021-09-30 12:16:23 +00:00
} catch ( e : Exception ) {
2021-09-24 22:51:08 +00:00
logError ( e )
}
2021-09-23 18:08:57 +00:00
}
2021-11-28 12:18:01 +00:00
2021-11-26 23:19:17 +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
}
2021-11-26 23:19:17 +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
2021-05-18 13:43:32 +00:00
override fun onBackPressed ( ) {
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-09-24 22:51:08 +00:00
backEvent . invoke ( true )
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
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 ( )
}
2021-07-30 01:14:53 +00:00
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 ( )
2021-07-30 01:14:53 +00:00
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
}
}
2021-07-30 01:14:53 +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
}
2021-07-30 01:14:53 +00:00
}
}
}
}
}
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 ( ) {
/ * 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 OAuth2accountApis ) {
2021-12-16 23:45:20 +00:00
api . init ( )
2021-11-08 18:13:39 +00:00
}
2022-03-16 15:29:11 +00:00
2022-05-05 16:16:41 +00:00
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
}
2022-04-11 20:17:34 +00:00
2022-06-02 22:51:41 +00:00
fun addNginxToJson ( data : java . util . HashMap < String , ProvidersInfoJson > ) : java . util . HashMap < String , ProvidersInfoJson > {
2022-05-05 16:16:41 +00:00
try {
val settingsManager = PreferenceManager . getDefaultSharedPreferences ( this )
val nginxUrl =
settingsManager . getString ( getString ( R . string . nginx _url _key ) , " nginx_url_key " )
. toString ( )
val nginxCredentials =
settingsManager . getString (
getString ( R . string . nginx _credentials ) ,
" nginx_credentials "
)
. toString ( )
2022-06-02 22:51:41 +00:00
val storedNginxProvider = NginxProvider ( )
2022-05-05 16:16:41 +00:00
if ( nginxUrl == " nginx_url_key " || nginxUrl == " " ) { // if key is default value, or empty:
2022-06-02 22:51:41 +00:00
data [ storedNginxProvider . javaClass . simpleName ] = ProvidersInfoJson (
2022-05-05 16:16:41 +00:00
url = nginxUrl ,
2022-06-02 22:51:41 +00:00
name = storedNginxProvider . name ,
2022-05-05 16:16:41 +00:00
status = PROVIDER _STATUS _DOWN , // the provider will not be display
credentials = nginxCredentials
)
} else { // valid url
2022-06-02 22:51:41 +00:00
data [ storedNginxProvider . javaClass . simpleName ] = ProvidersInfoJson (
2022-05-05 16:16:41 +00:00
url = nginxUrl ,
2022-06-02 22:51:41 +00:00
name = storedNginxProvider . name ,
2022-05-05 16:16:41 +00:00
status = PROVIDER _STATUS _OK ,
credentials = nginxCredentials
)
}
return data
} catch ( e : Exception ) {
logError ( e )
return data
}
2022-04-11 20:17:34 +00:00
}
2022-05-05 16:16:41 +00:00
fun createNginxJson ( ) : ProvidersInfoJson ? { //java.util.HashMap<String, ProvidersInfoJson>
return try {
val settingsManager = PreferenceManager . getDefaultSharedPreferences ( this )
val nginxUrl =
settingsManager . getString ( getString ( R . string . nginx _url _key ) , " nginx_url_key " )
. toString ( )
val nginxCredentials = settingsManager . getString (
getString ( R . string . nginx _credentials ) ,
" nginx_credentials "
) . toString ( )
if ( nginxUrl == " nginx_url_key " || nginxUrl == " " ) { // if key is default value or empty:
null // don't overwrite anything
} else {
ProvidersInfoJson (
url = nginxUrl ,
name = NginxProvider ( ) . name ,
status = PROVIDER _STATUS _OK ,
credentials = nginxCredentials
)
}
} catch ( e : Exception ) {
logError ( e )
null
2022-04-11 20:17:34 +00:00
}
}
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
2022-03-27 16:45:02 +00:00
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-04-11 20:17:34 +00:00
2022-05-05 16:16:41 +00:00
val newUpdatedCache =
2022-06-02 22:51:41 +00:00
newCache ?. let { addNginxToJson ( it ) }
initAll ( )
2022-05-05 16:16:41 +00:00
for ( api in apis ) { // update current providers
newUpdatedCache ?. 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
val providersJsonMapUpdated =
addNginxToJson ( providersJsonMap ) // if return null, use unchanged one
initAll ( )
2022-03-16 19:02:30 +00:00
val acceptableProviders =
2022-04-11 20:17:34 +00:00
providersJsonMapUpdated . 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 =
2022-04-11 20:17:34 +00:00
if ( hasBenene ) providersJsonMapUpdated . 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
2022-03-27 16:45:02 +00:00
! providersJsonMap . containsKey ( name ) || acceptableProviders . contains (
name
) || restrictedApis . contains ( name )
2022-03-16 15:29:11 +00:00
}
}
2022-03-27 16:45:02 +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-04-11 20:17:34 +00:00
try {
val nginxProviderName = NginxProvider ( ) . name
val nginxProviderIndex = apis . indexOf ( APIHolder . getApiFromName ( nginxProviderName ) )
val createdJsonProvider = createNginxJson ( )
if ( createdJsonProvider != null ) {
apis [ nginxProviderIndex ] . overrideWithNewData ( createdJsonProvider ) // people will have access to it if they disable metadata check (they are not filtered)
}
} catch ( e : Exception ) {
logError ( e )
}
2022-03-16 15:29:11 +00:00
}
2022-01-07 19:27:25 +00:00
loadThemes ( this )
2021-09-02 16:51:13 +00:00
updateLocale ( )
2021-12-05 16:22:30 +00:00
app . initClient ( this )
2021-04-30 17:20:15 +00:00
super . onCreate ( savedInstanceState )
2021-09-24 22:51:08 +00:00
try {
2021-09-30 12:16:23 +00:00
if ( isCastApiAvailable ( ) ) {
2021-09-24 22:51:08 +00:00
mSessionManager = CastContext . getSharedInstance ( this ) . sessionManager
}
2021-09-30 12:16:23 +00:00
} catch ( e : Exception ) {
2021-09-24 22:51:08 +00:00
logError ( e )
}
2021-07-30 01:14:53 +00:00
2021-07-28 01:04:32 +00:00
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 )
}
2022-02-18 19:54:55 +00:00
changeStatusBarState ( isEmulatorSettings ( ) )
2021-07-30 01:14:53 +00:00
// 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 )
2022-05-05 16:16:41 +00:00
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 ( )
2021-09-20 21:11:36 +00:00
/ * nav _view . setOnNavigationItemSelectedListener { item ->
2021-07-19 13:19:47 +00:00
when ( item . itemId ) {
2021-07-28 01:04:32 +00:00
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
2021-11-26 23:19:17 +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 ( !is Casting ) {
val castPlayer = CastPlayer ( castContext )
println ( " LOAD ITEM " )
castPlayer . loadItem ( buildMediaQueueItem ( " https://cdn.discordapp.com/attachments/551382684560261121/730169809408622702/ChromecastLogo6.png " ) , 0 )
}
}
} * /
2021-07-31 22:11:56 +00:00
/ * 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 "
}
2021-09-30 12:16:23 +00:00
2022-04-10 22:00:03 +00:00
println ( providersAndroidManifestString )
}
2021-09-30 12:16:23 +00:00
2021-07-30 01:14:53 +00:00
handleAppIntent ( intent )
2021-08-15 17:38:41 +00:00
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 ( )
}
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
}
2022-04-11 20:17:34 +00:00
}