replace LoginDialog with material-components based LoginModalBottomSheet

This commit is contained in:
Jannik 2022-04-02 18:54:17 +02:00
parent 42895a6fba
commit cf435fdb72
Signed by: Seil0
GPG Key ID: E8459F3723C52C24
12 changed files with 163 additions and 200 deletions

View File

@ -68,8 +68,6 @@ dependencies {
implementation 'com.github.bumptech.glide:glide:4.12.0'
implementation 'jp.wasabeef:glide-transformations:4.3.0'
implementation 'com.afollestad.material-dialogs:core:3.3.0' // TODO remove once unused
implementation 'com.afollestad.material-dialogs:bottomsheets:3.3.0' // TODO remove once unused
implementation "io.ktor:ktor-client-core:$ktor_version"
implementation "io.ktor:ktor-client-android:$ktor_version"

View File

@ -43,7 +43,7 @@ import org.mosad.teapod.ui.activity.main.fragments.LibraryFragment
import org.mosad.teapod.ui.activity.main.fragments.SearchFragment
import org.mosad.teapod.ui.activity.onboarding.OnboardingActivity
import org.mosad.teapod.ui.activity.player.PlayerActivity
import org.mosad.teapod.ui.components.LoginDialog
import org.mosad.teapod.ui.components.LoginModalBottomSheet
import org.mosad.teapod.util.DataTypes
import org.mosad.teapod.util.metadb.MetaDBController
import java.util.*
@ -185,18 +185,19 @@ class MainActivity : AppCompatActivity(), NavigationBarView.OnItemSelectedListen
}
private fun showLoginDialog() {
LoginDialog(this, false).positiveButton {
EncryptedPreferences.saveCredentials(login, password, context)
val loginModal = LoginModalBottomSheet().apply {
positiveAction = {
EncryptedPreferences.saveCredentials(login, password, requireContext())
// TODO
// if (!AoDParser.login()) {
// showLoginDialog()
// Log.w(javaClass.name, "Login failed, please try again.")
// }
}.negativeButton {
Log.i(classTag, "Login canceled, exiting.")
finish()
}.show()
// TODO only dismiss if login was successful
this.dismiss()
}
negativeAction = {
Log.i(classTag, "Login canceled, exiting.")
finish()
}
}
loginModal.show(this.supportFragmentManager, LoginModalBottomSheet.TAG)
}
/**

View File

@ -109,8 +109,6 @@ class AboutFragment : Fragment() {
"https://github.com/google/ExoPlayer", License.APACHE2),
ThirdPartyComponent("Material design icons", "2020", "Google Inc.",
"https://github.com/google/material-design-icons", License.APACHE2),
ThirdPartyComponent("Material Dialogs", "", "Aidan Follestad",
"https://github.com/afollestad/material-dialogs", License.APACHE2),
ThirdPartyComponent("Ktor", "2014-2021", "JetBrains s.r.o and contributors",
"https://ktor.io/", License.APACHE2),
ThirdPartyComponent("kotlinx.coroutines", "2016-2021", "JetBrains s.r.o",

View File

@ -1,12 +1,9 @@
package org.mosad.teapod.ui.activity.main.fragments
import android.app.Activity
import android.content.Intent
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.activity.result.contract.ActivityResultContracts
import androidx.core.view.isVisible
import androidx.fragment.app.Fragment
import androidx.lifecycle.lifecycleScope
@ -24,7 +21,7 @@ import org.mosad.teapod.parser.crunchyroll.supportedLocals
import org.mosad.teapod.preferences.EncryptedPreferences
import org.mosad.teapod.preferences.Preferences
import org.mosad.teapod.ui.activity.main.MainActivity
import org.mosad.teapod.ui.components.LoginDialog
import org.mosad.teapod.ui.components.LoginModalBottomSheet
import org.mosad.teapod.util.DataTypes.Theme
import org.mosad.teapod.util.showFragment
import org.mosad.teapod.util.toDisplayString
@ -37,28 +34,6 @@ class AccountFragment : Fragment() {
Crunchyroll.profile()
}
private val getUriExport = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
if (result.resultCode == Activity.RESULT_OK) {
result.data?.data?.also { uri ->
//StorageController.exportMyList(requireContext(), uri)
}
}
}
private val getUriImport = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
if (result.resultCode == Activity.RESULT_OK) {
result.data?.data?.also { uri ->
// val success = StorageController.importMyList(requireContext(), uri)
// if (success == 0) {
// Toast.makeText(
// context, getString(R.string.import_data_success),
// Toast.LENGTH_SHORT
// ).show()
// }
}
}
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
binding = FragmentAccountBinding.inflate(inflater, container, false)
return binding.root
@ -102,7 +77,7 @@ class AccountFragment : Fragment() {
private fun initActions() {
binding.linearAccountLogin.setOnClickListener {
showLoginDialog(true)
showLoginDialog()
}
binding.linearAccountSubscription.setOnClickListener {
@ -136,36 +111,29 @@ class AccountFragment : Fragment() {
}
binding.linearExportData.setOnClickListener {
val i = Intent(Intent.ACTION_CREATE_DOCUMENT).apply {
addCategory(Intent.CATEGORY_OPENABLE)
type = "text/json"
putExtra(Intent.EXTRA_TITLE, "my-list.json")
}
getUriExport.launch(i)
// unused
}
binding.linearImportData.setOnClickListener {
val i = Intent(Intent.ACTION_OPEN_DOCUMENT).apply {
addCategory(Intent.CATEGORY_OPENABLE)
type = "*/*"
}
getUriImport.launch(i)
// unused
}
}
private fun showLoginDialog(firstTry: Boolean) {
LoginDialog(requireContext(), firstTry).positiveButton {
EncryptedPreferences.saveCredentials(login, password, context)
// TODO
// if (!AoDParser.login()) {
// showLoginDialog(false)
// Log.w(javaClass.name, "Login failed, please try again.")
// }
}.show {
private fun showLoginDialog() {
val loginModal = LoginModalBottomSheet().apply {
login = EncryptedPreferences.login
password = ""
positiveAction = {
EncryptedPreferences.saveCredentials(login, password, requireContext())
// TODO only dismiss if login was successful
this.dismiss()
}
negativeAction = {
this.dismiss()
}
}
activity?.let { loginModal.show(it.supportFragmentManager, LoginModalBottomSheet.TAG) }
}
private fun showContentLanguageSelection() {

View File

@ -1,94 +0,0 @@
/**
* ProjectLaogai
*
* Copyright 2019-2020 <seil0@mosad.xyz>
*
* 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.
*
*/
package org.mosad.teapod.ui.components
import android.content.Context
import android.widget.EditText
import com.afollestad.materialdialogs.MaterialDialog
import com.afollestad.materialdialogs.bottomsheets.BottomSheet
import com.afollestad.materialdialogs.bottomsheets.setPeekHeight
import com.afollestad.materialdialogs.customview.customView
import com.afollestad.materialdialogs.customview.getCustomView
import org.mosad.teapod.R
// TODO rework and port away from MaterialDialog
class LoginDialog(val context: Context, firstTry: Boolean) {
private val dialog = MaterialDialog(context, BottomSheet())
private val editTextLogin: EditText
private val editTextPassword: EditText
var login = ""
var password = ""
init {
dialog.title(R.string.login)
.message(if (firstTry) R.string.login_desc else R.string.login_failed_desc)
.customView(R.layout.dialog_login)
.positiveButton(R.string.save)
.negativeButton(R.string.cancel)
.setPeekHeight(900)
editTextLogin = dialog.getCustomView().findViewById(R.id.edit_text_login)
editTextPassword = dialog.getCustomView().findViewById(R.id.edit_text_password)
// fix not working accent color
//dialog.getActionButton(WhichButton.POSITIVE).updateTextColor(Preferences.colorAccent)
//dialog.getActionButton(WhichButton.NEGATIVE).updateTextColor(Preferences.colorAccent)
}
fun positiveButton(func: LoginDialog.() -> Unit): LoginDialog = apply {
dialog.positiveButton {
login = editTextLogin.text.toString()
password = editTextPassword.text.toString()
func()
}
}
fun negativeButton(func: LoginDialog.() -> Unit): LoginDialog = apply {
dialog.negativeButton {
func()
}
}
fun show() {
dialog.show()
}
fun show(func: LoginDialog.() -> Unit): LoginDialog = apply {
func()
editTextLogin.setText(login)
editTextPassword.setText(password)
show()
}
@Suppress("unused")
fun dismiss() {
dialog.dismiss()
}
}

View File

@ -0,0 +1,54 @@
package org.mosad.teapod.ui.components
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
import org.mosad.teapod.databinding.ModalBottomSheetLoginBinding
/**
* A bottom sheet with login credential input fields.
*
* To initialize login or password values, use apply.
*/
class LoginModalBottomSheet : BottomSheetDialogFragment() {
private lateinit var binding: ModalBottomSheetLoginBinding
var login = ""
var password = ""
lateinit var positiveAction: LoginModalBottomSheet.() -> Unit
lateinit var negativeAction: LoginModalBottomSheet.() -> Unit
companion object {
const val TAG = "LoginModalBottomSheet"
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
binding = ModalBottomSheetLoginBinding.inflate(inflater, container, false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding.editTextLogin.setText(login)
binding.editTextPassword.setText(password)
binding.positiveButton.setOnClickListener {
login = binding.editTextLogin.text.toString()
password = binding.editTextPassword.text.toString()
positiveAction.invoke(this)
}
binding.negativeButton.setOnClickListener {
negativeAction.invoke(this)
}
}
}

View File

@ -1,30 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/linLayout_login"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingStart="24dp"
android:paddingEnd="24dp">
<EditText
android:id="@+id/edit_text_login"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="7dp"
android:ems="10"
android:hint="@string/login"
android:importantForAutofill="no"
android:inputType="textEmailAddress" />
<EditText
android:id="@+id/edit_text_password"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="7dp"
android:ems="10"
android:hint="@string/password"
android:importantForAutofill="no"
android:inputType="textPassword" />
</LinearLayout>

View File

@ -24,7 +24,7 @@
android:layout_height="72dp"
android:contentDescription="@string/component_poster_desc"
app:shapeAppearance="@style/ShapeAppearance.Teapod.RoundedPoster"
app:srcCompat="@color/md_disabled_text_dark_theme" />
app:srcCompat="@color/imagePlacholder" />
<ImageView
android:id="@+id/image_episode_play"

View File

@ -16,7 +16,7 @@
android:layout_height="108dp"
android:contentDescription="@string/component_poster_desc"
app:shapeAppearance="@style/ShapeAppearance.Teapod.RoundedPoster"
app:srcCompat="@color/md_disabled_text_dark_theme" />
app:srcCompat="@color/imagePlacholder" />
<ImageView
android:id="@+id/image_episode_play"

View File

@ -0,0 +1,77 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/standard_bottom_sheet"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?themeSecondary"
android:orientation="vertical"
android:paddingTop="24dp"
android:paddingStart="24dp"
android:paddingEnd="24dp"
app:layout_behavior="com.google.android.material.bottomsheet.BottomSheetBehavior">
<TextView
android:id="@+id/text_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingBottom="7dp"
android:text="@string/login"
android:textSize="20sp"
android:textStyle="bold" />
<TextView
android:id="@+id/text_supporting_desc"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingBottom="5dp"
android:text="@string/login_desc" />
<EditText
android:id="@+id/edit_text_login"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="7dp"
android:ems="10"
android:hint="@string/login"
android:importantForAutofill="no"
android:inputType="textEmailAddress"
android:minHeight="48dp" />
<EditText
android:id="@+id/edit_text_password"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="7dp"
android:ems="10"
android:hint="@string/password"
android:importantForAutofill="no"
android:inputType="textPassword"
android:minHeight="48dp" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="end"
android:orientation="horizontal">
<Button
android:id="@+id/negative_button"
style="@android:style/Widget.Material.Button.Borderless.Small"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="24dp"
android:text="@string/cancel"
android:textColor="?colorPrimary" />
<Button
android:id="@+id/positive_button"
style="@android:style/Widget.Material.Button.Borderless.Small"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="24dp"
android:text="@string/save"
android:textColor="?colorPrimary" />
</LinearLayout>
</LinearLayout>

View File

@ -5,6 +5,7 @@
<color name="colorPrimaryLight">#99dc45</color>
<color name="colorPrimaryDark">#317a00</color>
<color name="colorAccent">#607d8b</color>
<color name="imagePlacholder">#c2c2c2</color>
<!-- light theme colors -->
<color name="themePrimaryLight">#ffffff</color>

View File

@ -18,11 +18,6 @@
<item name="shapeTextBackground">@color/textBackgroundLight</item>
<item name="iconColor">@color/iconColorLight</item>
<item name="buttonBackground">@color/buttonBackgroundLight</item>
<item name="md_background_color">@color/themeSecondaryLight</item>
<item name="md_color_content">@color/textSecondaryLight</item>
<!-- without this, the unchecked single choice buttons while be white -->
<item name="md_color_widget_unchecked">@color/textSecondaryLight</item>
</style>
<style name="AppTheme.Dark" parent="AppTheme">
@ -37,11 +32,6 @@
<item name="iconColor">@color/iconColorDark</item>
<item name="buttonBackground">@color/buttonBackgroundDark</item>
<item name="md_background_color">@color/themeSecondaryDark</item>
<item name="md_color_content">@color/textSecondaryDark</item>
<!-- without this, the unchecked single choice buttons while be black -->
<item name="md_color_widget_unchecked">@color/textSecondaryDark</item>
<item name="materialAlertDialogTheme">@style/ThemeOverlay.App.MaterialAlertDialog.Dark</item>
<!-- change on click indicator color for manually set components -->
<item name="colorControlHighlight">@color/controlHighlightDark</item>