mirror of
https://github.com/android-password-store/Android-Password-Store
synced 2025-08-31 22:35:17 +00:00
Completely revamp decrypted password screen (#817)
* Completely revamp decrypted password screen Signed-off-by: Harsh Shandilya <me@msfjarvis.dev> * update changelog Signed-off-by: Harsh Shandilya <me@msfjarvis.dev> Co-authored-by: Fabian Henneke <FabianHenneke@users.noreply.github.com>
This commit is contained in:
@@ -3,6 +3,9 @@ All notable changes to this project will be documented in this file.
|
|||||||
|
|
||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
|
|
||||||
|
### Added
|
||||||
|
- Completely revamped decypted password view
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
- **BREAKING**: Remove support for HOTP/TOTP secrets - Please use FIDO keys or a dedicated app like [Aegis](https://github.com/beemdevelopment/Aegis) or [andOTP](https://github.com/andOTP/andOTP).
|
- **BREAKING**: Remove support for HOTP/TOTP secrets - Please use FIDO keys or a dedicated app like [Aegis](https://github.com/beemdevelopment/Aegis) or [andOTP](https://github.com/andOTP/andOTP).
|
||||||
- Reduce Autofill false positives on username fields by removing "name" from list of heuristic terms
|
- Reduce Autofill false positives on username fields by removing "name" from list of heuristic terms
|
||||||
|
@@ -4,7 +4,6 @@
|
|||||||
*/
|
*/
|
||||||
package com.zeapo.pwdstore.crypto
|
package com.zeapo.pwdstore.crypto
|
||||||
|
|
||||||
import android.annotation.SuppressLint
|
|
||||||
import android.app.PendingIntent
|
import android.app.PendingIntent
|
||||||
import android.content.BroadcastReceiver
|
import android.content.BroadcastReceiver
|
||||||
import android.content.ClipData
|
import android.content.ClipData
|
||||||
@@ -23,13 +22,9 @@ import android.text.format.DateUtils
|
|||||||
import android.text.method.PasswordTransformationMethod
|
import android.text.method.PasswordTransformationMethod
|
||||||
import android.view.Menu
|
import android.view.Menu
|
||||||
import android.view.MenuItem
|
import android.view.MenuItem
|
||||||
import android.view.MotionEvent
|
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.WindowManager
|
import android.view.WindowManager
|
||||||
import android.widget.Button
|
|
||||||
import android.widget.TextView
|
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.constraintlayout.widget.ConstraintLayout
|
|
||||||
import androidx.core.content.edit
|
import androidx.core.content.edit
|
||||||
import androidx.core.content.getSystemService
|
import androidx.core.content.getSystemService
|
||||||
import androidx.core.widget.doOnTextChanged
|
import androidx.core.widget.doOnTextChanged
|
||||||
@@ -48,19 +43,15 @@ import com.zeapo.pwdstore.autofill.oreo.AutofillPreferences
|
|||||||
import com.zeapo.pwdstore.autofill.oreo.DirectoryStructure
|
import com.zeapo.pwdstore.autofill.oreo.DirectoryStructure
|
||||||
import com.zeapo.pwdstore.ui.dialogs.PasswordGeneratorDialogFragment
|
import com.zeapo.pwdstore.ui.dialogs.PasswordGeneratorDialogFragment
|
||||||
import com.zeapo.pwdstore.ui.dialogs.XkPasswordGeneratorDialogFragment
|
import com.zeapo.pwdstore.ui.dialogs.XkPasswordGeneratorDialogFragment
|
||||||
import kotlinx.android.synthetic.main.decrypt_layout.crypto_container_decrypt
|
|
||||||
import kotlinx.android.synthetic.main.decrypt_layout.crypto_copy_username
|
|
||||||
import kotlinx.android.synthetic.main.decrypt_layout.crypto_extra_show
|
|
||||||
import kotlinx.android.synthetic.main.decrypt_layout.crypto_extra_show_layout
|
|
||||||
import kotlinx.android.synthetic.main.decrypt_layout.crypto_extra_toggle_show
|
|
||||||
import kotlinx.android.synthetic.main.decrypt_layout.crypto_password_category_decrypt
|
import kotlinx.android.synthetic.main.decrypt_layout.crypto_password_category_decrypt
|
||||||
import kotlinx.android.synthetic.main.decrypt_layout.crypto_password_file
|
import kotlinx.android.synthetic.main.decrypt_layout.crypto_password_file
|
||||||
import kotlinx.android.synthetic.main.decrypt_layout.crypto_password_last_changed
|
import kotlinx.android.synthetic.main.decrypt_layout.crypto_password_last_changed
|
||||||
import kotlinx.android.synthetic.main.decrypt_layout.crypto_password_show
|
import kotlinx.android.synthetic.main.decrypt_layout.extra_content
|
||||||
import kotlinx.android.synthetic.main.decrypt_layout.crypto_password_show_label
|
import kotlinx.android.synthetic.main.decrypt_layout.extra_content_container
|
||||||
import kotlinx.android.synthetic.main.decrypt_layout.crypto_password_toggle_show
|
import kotlinx.android.synthetic.main.decrypt_layout.password_text
|
||||||
import kotlinx.android.synthetic.main.decrypt_layout.crypto_username_show
|
import kotlinx.android.synthetic.main.decrypt_layout.password_text_container
|
||||||
import kotlinx.android.synthetic.main.decrypt_layout.crypto_username_show_label
|
import kotlinx.android.synthetic.main.decrypt_layout.username_text
|
||||||
|
import kotlinx.android.synthetic.main.decrypt_layout.username_text_container
|
||||||
import kotlinx.android.synthetic.main.encrypt_layout.crypto_extra_edit
|
import kotlinx.android.synthetic.main.encrypt_layout.crypto_extra_edit
|
||||||
import kotlinx.android.synthetic.main.encrypt_layout.crypto_password_category
|
import kotlinx.android.synthetic.main.encrypt_layout.crypto_password_category
|
||||||
import kotlinx.android.synthetic.main.encrypt_layout.crypto_password_edit
|
import kotlinx.android.synthetic.main.encrypt_layout.crypto_password_edit
|
||||||
@@ -119,7 +110,7 @@ class PgpActivity : AppCompatActivity(), OpenPgpServiceConnection.OnBound {
|
|||||||
val settings: SharedPreferences by lazy { PreferenceManager.getDefaultSharedPreferences(this) }
|
val settings: SharedPreferences by lazy { PreferenceManager.getDefaultSharedPreferences(this) }
|
||||||
private val keyIDs get() = _keyIDs
|
private val keyIDs get() = _keyIDs
|
||||||
private var _keyIDs = emptySet<String>()
|
private var _keyIDs = emptySet<String>()
|
||||||
private var mServiceConnection: OpenPgpServiceConnection? = null
|
private var serviceConnection: OpenPgpServiceConnection? = null
|
||||||
private var delayTask: DelayShow? = null
|
private var delayTask: DelayShow? = null
|
||||||
private val receiver = object : BroadcastReceiver() {
|
private val receiver = object : BroadcastReceiver() {
|
||||||
override fun onReceive(context: Context?, intent: Intent?) {
|
override fun onReceive(context: Context?, intent: Intent?) {
|
||||||
@@ -142,8 +133,8 @@ class PgpActivity : AppCompatActivity(), OpenPgpServiceConnection.OnBound {
|
|||||||
startActivityForResult(intent, OPEN_PGP_BOUND)
|
startActivityForResult(intent, OPEN_PGP_BOUND)
|
||||||
} else {
|
} else {
|
||||||
// bind to service
|
// bind to service
|
||||||
mServiceConnection = OpenPgpServiceConnection(this, providerPackageName, this)
|
serviceConnection = OpenPgpServiceConnection(this, providerPackageName, this)
|
||||||
mServiceConnection?.bindToService()
|
serviceConnection?.bindToService()
|
||||||
supportActionBar?.setDisplayHomeAsUpEnabled(true)
|
supportActionBar?.setDisplayHomeAsUpEnabled(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -156,12 +147,12 @@ class PgpActivity : AppCompatActivity(), OpenPgpServiceConnection.OnBound {
|
|||||||
val clipboard = clipboard ?: return@setOnLongClickListener false
|
val clipboard = clipboard ?: return@setOnLongClickListener false
|
||||||
val clip = ClipData.newPlainText("pgp_handler_result_pm", name)
|
val clip = ClipData.newPlainText("pgp_handler_result_pm", name)
|
||||||
clipboard.setPrimaryClip(clip)
|
clipboard.setPrimaryClip(clip)
|
||||||
showSnackbar(this.resources.getString(R.string.clipboard_username_toast_text))
|
showSnackbar(resources.getString(R.string.clipboard_copied_text))
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
crypto_password_last_changed.text = try {
|
crypto_password_last_changed.text = try {
|
||||||
this.resources.getString(R.string.last_changed, lastChangedString)
|
resources.getString(R.string.last_changed, lastChangedString)
|
||||||
} catch (e: RuntimeException) {
|
} catch (e: RuntimeException) {
|
||||||
showSnackbar(getString(R.string.get_last_changed_failed))
|
showSnackbar(getString(R.string.get_last_changed_failed))
|
||||||
""
|
""
|
||||||
@@ -277,7 +268,7 @@ class PgpActivity : AppCompatActivity(), OpenPgpServiceConnection.OnBound {
|
|||||||
|
|
||||||
override fun onDestroy() {
|
override fun onDestroy() {
|
||||||
super.onDestroy()
|
super.onDestroy()
|
||||||
mServiceConnection?.unbindFromService()
|
serviceConnection?.unbindFromService()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
|
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
|
||||||
@@ -354,7 +345,7 @@ class PgpActivity : AppCompatActivity(), OpenPgpServiceConnection.OnBound {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun initOpenPgpApi() {
|
private fun initOpenPgpApi() {
|
||||||
api = api ?: OpenPgpApi(this, mServiceConnection!!.service!!)
|
api = api ?: OpenPgpApi(this, serviceConnection!!.service!!)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun decryptAndVerify(receivedIntent: Intent? = null) {
|
private fun decryptAndVerify(receivedIntent: Intent? = null) {
|
||||||
@@ -372,7 +363,7 @@ class PgpActivity : AppCompatActivity(), OpenPgpServiceConnection.OnBound {
|
|||||||
val showPassword = settings.getBoolean("show_password", true)
|
val showPassword = settings.getBoolean("show_password", true)
|
||||||
val showExtraContent = settings.getBoolean("show_extra_content", true)
|
val showExtraContent = settings.getBoolean("show_extra_content", true)
|
||||||
|
|
||||||
crypto_container_decrypt.visibility = View.VISIBLE
|
password_text_container.visibility = View.VISIBLE
|
||||||
|
|
||||||
val monoTypeface = Typeface.createFromAsset(assets, "fonts/sourcecodepro.ttf")
|
val monoTypeface = Typeface.createFromAsset(assets, "fonts/sourcecodepro.ttf")
|
||||||
val entry = PasswordEntry(oStream)
|
val entry = PasswordEntry(oStream)
|
||||||
@@ -385,61 +376,34 @@ class PgpActivity : AppCompatActivity(), OpenPgpServiceConnection.OnBound {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (entry.password.isEmpty()) {
|
if (entry.password.isEmpty()) {
|
||||||
crypto_password_show.visibility = View.GONE
|
password_text_container.visibility = View.GONE
|
||||||
crypto_password_show_label.visibility = View.GONE
|
|
||||||
} else {
|
} else {
|
||||||
crypto_password_show.visibility = View.VISIBLE
|
password_text_container.visibility = View.VISIBLE
|
||||||
crypto_password_show_label.visibility = View.VISIBLE
|
password_text.setText(entry.password)
|
||||||
crypto_password_show.typeface = monoTypeface
|
if (!showPassword) {
|
||||||
crypto_password_show.text = entry.password
|
password_text.transformationMethod = PasswordTransformationMethod.getInstance()
|
||||||
}
|
}
|
||||||
crypto_password_show.typeface = monoTypeface
|
password_text_container.setOnClickListener { copyPasswordToClipBoard() }
|
||||||
crypto_password_show.text = entry.password
|
password_text.setOnClickListener { copyPasswordToClipBoard() }
|
||||||
|
|
||||||
crypto_password_toggle_show.visibility = if (showPassword) View.GONE else View.VISIBLE
|
|
||||||
crypto_password_show.transformationMethod = if (showPassword) {
|
|
||||||
null
|
|
||||||
} else {
|
|
||||||
HoldToShowPasswordTransformation(
|
|
||||||
crypto_password_toggle_show,
|
|
||||||
Runnable { crypto_password_show.text = entry.password }
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (entry.hasExtraContent()) {
|
if (entry.hasExtraContent()) {
|
||||||
crypto_extra_show.typeface = monoTypeface
|
extra_content_container.visibility = View.VISIBLE
|
||||||
crypto_extra_show.text = entry.extraContent
|
extra_content.typeface = monoTypeface
|
||||||
|
extra_content.setText(entry.extraContentWithoutUsername)
|
||||||
if (showExtraContent) {
|
if (!showExtraContent) {
|
||||||
crypto_extra_show_layout.visibility = View.VISIBLE
|
extra_content.transformationMethod = PasswordTransformationMethod.getInstance()
|
||||||
crypto_extra_toggle_show.visibility = View.GONE
|
|
||||||
crypto_extra_show.transformationMethod = null
|
|
||||||
} else {
|
|
||||||
crypto_extra_show_layout.visibility = View.GONE
|
|
||||||
crypto_extra_toggle_show.visibility = View.VISIBLE
|
|
||||||
crypto_extra_toggle_show.setOnCheckedChangeListener { _, _ ->
|
|
||||||
crypto_extra_show.text = entry.extraContent
|
|
||||||
}
|
|
||||||
|
|
||||||
crypto_extra_show.transformationMethod = object : PasswordTransformationMethod() {
|
|
||||||
override fun getTransformation(source: CharSequence, view: View): CharSequence {
|
|
||||||
return if (crypto_extra_toggle_show.isChecked) source else super.getTransformation(source, view)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
extra_content_container.setOnClickListener { copyTextToClipboard(entry.extraContentWithoutUsername) }
|
||||||
|
extra_content.setOnClickListener { copyTextToClipboard(entry.extraContentWithoutUsername) }
|
||||||
|
|
||||||
if (entry.hasUsername()) {
|
if (entry.hasUsername()) {
|
||||||
crypto_username_show.visibility = View.VISIBLE
|
username_text.typeface = monoTypeface
|
||||||
crypto_username_show_label.visibility = View.VISIBLE
|
username_text.setText(entry.username)
|
||||||
crypto_copy_username.visibility = View.VISIBLE
|
username_text_container.setEndIconOnClickListener { copyTextToClipboard(entry.username!!) }
|
||||||
|
username_text_container.visibility = View.VISIBLE
|
||||||
crypto_copy_username.setOnClickListener { copyUsernameToClipBoard(entry.username!!) }
|
|
||||||
crypto_username_show.typeface = monoTypeface
|
|
||||||
crypto_username_show.text = entry.username
|
|
||||||
} else {
|
} else {
|
||||||
crypto_username_show.visibility = View.GONE
|
username_text_container.visibility = View.GONE
|
||||||
crypto_username_show_label.visibility = View.GONE
|
|
||||||
crypto_copy_username.visibility = View.GONE
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -657,47 +621,9 @@ class PgpActivity : AppCompatActivity(), OpenPgpServiceConnection.OnBound {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressLint("ClickableViewAccessibility")
|
|
||||||
private inner class HoldToShowPasswordTransformation constructor(button: Button, private val onToggle: Runnable) :
|
|
||||||
PasswordTransformationMethod(), View.OnTouchListener {
|
|
||||||
|
|
||||||
private var shown = false
|
|
||||||
|
|
||||||
init {
|
|
||||||
button.setOnTouchListener(this)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getTransformation(charSequence: CharSequence, view: View): CharSequence {
|
|
||||||
return if (shown) charSequence else super.getTransformation("12345", view)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onTouch(view: View, motionEvent: MotionEvent): Boolean {
|
|
||||||
when (motionEvent.action) {
|
|
||||||
MotionEvent.ACTION_DOWN -> {
|
|
||||||
shown = true
|
|
||||||
onToggle.run()
|
|
||||||
}
|
|
||||||
MotionEvent.ACTION_UP -> {
|
|
||||||
shown = false
|
|
||||||
onToggle.run()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun copyPasswordToClipBoard() {
|
private fun copyPasswordToClipBoard() {
|
||||||
val clipboard = clipboard ?: return
|
val clipboard = clipboard ?: return
|
||||||
var pass = passwordEntry?.password
|
val pass = passwordEntry?.password
|
||||||
|
|
||||||
if (findViewById<TextView>(R.id.crypto_password_show) == null) {
|
|
||||||
if (editPass == null) {
|
|
||||||
return
|
|
||||||
} else {
|
|
||||||
pass = editPass
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val clip = ClipData.newPlainText("pgp_handler_result_pm", pass)
|
val clip = ClipData.newPlainText("pgp_handler_result_pm", pass)
|
||||||
clipboard.setPrimaryClip(clip)
|
clipboard.setPrimaryClip(clip)
|
||||||
|
|
||||||
@@ -710,23 +636,20 @@ class PgpActivity : AppCompatActivity(), OpenPgpServiceConnection.OnBound {
|
|||||||
|
|
||||||
if (clearAfter != 0) {
|
if (clearAfter != 0) {
|
||||||
setTimer()
|
setTimer()
|
||||||
showSnackbar(this.resources.getString(R.string.clipboard_password_toast_text, clearAfter))
|
showSnackbar(resources.getString(R.string.clipboard_password_toast_text, clearAfter))
|
||||||
} else {
|
} else {
|
||||||
showSnackbar(this.resources.getString(R.string.clipboard_password_no_clear_toast_text))
|
showSnackbar(resources.getString(R.string.clipboard_password_no_clear_toast_text))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun copyUsernameToClipBoard(username: String) {
|
private fun copyTextToClipboard(text: String) {
|
||||||
val clipboard = clipboard ?: return
|
val clipboard = clipboard ?: return
|
||||||
val clip = ClipData.newPlainText("pgp_handler_result_pm", username)
|
val clip = ClipData.newPlainText("pgp_handler_result_pm", text)
|
||||||
clipboard.setPrimaryClip(clip)
|
clipboard.setPrimaryClip(clip)
|
||||||
showSnackbar(resources.getString(R.string.clipboard_username_toast_text))
|
showSnackbar(resources.getString(R.string.clipboard_copied_text))
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun shareAsPlaintext() {
|
private fun shareAsPlaintext() {
|
||||||
if (findViewById<View>(R.id.share_password_as_plaintext) == null)
|
|
||||||
return
|
|
||||||
|
|
||||||
val sendIntent = Intent()
|
val sendIntent = Intent()
|
||||||
sendIntent.action = Intent.ACTION_SEND
|
sendIntent.action = Intent.ACTION_SEND
|
||||||
sendIntent.putExtra(Intent.EXTRA_TEXT, passwordEntry?.password)
|
sendIntent.putExtra(Intent.EXTRA_TEXT, passwordEntry?.password)
|
||||||
@@ -800,25 +723,18 @@ class PgpActivity : AppCompatActivity(), OpenPgpServiceConnection.OnBound {
|
|||||||
} catch (e: NumberFormatException) {
|
} catch (e: NumberFormatException) {
|
||||||
45
|
45
|
||||||
}
|
}
|
||||||
|
password_text_container?.visibility = View.VISIBLE
|
||||||
val container = findViewById<ConstraintLayout>(R.id.crypto_container_decrypt)
|
if (extra_content?.text?.isNotEmpty() == true)
|
||||||
container?.visibility = View.VISIBLE
|
extra_content_container?.visibility = View.VISIBLE
|
||||||
|
|
||||||
val extraText = findViewById<TextView>(R.id.crypto_extra_show)
|
|
||||||
|
|
||||||
if (extraText?.text?.isNotEmpty() == true)
|
|
||||||
findViewById<View>(R.id.crypto_extra_show_layout)?.visibility = View.VISIBLE
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun doOnPostExecute() {
|
fun doOnPostExecute() {
|
||||||
if (skip) return
|
if (skip) return
|
||||||
|
|
||||||
if (crypto_password_show != null) {
|
if (password_text != null) {
|
||||||
passwordEntry = null
|
passwordEntry = null
|
||||||
crypto_password_show.text = ""
|
extra_content_container.visibility = View.INVISIBLE
|
||||||
crypto_extra_show.text = ""
|
password_text_container.visibility = View.INVISIBLE
|
||||||
crypto_extra_show_layout.visibility = View.INVISIBLE
|
|
||||||
crypto_container_decrypt.visibility = View.INVISIBLE
|
|
||||||
finish()
|
finish()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -68,137 +68,68 @@
|
|||||||
app:layout_constraintTop_toBottomOf="@id/crypto_password_last_changed"
|
app:layout_constraintTop_toBottomOf="@id/crypto_password_last_changed"
|
||||||
tools:ignore="ContentDescription" />
|
tools:ignore="ContentDescription" />
|
||||||
|
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout
|
<com.google.android.material.textfield.TextInputLayout
|
||||||
android:id="@+id/crypto_container_decrypt"
|
android:id="@+id/password_text_container"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="@dimen/activity_vertical_margin"
|
android:layout_marginTop="16dp"
|
||||||
android:visibility="invisible"
|
android:hint="@string/password"
|
||||||
|
android:visibility="gone"
|
||||||
|
app:endIconMode="password_toggle"
|
||||||
app:layout_constraintTop_toBottomOf="@id/divider"
|
app:layout_constraintTop_toBottomOf="@id/divider"
|
||||||
tools:visibility="visible">
|
tools:visibility="visible">
|
||||||
|
|
||||||
<androidx.appcompat.widget.AppCompatTextView
|
<com.google.android.material.textfield.TextInputEditText
|
||||||
android:id="@+id/crypto_password_show_label"
|
android:id="@+id/password_text"
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="@string/password"
|
|
||||||
android:textColor="?android:attr/textColor"
|
|
||||||
android:textStyle="bold"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintTop_toTopOf="parent" />
|
|
||||||
|
|
||||||
<androidx.appcompat.widget.AppCompatTextView
|
|
||||||
android:id="@+id/crypto_password_show"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_gravity="fill"
|
|
||||||
android:gravity="bottom"
|
|
||||||
android:textColor="?android:attr/textColor"
|
|
||||||
android:typeface="monospace"
|
|
||||||
app:layout_constraintBaseline_toBaselineOf="@id/crypto_password_show_label"
|
|
||||||
app:layout_constraintStart_toEndOf="@id/crypto_password_show_label" />
|
|
||||||
|
|
||||||
<com.google.android.material.button.MaterialButton
|
|
||||||
android:id="@+id/crypto_password_toggle_show"
|
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="8dp"
|
android:editable="false"
|
||||||
android:text="@string/show_password"
|
android:fontFamily="@font/sourcecodepro"
|
||||||
app:layout_constraintTop_toBottomOf="@id/crypto_password_show_label" />
|
android:textIsSelectable="true"
|
||||||
|
tools:text="p@55w0rd!" />
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</com.google.android.material.textfield.TextInputLayout>
|
||||||
|
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout
|
<com.google.android.material.textfield.TextInputLayout
|
||||||
android:id="@+id/crypto_extra_show_layout"
|
android:id="@+id/username_text_container"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:visibility="invisible"
|
android:layout_marginTop="16dp"
|
||||||
app:layout_constraintTop_toBottomOf="@id/crypto_container_decrypt"
|
android:hint="@string/username"
|
||||||
|
android:visibility="gone"
|
||||||
|
app:endIconDrawable="@drawable/ic_content_copy"
|
||||||
|
app:endIconMode="custom"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/password_text_container"
|
||||||
tools:visibility="visible">
|
tools:visibility="visible">
|
||||||
|
|
||||||
<androidx.appcompat.widget.AppCompatImageButton
|
<com.google.android.material.textfield.TextInputEditText
|
||||||
android:id="@+id/crypto_copy_username"
|
android:id="@+id/username_text"
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_alignParentTop="true"
|
|
||||||
android:layout_alignParentEnd="true"
|
|
||||||
android:background="?android:attr/windowBackground"
|
|
||||||
android:contentDescription="@string/copy_username"
|
|
||||||
android:src="@drawable/ic_content_copy"
|
|
||||||
android:visibility="invisible"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
|
||||||
tools:visibility="visible" />
|
|
||||||
|
|
||||||
<androidx.appcompat.widget.AppCompatTextView
|
|
||||||
android:id="@+id/crypto_username_show_label"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_alignParentStart="true"
|
|
||||||
android:layout_alignParentTop="true"
|
|
||||||
android:layout_toStartOf="@id/crypto_copy_username"
|
|
||||||
android:text="@string/username"
|
|
||||||
android:textColor="?android:attr/textColor"
|
|
||||||
android:textStyle="bold"
|
|
||||||
android:visibility="invisible"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
|
||||||
tools:visibility="visible" />
|
|
||||||
|
|
||||||
<androidx.appcompat.widget.AppCompatTextView
|
|
||||||
android:id="@+id/crypto_username_show"
|
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_below="@id/crypto_username_show_label"
|
android:editable="false"
|
||||||
android:layout_alignParentStart="true"
|
|
||||||
android:layout_toStartOf="@id/crypto_copy_username"
|
|
||||||
android:textColor="?android:attr/textColor"
|
|
||||||
android:textIsSelectable="true"
|
android:textIsSelectable="true"
|
||||||
android:typeface="monospace"
|
tools:text="totally_real_user@example.com" />
|
||||||
android:visibility="invisible"
|
</com.google.android.material.textfield.TextInputLayout>
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintTop_toBottomOf="@id/crypto_username_show_label"
|
|
||||||
tools:visibility="visible" />
|
|
||||||
|
|
||||||
<androidx.appcompat.widget.AppCompatTextView
|
<com.google.android.material.textfield.TextInputLayout
|
||||||
android:id="@+id/crypto_extra_show_label"
|
android:id="@+id/extra_content_container"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_below="@id/crypto_username_show"
|
android:layout_marginTop="16dp"
|
||||||
android:layout_alignParentStart="true"
|
android:hint="@string/extra_content"
|
||||||
android:text="@string/extra_content"
|
android:visibility="gone"
|
||||||
android:textColor="?android:attr/textColor"
|
app:endIconMode="password_toggle"
|
||||||
android:textStyle="bold"
|
app:layout_constraintTop_toBottomOf="@id/username_text_container"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
tools:visibility="visible">
|
||||||
app:layout_constraintTop_toBottomOf="@id/crypto_username_show" />
|
|
||||||
|
|
||||||
<androidx.appcompat.widget.AppCompatTextView
|
<com.google.android.material.textfield.TextInputEditText
|
||||||
android:id="@+id/crypto_extra_show"
|
android:id="@+id/extra_content"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_below="@id/crypto_extra_show_label"
|
android:editable="false"
|
||||||
android:layout_alignParentStart="true"
|
|
||||||
android:textColor="?android:attr/textColor"
|
|
||||||
android:textIsSelectable="true"
|
android:textIsSelectable="true"
|
||||||
android:typeface="monospace"
|
tools:text="lots of extra content that will surely fill this \n up well" />
|
||||||
app:layout_constraintTop_toBottomOf="@id/crypto_extra_show_label" />
|
</com.google.android.material.textfield.TextInputLayout>
|
||||||
|
|
||||||
<ToggleButton
|
|
||||||
android:id="@+id/crypto_extra_toggle_show"
|
|
||||||
style="@style/Widget.MaterialComponents.Button"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_below="@id/crypto_extra_show"
|
|
||||||
android:layout_alignParentStart="true"
|
|
||||||
android:backgroundTint="?attr/colorSecondary"
|
|
||||||
android:checked="false"
|
|
||||||
android:paddingTop="8dp"
|
|
||||||
android:textColor="?android:attr/windowBackground"
|
|
||||||
android:textOff="@string/show_extra"
|
|
||||||
android:textOn="@string/hide_extra"
|
|
||||||
app:layout_constraintTop_toBottomOf="@id/crypto_extra_show" />
|
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
||||||
|
@@ -16,7 +16,6 @@
|
|||||||
<string name="delete">حذف</string>
|
<string name="delete">حذف</string>
|
||||||
<!-- PGPHandler -->
|
<!-- PGPHandler -->
|
||||||
<string name="provider_toast_text">لم يتم إختيار مزود الأوبن بي جي بي بعد !</string>
|
<string name="provider_toast_text">لم يتم إختيار مزود الأوبن بي جي بي بعد !</string>
|
||||||
<string name="clipboard_username_toast_text">تم نسخ إسم المستخدم إلى الحافظة</string>
|
|
||||||
<string name="file_toast_text">الرجاء إدخال إسم ملف</string>
|
<string name="file_toast_text">الرجاء إدخال إسم ملف</string>
|
||||||
<!-- Git Async Task -->
|
<!-- Git Async Task -->
|
||||||
<string name="running_dialog_text">جاري تنفيذ الأمر ...</string>
|
<string name="running_dialog_text">جاري تنفيذ الأمر ...</string>
|
||||||
|
@@ -33,7 +33,6 @@
|
|||||||
<string name="provider_toast_text">Nebyl vybrán poskytovatel OpenPGP!</string>
|
<string name="provider_toast_text">Nebyl vybrán poskytovatel OpenPGP!</string>
|
||||||
<string name="clipboard_password_toast_text">Heslo zkopírováno do schránky, máte %d sekund na jeho zkopírování.</string>
|
<string name="clipboard_password_toast_text">Heslo zkopírováno do schránky, máte %d sekund na jeho zkopírování.</string>
|
||||||
<string name="clipboard_password_no_clear_toast_text">Heslo zkopírováno do schránky</string>
|
<string name="clipboard_password_no_clear_toast_text">Heslo zkopírováno do schránky</string>
|
||||||
<string name="clipboard_username_toast_text">Jméno zkopírováno do schránky</string>
|
|
||||||
<string name="file_toast_text">Zadejte prosím jméno souboru</string>
|
<string name="file_toast_text">Zadejte prosím jméno souboru</string>
|
||||||
<string name="path_toast_text">Prosím zadejte cestu k souboru</string>
|
<string name="path_toast_text">Prosím zadejte cestu k souboru</string>
|
||||||
<string name="empty_toast_text">Nelze zadat prázdné heslo nebo další obsah</string>
|
<string name="empty_toast_text">Nelze zadat prázdné heslo nebo další obsah</string>
|
||||||
|
@@ -20,7 +20,6 @@
|
|||||||
<!-- PGPHandler -->
|
<!-- PGPHandler -->
|
||||||
<string name="provider_toast_text">Kein OpenPGP-Provider ausgewählt!</string>
|
<string name="provider_toast_text">Kein OpenPGP-Provider ausgewählt!</string>
|
||||||
<string name="clipboard_password_toast_text">Passwort ist in der Zwischenablage, du hast %d Sekunden, um es einzufügen.</string>
|
<string name="clipboard_password_toast_text">Passwort ist in der Zwischenablage, du hast %d Sekunden, um es einzufügen.</string>
|
||||||
<string name="clipboard_username_toast_text">Benutzername ist in der Zwischenablage</string>
|
|
||||||
<string name="file_toast_text">Bitte setze einen Pfad</string>
|
<string name="file_toast_text">Bitte setze einen Pfad</string>
|
||||||
<string name="empty_toast_text">Du kannst kein leeres Passwort setzen oder leere Extra-Angaben</string>
|
<string name="empty_toast_text">Du kannst kein leeres Passwort setzen oder leere Extra-Angaben</string>
|
||||||
|
|
||||||
|
@@ -29,7 +29,6 @@
|
|||||||
<string name="provider_toast_text">¡No se ha seleccionado ningún proveedor OpenGPG!</string>
|
<string name="provider_toast_text">¡No se ha seleccionado ningún proveedor OpenGPG!</string>
|
||||||
<string name="clipboard_password_toast_text">Contraseña copiada al portapapeles, tienes %d segundos para pegarla.</string>
|
<string name="clipboard_password_toast_text">Contraseña copiada al portapapeles, tienes %d segundos para pegarla.</string>
|
||||||
<string name="clipboard_password_no_clear_toast_text">Contraseña copiada al portapapeles</string>
|
<string name="clipboard_password_no_clear_toast_text">Contraseña copiada al portapapeles</string>
|
||||||
<string name="clipboard_username_toast_text">Nombre de usuario copiado al portapapeles</string>
|
|
||||||
<string name="file_toast_text">Por favor selecciona un nombre de archivo</string>
|
<string name="file_toast_text">Por favor selecciona un nombre de archivo</string>
|
||||||
<string name="empty_toast_text">No puedes dejar la contraseña y el contenido extra ambos vacíos</string>
|
<string name="empty_toast_text">No puedes dejar la contraseña y el contenido extra ambos vacíos</string>
|
||||||
|
|
||||||
|
@@ -35,7 +35,6 @@
|
|||||||
<!-- PGPHandler -->
|
<!-- PGPHandler -->
|
||||||
<string name="provider_toast_text">Aucun prestataire OpenPGP sélectionné !</string>
|
<string name="provider_toast_text">Aucun prestataire OpenPGP sélectionné !</string>
|
||||||
<string name="clipboard_password_toast_text">Mot de passe copié dans le presse papier, vous avez %d secondes pour coller celui-ci.</string>
|
<string name="clipboard_password_toast_text">Mot de passe copié dans le presse papier, vous avez %d secondes pour coller celui-ci.</string>
|
||||||
<string name="clipboard_username_toast_text">Nom d\'utilisateur copié</string>
|
|
||||||
<string name="file_toast_text">Renseignez un nom de fichier</string>
|
<string name="file_toast_text">Renseignez un nom de fichier</string>
|
||||||
<string name="empty_toast_text">Vous ne pouvez pas utiliser un mot de passe vide ou des données supplémentaires vide</string>
|
<string name="empty_toast_text">Vous ne pouvez pas utiliser un mot de passe vide ou des données supplémentaires vide</string>
|
||||||
|
|
||||||
|
@@ -36,7 +36,6 @@
|
|||||||
<string name="provider_toast_text">Не выбран провайдер OpenPGP!</string>
|
<string name="provider_toast_text">Не выбран провайдер OpenPGP!</string>
|
||||||
<string name="clipboard_password_toast_text">Пароль скопирован в буфер обмена, у вас есть %d секунд чтобы вставить его.</string>
|
<string name="clipboard_password_toast_text">Пароль скопирован в буфер обмена, у вас есть %d секунд чтобы вставить его.</string>
|
||||||
<string name="clipboard_password_no_clear_toast_text">Пароль скопирован в буфер обмена</string>
|
<string name="clipboard_password_no_clear_toast_text">Пароль скопирован в буфер обмена</string>
|
||||||
<string name="clipboard_username_toast_text">Имя пользователя скопировано в буфер обмена</string>
|
|
||||||
<string name="file_toast_text">Пожалуйста, укажите имя файла</string>
|
<string name="file_toast_text">Пожалуйста, укажите имя файла</string>
|
||||||
<string name="path_toast_text">Пожалуйста, задайте путь к файлу</string>
|
<string name="path_toast_text">Пожалуйста, задайте путь к файлу</string>
|
||||||
<string name="empty_toast_text">Вы не можете использовать пустой пароль или пустое поле информации</string>
|
<string name="empty_toast_text">Вы не можете использовать пустой пароль или пустое поле информации</string>
|
||||||
|
@@ -47,7 +47,7 @@
|
|||||||
<string name="provider_toast_text">No OpenPGP provider selected!</string>
|
<string name="provider_toast_text">No OpenPGP provider selected!</string>
|
||||||
<string name="clipboard_password_toast_text">Password copied to clipboard, you have %d seconds to paste it somewhere.</string>
|
<string name="clipboard_password_toast_text">Password copied to clipboard, you have %d seconds to paste it somewhere.</string>
|
||||||
<string name="clipboard_password_no_clear_toast_text">Password copied to clipboard</string>
|
<string name="clipboard_password_no_clear_toast_text">Password copied to clipboard</string>
|
||||||
<string name="clipboard_username_toast_text">Username copied to clipboard</string>
|
<string name="clipboard_copied_text">Copied to clipboard</string>
|
||||||
<string name="file_toast_text">Please provide a file name</string>
|
<string name="file_toast_text">Please provide a file name</string>
|
||||||
<string name="path_toast_text">Please provide a file path</string>
|
<string name="path_toast_text">Please provide a file path</string>
|
||||||
<string name="empty_toast_text">You cannot use an empty password or empty extra content</string>
|
<string name="empty_toast_text">You cannot use an empty password or empty extra content</string>
|
||||||
|
Reference in New Issue
Block a user