mirror of
https://github.com/Kunzisoft/KeePassDX.git
synced 2025-12-04 15:49:33 +01:00
fix: Add ProtectedFieldView callback #2283
This commit is contained in:
@@ -63,6 +63,8 @@ import com.kunzisoft.keepass.credentialprovider.EntrySelectionHelper.buildSpecia
|
|||||||
import com.kunzisoft.keepass.credentialprovider.EntrySelectionHelper.retrieveRegisterInfo
|
import com.kunzisoft.keepass.credentialprovider.EntrySelectionHelper.retrieveRegisterInfo
|
||||||
import com.kunzisoft.keepass.credentialprovider.EntrySelectionHelper.retrieveSearchInfo
|
import com.kunzisoft.keepass.credentialprovider.EntrySelectionHelper.retrieveSearchInfo
|
||||||
import com.kunzisoft.keepass.credentialprovider.TypeMode
|
import com.kunzisoft.keepass.credentialprovider.TypeMode
|
||||||
|
import com.kunzisoft.keepass.credentialprovider.UserVerificationData
|
||||||
|
import com.kunzisoft.keepass.credentialprovider.UserVerificationHelper.Companion.checkUserVerification
|
||||||
import com.kunzisoft.keepass.credentialprovider.passkey.util.PasskeyHelper.buildPasskeyResponseAndSetResult
|
import com.kunzisoft.keepass.credentialprovider.passkey.util.PasskeyHelper.buildPasskeyResponseAndSetResult
|
||||||
import com.kunzisoft.keepass.database.ContextualDatabase
|
import com.kunzisoft.keepass.database.ContextualDatabase
|
||||||
import com.kunzisoft.keepass.database.element.Attachment
|
import com.kunzisoft.keepass.database.element.Attachment
|
||||||
@@ -101,6 +103,7 @@ import com.kunzisoft.keepass.view.showActionErrorIfNeeded
|
|||||||
import com.kunzisoft.keepass.view.updateLockPaddingStart
|
import com.kunzisoft.keepass.view.updateLockPaddingStart
|
||||||
import com.kunzisoft.keepass.viewmodels.ColorPickerViewModel
|
import com.kunzisoft.keepass.viewmodels.ColorPickerViewModel
|
||||||
import com.kunzisoft.keepass.viewmodels.EntryEditViewModel
|
import com.kunzisoft.keepass.viewmodels.EntryEditViewModel
|
||||||
|
import com.kunzisoft.keepass.viewmodels.UserVerificationViewModel
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import java.util.EnumSet
|
import java.util.EnumSet
|
||||||
import java.util.UUID
|
import java.util.UUID
|
||||||
@@ -129,6 +132,7 @@ class EntryEditActivity : DatabaseLockActivity(),
|
|||||||
private var mTemplatesSelectorAdapter: TemplatesSelectorAdapter? = null
|
private var mTemplatesSelectorAdapter: TemplatesSelectorAdapter? = null
|
||||||
|
|
||||||
private val mColorPickerViewModel: ColorPickerViewModel by viewModels()
|
private val mColorPickerViewModel: ColorPickerViewModel by viewModels()
|
||||||
|
private val mUserVerificationViewModel: UserVerificationViewModel by viewModels()
|
||||||
|
|
||||||
private var mAllowCustomFields = false
|
private var mAllowCustomFields = false
|
||||||
private var mAllowOTP = false
|
private var mAllowOTP = false
|
||||||
@@ -383,23 +387,48 @@ class EntryEditActivity : DatabaseLockActivity(),
|
|||||||
|
|
||||||
lifecycleScope.launch {
|
lifecycleScope.launch {
|
||||||
repeatOnLifecycle(Lifecycle.State.STARTED) {
|
repeatOnLifecycle(Lifecycle.State.STARTED) {
|
||||||
mEntryEditViewModel.uiState.collect { uiState ->
|
mEntryEditViewModel.entryEditState.collect { uiState ->
|
||||||
when (uiState) {
|
when (uiState) {
|
||||||
EntryEditViewModel.UIState.Loading -> {}
|
is EntryEditViewModel.EntryEditState.Loading -> {}
|
||||||
EntryEditViewModel.UIState.ShowOverwriteMessage -> {
|
is EntryEditViewModel.EntryEditState.ShowOverwriteMessage -> {
|
||||||
if (mEntryEditViewModel.warningOverwriteDataAlreadyApproved.not()) {
|
AlertDialog.Builder(this@EntryEditActivity)
|
||||||
AlertDialog.Builder(this@EntryEditActivity)
|
.setTitle(R.string.warning_overwrite_data_title)
|
||||||
.setTitle(R.string.warning_overwrite_data_title)
|
.setMessage(R.string.warning_overwrite_data_description)
|
||||||
.setMessage(R.string.warning_overwrite_data_description)
|
.setNegativeButton(android.R.string.cancel) { _, _ ->
|
||||||
.setNegativeButton(android.R.string.cancel) { _, _ ->
|
mEntryEditViewModel.backPressedAlreadyApproved = true
|
||||||
mEntryEditViewModel.backPressedAlreadyApproved = true
|
onCancelSpecialMode()
|
||||||
onCancelSpecialMode()
|
}
|
||||||
}
|
.setPositiveButton(android.R.string.ok) { _, _ -> }
|
||||||
.setPositiveButton(android.R.string.ok) { _, _ ->
|
.create().show()
|
||||||
mEntryEditViewModel.warningOverwriteDataAlreadyApproved = true
|
mEntryEditViewModel.actionPerformed()
|
||||||
}
|
}
|
||||||
.create().show()
|
is EntryEditViewModel.EntryEditState.RequestUnprotectField -> {
|
||||||
|
val fieldView = uiState.protectedFieldView
|
||||||
|
if (fieldView.isCurrentlyProtected()) {
|
||||||
|
checkUserVerification(
|
||||||
|
userVerificationViewModel = mUserVerificationViewModel,
|
||||||
|
dataToVerify = UserVerificationData(protectedFieldView = fieldView)
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
fieldView.protect()
|
||||||
}
|
}
|
||||||
|
mEntryEditViewModel.actionPerformed()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
lifecycleScope.launch {
|
||||||
|
repeatOnLifecycle(Lifecycle.State.STARTED) {
|
||||||
|
mUserVerificationViewModel.userVerificationState.collect { uVState ->
|
||||||
|
when (uVState) {
|
||||||
|
is UserVerificationViewModel.UIState.Loading -> {}
|
||||||
|
is UserVerificationViewModel.UIState.OnUserVerificationCanceled -> {
|
||||||
|
mUserVerificationViewModel.onUserVerificationReceived()
|
||||||
|
}
|
||||||
|
is UserVerificationViewModel.UIState.OnUserVerificationSucceeded -> {
|
||||||
|
uVState.dataToVerify.protectedFieldView?.unprotect()
|
||||||
|
mUserVerificationViewModel.onUserVerificationReceived()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -116,6 +116,9 @@ class EntryEditFragment: DatabaseFragment() {
|
|||||||
setOnForegroundColorClickListener {
|
setOnForegroundColorClickListener {
|
||||||
mEntryEditViewModel.requestForegroundColorSelection(templateView.getForegroundColor())
|
mEntryEditViewModel.requestForegroundColorSelection(templateView.getForegroundColor())
|
||||||
}
|
}
|
||||||
|
setOnUnprotectClickListener { _, textEditFieldView ->
|
||||||
|
mEntryEditViewModel.requestUnprotectField(textEditFieldView)
|
||||||
|
}
|
||||||
setOnCustomEditionActionClickListener { field ->
|
setOnCustomEditionActionClickListener { field ->
|
||||||
mEntryEditViewModel.requestCustomFieldEdition(field)
|
mEntryEditViewModel.requestCustomFieldEdition(field)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,9 +2,11 @@ package com.kunzisoft.keepass.credentialprovider
|
|||||||
|
|
||||||
import com.kunzisoft.keepass.database.ContextualDatabase
|
import com.kunzisoft.keepass.database.ContextualDatabase
|
||||||
import com.kunzisoft.keepass.database.element.node.NodeId
|
import com.kunzisoft.keepass.database.element.node.NodeId
|
||||||
|
import com.kunzisoft.keepass.view.ProtectedFieldView
|
||||||
|
|
||||||
data class UserVerificationData(
|
data class UserVerificationData(
|
||||||
val database: ContextualDatabase? = null,
|
val database: ContextualDatabase? = null,
|
||||||
val entryId: NodeId<*>? = null,
|
val entryId: NodeId<*>? = null,
|
||||||
|
val protectedFieldView: ProtectedFieldView? = null,
|
||||||
val preferenceKey: String? = null
|
val preferenceKey: String? = null
|
||||||
)
|
)
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
package com.kunzisoft.keepass.view
|
||||||
|
|
||||||
|
import android.view.View.OnClickListener
|
||||||
|
|
||||||
|
interface ProtectedFieldView {
|
||||||
|
fun setOnUnprotectClickListener(onUnprotectClickListener: OnClickListener?)
|
||||||
|
fun protect()
|
||||||
|
fun unprotect()
|
||||||
|
fun isCurrentlyProtected(): Boolean
|
||||||
|
}
|
||||||
@@ -18,9 +18,9 @@ import com.kunzisoft.keepass.database.element.template.TemplateAttributeAction
|
|||||||
import com.kunzisoft.keepass.database.element.template.TemplateField
|
import com.kunzisoft.keepass.database.element.template.TemplateField
|
||||||
import com.kunzisoft.keepass.database.helper.getLocalizedName
|
import com.kunzisoft.keepass.database.helper.getLocalizedName
|
||||||
import com.kunzisoft.keepass.database.helper.isStandardPasswordName
|
import com.kunzisoft.keepass.database.helper.isStandardPasswordName
|
||||||
|
import com.kunzisoft.keepass.model.AppOriginEntryField
|
||||||
import com.kunzisoft.keepass.model.DataDate
|
import com.kunzisoft.keepass.model.DataDate
|
||||||
import com.kunzisoft.keepass.model.DataTime
|
import com.kunzisoft.keepass.model.DataTime
|
||||||
import com.kunzisoft.keepass.model.AppOriginEntryField
|
|
||||||
import com.kunzisoft.keepass.model.PasskeyEntryFields
|
import com.kunzisoft.keepass.model.PasskeyEntryFields
|
||||||
import com.kunzisoft.keepass.otp.OtpEntryFields
|
import com.kunzisoft.keepass.otp.OtpEntryFields
|
||||||
|
|
||||||
@@ -35,6 +35,11 @@ class TemplateEditView @JvmOverloads constructor(context: Context,
|
|||||||
@IdRes
|
@IdRes
|
||||||
private var mTempDateTimeViewId: Int? = null
|
private var mTempDateTimeViewId: Int? = null
|
||||||
|
|
||||||
|
private var mOnUnprotectClickListener: ((Field, ProtectedFieldView) -> Unit)? = null
|
||||||
|
fun setOnUnprotectClickListener(listener: ((Field, ProtectedFieldView) -> Unit)?) {
|
||||||
|
this.mOnUnprotectClickListener = listener
|
||||||
|
}
|
||||||
|
|
||||||
private var mOnCustomEditionActionClickListener: ((Field) -> Unit)? = null
|
private var mOnCustomEditionActionClickListener: ((Field) -> Unit)? = null
|
||||||
fun setOnCustomEditionActionClickListener(listener: ((Field) -> Unit)?) {
|
fun setOnCustomEditionActionClickListener(listener: ((Field) -> Unit)?) {
|
||||||
this.mOnCustomEditionActionClickListener = listener
|
this.mOnCustomEditionActionClickListener = listener
|
||||||
@@ -80,9 +85,9 @@ class TemplateEditView @JvmOverloads constructor(context: Context,
|
|||||||
if (color != null) {
|
if (color != null) {
|
||||||
backgroundColorView.background.colorFilter = BlendModeColorFilterCompat
|
backgroundColorView.background.colorFilter = BlendModeColorFilterCompat
|
||||||
.createBlendModeColorFilterCompat(color, BlendModeCompat.SRC_ATOP)
|
.createBlendModeColorFilterCompat(color, BlendModeCompat.SRC_ATOP)
|
||||||
backgroundColorView.visibility = View.VISIBLE
|
backgroundColorView.visibility = VISIBLE
|
||||||
} else {
|
} else {
|
||||||
backgroundColorView.visibility = View.GONE
|
backgroundColorView.visibility = GONE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -103,9 +108,9 @@ class TemplateEditView @JvmOverloads constructor(context: Context,
|
|||||||
if (color != null) {
|
if (color != null) {
|
||||||
foregroundColorView.background.colorFilter = BlendModeColorFilterCompat
|
foregroundColorView.background.colorFilter = BlendModeColorFilterCompat
|
||||||
.createBlendModeColorFilterCompat(color, BlendModeCompat.SRC_ATOP)
|
.createBlendModeColorFilterCompat(color, BlendModeCompat.SRC_ATOP)
|
||||||
foregroundColorView.visibility = View.VISIBLE
|
foregroundColorView.visibility = VISIBLE
|
||||||
} else {
|
} else {
|
||||||
foregroundColorView.visibility = View.GONE
|
foregroundColorView.visibility = GONE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -113,14 +118,20 @@ class TemplateEditView @JvmOverloads constructor(context: Context,
|
|||||||
headerContainerView.isVisible = true
|
headerContainerView.isVisible = true
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun buildLinearTextView(templateAttribute: TemplateAttribute,
|
override fun buildLinearTextView(
|
||||||
field: Field): TextEditFieldView? {
|
templateAttribute: TemplateAttribute,
|
||||||
|
field: Field
|
||||||
|
): TextEditFieldView? {
|
||||||
return context?.let {
|
return context?.let {
|
||||||
(if (TemplateField.isStandardPasswordName(context, templateAttribute.label))
|
(if (TemplateField.isStandardPasswordName(context, templateAttribute.label))
|
||||||
PasswordTextEditFieldView(it)
|
PasswordTextEditFieldView(it)
|
||||||
else TextEditFieldView(it)).apply {
|
else TextEditFieldView(it)).apply {
|
||||||
// hiddenProtectedValue (mHideProtectedValue) don't work with TextInputLayout
|
// hiddenProtectedValue (mHideProtectedValue) don't work with TextInputLayout
|
||||||
setProtection(field.protectedValue.isProtected)
|
if (field.protectedValue.isProtected) {
|
||||||
|
setOnUnprotectClickListener {
|
||||||
|
mOnUnprotectClickListener?.invoke(field, this)
|
||||||
|
}
|
||||||
|
}
|
||||||
default = templateAttribute.default
|
default = templateAttribute.default
|
||||||
setMaxChars(templateAttribute.options.getNumberChars())
|
setMaxChars(templateAttribute.options.getNumberChars())
|
||||||
setMaxLines(templateAttribute.options.getNumberLines())
|
setMaxLines(templateAttribute.options.getNumberLines())
|
||||||
@@ -129,7 +140,7 @@ class TemplateEditView @JvmOverloads constructor(context: Context,
|
|||||||
textDirection = TEXT_DIRECTION_LTR
|
textDirection = TEXT_DIRECTION_LTR
|
||||||
}
|
}
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||||
importantForAutofill = View.IMPORTANT_FOR_AUTOFILL_NO
|
importantForAutofill = IMPORTANT_FOR_AUTOFILL_NO
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -143,7 +154,7 @@ class TemplateEditView @JvmOverloads constructor(context: Context,
|
|||||||
default = templateAttribute.default
|
default = templateAttribute.default
|
||||||
setActionClick(templateAttribute, field, this)
|
setActionClick(templateAttribute, field, this)
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||||
importantForAutofill = View.IMPORTANT_FOR_AUTOFILL_NO
|
importantForAutofill = IMPORTANT_FOR_AUTOFILL_NO
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -157,7 +168,7 @@ class TemplateEditView @JvmOverloads constructor(context: Context,
|
|||||||
label = templateAttribute.alias
|
label = templateAttribute.alias
|
||||||
?: TemplateField.getLocalizedName(context, field.name)
|
?: TemplateField.getLocalizedName(context, field.name)
|
||||||
val fieldValue = field.protectedValue.stringValue
|
val fieldValue = field.protectedValue.stringValue
|
||||||
value = if (fieldValue.isEmpty()) templateAttribute.default else fieldValue
|
value = fieldValue.ifEmpty { templateAttribute.default }
|
||||||
// TODO edition and password generator at same time
|
// TODO edition and password generator at same time
|
||||||
when (templateAttribute.action) {
|
when (templateAttribute.action) {
|
||||||
TemplateAttributeAction.NONE -> {
|
TemplateAttributeAction.NONE -> {
|
||||||
|
|||||||
@@ -6,6 +6,8 @@ import android.text.InputFilter
|
|||||||
import android.text.InputType
|
import android.text.InputType
|
||||||
import android.text.Spannable
|
import android.text.Spannable
|
||||||
import android.text.SpannableString
|
import android.text.SpannableString
|
||||||
|
import android.text.method.PasswordTransformationMethod
|
||||||
|
import android.text.method.SingleLineTransformationMethod
|
||||||
import android.util.AttributeSet
|
import android.util.AttributeSet
|
||||||
import android.util.TypedValue
|
import android.util.TypedValue
|
||||||
import android.view.View
|
import android.view.View
|
||||||
@@ -25,7 +27,8 @@ import com.kunzisoft.keepass.R
|
|||||||
open class TextEditFieldView @JvmOverloads constructor(context: Context,
|
open class TextEditFieldView @JvmOverloads constructor(context: Context,
|
||||||
attrs: AttributeSet? = null,
|
attrs: AttributeSet? = null,
|
||||||
defStyle: Int = 0)
|
defStyle: Int = 0)
|
||||||
: RelativeLayout(context, attrs, defStyle), GenericTextFieldView {
|
: RelativeLayout(context, attrs, defStyle),
|
||||||
|
GenericTextFieldView, ProtectedFieldView {
|
||||||
|
|
||||||
private var labelViewId = ViewCompat.generateViewId()
|
private var labelViewId = ViewCompat.generateViewId()
|
||||||
private var valueViewId = ViewCompat.generateViewId()
|
private var valueViewId = ViewCompat.generateViewId()
|
||||||
@@ -168,11 +171,28 @@ open class TextEditFieldView @JvmOverloads constructor(context: Context,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun setProtection(protection: Boolean) {
|
override fun setOnUnprotectClickListener(onUnprotectClickListener: OnClickListener?) {
|
||||||
if (protection) {
|
labelView.endIconMode = TextInputLayout.END_ICON_PASSWORD_TOGGLE
|
||||||
labelView.endIconMode = TextInputLayout.END_ICON_PASSWORD_TOGGLE
|
valueView.inputType = valueView.inputType or InputType.TYPE_TEXT_VARIATION_PASSWORD
|
||||||
valueView.inputType = valueView.inputType or InputType.TYPE_TEXT_VARIATION_PASSWORD
|
/*
|
||||||
}
|
// FIXME Called by itself during orientation change
|
||||||
|
labelView.setEndIconOnClickListener {
|
||||||
|
onUnprotectClickListener?.onClick(this@TextEditFieldView)
|
||||||
|
}*/
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun isCurrentlyProtected(): Boolean {
|
||||||
|
return valueView.transformationMethod == PasswordTransformationMethod.getInstance()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun protect() {
|
||||||
|
valueView.inputType = valueView.inputType or InputType.TYPE_TEXT_VARIATION_PASSWORD
|
||||||
|
valueView.transformationMethod = PasswordTransformationMethod.getInstance()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun unprotect() {
|
||||||
|
valueView.inputType = valueView.inputType or InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD
|
||||||
|
valueView.transformationMethod = SingleLineTransformationMethod.getInstance()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun setOnActionClickListener(onActionClickListener: OnClickListener?,
|
override fun setOnActionClickListener(onActionClickListener: OnClickListener?,
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ import com.kunzisoft.keepass.model.RegisterInfo
|
|||||||
import com.kunzisoft.keepass.model.StreamDirection
|
import com.kunzisoft.keepass.model.StreamDirection
|
||||||
import com.kunzisoft.keepass.otp.OtpElement
|
import com.kunzisoft.keepass.otp.OtpElement
|
||||||
import com.kunzisoft.keepass.utils.IOActionTask
|
import com.kunzisoft.keepass.utils.IOActionTask
|
||||||
|
import com.kunzisoft.keepass.view.ProtectedFieldView
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
import kotlinx.coroutines.flow.StateFlow
|
import kotlinx.coroutines.flow.StateFlow
|
||||||
import java.util.UUID
|
import java.util.UUID
|
||||||
@@ -37,7 +38,6 @@ class EntryEditViewModel: NodeEditViewModel() {
|
|||||||
|
|
||||||
// To show dialog only one time
|
// To show dialog only one time
|
||||||
var backPressedAlreadyApproved = false
|
var backPressedAlreadyApproved = false
|
||||||
var warningOverwriteDataAlreadyApproved = false
|
|
||||||
|
|
||||||
// Useful to not relaunch a current action
|
// Useful to not relaunch a current action
|
||||||
private var actionLocked: Boolean = false
|
private var actionLocked: Boolean = false
|
||||||
@@ -81,8 +81,8 @@ class EntryEditViewModel: NodeEditViewModel() {
|
|||||||
val onBinaryPreviewLoaded : LiveData<AttachmentPosition> get() = _onBinaryPreviewLoaded
|
val onBinaryPreviewLoaded : LiveData<AttachmentPosition> get() = _onBinaryPreviewLoaded
|
||||||
private val _onBinaryPreviewLoaded = SingleLiveEvent<AttachmentPosition>()
|
private val _onBinaryPreviewLoaded = SingleLiveEvent<AttachmentPosition>()
|
||||||
|
|
||||||
private val mUiState = MutableStateFlow<UIState>(UIState.Loading)
|
private val mEntryEditState = MutableStateFlow<EntryEditState>(EntryEditState.Loading)
|
||||||
val uiState: StateFlow<UIState> = mUiState
|
val entryEditState: StateFlow<EntryEditState> = mEntryEditState
|
||||||
|
|
||||||
fun loadTemplateEntry(database: ContextualDatabase?) {
|
fun loadTemplateEntry(database: ContextualDatabase?) {
|
||||||
loadTemplateEntry(database, mEntryId, mParentId, mRegisterInfo)
|
loadTemplateEntry(database, mEntryId, mParentId, mRegisterInfo)
|
||||||
@@ -125,7 +125,7 @@ class EntryEditViewModel: NodeEditViewModel() {
|
|||||||
mEntryId = null
|
mEntryId = null
|
||||||
_templatesEntry.value = templatesEntry
|
_templatesEntry.value = templatesEntry
|
||||||
if (templatesEntry?.overwrittenData == true) {
|
if (templatesEntry?.overwrittenData == true) {
|
||||||
mUiState.value = UIState.ShowOverwriteMessage
|
mEntryEditState.value = EntryEditState.ShowOverwriteMessage
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
).execute()
|
).execute()
|
||||||
@@ -293,6 +293,10 @@ class EntryEditViewModel: NodeEditViewModel() {
|
|||||||
_onPasswordSelected.value = passwordField
|
_onPasswordSelected.value = passwordField
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun requestUnprotectField(fieldView: ProtectedFieldView) {
|
||||||
|
mEntryEditState.value = EntryEditState.RequestUnprotectField(fieldView)
|
||||||
|
}
|
||||||
|
|
||||||
fun requestCustomFieldEdition(customField: Field) {
|
fun requestCustomFieldEdition(customField: Field) {
|
||||||
_requestCustomFieldEdition.value = customField
|
_requestCustomFieldEdition.value = customField
|
||||||
}
|
}
|
||||||
@@ -348,6 +352,10 @@ class EntryEditViewModel: NodeEditViewModel() {
|
|||||||
_onBinaryPreviewLoaded.value = AttachmentPosition(entryAttachmentState, viewPosition)
|
_onBinaryPreviewLoaded.value = AttachmentPosition(entryAttachmentState, viewPosition)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun actionPerformed() {
|
||||||
|
mEntryEditState.value = EntryEditState.Loading
|
||||||
|
}
|
||||||
|
|
||||||
data class TemplatesEntry(
|
data class TemplatesEntry(
|
||||||
val isTemplate: Boolean,
|
val isTemplate: Boolean,
|
||||||
val templates: List<Template>,
|
val templates: List<Template>,
|
||||||
@@ -362,9 +370,12 @@ class EntryEditViewModel: NodeEditViewModel() {
|
|||||||
data class AttachmentUpload(val attachmentToUploadUri: Uri, val attachment: Attachment)
|
data class AttachmentUpload(val attachmentToUploadUri: Uri, val attachment: Attachment)
|
||||||
data class AttachmentPosition(val entryAttachmentState: EntryAttachmentState, val viewPosition: Float)
|
data class AttachmentPosition(val entryAttachmentState: EntryAttachmentState, val viewPosition: Float)
|
||||||
|
|
||||||
sealed class UIState {
|
sealed class EntryEditState {
|
||||||
object Loading: UIState()
|
object Loading: EntryEditState()
|
||||||
object ShowOverwriteMessage: UIState()
|
object ShowOverwriteMessage: EntryEditState()
|
||||||
|
data class RequestUnprotectField(
|
||||||
|
val protectedFieldView: ProtectedFieldView
|
||||||
|
): EntryEditState()
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|||||||
Reference in New Issue
Block a user