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

737 lines
28 KiB
Kotlin
Raw Normal View History

2021-04-30 17:20:15 +00:00
package com.lagradost.cloudstream3
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
import android.view.*
import android.view.KeyEvent.ACTION_DOWN
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
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
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
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
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
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
import com.lagradost.cloudstream3.utils.AppUtils.isCastApiAvailable
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
import com.lagradost.cloudstream3.utils.InAppUpdater.Companion.runAutoUpdate
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
import com.lagradost.cloudstream3.utils.UIHelper.requestRW
import com.lagradost.cloudstream3.utils.UIHelper.shouldShowPIPMode
import com.lagradost.cloudstream3.utils.UIHelper.showInputMethod
import com.lagradost.cloudstream3.utils.UIHelper.toPx
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.*
import kotlin.concurrent.thread
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"
// 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
}
//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
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
}
}
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-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())
}
}
}
}
//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
}
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 -> {
// 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 {
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-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
var currentToast: Toast? = null
2021-08-29 18:42:44 +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
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
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()
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()
}
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}")) {
api.handleRedirect(str)
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
}
}
}
}
}
}
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) {
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
"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()
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)
}
// 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)
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) {
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
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(!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
var providersString = "Current providers are:\n"
var providersAndroidManifestString = "Current androidmanifest should be:\n"
2021-08-19 20:05:18 +00:00
for (api in apis) {
providersString += "+ ${api.mainUrl}\n"
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)
println(providersAndroidManifestString)
handleAppIntent(intent)
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
}
}