mirror of
https://github.com/Kunzisoft/KeePassDX.git
synced 2025-12-04 15:49:33 +01:00
Merge branch 'release/4.2.3'
This commit is contained in:
@@ -1,3 +1,9 @@
|
|||||||
|
KeePassDX(4.2.3)
|
||||||
|
* Fix multiple Passkey selection #2253
|
||||||
|
* Fix database dialog subtitle #2254
|
||||||
|
* Fix save search info if URL present #2255
|
||||||
|
* Small fixes
|
||||||
|
|
||||||
KeePassDX(4.2.2)
|
KeePassDX(4.2.2)
|
||||||
* Fix database merge algorithm #2223
|
* Fix database merge algorithm #2223
|
||||||
* Fix save search info #2243
|
* Fix save search info #2243
|
||||||
|
|||||||
@@ -11,8 +11,8 @@ android {
|
|||||||
applicationId "com.kunzisoft.keepass"
|
applicationId "com.kunzisoft.keepass"
|
||||||
minSdkVersion 19
|
minSdkVersion 19
|
||||||
targetSdkVersion 35
|
targetSdkVersion 35
|
||||||
versionCode = 147
|
versionCode = 148
|
||||||
versionName = "4.2.2"
|
versionName = "4.2.3"
|
||||||
multiDexEnabled true
|
multiDexEnabled true
|
||||||
|
|
||||||
testApplicationId = "com.kunzisoft.keepass.tests"
|
testApplicationId = "com.kunzisoft.keepass.tests"
|
||||||
|
|||||||
@@ -841,7 +841,7 @@ class GroupActivity : DatabaseLockActivity(),
|
|||||||
// Open child group
|
// Open child group
|
||||||
loadMainGroup(GroupState(group.nodeId, 0))
|
loadMainGroup(GroupState(group.nodeId, 0))
|
||||||
} catch (e: ClassCastException) {
|
} catch (e: ClassCastException) {
|
||||||
Log.e(TAG, "Node can't be cast in Group")
|
Log.e(TAG, "Node can't be cast in Group", e)
|
||||||
}
|
}
|
||||||
|
|
||||||
Type.ENTRY -> try {
|
Type.ENTRY -> try {
|
||||||
@@ -867,6 +867,7 @@ class GroupActivity : DatabaseLockActivity(),
|
|||||||
if (!database.isReadOnly
|
if (!database.isReadOnly
|
||||||
&& searchInfo != null
|
&& searchInfo != null
|
||||||
&& PreferencesUtil.isKeyboardSaveSearchInfoEnable(this@GroupActivity)
|
&& PreferencesUtil.isKeyboardSaveSearchInfoEnable(this@GroupActivity)
|
||||||
|
&& entryVersioned.containsSearchInfo(database, searchInfo).not()
|
||||||
) {
|
) {
|
||||||
updateEntryWithRegisterInfo(
|
updateEntryWithRegisterInfo(
|
||||||
database,
|
database,
|
||||||
@@ -884,6 +885,7 @@ class GroupActivity : DatabaseLockActivity(),
|
|||||||
if (!database.isReadOnly
|
if (!database.isReadOnly
|
||||||
&& searchInfo != null
|
&& searchInfo != null
|
||||||
&& PreferencesUtil.isAutofillSaveSearchInfoEnable(this@GroupActivity)
|
&& PreferencesUtil.isAutofillSaveSearchInfoEnable(this@GroupActivity)
|
||||||
|
&& entryVersioned.containsSearchInfo(database, searchInfo).not()
|
||||||
) {
|
) {
|
||||||
updateEntryWithRegisterInfo(
|
updateEntryWithRegisterInfo(
|
||||||
database,
|
database,
|
||||||
@@ -912,7 +914,7 @@ class GroupActivity : DatabaseLockActivity(),
|
|||||||
finish()
|
finish()
|
||||||
})
|
})
|
||||||
} catch (e: ClassCastException) {
|
} catch (e: ClassCastException) {
|
||||||
Log.e(TAG, "Node can't be cast in Entry")
|
Log.e(TAG, "Node can't be cast in Entry", e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -981,6 +983,17 @@ class GroupActivity : DatabaseLockActivity(),
|
|||||||
updateEntry(entry, newEntry)
|
updateEntry(entry, newEntry)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun Entry.containsSearchInfo(
|
||||||
|
database: ContextualDatabase,
|
||||||
|
searchInfo: SearchInfo
|
||||||
|
): Boolean {
|
||||||
|
return getEntryInfo(
|
||||||
|
database,
|
||||||
|
raw = true,
|
||||||
|
removeTemplateConfiguration = false
|
||||||
|
).containsSearchInfo(searchInfo)
|
||||||
|
}
|
||||||
|
|
||||||
private fun finishNodeAction() {
|
private fun finishNodeAction() {
|
||||||
actionNodeMode?.finish()
|
actionNodeMode?.finish()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +1,17 @@
|
|||||||
package com.kunzisoft.keepass.activities.legacy
|
package com.kunzisoft.keepass.activities.legacy
|
||||||
|
|
||||||
import android.Manifest
|
import android.Manifest
|
||||||
|
import android.content.Intent
|
||||||
import android.content.pm.PackageManager
|
import android.content.pm.PackageManager
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
|
import androidx.activity.result.ActivityResultLauncher
|
||||||
|
import androidx.activity.result.contract.ActivityResultContract
|
||||||
import androidx.activity.result.contract.ActivityResultContracts
|
import androidx.activity.result.contract.ActivityResultContracts
|
||||||
import androidx.activity.viewModels
|
import androidx.activity.viewModels
|
||||||
import androidx.appcompat.app.AlertDialog
|
import androidx.appcompat.app.AlertDialog
|
||||||
import androidx.core.app.ActivityCompat
|
import androidx.core.app.ActivityCompat
|
||||||
|
import androidx.core.app.ActivityOptionsCompat
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
import androidx.lifecycle.Lifecycle
|
import androidx.lifecycle.Lifecycle
|
||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.lifecycle.lifecycleScope
|
||||||
@@ -16,6 +20,7 @@ import com.kunzisoft.keepass.R
|
|||||||
import com.kunzisoft.keepass.activities.dialogs.DatabaseChangedDialogFragment
|
import com.kunzisoft.keepass.activities.dialogs.DatabaseChangedDialogFragment
|
||||||
import com.kunzisoft.keepass.activities.dialogs.DatabaseChangedDialogFragment.Companion.DATABASE_CHANGED_DIALOG_TAG
|
import com.kunzisoft.keepass.activities.dialogs.DatabaseChangedDialogFragment.Companion.DATABASE_CHANGED_DIALOG_TAG
|
||||||
import com.kunzisoft.keepass.activities.stylish.StylishActivity
|
import com.kunzisoft.keepass.activities.stylish.StylishActivity
|
||||||
|
import com.kunzisoft.keepass.credentialprovider.EntrySelectionHelper.setActivityResult
|
||||||
import com.kunzisoft.keepass.database.ContextualDatabase
|
import com.kunzisoft.keepass.database.ContextualDatabase
|
||||||
import com.kunzisoft.keepass.database.DatabaseTaskProvider.Companion.startDatabaseService
|
import com.kunzisoft.keepass.database.DatabaseTaskProvider.Companion.startDatabaseService
|
||||||
import com.kunzisoft.keepass.model.SnapFileDatabaseInfo
|
import com.kunzisoft.keepass.model.SnapFileDatabaseInfo
|
||||||
@@ -54,13 +59,67 @@ abstract class DatabaseActivity : StylishActivity(), DatabaseRetrieval {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Useful to only waiting for the activity result and prevent any parallel action
|
||||||
|
*/
|
||||||
|
var credentialResultLaunched = false
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Utility activity result launcher,
|
||||||
|
* Used recursively, close each activity with return data
|
||||||
|
*/
|
||||||
|
protected var mCredentialActivityResultLauncher: CredentialActivityResultLauncher =
|
||||||
|
CredentialActivityResultLauncher(
|
||||||
|
registerForActivityResult(
|
||||||
|
ActivityResultContracts.StartActivityForResult()
|
||||||
|
) {
|
||||||
|
setActivityResult(
|
||||||
|
lockDatabase = false,
|
||||||
|
resultCode = it.resultCode,
|
||||||
|
data = it.data
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Custom ActivityResultLauncher to manage the database action
|
||||||
|
*/
|
||||||
|
protected inner class CredentialActivityResultLauncher(
|
||||||
|
val builder: ActivityResultLauncher<Intent>
|
||||||
|
) : ActivityResultLauncher<Intent>() {
|
||||||
|
|
||||||
|
override fun launch(
|
||||||
|
input: Intent?,
|
||||||
|
options: ActivityOptionsCompat?
|
||||||
|
) {
|
||||||
|
credentialResultLaunched = true
|
||||||
|
builder.launch(input, options)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun unregister() {
|
||||||
|
builder.unregister()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getContract(): ActivityResultContract<Intent?, *> {
|
||||||
|
return builder.getContract()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
|
|
||||||
|
if (savedInstanceState != null
|
||||||
|
&& savedInstanceState.containsKey(CREDENTIAL_RESULT_LAUNCHER_KEY)
|
||||||
|
) {
|
||||||
|
credentialResultLaunched = savedInstanceState.getBoolean(CREDENTIAL_RESULT_LAUNCHER_KEY)
|
||||||
|
}
|
||||||
|
|
||||||
lifecycleScope.launch {
|
lifecycleScope.launch {
|
||||||
repeatOnLifecycle(Lifecycle.State.STARTED) {
|
repeatOnLifecycle(Lifecycle.State.STARTED) {
|
||||||
mDatabaseViewModel.actionState.collect { uiState ->
|
mDatabaseViewModel.actionState.collect { uiState ->
|
||||||
|
if (credentialResultLaunched.not()) {
|
||||||
when (uiState) {
|
when (uiState) {
|
||||||
is DatabaseViewModel.ActionState.Loading -> {}
|
is DatabaseViewModel.ActionState.Wait -> {}
|
||||||
is DatabaseViewModel.ActionState.OnDatabaseReloaded -> {
|
is DatabaseViewModel.ActionState.OnDatabaseReloaded -> {
|
||||||
if (finishActivityIfReloadRequested()) {
|
if (finishActivityIfReloadRequested()) {
|
||||||
finish()
|
finish()
|
||||||
@@ -82,13 +141,13 @@ abstract class DatabaseActivity : StylishActivity(), DatabaseRetrieval {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
is DatabaseViewModel.ActionState.OnDatabaseActionStarted -> {
|
is DatabaseViewModel.ActionState.OnDatabaseActionStarted -> {
|
||||||
progressTaskViewModel.start(uiState.progressMessage)
|
progressTaskViewModel.show(uiState.progressMessage)
|
||||||
}
|
}
|
||||||
is DatabaseViewModel.ActionState.OnDatabaseActionUpdated -> {
|
is DatabaseViewModel.ActionState.OnDatabaseActionUpdated -> {
|
||||||
progressTaskViewModel.update(uiState.progressMessage)
|
progressTaskViewModel.show(uiState.progressMessage)
|
||||||
}
|
}
|
||||||
is DatabaseViewModel.ActionState.OnDatabaseActionStopped -> {
|
is DatabaseViewModel.ActionState.OnDatabaseActionStopped -> {
|
||||||
progressTaskViewModel.stop()
|
progressTaskViewModel.hide()
|
||||||
}
|
}
|
||||||
is DatabaseViewModel.ActionState.OnDatabaseActionFinished -> {
|
is DatabaseViewModel.ActionState.OnDatabaseActionFinished -> {
|
||||||
onDatabaseActionFinished(
|
onDatabaseActionFinished(
|
||||||
@@ -96,7 +155,8 @@ abstract class DatabaseActivity : StylishActivity(), DatabaseRetrieval {
|
|||||||
uiState.actionTask,
|
uiState.actionTask,
|
||||||
uiState.result
|
uiState.result
|
||||||
)
|
)
|
||||||
progressTaskViewModel.stop()
|
progressTaskViewModel.hide()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -106,9 +166,9 @@ abstract class DatabaseActivity : StylishActivity(), DatabaseRetrieval {
|
|||||||
repeatOnLifecycle(Lifecycle.State.RESUMED) {
|
repeatOnLifecycle(Lifecycle.State.RESUMED) {
|
||||||
progressTaskViewModel.progressTaskState.collect { state ->
|
progressTaskViewModel.progressTaskState.collect { state ->
|
||||||
when (state) {
|
when (state) {
|
||||||
ProgressTaskViewModel.ProgressTaskState.Start ->
|
is ProgressTaskViewModel.ProgressTaskState.Show ->
|
||||||
showDialog()
|
startDialog()
|
||||||
ProgressTaskViewModel.ProgressTaskState.Stop ->
|
is ProgressTaskViewModel.ProgressTaskState.Hide ->
|
||||||
stopDialog()
|
stopDialog()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -117,6 +177,7 @@ abstract class DatabaseActivity : StylishActivity(), DatabaseRetrieval {
|
|||||||
lifecycleScope.launch {
|
lifecycleScope.launch {
|
||||||
repeatOnLifecycle(Lifecycle.State.RESUMED) {
|
repeatOnLifecycle(Lifecycle.State.RESUMED) {
|
||||||
mDatabaseViewModel.databaseState.collect { database ->
|
mDatabaseViewModel.databaseState.collect { database ->
|
||||||
|
if (credentialResultLaunched.not()) {
|
||||||
// Nullable function
|
// Nullable function
|
||||||
onUnknownDatabaseRetrieved(database)
|
onUnknownDatabaseRetrieved(database)
|
||||||
database?.let {
|
database?.let {
|
||||||
@@ -126,6 +187,12 @@ abstract class DatabaseActivity : StylishActivity(), DatabaseRetrieval {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onSaveInstanceState(outState: Bundle) {
|
||||||
|
outState.putBoolean(CREDENTIAL_RESULT_LAUNCHER_KEY, credentialResultLaunched)
|
||||||
|
super.onSaveInstanceState(outState)
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Nullable function to retrieve a database
|
* Nullable function to retrieve a database
|
||||||
@@ -207,7 +274,7 @@ abstract class DatabaseActivity : StylishActivity(), DatabaseRetrieval {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun showDialog() {
|
private fun startDialog() {
|
||||||
lifecycleScope.launch {
|
lifecycleScope.launch {
|
||||||
if (showDatabaseDialog()) {
|
if (showDatabaseDialog()) {
|
||||||
if (progressTaskDialogFragment == null) {
|
if (progressTaskDialogFragment == null) {
|
||||||
@@ -233,4 +300,8 @@ abstract class DatabaseActivity : StylishActivity(), DatabaseRetrieval {
|
|||||||
protected open fun showDatabaseDialog(): Boolean {
|
protected open fun showDatabaseDialog(): Boolean {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
const val CREDENTIAL_RESULT_LAUNCHER_KEY = "com.kunzisoft.keepass.CREDENTIAL_RESULT_LAUNCHER_KEY"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,12 +1,9 @@
|
|||||||
package com.kunzisoft.keepass.activities.legacy
|
package com.kunzisoft.keepass.activities.legacy
|
||||||
|
|
||||||
import android.content.Intent
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.activity.OnBackPressedCallback
|
import androidx.activity.OnBackPressedCallback
|
||||||
import androidx.activity.result.ActivityResultLauncher
|
|
||||||
import androidx.activity.result.contract.ActivityResultContracts
|
|
||||||
import com.kunzisoft.keepass.R
|
import com.kunzisoft.keepass.R
|
||||||
import com.kunzisoft.keepass.credentialprovider.EntrySelectionHelper.isIntentSenderMode
|
import com.kunzisoft.keepass.credentialprovider.EntrySelectionHelper.isIntentSenderMode
|
||||||
import com.kunzisoft.keepass.credentialprovider.EntrySelectionHelper.removeInfo
|
import com.kunzisoft.keepass.credentialprovider.EntrySelectionHelper.removeInfo
|
||||||
@@ -15,7 +12,6 @@ import com.kunzisoft.keepass.credentialprovider.EntrySelectionHelper.retrieveReg
|
|||||||
import com.kunzisoft.keepass.credentialprovider.EntrySelectionHelper.retrieveSearchInfo
|
import com.kunzisoft.keepass.credentialprovider.EntrySelectionHelper.retrieveSearchInfo
|
||||||
import com.kunzisoft.keepass.credentialprovider.EntrySelectionHelper.retrieveSpecialMode
|
import com.kunzisoft.keepass.credentialprovider.EntrySelectionHelper.retrieveSpecialMode
|
||||||
import com.kunzisoft.keepass.credentialprovider.EntrySelectionHelper.retrieveTypeMode
|
import com.kunzisoft.keepass.credentialprovider.EntrySelectionHelper.retrieveTypeMode
|
||||||
import com.kunzisoft.keepass.credentialprovider.EntrySelectionHelper.setActivityResult
|
|
||||||
import com.kunzisoft.keepass.credentialprovider.SpecialMode
|
import com.kunzisoft.keepass.credentialprovider.SpecialMode
|
||||||
import com.kunzisoft.keepass.credentialprovider.TypeMode
|
import com.kunzisoft.keepass.credentialprovider.TypeMode
|
||||||
import com.kunzisoft.keepass.model.RegisterInfo
|
import com.kunzisoft.keepass.model.RegisterInfo
|
||||||
@@ -34,21 +30,6 @@ abstract class DatabaseModeActivity : DatabaseActivity() {
|
|||||||
|
|
||||||
private var mToolbarSpecial: ToolbarSpecial? = null
|
private var mToolbarSpecial: ToolbarSpecial? = null
|
||||||
|
|
||||||
/**
|
|
||||||
* Utility activity result launcher,
|
|
||||||
* Used recursively, close each activity with return data
|
|
||||||
*/
|
|
||||||
protected open var mCredentialActivityResultLauncher: ActivityResultLauncher<Intent>? =
|
|
||||||
registerForActivityResult(
|
|
||||||
ActivityResultContracts.StartActivityForResult()
|
|
||||||
) {
|
|
||||||
setActivityResult(
|
|
||||||
lockDatabase = false,
|
|
||||||
resultCode = it.resultCode,
|
|
||||||
data = it.data
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
open fun onDatabaseBackPressed() {
|
open fun onDatabaseBackPressed() {
|
||||||
if (mSpecialMode != SpecialMode.DEFAULT)
|
if (mSpecialMode != SpecialMode.DEFAULT)
|
||||||
onCancelSpecialMode()
|
onCancelSpecialMode()
|
||||||
|
|||||||
@@ -78,6 +78,7 @@ class EntrySelectionLauncherActivity : DatabaseModeActivity() {
|
|||||||
context = this@EntrySelectionLauncherActivity,
|
context = this@EntrySelectionLauncherActivity,
|
||||||
searchInfo = uiState.searchInfo
|
searchInfo = uiState.searchInfo
|
||||||
)
|
)
|
||||||
|
finish()
|
||||||
}
|
}
|
||||||
is EntrySelectionViewModel.UIState.LaunchGroupActivityForSearch -> {
|
is EntrySelectionViewModel.UIState.LaunchGroupActivityForSearch -> {
|
||||||
GroupActivity.launchForSearch(
|
GroupActivity.launchForSearch(
|
||||||
@@ -85,6 +86,7 @@ class EntrySelectionLauncherActivity : DatabaseModeActivity() {
|
|||||||
database = uiState.database,
|
database = uiState.database,
|
||||||
searchInfo = uiState.searchInfo
|
searchInfo = uiState.searchInfo
|
||||||
)
|
)
|
||||||
|
finish()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -661,7 +661,9 @@ open class DatabaseTaskNotificationService : LockNotificationService(), Progress
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun updateMessage(resId: Int) {
|
private fun updateMessage(resId: Int) {
|
||||||
mProgressMessage.messageId = resId
|
mProgressMessage = mProgressMessage.copy(
|
||||||
|
messageId = resId
|
||||||
|
)
|
||||||
notifyProgressMessage()
|
notifyProgressMessage()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -70,16 +70,35 @@ open class ProgressTaskDialogFragment : DialogFragment() {
|
|||||||
|
|
||||||
lifecycleScope.launch {
|
lifecycleScope.launch {
|
||||||
repeatOnLifecycle(Lifecycle.State.STARTED) {
|
repeatOnLifecycle(Lifecycle.State.STARTED) {
|
||||||
progressTaskViewModel.progressMessageState.collect { state ->
|
progressTaskViewModel.progressTaskState.collect { state ->
|
||||||
updateView(titleView,
|
when (state) {
|
||||||
state.titleId?.let { title -> getString(title) })
|
is ProgressTaskViewModel.ProgressTaskState.Show -> {
|
||||||
updateView(messageView,
|
val value = state.value
|
||||||
state.messageId?.let { message -> getString(message) })
|
updateView(
|
||||||
updateView(warningView,
|
titleView,
|
||||||
state.warningId?.let { warning -> getString(warning) })
|
value.titleId?.let { title ->
|
||||||
cancelButton?.isVisible = state.cancelable != null
|
getString(title)
|
||||||
cancelButton?.setOnClickListener {
|
})
|
||||||
state.cancelable?.invoke()
|
updateView(
|
||||||
|
messageView,
|
||||||
|
value.messageId?.let { message ->
|
||||||
|
getString(message)
|
||||||
|
})
|
||||||
|
updateView(
|
||||||
|
warningView,
|
||||||
|
value.warningId?.let { warning ->
|
||||||
|
getString(warning)
|
||||||
|
})
|
||||||
|
cancelButton?.apply {
|
||||||
|
isVisible = value.cancelable != null
|
||||||
|
setOnClickListener {
|
||||||
|
value.cancelable?.invoke()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else -> {
|
||||||
|
// Nothing here, this fragment is stopped externally
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,30 +4,25 @@ import androidx.lifecycle.ViewModel
|
|||||||
import com.kunzisoft.keepass.database.ProgressMessage
|
import com.kunzisoft.keepass.database.ProgressMessage
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
import kotlinx.coroutines.flow.StateFlow
|
import kotlinx.coroutines.flow.StateFlow
|
||||||
|
import kotlinx.coroutines.flow.update
|
||||||
|
|
||||||
class ProgressTaskViewModel: ViewModel() {
|
class ProgressTaskViewModel: ViewModel() {
|
||||||
|
|
||||||
private val mProgressMessageState = MutableStateFlow(ProgressMessage())
|
private val mProgressTaskState = MutableStateFlow<ProgressTaskState>(ProgressTaskState.Hide)
|
||||||
val progressMessageState: StateFlow<ProgressMessage> = mProgressMessageState
|
|
||||||
|
|
||||||
private val mProgressTaskState = MutableStateFlow<ProgressTaskState>(ProgressTaskState.Stop)
|
|
||||||
val progressTaskState: StateFlow<ProgressTaskState> = mProgressTaskState
|
val progressTaskState: StateFlow<ProgressTaskState> = mProgressTaskState
|
||||||
|
|
||||||
fun update(value: ProgressMessage) {
|
fun show(value: ProgressMessage) {
|
||||||
mProgressMessageState.value = value
|
mProgressTaskState.update { currentState ->
|
||||||
|
ProgressTaskState.Show(value)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun start(value: ProgressMessage) {
|
fun hide() {
|
||||||
mProgressTaskState.value = ProgressTaskState.Start
|
mProgressTaskState.value = ProgressTaskState.Hide
|
||||||
update(value)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun stop() {
|
|
||||||
mProgressTaskState.value = ProgressTaskState.Stop
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sealed class ProgressTaskState {
|
sealed class ProgressTaskState {
|
||||||
object Start: ProgressTaskState()
|
data class Show(val value: ProgressMessage): ProgressTaskState()
|
||||||
object Stop: ProgressTaskState()
|
object Hide: ProgressTaskState()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -32,7 +32,7 @@ class DatabaseViewModel(application: Application): AndroidViewModel(application)
|
|||||||
val database: ContextualDatabase?
|
val database: ContextualDatabase?
|
||||||
get() = databaseState.value
|
get() = databaseState.value
|
||||||
|
|
||||||
private val mActionState = MutableStateFlow<ActionState>(ActionState.Loading)
|
private val mActionState = MutableStateFlow<ActionState>(ActionState.Wait)
|
||||||
val actionState: StateFlow<ActionState> = mActionState
|
val actionState: StateFlow<ActionState> = mActionState
|
||||||
|
|
||||||
private var mDatabaseTaskProvider: DatabaseTaskProvider = DatabaseTaskProvider(
|
private var mDatabaseTaskProvider: DatabaseTaskProvider = DatabaseTaskProvider(
|
||||||
@@ -469,7 +469,7 @@ class DatabaseViewModel(application: Application): AndroidViewModel(application)
|
|||||||
}
|
}
|
||||||
|
|
||||||
sealed class ActionState {
|
sealed class ActionState {
|
||||||
object Loading: ActionState()
|
object Wait: ActionState()
|
||||||
object OnDatabaseReloaded: ActionState()
|
object OnDatabaseReloaded: ActionState()
|
||||||
data class OnDatabaseActionRequested(
|
data class OnDatabaseActionRequested(
|
||||||
val bundle: Bundle? = null,
|
val bundle: Bundle? = null,
|
||||||
|
|||||||
@@ -71,7 +71,7 @@ object AppOriginEntryField {
|
|||||||
/**
|
/**
|
||||||
* Useful to detect if an other KeePass compatibility app already add a web domain or an app id
|
* Useful to detect if an other KeePass compatibility app already add a web domain or an app id
|
||||||
*/
|
*/
|
||||||
private fun EntryInfo.containsDomainOrApplicationId(search: String): Boolean {
|
fun EntryInfo.containsDomainOrApplicationId(search: String): Boolean {
|
||||||
if (url.contains(search))
|
if (url.contains(search))
|
||||||
return true
|
return true
|
||||||
return customFields.find {
|
return customFields.find {
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ import com.kunzisoft.keepass.database.element.Database
|
|||||||
import com.kunzisoft.keepass.database.element.Field
|
import com.kunzisoft.keepass.database.element.Field
|
||||||
import com.kunzisoft.keepass.database.element.Tags
|
import com.kunzisoft.keepass.database.element.Tags
|
||||||
import com.kunzisoft.keepass.database.element.entry.AutoType
|
import com.kunzisoft.keepass.database.element.entry.AutoType
|
||||||
|
import com.kunzisoft.keepass.model.AppOriginEntryField.containsDomainOrApplicationId
|
||||||
import com.kunzisoft.keepass.model.AppOriginEntryField.setAppOrigin
|
import com.kunzisoft.keepass.model.AppOriginEntryField.setAppOrigin
|
||||||
import com.kunzisoft.keepass.model.AppOriginEntryField.setApplicationId
|
import com.kunzisoft.keepass.model.AppOriginEntryField.setApplicationId
|
||||||
import com.kunzisoft.keepass.model.AppOriginEntryField.setWebDomain
|
import com.kunzisoft.keepass.model.AppOriginEntryField.setWebDomain
|
||||||
@@ -183,6 +184,18 @@ class EntryInfo : NodeInfo {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* True if this entry contains domain or applicationId,
|
||||||
|
* OTP is ignored and considered not present
|
||||||
|
*/
|
||||||
|
fun containsSearchInfo(searchInfo: SearchInfo): Boolean {
|
||||||
|
return searchInfo.webDomain?.let { webDomain ->
|
||||||
|
containsDomainOrApplicationId(webDomain)
|
||||||
|
} ?: searchInfo.applicationId?.let { applicationId ->
|
||||||
|
containsDomainOrApplicationId(applicationId)
|
||||||
|
} ?: false
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add searchInfo to current EntryInfo
|
* Add searchInfo to current EntryInfo
|
||||||
*/
|
*/
|
||||||
|
|||||||
4
fastlane/metadata/android/en-US/changelogs/148.txt
Normal file
4
fastlane/metadata/android/en-US/changelogs/148.txt
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
* Fix multiple Passkey selection #2253
|
||||||
|
* Fix database dialog subtitle #2254
|
||||||
|
* Fix save search info if URL present #2255
|
||||||
|
* Small fixes
|
||||||
4
fastlane/metadata/android/fr-FR/changelogs/148.txt
Normal file
4
fastlane/metadata/android/fr-FR/changelogs/148.txt
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
* Correction de la selection multiple des Passkeys #2253
|
||||||
|
* Correction du sous-titre du dialogue de la base de données #2254
|
||||||
|
* Correction de la sauvegarde des infos de recherchesi l'URL est present #2255
|
||||||
|
* Petites corrections
|
||||||
Reference in New Issue
Block a user