replace LoginDialog with material-components based LoginModalBottomSheet
This commit is contained in:
		| @ -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) | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|  | ||||
| @ -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", | ||||
|  | ||||
| @ -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() { | ||||
|  | ||||
| @ -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() | ||||
|     } | ||||
|  | ||||
| } | ||||
| @ -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) | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @ -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> | ||||
| @ -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" | ||||
|  | ||||
| @ -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" | ||||
|  | ||||
							
								
								
									
										77
									
								
								app/src/main/res/layout/modal_bottom_sheet_login.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										77
									
								
								app/src/main/res/layout/modal_bottom_sheet_login.xml
									
									
									
									
									
										Normal 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> | ||||
| @ -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> | ||||
|  | ||||
| @ -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> | ||||
|  | ||||
		Reference in New Issue
	
	Block a user