Update the onboarding process to support crunchyroll
* only save credentials during onboarding, if login was successful * show onboarding, if login failed
This commit is contained in:
		| @ -38,6 +38,14 @@ object Crunchyroll { | ||||
|  | ||||
|     private val browsingCache = arrayListOf<Item>() | ||||
|  | ||||
|     /** | ||||
|      * Login to the crunchyroll API. | ||||
|      * | ||||
|      * @param username The Username/Email of the user to log in | ||||
|      * @param password The Accounts Password | ||||
|      * | ||||
|      * @return Boolean: True if login was successful, else false | ||||
|      */ | ||||
|     fun login(username: String, password: String): Boolean = runBlocking { | ||||
|         val tokenEndpoint = "/auth/v1/token" | ||||
|         val formData = listOf( | ||||
| @ -47,6 +55,7 @@ object Crunchyroll { | ||||
|             "scope" to "offline_access" | ||||
|         ) | ||||
|  | ||||
|         var success: Boolean // is false | ||||
|         withContext(Dispatchers.IO) { | ||||
|             val (request, response, result) = Fuel.post("$baseUrl$tokenEndpoint", parameters = formData) | ||||
|                 .header("Content-Type", "application/x-www-form-urlencoded") | ||||
| @ -67,11 +76,10 @@ object Crunchyroll { | ||||
| //            println("response: $result") | ||||
|  | ||||
|             Log.i(javaClass.name, "login complete with code ${response.statusCode}") | ||||
|  | ||||
|             return@withContext response.statusCode == 200 | ||||
|             success = (response.statusCode == 200) | ||||
|         } | ||||
|  | ||||
|         return@runBlocking false | ||||
|         return@runBlocking success | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|  | ||||
| @ -52,7 +52,6 @@ class MainActivity : AppCompatActivity(), NavigationBarView.OnItemSelectedListen | ||||
|     private var activeBaseFragment: Fragment = HomeFragment() // the currently active fragment, home at the start | ||||
|  | ||||
|     companion object { | ||||
|         var wasInitialized = false | ||||
|         lateinit var instance: MainActivity | ||||
|     } | ||||
|  | ||||
| @ -63,7 +62,7 @@ class MainActivity : AppCompatActivity(), NavigationBarView.OnItemSelectedListen | ||||
|     override fun onCreate(savedInstanceState: Bundle?) { | ||||
|         super.onCreate(savedInstanceState) | ||||
|  | ||||
|         if (!wasInitialized) { load() } | ||||
|         load() // start the initial loading | ||||
|         theme.applyStyle(getThemeResource(), true) | ||||
|  | ||||
|         binding = ActivityMainBinding.inflate(layoutInflater) | ||||
| @ -132,47 +131,27 @@ class MainActivity : AppCompatActivity(), NavigationBarView.OnItemSelectedListen | ||||
|      */ | ||||
|     private fun load() { | ||||
|         val time = measureTimeMillis { | ||||
|             // start the initial loading | ||||
|  | ||||
|             // load all saved stuff here | ||||
|             Preferences.load(this) | ||||
|             EncryptedPreferences.readCredentials(this) | ||||
|  | ||||
|             // show onboarding TODO rework | ||||
|             if (EncryptedPreferences.password.isEmpty()) { | ||||
|             // show onboarding if no password is set, or login fails | ||||
|             if (EncryptedPreferences.password.isEmpty() || !Crunchyroll.login( | ||||
|                     EncryptedPreferences.login, | ||||
|                     EncryptedPreferences.password | ||||
|                 ) | ||||
|             ) { | ||||
|                 showOnboarding() | ||||
|             } else { | ||||
|                 Crunchyroll.login(EncryptedPreferences.login, EncryptedPreferences.password) | ||||
|                 runBlocking { initCrunchyroll().joinAll() } | ||||
|             } | ||||
|  | ||||
| //            if (EncryptedPreferences.password.isEmpty()) { | ||||
| //                showOnboarding() | ||||
| //            } else { | ||||
| //                try { | ||||
| //                    if (!AoDParser.login()) { | ||||
| //                        showLoginDialog() | ||||
| //                    } | ||||
| //                } catch (ex: SocketTimeoutException) { | ||||
| //                    Log.w(javaClass.name, "Timeout during login!") | ||||
| // | ||||
| //                    // show waring dialog before finishing | ||||
| //                    MaterialDialog(this).show { | ||||
| //                        title(R.string.dialog_timeout_head) | ||||
| //                        message(R.string.dialog_timeout_desc) | ||||
| //                        onDismiss { exitAndRemoveTask() } | ||||
| //                    } | ||||
| //                } | ||||
| //            } | ||||
|  | ||||
| //            runBlocking { loadingJob.await() } // wait for initial loading to finish | ||||
|         } | ||||
|         Log.i(javaClass.name, "loading and login in $time ms") | ||||
|  | ||||
|         wasInitialized = true | ||||
|         Log.i(javaClass.name, "loading in $time ms") | ||||
|     } | ||||
|  | ||||
|     private fun initCrunchyroll(): List<Job> { | ||||
|         println("init") | ||||
|  | ||||
|         val scope = CoroutineScope(Dispatchers.IO + CoroutineName("InitialLoadingScope")) | ||||
|         return listOf( | ||||
|             scope.launch { Crunchyroll.index() }, | ||||
|  | ||||
| @ -4,16 +4,18 @@ import android.os.Bundle | ||||
| import android.view.LayoutInflater | ||||
| import android.view.View | ||||
| import android.view.ViewGroup | ||||
| import android.view.inputmethod.EditorInfo | ||||
| import androidx.fragment.app.Fragment | ||||
| import androidx.lifecycle.lifecycleScope | ||||
| import kotlinx.coroutines.* | ||||
| import org.mosad.teapod.R | ||||
| import org.mosad.teapod.databinding.FragmentOnLoginBinding | ||||
| import org.mosad.teapod.parser.crunchyroll.Crunchyroll | ||||
| import org.mosad.teapod.preferences.EncryptedPreferences | ||||
|  | ||||
| class OnLoginFragment: Fragment() { | ||||
|  | ||||
|     private lateinit var binding: FragmentOnLoginBinding | ||||
|     private var loginJob: Job? = null | ||||
|  | ||||
|     override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View { | ||||
|         binding = FragmentOnLoginBinding.inflate(inflater, container, false) | ||||
| @ -27,26 +29,41 @@ class OnLoginFragment: Fragment() { | ||||
|  | ||||
|     private fun initActions() { | ||||
|         binding.buttonLogin.setOnClickListener { | ||||
|             // get login credentials from gui | ||||
|             val email = binding.editTextLogin.text.toString() | ||||
|             val password = binding.editTextPassword.text.toString() | ||||
|             onLogin() | ||||
|         } | ||||
|  | ||||
|             EncryptedPreferences.saveCredentials(email, password, requireContext()) // save the credentials | ||||
|         binding.editTextPassword.setOnEditorActionListener { _, actionId, _ -> | ||||
|             return@setOnEditorActionListener when (actionId) { | ||||
|                 EditorInfo.IME_ACTION_DONE -> { | ||||
|                     onLogin() | ||||
|                     false // false will hide the keyboards | ||||
|                 } | ||||
|                 else -> false | ||||
|             } | ||||
|         } | ||||
|  | ||||
|             binding.buttonLogin.isClickable = false | ||||
|             loginJob = lifecycleScope.launch { | ||||
|                 // TODO | ||||
| //                if (AoDParser.login()) { | ||||
| //                    // if login was successful, switch to main | ||||
| //                    if (activity is OnboardingActivity) { | ||||
| //                            (activity as OnboardingActivity).launchMainActivity() | ||||
| //                    } | ||||
| //                } else { | ||||
| //                    withContext(Dispatchers.Main) { | ||||
| //                        binding.textLoginDesc.text = getString(R.string.on_login_failed) | ||||
| //                        binding.buttonLogin.isClickable = true | ||||
| //                    } | ||||
| //                } | ||||
|     } | ||||
|  | ||||
|     private fun onLogin() { | ||||
|         // get login credentials from gui | ||||
|         val email = binding.editTextLogin.text.toString() | ||||
|         val password = binding.editTextPassword.text.toString() | ||||
|  | ||||
|         binding.buttonLogin.isClickable = false | ||||
|         // FIXME, this seems to run blocking | ||||
|         lifecycleScope.launch { | ||||
|             // try login credentials | ||||
|             val login = Crunchyroll.login(email, password) | ||||
|  | ||||
|             if (login) { | ||||
|                 // save the credentials and show the main activity | ||||
|                 EncryptedPreferences.saveCredentials(email, password, requireContext()) | ||||
|                 if (activity is OnboardingActivity) (activity as OnboardingActivity).launchMainActivity() | ||||
|             } else { | ||||
|                 withContext(Dispatchers.Main) { | ||||
|                     binding.textLoginDesc.text = getString(R.string.on_login_failed) | ||||
|                     binding.buttonLogin.isClickable = true | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
| @ -16,7 +16,7 @@ class OnboardingActivity : AppCompatActivity() { | ||||
|     private lateinit var binding: ActivityOnboardingBinding | ||||
|     private lateinit var pagerAdapter: FragmentStateAdapter | ||||
|  | ||||
|     private val fragments = arrayOf(OnLoginFragment()) | ||||
|     private val fragments = arrayOf(OnWelcomeFragment(), OnLoginFragment()) | ||||
|  | ||||
|     override fun onCreate(savedInstanceState: Bundle?) { | ||||
|         super.onCreate(savedInstanceState) | ||||
|  | ||||
| @ -65,6 +65,7 @@ | ||||
|             android:layout_margin="7dp" | ||||
|             android:ems="10" | ||||
|             android:hint="@string/password" | ||||
|             android:imeOptions="actionDone" | ||||
|             android:importantForAutofill="no" | ||||
|             android:inputType="textPassword" /> | ||||
|  | ||||
|  | ||||
| @ -38,7 +38,7 @@ | ||||
|                 android:id="@+id/text_app_name" | ||||
|                 android:layout_width="match_parent" | ||||
|                 android:layout_height="wrap_content" | ||||
|                 android:text="@string/app_name" | ||||
|                 android:text="@string/on_welcome_heading" | ||||
|                 android:textAlignment="center" | ||||
|                 android:textSize="26sp" | ||||
|                 android:textStyle="bold" /> | ||||
|  | ||||
| @ -58,7 +58,7 @@ | ||||
|     <string name="authors">Autor</string> | ||||
|     <string name="source">Quellcode</string> | ||||
|     <string name="license">Lizenz</string> | ||||
|     <string name="about_info">Eine inoffizielle App für Anime on Demand.</string> | ||||
|     <string name="about_info">Eine inoffizielle App für Crunchyroll.</string> | ||||
|     <string name="third_party_heading">Lizenzen von Drittanbietern</string> | ||||
|     <string name="third_party_component_desc">© %1$s %2$s unter %3$s</string> | ||||
|     <string name="dev_settings_enabled">Du bist jetzt ein Entwickler</string> | ||||
| @ -81,10 +81,11 @@ | ||||
|     <string name="skip">Überspringen</string> | ||||
|     <string name="next">Weiter</string> | ||||
|     <string name="start">Fertig</string> | ||||
|     <string name="on_welcome">Willkommen!\nTeapod ist eine inoffizielle App für AoD.</string> | ||||
|     <string name="on_welcome_heading">Willkommen</string> | ||||
|     <string name="on_welcome">Teapod ist eine inoffizielle App für Crunchyroll, die unter den Bedingungen der GPL 3 lizenziert ist.\n\nHinweis: Die Benutzung von Teapod kann gegen die Nutzungsbedingungen von Crunchyroll verstoßen.</string> | ||||
|     <string name="on_get_started">Los geht\'s</string> | ||||
|     <string name="on_login_heading">Login</string> | ||||
|     <string name="on_login_desc">Um Teapod verwenden zu können musst du dich mit deinem AoD Account anmelden. Deine Login-Daten werden verschlüsselt auf deinem Gerät gespeichert.</string> | ||||
|     <string name="on_login_desc">Um Teapod verwenden zu können musst du dich mit deinem Crunchyroll Account anmelden. Deine Login-Daten werden verschlüsselt auf deinem Gerät gespeichert.</string> | ||||
|     <string name="on_login_failed">Login nicht erfolgreich! Stelle sicher das deine Login-Daten korrekt sind und versuche es erneut.</string> | ||||
|  | ||||
|     <!-- dialogs --> | ||||
|  | ||||
| @ -74,7 +74,7 @@ | ||||
|     <string name="teapod_repo" translatable="false">git.mosad.xyz/Seil0/teapod</string> | ||||
|     <string name="license">License</string> | ||||
|     <string name="license_desc" translatable="false">GNU General Public License 3</string> | ||||
|     <string name="about_info">An unofficial app for anime on demand.</string> | ||||
|     <string name="about_info">An unofficial app for Crunchyroll.</string> | ||||
|     <string name="tmdb_notice" translatable="false">This product uses the TMDb API but is not endorsed or certified by TMDb.</string> | ||||
|     <string name="third_party_heading">Third Party Licenses</string> | ||||
|     <string name="third_party_component_desc">© %1$s %2$s under %3$s</string> | ||||
| @ -102,10 +102,11 @@ | ||||
|     <string name="skip">Skip</string> | ||||
|     <string name="next">Next</string> | ||||
|     <string name="start">Start</string> | ||||
|     <string name="on_welcome">Welcome!\nTeapod is an unofficial App for AoD.</string> | ||||
|     <string name="on_welcome_heading">Welcome</string> | ||||
|     <string name="on_welcome">Teapod is an unofficial app for Crunchyroll, licensed under the terms and conditions of GPL 3.\n\nPlease note: Using Teapod may violate the ToS of Crunchyroll.</string> | ||||
|     <string name="on_get_started">Get started</string> | ||||
|     <string name="on_login_heading">Login</string> | ||||
|     <string name="on_login_desc">To use Teapod you need to log in with your AoD account. Your Login-Data will be stored encrypted on your device.</string> | ||||
|     <string name="on_login_desc">To use Teapod you have to log in with your Crunchyroll account. Your login data will be stored encrypted on your device.</string> | ||||
|     <string name="on_login_failed">Could not login! Make sure Username and Password are correct and try again.</string> | ||||
|  | ||||
|     <!-- dialogs --> | ||||
|  | ||||
		Reference in New Issue
	
	Block a user