replace LoginDialog with material-components based LoginModalBottomSheet
This commit is contained in:
		@ -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"
 | 
			
		||||
 | 
			
		||||
@ -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