From 287f7e919bc63e36f082b2dfe2c7a247266f89af Mon Sep 17 00:00:00 2001 From: Harsh Shandilya Date: Mon, 12 Aug 2024 01:42:38 +0530 Subject: [PATCH] refactor: rework FieldItem to drop hard-coded strings --- .../java/app/passwordstore/Application.kt | 1 - .../passwordstore/data/password/FieldItem.kt | 38 +++++++++++++------ .../ui/adapters/FieldItemAdapter.kt | 13 +++---- .../ui/crypto/DecryptActivity.kt | 13 +++---- 4 files changed, 38 insertions(+), 27 deletions(-) diff --git a/app/src/main/java/app/passwordstore/Application.kt b/app/src/main/java/app/passwordstore/Application.kt index 36f98b389..ea730e7eb 100644 --- a/app/src/main/java/app/passwordstore/Application.kt +++ b/app/src/main/java/app/passwordstore/Application.kt @@ -147,6 +147,5 @@ class Application : android.app.Application(), SharedPreferences.OnSharedPrefere lateinit var instance: Application var screenWasOff: Boolean = true - var otpLabelFormat: String = "" } } diff --git a/app/src/main/java/app/passwordstore/data/password/FieldItem.kt b/app/src/main/java/app/passwordstore/data/password/FieldItem.kt index 90cb7fda0..7ff8b8a43 100644 --- a/app/src/main/java/app/passwordstore/data/password/FieldItem.kt +++ b/app/src/main/java/app/passwordstore/data/password/FieldItem.kt @@ -7,31 +7,45 @@ package app.passwordstore.data.password import app.passwordstore.data.passfile.Totp -class FieldItem(val key: String, val value: String, val action: ActionType) { +class FieldItem +private constructor( + val type: ItemType, + val label: String, + val value: String, + val action: ActionType, +) { enum class ActionType { COPY, HIDE, } - enum class ItemType(val type: String, val label: String) { - USERNAME("Username", "User ID"), - PASSWORD("Password", "Password"), - OTP("OTP", "OTP (expires in %ds)"), + enum class ItemType() { + USERNAME, + PASSWORD, + OTP, + FREEFORM, } companion object { + fun createOtpField(label: String, totp: Totp): FieldItem { + return FieldItem( + ItemType.OTP, + label.format(totp.remainingTime.inWholeSeconds), + totp.value, + ActionType.COPY, + ) + } - // Extra helper methods - fun createOtpField(totp: Totp, label: String): FieldItem { - return FieldItem(label.format(totp.remainingTime.inWholeSeconds), totp.value, ActionType.COPY) + fun createPasswordField(label: String, password: String): FieldItem { + return FieldItem(ItemType.PASSWORD, label, password, ActionType.HIDE) } - fun createPasswordField(password: String, label: String): FieldItem { - return FieldItem(label, password, ActionType.HIDE) + fun createUsernameField(label: String, username: String): FieldItem { + return FieldItem(ItemType.USERNAME, label, username, ActionType.COPY) } - fun createUsernameField(username: String, label: String): FieldItem { - return FieldItem(label, username, ActionType.COPY) + fun createFreeformField(label: String, content: String): FieldItem { + return FieldItem(ItemType.FREEFORM, label, content, ActionType.COPY) } } } diff --git a/app/src/main/java/app/passwordstore/ui/adapters/FieldItemAdapter.kt b/app/src/main/java/app/passwordstore/ui/adapters/FieldItemAdapter.kt index e73f6f404..b98cdcc03 100644 --- a/app/src/main/java/app/passwordstore/ui/adapters/FieldItemAdapter.kt +++ b/app/src/main/java/app/passwordstore/ui/adapters/FieldItemAdapter.kt @@ -12,7 +12,6 @@ import android.view.ViewGroup import androidx.core.content.ContextCompat import androidx.core.content.res.ResourcesCompat import androidx.recyclerview.widget.RecyclerView -import app.passwordstore.Application.Companion.otpLabelFormat import app.passwordstore.R import app.passwordstore.data.passfile.Totp import app.passwordstore.data.password.FieldItem @@ -39,13 +38,13 @@ class FieldItemAdapter( return fieldItemList.size } - fun updateOTPCode(totp: Totp) { + fun updateOTPCode(totp: Totp, labelFormat: String) { var otpItemPosition = -1 fieldItemList = fieldItemList.mapIndexed { position, item -> - if (item.key.startsWith(FieldItem.ItemType.OTP.type, true)) { + if (item.type == FieldItem.ItemType.OTP) { otpItemPosition = position - return@mapIndexed FieldItem.createOtpField(totp, otpLabelFormat) + return@mapIndexed FieldItem.createOtpField(labelFormat, totp) } return@mapIndexed item @@ -59,8 +58,8 @@ class FieldItemAdapter( fun bind(fieldItem: FieldItem, showPassword: Boolean, copyTextToClipboard: (String?) -> Unit) { with(binding) { - itemText.hint = fieldItem.key - itemTextContainer.hint = fieldItem.key + itemText.hint = fieldItem.label + itemTextContainer.hint = fieldItem.label itemText.setText(fieldItem.value) when (fieldItem.action) { @@ -85,7 +84,7 @@ class FieldItemAdapter( } else { null } - if (fieldItem.key == FieldItem.ItemType.PASSWORD.type) { + if (fieldItem.type == FieldItem.ItemType.PASSWORD) { typeface = ResourcesCompat.getFont( binding.root.context, diff --git a/app/src/main/java/app/passwordstore/ui/crypto/DecryptActivity.kt b/app/src/main/java/app/passwordstore/ui/crypto/DecryptActivity.kt index 5d84629e9..e4121258f 100644 --- a/app/src/main/java/app/passwordstore/ui/crypto/DecryptActivity.kt +++ b/app/src/main/java/app/passwordstore/ui/crypto/DecryptActivity.kt @@ -12,7 +12,6 @@ import android.view.MenuItem import androidx.core.content.edit import androidx.fragment.app.setFragmentResultListener import androidx.lifecycle.lifecycleScope -import app.passwordstore.Application.Companion.otpLabelFormat import app.passwordstore.Application.Companion.screenWasOff import app.passwordstore.R import app.passwordstore.crypto.PGPIdentifier @@ -279,28 +278,28 @@ class DecryptActivity : BasePGPActivity() { private suspend fun createPasswordUI(entry: PasswordEntry) = withContext(dispatcherProvider.main()) { + val labelFormat = resources.getString(R.string.otp_label_format) val showPassword = settings.getBoolean(PreferenceKeys.SHOW_PASSWORD, true) invalidateOptionsMenu() val items = arrayListOf() if (!entry.password.isNullOrBlank()) { - items.add(FieldItem.createPasswordField(entry.password!!, getString(R.string.password))) + items.add(FieldItem.createPasswordField(getString(R.string.password), entry.password!!)) if (settings.getBoolean(PreferenceKeys.COPY_ON_DECRYPT, false)) { copyPasswordToClipboard(entry.password) } } - otpLabelFormat = getString(R.string.otp_label_format) if (entry.hasTotp()) { - items.add(FieldItem.createOtpField(entry.totp.first(), otpLabelFormat)) + items.add(FieldItem.createOtpField(labelFormat, entry.totp.first())) } if (!entry.username.isNullOrBlank()) { - items.add(FieldItem.createUsernameField(entry.username!!, getString(R.string.username))) + items.add(FieldItem.createUsernameField(getString(R.string.username), entry.username!!)) } entry.extraContent.forEach { (key, value) -> - items.add(FieldItem(key, value, FieldItem.ActionType.COPY)) + items.add(FieldItem.createFreeformField(key, value)) } val adapter = FieldItemAdapter(items, showPassword) { text -> copyTextToClipboard(text) } @@ -308,7 +307,7 @@ class DecryptActivity : BasePGPActivity() { binding.recyclerView.itemAnimator = null if (entry.hasTotp()) { - lifecycleScope.launch { entry.totp.collect(adapter::updateOTPCode) } + lifecycleScope.launch { entry.totp.collect { adapter.updateOTPCode(it, labelFormat) } } } }