2020-10-13 21:27:05 +02:00
/ * *
* Teapod
*
2022-01-02 17:59:23 +01:00
* Copyright 2020 - 2022 < seil0 @mosad . xyz >
2020-10-13 21:27:05 +02:00
*
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation ; either version 3 of the License , or
* ( at your option ) any later version .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
* along with this program ; if not , write to the Free Software
* Foundation , Inc . , 51 Franklin Street , Fifth Floor , Boston ,
* MA 02110 - 1301 , USA .
*
* /
2021-02-06 19:02:12 +01:00
package org.mosad.teapod.ui.activity.main
2020-10-08 22:20:20 +02:00
2020-10-11 13:18:20 +02:00
import android.content.Intent
2020-10-08 22:20:20 +02:00
import android.os.Bundle
2020-10-11 13:18:20 +02:00
import android.util.Log
2020-10-11 10:02:00 +02:00
import android.view.MenuItem
2022-09-14 20:33:08 +02:00
import androidx.activity.addCallback
2020-10-08 22:20:20 +02:00
import androidx.appcompat.app.AppCompatActivity
2022-03-19 22:09:47 +01:00
import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
2020-10-11 10:02:00 +02:00
import androidx.fragment.app.Fragment
import androidx.fragment.app.commit
2021-07-03 15:58:20 +02:00
import com.google.android.material.navigation.NavigationBarView
2021-06-06 17:54:19 +02:00
import kotlinx.coroutines.*
2021-01-16 00:16:47 +01:00
import org.mosad.teapod.R
2020-11-25 22:35:55 +01:00
import org.mosad.teapod.databinding.ActivityMainBinding
2021-12-05 00:42:56 +01:00
import org.mosad.teapod.parser.crunchyroll.Crunchyroll
2020-10-11 13:18:20 +02:00
import org.mosad.teapod.preferences.EncryptedPreferences
2020-10-23 11:28:47 +02:00
import org.mosad.teapod.preferences.Preferences
2021-02-06 19:02:12 +01:00
import org.mosad.teapod.ui.activity.main.fragments.AccountFragment
import org.mosad.teapod.ui.activity.main.fragments.HomeFragment
2022-12-26 16:10:38 +01:00
import org.mosad.teapod.ui.activity.main.fragments.MyListsFragment
2021-02-06 19:02:12 +01:00
import org.mosad.teapod.ui.activity.main.fragments.LibraryFragment
import org.mosad.teapod.ui.activity.onboarding.OnboardingActivity
2020-11-23 20:11:10 +01:00
import org.mosad.teapod.util.DataTypes
2022-03-20 14:29:32 +01:00
import org.mosad.teapod.util.metadb.MetaDBController
2022-03-06 18:57:55 +01:00
import java.util.*
2020-10-15 18:51:29 +02:00
import kotlin.system.measureTimeMillis
2020-10-08 22:20:20 +02:00
2021-07-03 15:58:20 +02:00
class MainActivity : AppCompatActivity ( ) , NavigationBarView . OnItemSelectedListener {
2022-03-06 18:57:55 +01:00
private val classTag = javaClass . name
2020-10-11 10:02:00 +02:00
2020-11-25 22:35:55 +01:00
private lateinit var binding : ActivityMainBinding
2020-10-16 11:23:32 +02:00
private var activeBaseFragment : Fragment = HomeFragment ( ) // the currently active fragment, home at the start
2020-10-08 22:20:20 +02:00
2020-11-23 20:11:10 +01:00
companion object {
2021-02-06 19:02:12 +01:00
lateinit var instance : MainActivity
}
init {
instance = this
2020-11-23 20:11:10 +01:00
}
2020-10-08 22:20:20 +02:00
override fun onCreate ( savedInstanceState : Bundle ? ) {
2022-03-19 22:09:47 +01:00
// Handle the splash screen transition.
installSplashScreen ( )
2020-10-08 22:20:20 +02:00
super . onCreate ( savedInstanceState )
2020-11-23 20:11:10 +01:00
2022-01-08 19:20:21 +01:00
load ( ) // start the initial loading
2020-11-23 20:11:10 +01:00
theme . applyStyle ( getThemeResource ( ) , true )
2020-11-25 23:26:46 +01:00
binding = ActivityMainBinding . inflate ( layoutInflater )
2021-07-03 15:58:20 +02:00
binding . navView . setOnItemSelectedListener ( this )
2020-11-25 23:26:46 +01:00
setContentView ( binding . root )
2020-10-08 22:20:20 +02:00
2020-10-16 11:23:32 +02:00
supportFragmentManager . commit {
replace ( R . id . nav _host _fragment , activeBaseFragment , activeBaseFragment . javaClass . simpleName )
}
2020-10-08 22:20:20 +02:00
2022-09-14 20:33:08 +02:00
onBackPressedDispatcher . addCallback {
if ( supportFragmentManager . backStackEntryCount > 0 ) {
supportFragmentManager . popBackStack ( )
2020-10-11 10:02:00 +02:00
} else {
2022-09-14 20:33:08 +02:00
if ( activeBaseFragment !is HomeFragment ) {
binding . navView . selectedItemId = R . id . navigation _home
}
2020-10-11 10:02:00 +02:00
}
}
}
override fun onNavigationItemSelected ( item : MenuItem ) : Boolean {
2020-10-14 20:22:20 +02:00
if ( supportFragmentManager . backStackEntryCount > 0 ) {
supportFragmentManager . popBackStack ( )
}
2020-10-11 10:02:00 +02:00
val ret = when ( item . itemId ) {
R . id . navigation _home -> {
2020-10-16 11:23:32 +02:00
activeBaseFragment = HomeFragment ( )
2020-10-11 10:02:00 +02:00
true
}
2022-12-26 16:10:38 +01:00
R . id . navigation _my _lists -> {
activeBaseFragment = MyListsFragment ( )
2020-10-11 10:02:00 +02:00
true
}
2022-12-26 16:10:38 +01:00
R . id . navigation _library -> {
activeBaseFragment = LibraryFragment ( )
2020-10-11 10:02:00 +02:00
true
}
R . id . navigation _account -> {
2020-10-16 11:23:32 +02:00
activeBaseFragment = AccountFragment ( )
2020-10-11 10:02:00 +02:00
true
}
else -> false
}
supportFragmentManager . commit {
2020-10-16 11:23:32 +02:00
replace ( R . id . nav _host _fragment , activeBaseFragment , activeBaseFragment . javaClass . simpleName )
2020-10-11 10:02:00 +02:00
}
return ret
}
2020-11-23 20:11:10 +01:00
private fun getThemeResource ( ) : Int {
return when ( Preferences . theme ) {
2021-01-16 00:16:47 +01:00
DataTypes . Theme . LIGHT -> R . style . AppTheme _Light
else -> R . style . AppTheme _Dark
2020-11-23 20:11:10 +01:00
}
}
2021-01-13 20:57:00 +01:00
/ * *
* initial loading and login are run in parallel , as initial loading doesn ' t require
* any login cookies
* /
2020-10-08 22:20:20 +02:00
private fun load ( ) {
2020-10-15 18:51:29 +02:00
val time = measureTimeMillis {
2021-01-13 20:57:00 +01:00
// load all saved stuff here
Preferences . load ( this )
2020-10-16 19:56:08 +02:00
EncryptedPreferences . readCredentials ( this )
2020-11-23 20:11:10 +01:00
2022-03-20 14:29:32 +01:00
// load meta db at the start, it doesn't depend on any third party
val metaJob = initMetaDB ( )
2022-03-19 20:14:16 +01:00
// always initialize the api token
Crunchyroll . initBasicApiToken ( )
2022-01-08 19:20:21 +01:00
// show onboarding if no password is set, or login fails
if ( EncryptedPreferences . password . isEmpty ( ) || ! Crunchyroll . login (
EncryptedPreferences . login ,
EncryptedPreferences . password
)
) {
2021-01-16 00:16:47 +01:00
showOnboarding ( )
} else {
2022-03-20 14:29:32 +01:00
runBlocking {
initCrunchyroll ( ) . joinAll ( )
metaJob . join ( ) // meta loading should be done here
}
2021-01-13 20:57:00 +01:00
}
2020-10-15 18:51:29 +02:00
}
2022-03-06 18:57:55 +01:00
Log . i ( classTag , " loading in $time ms " )
2020-10-08 22:20:20 +02:00
}
2020-10-11 10:02:00 +02:00
2022-01-02 22:39:31 +01:00
private fun initCrunchyroll ( ) : List < Job > {
2022-03-20 14:29:32 +01:00
val scope = CoroutineScope ( Dispatchers . IO + CoroutineName ( " InitialCrunchyLoading " ) )
2022-01-02 22:39:31 +01:00
return listOf (
scope . launch { Crunchyroll . index ( ) } ,
2022-03-06 18:57:55 +01:00
scope . launch { Crunchyroll . account ( ) } ,
scope . launch {
// update the local preferred content language, since it may have changed
val locale = Locale . forLanguageTag ( Crunchyroll . profile ( ) . preferredContentSubtitleLanguage )
Preferences . savePreferredLocal ( this @MainActivity , locale )
}
2022-01-02 22:39:31 +01:00
)
}
2022-03-20 14:29:32 +01:00
private fun initMetaDB ( ) : Job {
val scope = CoroutineScope ( Dispatchers . IO + CoroutineName ( " InitialMetaDBLoading " ) )
return scope . launch { MetaDBController . list ( ) }
}
2021-01-16 00:16:47 +01:00
/ * *
* start the onboarding activity and finish the main activity
* /
private fun showOnboarding ( ) {
startActivity ( Intent ( this , OnboardingActivity :: class . java ) )
finish ( )
}
2020-11-23 20:11:10 +01:00
/ * *
* use custom restart instead of recreate ( ) , since it has animations
* /
fun restart ( ) {
val restartIntent = intent
restartIntent . addFlags ( Intent . FLAG _ACTIVITY _NO _ANIMATION )
finish ( )
startActivity ( restartIntent )
2020-10-12 23:26:32 +02:00
}
2020-11-23 20:11:10 +01:00
2020-10-08 22:20:20 +02:00
}