From 2bfb9b048da96a129be541516682c9bc76197700 Mon Sep 17 00:00:00 2001 From: J-Jamet Date: Thu, 14 Jan 2021 13:23:35 +0100 Subject: [PATCH] Better entry visualisation --- .../keepass/activities/EntryActivity.kt | 100 ++++++++---------- .../keepass/database/element/Entry.kt | 8 +- .../com/kunzisoft/keepass/model/EntryInfo.kt | 6 ++ .../keepass/view/EntryContentsView.kt | 22 ++-- .../main/res/layout/view_entry_contents.xml | 6 -- 5 files changed, 61 insertions(+), 81 deletions(-) diff --git a/app/src/main/java/com/kunzisoft/keepass/activities/EntryActivity.kt b/app/src/main/java/com/kunzisoft/keepass/activities/EntryActivity.kt index 10005f94a..7da549d96 100644 --- a/app/src/main/java/com/kunzisoft/keepass/activities/EntryActivity.kt +++ b/app/src/main/java/com/kunzisoft/keepass/activities/EntryActivity.kt @@ -56,6 +56,7 @@ import com.kunzisoft.keepass.notifications.ClipboardEntryNotificationService import com.kunzisoft.keepass.notifications.DatabaseTaskNotificationService.Companion.ACTION_DATABASE_DELETE_ENTRY_HISTORY import com.kunzisoft.keepass.notifications.DatabaseTaskNotificationService.Companion.ACTION_DATABASE_RELOAD_TASK import com.kunzisoft.keepass.notifications.DatabaseTaskNotificationService.Companion.ACTION_DATABASE_RESTORE_ENTRY_HISTORY +import com.kunzisoft.keepass.otp.OtpEntryFields import com.kunzisoft.keepass.settings.PreferencesUtil import com.kunzisoft.keepass.tasks.AttachmentFileBinderManager import com.kunzisoft.keepass.timeout.ClipboardHelper @@ -205,8 +206,7 @@ class EntryActivity : LockingActivity() { // Refresh Menu invalidateOptionsMenu() - val entryInfo = entry.getEntryInfo(Database.getInstance()) - + val entryInfo = entry.getEntryInfo(mDatabase) // Manage entry copy to start notification if allowed if (mFirstLaunchOfActivity) { // Manage entry to launch copying notification if allowed @@ -238,23 +238,21 @@ class EntryActivity : LockingActivity() { private fun fillEntryDataInContentsView(entry: Entry) { - val database = Database.getInstance() - database.startManageEntry(entry) + val entryInfo = entry.getEntryInfo(mDatabase) + // Assign title icon - titleIconView?.assignDatabaseIcon(database.drawFactory, entry.icon, iconColor) + titleIconView?.assignDatabaseIcon(mDatabase!!.drawFactory, entryInfo.icon, iconColor) // Assign title text - val entryTitle = entry.title + val entryTitle = entryInfo.title collapsingToolbarLayout?.title = entryTitle toolbar?.title = entryTitle // Assign basic fields - entryContentsView?.assignUserName(entry.username) { - database.startManageEntry(entry) - clipboardHelper?.timeoutCopyToClipboard(entry.username, + entryContentsView?.assignUserName(entryInfo.username) { + clipboardHelper?.timeoutCopyToClipboard(entryInfo.username, getString(R.string.copy_field, getString(R.string.entry_user_name))) - database.stopManageEntry(entry) } val isFirstTimeAskAllowCopyPasswordAndProtectedFields = @@ -284,11 +282,9 @@ class EntryActivity : LockingActivity() { val onPasswordCopyClickListener: View.OnClickListener? = if (allowCopyPasswordAndProtectedFields) { View.OnClickListener { - database.startManageEntry(entry) - clipboardHelper?.timeoutCopyToClipboard(entry.password, + clipboardHelper?.timeoutCopyToClipboard(entryInfo.password, getString(R.string.copy_field, getString(R.string.entry_password))) - database.stopManageEntry(entry) } } else { // If dialog not already shown @@ -298,44 +294,46 @@ class EntryActivity : LockingActivity() { null } } - entryContentsView?.assignPassword(entry.password, + entryContentsView?.assignPassword(entryInfo.password, allowCopyPasswordAndProtectedFields, onPasswordCopyClickListener) //Assign OTP field - entryContentsView?.assignOtp(entry.getOtpElement(), entryProgress, - View.OnClickListener { - entry.getOtpElement()?.let { otpElement -> - clipboardHelper?.timeoutCopyToClipboard( - otpElement.token, - getString(R.string.copy_field, getString(R.string.entry_otp)) - ) - } - }) + entry.getOtpElement()?.let { otpElement -> + entryContentsView?.assignOtp(otpElement, entryProgress) { + clipboardHelper?.timeoutCopyToClipboard( + otpElement.token, + getString(R.string.copy_field, getString(R.string.entry_otp)) + ) + } + } - entryContentsView?.assignURL(entry.url) - entryContentsView?.assignNotes(entry.notes) + entryContentsView?.assignURL(entryInfo.url) + entryContentsView?.assignNotes(entryInfo.notes) // Assign custom fields if (mDatabase?.allowEntryCustomFields() == true) { entryContentsView?.clearExtraFields() - entry.getExtraFields().forEach { field -> + entryInfo.customFields.forEach { field -> val label = field.name - val value = field.protectedValue - val allowCopyProtectedField = !value.isProtected || allowCopyPasswordAndProtectedFields - if (allowCopyProtectedField) { - entryContentsView?.addExtraField(label, value, allowCopyProtectedField) { - clipboardHelper?.timeoutCopyToClipboard( - value.toString(), - getString(R.string.copy_field, label) - ) - } - } else { - // If dialog not already shown - if (isFirstTimeAskAllowCopyPasswordAndProtectedFields) { - entryContentsView?.addExtraField(label, value, allowCopyProtectedField, showWarningClipboardDialogOnClickListener) + // OTP field is already managed in dedicated view + if (label != OtpEntryFields.OTP_TOKEN_FIELD) { + val value = field.protectedValue + val allowCopyProtectedField = !value.isProtected || allowCopyPasswordAndProtectedFields + if (allowCopyProtectedField) { + entryContentsView?.addExtraField(label, value, allowCopyProtectedField) { + clipboardHelper?.timeoutCopyToClipboard( + value.toString(), + getString(R.string.copy_field, label) + ) + } } else { - entryContentsView?.addExtraField(label, value, allowCopyProtectedField, null) + // If dialog not already shown + if (isFirstTimeAskAllowCopyPasswordAndProtectedFields) { + entryContentsView?.addExtraField(label, value, allowCopyProtectedField, showWarningClipboardDialogOnClickListener) + } else { + entryContentsView?.addExtraField(label, value, allowCopyProtectedField, null) + } } } } @@ -343,24 +341,16 @@ class EntryActivity : LockingActivity() { entryContentsView?.setHiddenProtectedValue(!mShowPassword) // Manage attachments - mDatabase?.binaryPool?.let { binaryPool -> - entryContentsView?.assignAttachments(entry.getAttachments(binaryPool).toSet(), StreamDirection.DOWNLOAD) { attachmentItem -> - createDocument(this, attachmentItem.name)?.let { requestCode -> - mAttachmentsToDownload[requestCode] = attachmentItem - } + entryContentsView?.assignAttachments(entryInfo.attachments.toSet(), StreamDirection.DOWNLOAD) { attachmentItem -> + createDocument(this, attachmentItem.name)?.let { requestCode -> + mAttachmentsToDownload[requestCode] = attachmentItem } } // Assign dates - entryContentsView?.assignCreationDate(entry.creationTime) - entryContentsView?.assignModificationDate(entry.lastModificationTime) - entryContentsView?.assignLastAccessDate(entry.lastAccessTime) - entryContentsView?.setExpires(entry.isCurrentlyExpires) - if (entry.expires) { - entryContentsView?.assignExpiresDate(entry.expiryTime) - } else { - entryContentsView?.assignExpiresDate(getString(R.string.never)) - } + entryContentsView?.assignCreationDate(entryInfo.creationTime) + entryContentsView?.assignModificationDate(entryInfo.modificationTime) + entryContentsView?.setExpires(entryInfo.expires, entryInfo.expiryTime) // Manage history historyView?.visibility = if (mIsHistory) View.VISIBLE else View.GONE @@ -375,8 +365,6 @@ class EntryActivity : LockingActivity() { // Assign special data entryContentsView?.assignUUID(entry.nodeId.id) - - database.stopManageEntry(entry) } override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { diff --git a/app/src/main/java/com/kunzisoft/keepass/database/element/Entry.kt b/app/src/main/java/com/kunzisoft/keepass/database/element/Entry.kt index 7733af0a7..b985fbe38 100644 --- a/app/src/main/java/com/kunzisoft/keepass/database/element/Entry.kt +++ b/app/src/main/java/com/kunzisoft/keepass/database/element/Entry.kt @@ -426,6 +426,8 @@ class Entry : Node, EntryVersionedInterface { entryInfo.icon = icon entryInfo.username = username entryInfo.password = password + entryInfo.creationTime = creationTime + entryInfo.modificationTime = lastModificationTime entryInfo.expires = expires entryInfo.expiryTime = expiryTime entryInfo.url = url @@ -456,6 +458,9 @@ class Entry : Node, EntryVersionedInterface { icon = newEntryInfo.icon username = newEntryInfo.username password = newEntryInfo.password + // Update date time, creation time stay as is + lastModificationTime = DateInstant() + lastAccessTime = DateInstant() expires = newEntryInfo.expires expiryTime = newEntryInfo.expiryTime url = newEntryInfo.url @@ -464,9 +469,6 @@ class Entry : Node, EntryVersionedInterface { database?.binaryPool?.let { binaryPool -> addAttachments(binaryPool, newEntryInfo.attachments) } - // Update date time - lastAccessTime = DateInstant() - lastModificationTime = DateInstant() database?.stopManageEntry(this) } diff --git a/app/src/main/java/com/kunzisoft/keepass/model/EntryInfo.kt b/app/src/main/java/com/kunzisoft/keepass/model/EntryInfo.kt index 4d945e873..73f2ab8f2 100644 --- a/app/src/main/java/com/kunzisoft/keepass/model/EntryInfo.kt +++ b/app/src/main/java/com/kunzisoft/keepass/model/EntryInfo.kt @@ -39,6 +39,8 @@ class EntryInfo : Parcelable { var icon: IconImage = IconImageStandard() var username: String = "" var password: String = "" + var creationTime: DateInstant = DateInstant() + var modificationTime: DateInstant = DateInstant() var expires: Boolean = false var expiryTime: DateInstant = DateInstant.IN_ONE_MONTH var url: String = "" @@ -55,6 +57,8 @@ class EntryInfo : Parcelable { icon = parcel.readParcelable(IconImage::class.java.classLoader) ?: icon username = parcel.readString() ?: username password = parcel.readString() ?: password + creationTime = parcel.readParcelable(DateInstant::class.java.classLoader) ?: creationTime + modificationTime = parcel.readParcelable(DateInstant::class.java.classLoader) ?: modificationTime expires = parcel.readInt() != 0 expiryTime = parcel.readParcelable(DateInstant::class.java.classLoader) ?: expiryTime url = parcel.readString() ?: url @@ -74,6 +78,8 @@ class EntryInfo : Parcelable { parcel.writeParcelable(icon, flags) parcel.writeString(username) parcel.writeString(password) + parcel.writeParcelable(creationTime, flags) + parcel.writeParcelable(modificationTime, flags) parcel.writeInt(if (expires) 1 else 0) parcel.writeParcelable(expiryTime, flags) parcel.writeString(url) diff --git a/app/src/main/java/com/kunzisoft/keepass/view/EntryContentsView.kt b/app/src/main/java/com/kunzisoft/keepass/view/EntryContentsView.kt index e0d3767dc..e54399b2a 100644 --- a/app/src/main/java/com/kunzisoft/keepass/view/EntryContentsView.kt +++ b/app/src/main/java/com/kunzisoft/keepass/view/EntryContentsView.kt @@ -67,7 +67,6 @@ class EntryContentsView @JvmOverloads constructor(context: Context, private val creationDateView: TextView private val modificationDateView: TextView - private val lastAccessDateView: TextView private val expiresImageView: ImageView private val expiresDateView: TextView @@ -117,7 +116,6 @@ class EntryContentsView @JvmOverloads constructor(context: Context, creationDateView = findViewById(R.id.entry_created) modificationDateView = findViewById(R.id.entry_modified) - lastAccessDateView = findViewById(R.id.entry_accessed) expiresImageView = findViewById(R.id.entry_expires_image) expiresDateView = findViewById(R.id.entry_expires_date) @@ -258,20 +256,13 @@ class EntryContentsView @JvmOverloads constructor(context: Context, modificationDateView.text = date.getDateTimeString(resources) } - fun assignLastAccessDate(date: DateInstant) { - lastAccessDateView.text = date.getDateTimeString(resources) - } - - fun setExpires(isExpires: Boolean) { + fun setExpires(isExpires: Boolean, expiryTime: DateInstant) { expiresImageView.visibility = if (isExpires) View.VISIBLE else View.GONE - } - - fun assignExpiresDate(date: DateInstant) { - assignExpiresDate(date.getDateTimeString(resources)) - } - - fun assignExpiresDate(constString: String) { - expiresDateView.text = constString + expiresDateView.text = if (isExpires) { + expiryTime.getDateTimeString(resources) + } else { + resources.getString(R.string.never) + } } fun assignUUID(uuid: UUID) { @@ -279,7 +270,6 @@ class EntryContentsView @JvmOverloads constructor(context: Context, uuidReferenceView.text = UuidUtil.toHexString(uuid) } - fun setHiddenProtectedValue(hiddenProtectedValue: Boolean) { passwordFieldView.hiddenProtectedValue = hiddenProtectedValue // Hidden style for custom fields diff --git a/app/src/main/res/layout/view_entry_contents.xml b/app/src/main/res/layout/view_entry_contents.xml index c5922f214..48164dfa5 100644 --- a/app/src/main/res/layout/view_entry_contents.xml +++ b/app/src/main/res/layout/view_entry_contents.xml @@ -175,12 +175,6 @@ android:layout_height="wrap_content" android:text="@string/entry_accessed" style="@style/KeepassDXStyle.TextAppearance.LabelTextStyle" /> -