Skip to content
This repository has been archived by the owner on Oct 15, 2024. It is now read-only.

Commit

Permalink
refactor: rework FieldItem to drop hard-coded strings
Browse files Browse the repository at this point in the history
  • Loading branch information
msfjarvis committed Aug 11, 2024
1 parent 9cd09e8 commit 287f7e9
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 27 deletions.
1 change: 0 additions & 1 deletion app/src/main/java/app/passwordstore/Application.kt
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,5 @@ class Application : android.app.Application(), SharedPreferences.OnSharedPrefere

lateinit var instance: Application
var screenWasOff: Boolean = true
var otpLabelFormat: String = ""
}
}
38 changes: 26 additions & 12 deletions app/src/main/java/app/passwordstore/data/password/FieldItem.kt
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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) {
Expand All @@ -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,
Expand Down
13 changes: 6 additions & 7 deletions app/src/main/java/app/passwordstore/ui/crypto/DecryptActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -279,36 +278,36 @@ 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<FieldItem>()
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) }
binding.recyclerView.adapter = adapter
binding.recyclerView.itemAnimator = null

if (entry.hasTotp()) {
lifecycleScope.launch { entry.totp.collect(adapter::updateOTPCode) }
lifecycleScope.launch { entry.totp.collect { adapter.updateOTPCode(it, labelFormat) } }
}
}

Expand Down

0 comments on commit 287f7e9

Please sign in to comment.