2021-04-30 17:20:15 +00:00
package com.lagradost.cloudstream3
2021-08-24 22:19:15 +00:00
import android.app.Activity
2021-06-10 23:00:22 +00:00
import android.app.PictureInPictureParams
2021-07-17 21:36:50 +00:00
import android.content.ComponentName
2021-09-02 16:51:13 +00:00
import android.content.Context
2021-07-04 00:59:51 +00:00
import android.content.Intent
2021-06-10 23:00:22 +00:00
import android.content.pm.PackageManager
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-09-02 16:51:13 +00:00
import android.content.res.Resources
2021-06-10 23:00:22 +00:00
import android.os.Build
2021-04-30 17:20:15 +00:00
import android.os.Bundle
2021-08-24 22:19:15 +00:00
import android.view.*
2021-11-26 23:19:17 +00:00
import android.view.KeyEvent.ACTION_DOWN
2021-08-24 22:19:15 +00:00
import android.widget.TextView
import android.widget.Toast
import androidx.annotation.StringRes
2021-04-30 17:20:15 +00:00
import androidx.appcompat.app.AppCompatActivity
2021-11-26 23:19:17 +00:00
import androidx.appcompat.widget.SearchView
2021-09-20 21:11:36 +00:00
import androidx.core.view.isVisible
2021-12-12 02:33:17 +00:00
import androidx.navigation.NavDestination
2021-04-30 17:20:15 +00:00
import androidx.navigation.findNavController
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
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
2021-08-30 21:42:58 +00:00
import com.lagradost.cloudstream3.APIHolder.restrictedApis
2021-09-12 15:57:07 +00:00
import com.lagradost.cloudstream3.mvvm.logError
2021-12-05 16:22:30 +00:00
import com.lagradost.cloudstream3.network.Requests
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
2021-10-27 14:54:57 +00:00
import com.lagradost.cloudstream3.ui.player.PlayerEventType
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
2021-07-30 01:14:53 +00:00
import com.lagradost.cloudstream3.utils.AppUtils.loadResult
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
import com.lagradost.cloudstream3.utils.DataStoreHelper.setViewPos
2021-07-30 23:41:54 +00:00
import com.lagradost.cloudstream3.utils.Event
2021-08-15 17:38:41 +00:00
import com.lagradost.cloudstream3.utils.InAppUpdater.Companion.runAutoUpdate
2021-08-24 22:19:15 +00:00
import com.lagradost.cloudstream3.utils.UIHelper.checkWrite
import com.lagradost.cloudstream3.utils.UIHelper.getResourceColor
import com.lagradost.cloudstream3.utils.UIHelper.hasPIPPermission
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
import com.lagradost.cloudstream3.utils.UIHelper.shouldShowPIPMode
2021-11-26 23:19:17 +00:00
import com.lagradost.cloudstream3.utils.UIHelper.showInputMethod
2021-08-24 22:19:15 +00:00
import com.lagradost.cloudstream3.utils.UIHelper.toPx
2021-07-30 01:14:53 +00:00
import kotlinx.android.synthetic.main.activity_main.*
2021-06-14 00:00:29 +00:00
import kotlinx.android.synthetic.main.fragment_result.*
2021-09-02 14:06:43 +00:00
import java.util.*
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 "
2021-12-05 16:22:30 +00:00
// Short name for requests client to make it nicer to use
var app = Requests ( )
2021-06-14 16:58:43 +00:00
2021-08-06 20:55:11 +00:00
class MainActivity : AppCompatActivity ( ) , ColorPickerDialogListener {
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
2021-12-12 02:33:17 +00:00
findNavController ( R . id . nav _host _fragment ) . currentDestination ?. let { updateNavBar ( it ) }
}
private fun updateNavBar ( destination : NavDestination ) {
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 ,
R . id . navigation _download _child
) . contains ( destination . id )
val landscape = when ( resources . configuration . orientation ) {
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
enum class FocusDirection {
Left ,
Right ,
Up ,
Down ,
}
private fun getNextFocus ( view : View ? , direction : FocusDirection , depth : Int = 0 ) : Int ? {
if ( view == null || depth >= 10 ) {
return null
}
val nextId = when ( direction ) {
FocusDirection . Left -> {
view . nextFocusLeftId
}
FocusDirection . Up -> {
view . nextFocusUpId
}
FocusDirection . Right -> {
view . nextFocusRightId
}
FocusDirection . Down -> {
view . nextFocusDownId
}
}
return if ( nextId != - 1 ) {
val next = findViewById < View ? > ( nextId )
//println("NAME: ${next.accessibilityClassName} | ${next?.isShown}" )
if ( next ?. isShown == false ) {
getNextFocus ( next , direction , depth + 1 )
} else {
if ( depth == 0 ) {
null
} else {
nextId
}
}
} else {
null
}
}
2021-11-26 23:19:17 +00:00
override fun dispatchKeyEvent ( event : KeyEvent ? ) : Boolean {
event ?. keyCode ?. let { keyCode ->
when ( event . action ) {
ACTION _DOWN -> {
2021-11-28 12:18:01 +00:00
if ( currentFocus != null ) {
val next = when ( keyCode ) {
KeyEvent . KEYCODE _DPAD _LEFT -> getNextFocus ( currentFocus , FocusDirection . Left )
KeyEvent . KEYCODE _DPAD _RIGHT -> getNextFocus ( currentFocus , FocusDirection . Right )
KeyEvent . KEYCODE _DPAD _UP -> getNextFocus ( currentFocus , FocusDirection . Up )
KeyEvent . KEYCODE _DPAD _DOWN -> getNextFocus ( currentFocus , FocusDirection . Down )
else -> null
}
if ( next != null && next != - 1 ) {
val nextView = findViewById < View ? > ( next )
if ( nextView != null ) {
nextView . requestFocus ( )
return true
2021-11-26 23:19:17 +00:00
}
}
2021-11-28 12:18:01 +00:00
when ( keyCode ) {
KeyEvent . KEYCODE _DPAD _CENTER -> {
println ( " DPAD PRESSED $currentFocus " )
if ( currentFocus is SearchView || currentFocus is SearchView . SearchAutoComplete ) {
println ( " current PRESSED " )
showInputMethod ( currentFocus ?. findFocus ( ) )
}
}
}
}
2021-11-26 23:19:17 +00:00
//println("Keycode: $keyCode")
//showToast(
// this,
// "Got Keycode $keyCode | ${KeyEvent.keyCodeToString(keyCode)} \n ${event?.action}",
// Toast.LENGTH_LONG
//)
}
}
}
2021-11-28 12:18:01 +00:00
if ( keyEventListener ?. invoke ( event ) == true ) {
2021-11-27 18:49:51 +00:00
return true
}
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 {
2021-10-30 18:42:58 +00:00
//println("Keycode: $keyCode")
2021-10-27 19:45:15 +00:00
//showToast(
// this,
// "Got Keycode $keyCode | ${KeyEvent.keyCodeToString(keyCode)} \n ${event?.action}",
// Toast.LENGTH_LONG
//)
// Tested keycodes on remote:
// KeyEvent.KEYCODE_MEDIA_FAST_FORWARD
// KeyEvent.KEYCODE_MEDIA_REWIND
// KeyEvent.KEYCODE_MENU
// KeyEvent.KEYCODE_MEDIA_NEXT
// KeyEvent.KEYCODE_MEDIA_PREVIOUS
// KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE
// 149 keycode_numpad 5
2021-10-27 14:54:57 +00:00
when ( keyCode ) {
2021-10-27 19:45:15 +00:00
KeyEvent . KEYCODE _FORWARD , KeyEvent . KEYCODE _D , KeyEvent . KEYCODE _MEDIA _SKIP _FORWARD , KeyEvent . KEYCODE _MEDIA _FAST _FORWARD -> {
2021-10-27 14:54:57 +00:00
PlayerEventType . SeekForward
}
2021-12-24 15:35:44 +00:00
KeyEvent . KEYCODE _A , KeyEvent . KEYCODE _MEDIA _SKIP _BACKWARD , KeyEvent . KEYCODE _MEDIA _REWIND -> {
2021-10-27 14:54:57 +00:00
PlayerEventType . SeekBack
}
2021-10-30 18:14:12 +00:00
KeyEvent . KEYCODE _MEDIA _NEXT , KeyEvent . KEYCODE _BUTTON _R1 -> {
2021-10-27 14:54:57 +00:00
PlayerEventType . NextEpisode
}
2021-10-30 18:14:12 +00:00
KeyEvent . KEYCODE _MEDIA _PREVIOUS , KeyEvent . KEYCODE _BUTTON _L1 -> {
2021-10-27 14:54:57 +00:00
PlayerEventType . PrevEpisode
}
KeyEvent . KEYCODE _MEDIA _PAUSE -> {
PlayerEventType . Pause
}
2021-10-30 18:14:12 +00:00
KeyEvent . KEYCODE _MEDIA _PLAY , KeyEvent . KEYCODE _BUTTON _START -> {
2021-10-27 14:54:57 +00:00
PlayerEventType . Play
}
2021-10-27 19:45:15 +00:00
KeyEvent . KEYCODE _L , KeyEvent . KEYCODE _NUMPAD _7 -> {
2021-10-27 14:54:57 +00:00
PlayerEventType . Lock
}
2021-10-27 19:45:15 +00:00
KeyEvent . KEYCODE _H , KeyEvent . KEYCODE _MENU -> {
2021-10-27 14:54:57 +00:00
PlayerEventType . ToggleHide
}
2021-10-27 19:45:15 +00:00
KeyEvent . KEYCODE _M , KeyEvent . KEYCODE _VOLUME _MUTE -> {
2021-10-27 14:54:57 +00:00
PlayerEventType . ToggleMute
}
2021-10-27 19:45:15 +00:00
KeyEvent . KEYCODE _S , KeyEvent . KEYCODE _NUMPAD _9 -> {
PlayerEventType . ShowMirrors
}
2021-10-30 18:14:12 +00:00
KeyEvent . KEYCODE _E , KeyEvent . KEYCODE _NUMPAD _3 -> {
2021-10-27 19:45:15 +00:00
PlayerEventType . ShowSpeed
}
KeyEvent . KEYCODE _R , KeyEvent . KEYCODE _NUMPAD _0 -> {
PlayerEventType . Resize
}
2021-10-30 18:14:12 +00:00
KeyEvent . KEYCODE _MEDIA _PLAY _PAUSE , KeyEvent . KEYCODE _P , KeyEvent . KEYCODE _SPACE , KeyEvent . KEYCODE _NUMPAD _ENTER , KeyEvent . KEYCODE _ENTER -> { // space is not captured due to navigation
2021-10-27 14:54:57 +00:00
PlayerEventType . PlayPauseToggle
}
else -> null
} ?. let { playerEvent ->
playerEventListener ?. invoke ( playerEvent )
}
2021-10-30 18:42:58 +00:00
//when (keyCode) {
// KeyEvent.KEYCODE_DPAD_CENTER -> {
2021-11-26 23:19:17 +00:00
// println("DPAD PRESSED")
2021-10-30 18:42:58 +00:00
// }
//}
2021-10-30 18:14:12 +00:00
2021-10-27 14:54:57 +00:00
return super . onKeyDown ( keyCode , event )
}
2021-06-10 23:00:22 +00:00
companion object {
2021-10-18 14:02:05 +00:00
fun Activity ?. getCastSession ( ) : CastSession ? {
2021-09-30 12:55:56 +00:00
return ( this as MainActivity ? ) ?. mSessionManager ?. currentCastSession
}
2021-08-04 01:50:24 +00:00
var canEnterPipMode : Boolean = false
2021-06-10 23:00:22 +00:00
var canShowPipMode : Boolean = false
var isInPIPMode : Boolean = false
2021-07-30 23:41:54 +00:00
val backEvent = Event < Boolean > ( )
2021-08-06 20:55:11 +00:00
val onColorSelectedEvent = Event < Pair < Int , Int > > ( )
val onDialogDismissedEvent = Event < Int > ( )
2021-08-24 22:19:15 +00:00
2021-10-27 14:54:57 +00:00
var playerEventListener : ( ( PlayerEventType ) -> Unit ) ? = null
2021-11-27 18:49:51 +00:00
var keyEventListener : ( ( KeyEvent ? ) -> Boolean ) ? = null
2021-10-27 14:54:57 +00:00
2021-08-24 22:19:15 +00:00
var currentToast : Toast ? = null
2021-08-29 18:42:44 +00:00
2021-08-24 22:19:15 +00:00
fun showToast ( act : Activity ? , @StringRes message : Int , duration : Int ) {
if ( act == null ) return
showToast ( act , act . getString ( message ) , duration )
}
2021-12-13 18:41:33 +00:00
fun showToast ( act : Activity ? , message : String ? , duration : Int ? = null ) {
if ( act == null || message == null ) return
2021-08-24 22:19:15 +00:00
try {
currentToast ?. cancel ( )
} catch ( e : Exception ) {
e . printStackTrace ( )
}
try {
val inflater = act . getSystemService ( LAYOUT _INFLATER _SERVICE ) as LayoutInflater
val layout : View = inflater . inflate (
R . layout . toast ,
act . findViewById < View > ( R . id . toast _layout _root ) as ViewGroup ?
)
val text = layout . findViewById ( R . id . text ) as TextView
text . text = message . trim ( )
val toast = Toast ( act )
toast . setGravity ( Gravity . CENTER _HORIZONTAL or Gravity . BOTTOM , 0 , 5. toPx )
2021-12-13 18:41:33 +00:00
toast . duration = duration ?: Toast . LENGTH _SHORT
2021-08-24 22:19:15 +00:00
toast . view = layout
toast . show ( )
currentToast = toast
} catch ( e : Exception ) {
}
}
2021-09-02 14:06:43 +00:00
2021-09-02 16:51:13 +00:00
fun setLocale ( context : Context ? , languageCode : String ? ) {
if ( context == null || languageCode == null ) return
2021-09-02 14:06:43 +00:00
val locale = Locale ( languageCode )
2021-09-02 16:51:13 +00:00
val resources : Resources = context . resources
val config = resources . configuration
2021-09-02 14:06:43 +00:00
Locale . setDefault ( locale )
config . setLocale ( locale )
2021-09-02 16:51:13 +00:00
if ( Build . VERSION . SDK _INT >= Build . VERSION_CODES . N )
context . createConfigurationContext ( config )
2021-09-02 14:06:43 +00:00
resources . updateConfiguration ( config , resources . displayMetrics )
}
2021-09-02 16:51:13 +00:00
fun Context . updateLocale ( ) {
val settingsManager = PreferenceManager . getDefaultSharedPreferences ( this )
val localeCode = settingsManager . getString ( getString ( R . string . locale _key ) , null )
setLocale ( this , localeCode )
}
2021-06-10 23:00:22 +00:00
}
private fun enterPIPMode ( ) {
2021-08-04 01:50:24 +00:00
if ( ! shouldShowPIPMode ( canEnterPipMode ) || ! canShowPipMode ) return
2021-09-12 15:57:07 +00:00
try {
if ( Build . VERSION . SDK _INT >= Build . VERSION_CODES . O ) {
try {
enterPictureInPictureMode ( PictureInPictureParams . Builder ( ) . build ( ) )
} catch ( e : Exception ) {
enterPictureInPictureMode ( )
}
} else {
if ( Build . VERSION . SDK _INT >= Build . VERSION_CODES . N ) {
enterPictureInPictureMode ( )
}
2021-06-10 23:00:22 +00:00
}
2021-09-23 10:50:10 +00:00
} catch ( e : Exception ) {
2021-09-12 15:57:07 +00:00
logError ( e )
2021-06-10 23:00:22 +00:00
}
2021-05-22 22:25:56 +00:00
}
2021-06-10 23:00:22 +00:00
override fun onUserLeaveHint ( ) {
super . onUserLeaveHint ( )
2021-08-04 01:50:24 +00:00
if ( canEnterPipMode && canShowPipMode ) {
2021-06-10 23:00:22 +00:00
enterPIPMode ( )
}
}
2021-05-22 22:25:56 +00:00
2021-05-18 13:43:32 +00:00
override fun onBackPressed ( ) {
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 =
data . getLongExtra ( VLC _EXTRA _POSITION _OUT , - 1 ) //Last position in media when player exited
val dur : Long =
data . getLongExtra ( VLC _EXTRA _DURATION _OUT , - 1 ) //Last position in media when player exited
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 )
}
}
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
if ( str != null ) {
2021-11-07 22:10:19 +00:00
if ( str . contains ( appString ) ) {
for ( api in OAuth2Apis ) {
if ( str . contains ( " / ${api.redirectUrl} " ) ) {
2021-12-16 23:45:20 +00:00
api . handleRedirect ( str )
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
}
}
}
}
}
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
}
2021-10-31 01:17:56 +00:00
val settingsManager = PreferenceManager . getDefaultSharedPreferences ( this )
2021-11-27 18:49:51 +00:00
val currentTheme = when ( settingsManager . getString ( getString ( R . string . app _theme _key ) , " AmoledLight " ) ) {
2021-10-31 01:17:56 +00:00
" Black " -> R . style . AppTheme
" Light " -> R . style . LightMode
2021-10-31 14:14:01 +00:00
" Amoled " -> R . style . AmoledMode
2021-11-26 23:19:17 +00:00
" AmoledLight " -> R . style . AmoledModeLight
2021-10-31 01:17:56 +00:00
else -> R . style . AppTheme
}
val currentOverlayTheme = when ( settingsManager . getString ( getString ( R . string . primary _color _key ) , " Normal " ) ) {
" Normal " -> R . style . OverlayPrimaryColorNormal
" Blue " -> R . style . OverlayPrimaryColorBlue
" Purple " -> R . style . OverlayPrimaryColorPurple
" Green " -> R . style . OverlayPrimaryColorGreen
" GreenApple " -> R . style . OverlayPrimaryColorGreenApple
" Red " -> R . style . OverlayPrimaryColorRed
" Banana " -> R . style . OverlayPrimaryColorBanana
" Party " -> R . style . OverlayPrimaryColorParty
else -> R . style . OverlayPrimaryColorNormal
}
2021-10-31 14:14:01 +00:00
theme . applyStyle ( currentTheme , true )
2021-10-31 01:17:56 +00:00
theme . applyStyle ( currentOverlayTheme , true )
2021-10-31 14:14:01 +00:00
theme . applyStyle (
R . style . LoadedStyle ,
true
) // THEME IS SET BEFORE VIEW IS CREATED TO APPLY THE THEME TO THE MAIN VIEW
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 )
}
2021-07-30 01:14:53 +00:00
// val navView: BottomNavigationView = findViewById(R.id.nav_view)
2021-04-30 17:20:15 +00:00
2021-06-10 23:00:22 +00:00
//https://stackoverflow.com/questions/52594181/how-to-know-if-user-has-disabled-picture-in-picture-feature-permission
//https://developer.android.com/guide/topics/ui/picture-in-picture
canShowPipMode =
Build . VERSION . SDK _INT >= Build . VERSION_CODES . O && // OS SUPPORT
packageManager . hasSystemFeature ( PackageManager . FEATURE _PICTURE _IN _PICTURE ) && // HAS FEATURE, MIGHT BE BLOCKED DUE TO POWER DRAIN
hasPIPPermission ( ) // CHECK IF FEATURE IS ENABLED IN SETTINGS
2021-04-30 17:20:15 +00:00
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 )
2021-11-25 22:36:35 +00:00
val navRail = findViewById < NavigationRailView ? > ( R . id . nav _rail _view )
navRail ?. setupWithNavController ( 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
}
2021-07-19 13:19:47 +00:00
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
2021-11-25 22:36:35 +00:00
navRail ?. itemRippleColor = 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
var providersString = " Current providers are: \n "
2021-09-30 12:16:23 +00:00
var providersAndroidManifestString = " Current androidmanifest should be: \n "
2021-08-19 20:05:18 +00:00
for ( api in apis ) {
providersString += " + ${api.mainUrl} \n "
2021-09-30 12:16:23 +00:00
providersAndroidManifestString += " <data android:scheme= \" https \" android:host= \" $ {
api . mainUrl . removePrefix (
" https:// "
)
} \ " android:pathPrefix= \" / \" /> \n "
}
for ( api in restrictedApis ) {
providersString += " + ${api.mainUrl} \n "
providersAndroidManifestString += " <data android:scheme= \" https \" android:host= \" $ {
api . mainUrl . removePrefix (
" https:// "
)
} \ " android:pathPrefix= \" / \" /> \n "
2021-08-19 20:05:18 +00:00
}
println ( providersString )
2021-09-30 12:16:23 +00:00
println ( providersAndroidManifestString )
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
// must give benenes to get beta providers
try {
val settingsManager = PreferenceManager . getDefaultSharedPreferences ( this )
val count = settingsManager . getInt ( getString ( R . string . benene _count ) , 0 )
2021-09-07 19:16:12 +00:00
if ( count > 30 && restrictedApis . size > 0 && ! apis . contains ( restrictedApis . first ( ) ) )
2021-08-30 21:42:58 +00:00
apis . addAll ( restrictedApis )
2021-09-02 14:06:43 +00:00
} catch ( e : Exception ) {
2021-08-30 21:42:58 +00:00
e . printStackTrace ( )
}
2021-09-12 14:10:22 +00:00
APIRepository . dubStatusActive = getApiDubstatusSettings ( )
2021-11-08 18:13:39 +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
}
}