Start using ViewModel for internal database action

This commit is contained in:
J-Jamet
2020-08-07 16:41:28 +02:00
parent 31b322a108
commit 0f7839027f
12 changed files with 393 additions and 134 deletions

View File

@@ -101,10 +101,9 @@ dependencies {
implementation 'androidx.constraintlayout:constraintlayout:1.1.3' implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
implementation 'androidx.documentfile:documentfile:1.0.1' implementation 'androidx.documentfile:documentfile:1.0.1'
implementation 'androidx.biometric:biometric:1.0.1' implementation 'androidx.biometric:biometric:1.0.1'
implementation 'androidx.core:core-ktx:1.2.0' // Lifecycle - LiveData - ViewModel - Coroutines
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.3' implementation "androidx.core:core-ktx:1.2.0"
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.3' implementation 'androidx.fragment:fragment-ktx:1.2.4'
// TODO #538 implementation "androidx.lifecycle:lifecycle-runtime-ktx:2.2.0"
// To upgrade with style // To upgrade with style
implementation 'com.google.android.material:material:1.0.0' implementation 'com.google.android.material:material:1.0.0'
// Database // Database

View File

@@ -32,9 +32,11 @@ import android.util.Log
import android.view.Menu import android.view.Menu
import android.view.MenuItem import android.view.MenuItem
import android.view.View import android.view.View
import androidx.activity.viewModels
import androidx.annotation.RequiresApi import androidx.annotation.RequiresApi
import androidx.appcompat.widget.Toolbar import androidx.appcompat.widget.Toolbar
import androidx.coordinatorlayout.widget.CoordinatorLayout import androidx.coordinatorlayout.widget.CoordinatorLayout
import androidx.lifecycle.Observer
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import androidx.recyclerview.widget.SimpleItemAnimator import androidx.recyclerview.widget.SimpleItemAnimator
@@ -56,6 +58,7 @@ import com.kunzisoft.keepass.notifications.DatabaseTaskNotificationService.Compa
import com.kunzisoft.keepass.settings.PreferencesUtil import com.kunzisoft.keepass.settings.PreferencesUtil
import com.kunzisoft.keepass.utils.* import com.kunzisoft.keepass.utils.*
import com.kunzisoft.keepass.view.asError import com.kunzisoft.keepass.view.asError
import com.kunzisoft.keepass.viewmodels.DatabaseFilesViewModel
import kotlinx.android.synthetic.main.activity_file_selection.* import kotlinx.android.synthetic.main.activity_file_selection.*
import java.io.FileNotFoundException import java.io.FileNotFoundException
@@ -68,6 +71,8 @@ class FileDatabaseSelectActivity : SpecialModeActivity(),
private var createDatabaseButtonView: View? = null private var createDatabaseButtonView: View? = null
private var openDatabaseButtonView: View? = null private var openDatabaseButtonView: View? = null
private val databaseFilesViewModel: DatabaseFilesViewModel by viewModels()
// Adapter to manage database history list // Adapter to manage database history list
private var mAdapterDatabaseHistory: FileDatabaseHistoryAdapter? = null private var mAdapterDatabaseHistory: FileDatabaseHistoryAdapter? = null
@@ -118,25 +123,21 @@ class FileDatabaseSelectActivity : SpecialModeActivity(),
// Construct adapter with listeners // Construct adapter with listeners
mAdapterDatabaseHistory = FileDatabaseHistoryAdapter(this) mAdapterDatabaseHistory = FileDatabaseHistoryAdapter(this)
mAdapterDatabaseHistory?.setOnFileDatabaseHistoryOpenListener { fileDatabaseHistoryEntityToOpen -> mAdapterDatabaseHistory?.setOnFileDatabaseHistoryOpenListener { fileDatabaseHistoryEntityToOpen ->
UriUtil.parse(fileDatabaseHistoryEntityToOpen.databaseUri)?.let { databaseFileUri -> fileDatabaseHistoryEntityToOpen.databaseUri?.let { databaseFileUri ->
launchPasswordActivity( launchPasswordActivity(
databaseFileUri, databaseFileUri,
UriUtil.parse(fileDatabaseHistoryEntityToOpen.keyFileUri)) fileDatabaseHistoryEntityToOpen.keyFileUri
)
} }
} }
mAdapterDatabaseHistory?.setOnFileDatabaseHistoryDeleteListener { fileDatabaseHistoryToDelete -> mAdapterDatabaseHistory?.setOnFileDatabaseHistoryDeleteListener { fileDatabaseHistoryToDelete ->
// Remove from app database // Remove from app database
mFileDatabaseHistoryAction?.deleteFileDatabaseHistory(fileDatabaseHistoryToDelete) { fileHistoryDeleted -> databaseFilesViewModel.deleteDatabaseFile(fileDatabaseHistoryToDelete)
// Remove from adapter
fileHistoryDeleted?.let { databaseFileHistoryDeleted ->
mAdapterDatabaseHistory?.deleteDatabaseFileHistory(databaseFileHistoryDeleted)
mAdapterDatabaseHistory?.notifyDataSetChanged()
}
}
true true
} }
mAdapterDatabaseHistory?.setOnSaveAliasListener { fileDatabaseHistoryWithNewAlias -> mAdapterDatabaseHistory?.setOnSaveAliasListener { fileDatabaseHistoryWithNewAlias ->
mFileDatabaseHistoryAction?.addOrUpdateFileDatabaseHistory(fileDatabaseHistoryWithNewAlias) // Update in app database
databaseFilesViewModel.updateDatabaseFile(fileDatabaseHistoryWithNewAlias)
} }
fileDatabaseHistoryRecyclerView.adapter = mAdapterDatabaseHistory fileDatabaseHistoryRecyclerView.adapter = mAdapterDatabaseHistory
@@ -159,17 +160,49 @@ class FileDatabaseSelectActivity : SpecialModeActivity(),
mDatabaseFileUri = savedInstanceState.getParcelable(EXTRA_DATABASE_URI) mDatabaseFileUri = savedInstanceState.getParcelable(EXTRA_DATABASE_URI)
} }
// Observe list of databases
databaseFilesViewModel.databaseFilesLoaded.observe(this, Observer { databaseFiles ->
when (databaseFiles.databaseFileAction) {
DatabaseFilesViewModel.DatabaseFileAction.NONE -> {
mAdapterDatabaseHistory?.replaceAllDatabaseFileHistoryList(databaseFiles.databaseFileList)
mAdapterDatabaseHistory?.notifyDataSetChanged()
}
DatabaseFilesViewModel.DatabaseFileAction.ADD -> {
databaseFiles.databaseFileToActivate?.let { databaseFileToAdd ->
mAdapterDatabaseHistory?.notifyDataSetChanged()
}
}
DatabaseFilesViewModel.DatabaseFileAction.UPDATE -> {
databaseFiles.databaseFileToActivate?.let { databaseFileToUpdate ->
mAdapterDatabaseHistory?.notifyDataSetChanged()
}
}
DatabaseFilesViewModel.DatabaseFileAction.DELETE -> {
databaseFiles.databaseFileToActivate?.let { databaseFileToDelete ->
mAdapterDatabaseHistory?.deleteDatabaseFileHistory(databaseFileToDelete)
mAdapterDatabaseHistory?.notifyDataSetChanged()
}
}
}
databaseFilesViewModel.consumeAction()
})
// Attach the dialog thread to this activity // Attach the dialog thread to this activity
mProgressDialogThread = ProgressDialogThread(this).apply { mProgressDialogThread = ProgressDialogThread(this).apply {
onActionFinish = { actionTask, _ -> onActionFinish = { actionTask, _ ->
when (actionTask) { when (actionTask) {
ACTION_DATABASE_CREATE_TASK -> { ACTION_DATABASE_CREATE_TASK -> {
// TODO add Database file
// databaseFilesViewModel.addDatabaseFile()
databaseFilesViewModel.loadListOfDatabases()
runOnUiThread {
GroupActivity.launch(this@FileDatabaseSelectActivity) GroupActivity.launch(this@FileDatabaseSelectActivity)
} }
} }
} }
} }
} }
}
/** /**
* Create a new file by calling the content provider * Create a new file by calling the content provider
@@ -286,21 +319,7 @@ class FileDatabaseSelectActivity : SpecialModeActivity(),
} else { } else {
// Construct adapter with listeners // Construct adapter with listeners
if (PreferencesUtil.showRecentFiles(this)) { if (PreferencesUtil.showRecentFiles(this)) {
mFileDatabaseHistoryAction?.getAllFileDatabaseHistories { databaseFileHistoryList -> databaseFilesViewModel.loadListOfDatabases()
databaseFileHistoryList?.let { historyList ->
val hideBrokenLocations = PreferencesUtil.hideBrokenLocations(this@FileDatabaseSelectActivity)
mAdapterDatabaseHistory?.addDatabaseFileHistoryList(
// Show only uri accessible
historyList.filter {
if (hideBrokenLocations) {
FileDatabaseInfo(this@FileDatabaseSelectActivity,
it.databaseUri).exists
} else
true
})
mAdapterDatabaseHistory?.notifyDataSetChanged()
}
}
} else { } else {
mAdapterDatabaseHistory?.clearDatabaseFileHistoryList() mAdapterDatabaseHistory?.clearDatabaseFileHistoryList()
mAdapterDatabaseHistory?.notifyDataSetChanged() mAdapterDatabaseHistory?.notifyDataSetChanged()
@@ -362,8 +381,7 @@ class FileDatabaseSelectActivity : SpecialModeActivity(),
AutofillHelper.onActivityResultSetResultAndFinish(this, requestCode, resultCode, data) AutofillHelper.onActivityResultSetResultAndFinish(this, requestCode, resultCode, data)
} }
mOpenFileHelper?.onActivityResultCallback(requestCode, resultCode, data mOpenFileHelper?.onActivityResultCallback(requestCode, resultCode, data) { uri ->
) { uri ->
if (uri != null) { if (uri != null) {
launchPasswordActivityWithPath(uri) launchPasswordActivityWithPath(uri)
} }

View File

@@ -34,10 +34,12 @@ import android.util.Log
import android.view.* import android.view.*
import android.view.inputmethod.EditorInfo.IME_ACTION_DONE import android.view.inputmethod.EditorInfo.IME_ACTION_DONE
import android.widget.* import android.widget.*
import androidx.activity.viewModels
import androidx.annotation.RequiresApi import androidx.annotation.RequiresApi
import androidx.appcompat.widget.Toolbar import androidx.appcompat.widget.Toolbar
import androidx.biometric.BiometricManager import androidx.biometric.BiometricManager
import androidx.core.app.ActivityCompat import androidx.core.app.ActivityCompat
import androidx.lifecycle.Observer
import com.google.android.material.snackbar.Snackbar import com.google.android.material.snackbar.Snackbar
import com.kunzisoft.keepass.R import com.kunzisoft.keepass.R
import com.kunzisoft.keepass.activities.dialogs.DuplicateUuidDialog import com.kunzisoft.keepass.activities.dialogs.DuplicateUuidDialog
@@ -48,7 +50,6 @@ import com.kunzisoft.keepass.activities.helpers.ReadOnlyHelper
import com.kunzisoft.keepass.activities.lock.LockingActivity import com.kunzisoft.keepass.activities.lock.LockingActivity
import com.kunzisoft.keepass.activities.selection.SpecialModeActivity import com.kunzisoft.keepass.activities.selection.SpecialModeActivity
import com.kunzisoft.keepass.app.database.CipherDatabaseEntity import com.kunzisoft.keepass.app.database.CipherDatabaseEntity
import com.kunzisoft.keepass.app.database.FileDatabaseHistoryAction
import com.kunzisoft.keepass.autofill.AutofillHelper import com.kunzisoft.keepass.autofill.AutofillHelper
import com.kunzisoft.keepass.biometric.AdvancedUnlockedManager import com.kunzisoft.keepass.biometric.AdvancedUnlockedManager
import com.kunzisoft.keepass.database.action.ProgressDialogThread import com.kunzisoft.keepass.database.action.ProgressDialogThread
@@ -60,7 +61,7 @@ import com.kunzisoft.keepass.model.SearchInfo
import com.kunzisoft.keepass.notifications.DatabaseTaskNotificationService.Companion.ACTION_DATABASE_LOAD_TASK import com.kunzisoft.keepass.notifications.DatabaseTaskNotificationService.Companion.ACTION_DATABASE_LOAD_TASK
import com.kunzisoft.keepass.notifications.DatabaseTaskNotificationService.Companion.CIPHER_ENTITY_KEY import com.kunzisoft.keepass.notifications.DatabaseTaskNotificationService.Companion.CIPHER_ENTITY_KEY
import com.kunzisoft.keepass.notifications.DatabaseTaskNotificationService.Companion.DATABASE_URI_KEY import com.kunzisoft.keepass.notifications.DatabaseTaskNotificationService.Companion.DATABASE_URI_KEY
import com.kunzisoft.keepass.notifications.DatabaseTaskNotificationService.Companion.KEY_FILE_KEY import com.kunzisoft.keepass.notifications.DatabaseTaskNotificationService.Companion.KEY_FILE_URI_KEY
import com.kunzisoft.keepass.notifications.DatabaseTaskNotificationService.Companion.MASTER_PASSWORD_KEY import com.kunzisoft.keepass.notifications.DatabaseTaskNotificationService.Companion.MASTER_PASSWORD_KEY
import com.kunzisoft.keepass.notifications.DatabaseTaskNotificationService.Companion.READ_ONLY_KEY import com.kunzisoft.keepass.notifications.DatabaseTaskNotificationService.Companion.READ_ONLY_KEY
import com.kunzisoft.keepass.settings.PreferencesUtil import com.kunzisoft.keepass.settings.PreferencesUtil
@@ -68,6 +69,7 @@ import com.kunzisoft.keepass.utils.*
import com.kunzisoft.keepass.view.AdvancedUnlockInfoView import com.kunzisoft.keepass.view.AdvancedUnlockInfoView
import com.kunzisoft.keepass.view.KeyFileSelectionView import com.kunzisoft.keepass.view.KeyFileSelectionView
import com.kunzisoft.keepass.view.asError import com.kunzisoft.keepass.view.asError
import com.kunzisoft.keepass.viewmodels.DatabaseFileViewModel
import kotlinx.android.synthetic.main.activity_password.* import kotlinx.android.synthetic.main.activity_password.*
import java.io.FileNotFoundException import java.io.FileNotFoundException
@@ -86,6 +88,8 @@ open class PasswordActivity : SpecialModeActivity() {
private var infoContainerView: ViewGroup? = null private var infoContainerView: ViewGroup? = null
private var enableButtonOnCheckedChangeListener: CompoundButton.OnCheckedChangeListener? = null private var enableButtonOnCheckedChangeListener: CompoundButton.OnCheckedChangeListener? = null
private val databaseFilesViewModel: DatabaseFileViewModel by viewModels()
private var mDatabaseFileUri: Uri? = null private var mDatabaseFileUri: Uri? = null
private var mDatabaseKeyFileUri: Uri? = null private var mDatabaseKeyFileUri: Uri? = null
@@ -133,6 +137,7 @@ open class PasswordActivity : SpecialModeActivity() {
mPermissionAsked = savedInstanceState?.getBoolean(KEY_PERMISSION_ASKED) ?: mPermissionAsked mPermissionAsked = savedInstanceState?.getBoolean(KEY_PERMISSION_ASKED) ?: mPermissionAsked
readOnly = ReadOnlyHelper.retrieveReadOnlyFromInstanceStateOrPreference(this, savedInstanceState) readOnly = ReadOnlyHelper.retrieveReadOnlyFromInstanceStateOrPreference(this, savedInstanceState)
mRememberKeyFile = PreferencesUtil.rememberKeyFileLocations(this)
mOpenFileHelper = OpenFileHelper(this@PasswordActivity) mOpenFileHelper = OpenFileHelper(this@PasswordActivity)
keyFileSelectionView?.apply { keyFileSelectionView?.apply {
@@ -163,11 +168,33 @@ open class PasswordActivity : SpecialModeActivity() {
if (savedInstanceState?.containsKey(KEY_KEYFILE) == true) { if (savedInstanceState?.containsKey(KEY_KEYFILE) == true) {
mDatabaseKeyFileUri = UriUtil.parse(savedInstanceState.getString(KEY_KEYFILE)) mDatabaseKeyFileUri = UriUtil.parse(savedInstanceState.getString(KEY_KEYFILE))
} }
if (savedInstanceState?.containsKey(ALLOW_AUTO_OPEN_BIOMETRIC_PROMPT) == true) { if (savedInstanceState?.containsKey(ALLOW_AUTO_OPEN_BIOMETRIC_PROMPT) == true) {
mAllowAutoOpenBiometricPrompt = savedInstanceState.getBoolean(ALLOW_AUTO_OPEN_BIOMETRIC_PROMPT) mAllowAutoOpenBiometricPrompt = savedInstanceState.getBoolean(ALLOW_AUTO_OPEN_BIOMETRIC_PROMPT)
} }
// Observe database file change
databaseFilesViewModel.databaseFileLoaded.observe(this, Observer { databaseFile ->
// Force read only if the file does not exists
mForceReadOnly = databaseFile?.let {
!it.databaseFileExists
} ?: true
invalidateOptionsMenu()
// Post init uri with KeyFile only if needed
val keyFileUri =
if (mRememberKeyFile
&& (mDatabaseKeyFileUri == null || mDatabaseKeyFileUri.toString().isEmpty())) {
databaseFile?.keyFileUri
} else {
mDatabaseKeyFileUri
}
// Define title
filenameView?.text = databaseFile?.databaseAlias ?: ""
onDatabaseFileLoaded(databaseFile?.databaseUri, keyFileUri)
})
mProgressDialogThread = ProgressDialogThread(this).apply { mProgressDialogThread = ProgressDialogThread(this).apply {
onActionFinish = { actionTask, result -> onActionFinish = { actionTask, result ->
when (actionTask) { when (actionTask) {
@@ -205,7 +232,7 @@ open class PasswordActivity : SpecialModeActivity() {
result.data?.let { resultData -> result.data?.let { resultData ->
databaseUri = resultData.getParcelable(DATABASE_URI_KEY) databaseUri = resultData.getParcelable(DATABASE_URI_KEY)
masterPassword = resultData.getString(MASTER_PASSWORD_KEY) masterPassword = resultData.getString(MASTER_PASSWORD_KEY)
keyFileUri = resultData.getParcelable(KEY_FILE_KEY) keyFileUri = resultData.getParcelable(KEY_FILE_URI_KEY)
readOnly = resultData.getBoolean(READ_ONLY_KEY) readOnly = resultData.getBoolean(READ_ONLY_KEY)
cipherEntity = resultData.getParcelable(CIPHER_ENTITY_KEY) cipherEntity = resultData.getParcelable(CIPHER_ENTITY_KEY)
} }
@@ -364,45 +391,15 @@ open class PasswordActivity : SpecialModeActivity() {
else else
mAllowAutoOpenBiometricPrompt mAllowAutoOpenBiometricPrompt
initUriFromIntent() mDatabaseFileUri?.let { databaseFileUri ->
databaseFilesViewModel.loadDatabaseFile(databaseFileUri)
}
checkPermission() checkPermission()
} }
} }
private fun initUriFromIntent() { private fun onDatabaseFileLoaded(databaseFileUri: Uri?, keyFileUri: Uri?) {
/*
// "canXrite" doesn't work with Google Drive, don't really know why?
mForceReadOnly = mDatabaseFileUri?.let {
!FileDatabaseInfo(this, it).canWrite
} ?: false
*/
mForceReadOnly = mDatabaseFileUri?.let {
!FileDatabaseInfo(this, it).exists
} ?: true
// Post init uri with KeyFile if needed
if (mRememberKeyFile && (mDatabaseKeyFileUri == null || mDatabaseKeyFileUri.toString().isEmpty())) {
// Retrieve KeyFile in a thread
mDatabaseFileUri?.let { databaseUri ->
FileDatabaseHistoryAction.getInstance(applicationContext)
.getKeyFileUriByDatabaseUri(databaseUri) {
onPostInitUri(databaseUri, it)
}
}
} else {
onPostInitUri(mDatabaseFileUri, mDatabaseKeyFileUri)
}
}
private fun onPostInitUri(databaseFileUri: Uri?, keyFileUri: Uri?) {
// Define title
databaseFileUri?.let {
FileDatabaseInfo(this, it).retrieveDatabaseTitle { title ->
filenameView?.text = title
}
}
// Define Key File text // Define Key File text
if (mRememberKeyFile) { if (mRememberKeyFile) {
populateKeyFileTextView(keyFileUri) populateKeyFileTextView(keyFileUri)

View File

@@ -31,19 +31,17 @@ import android.widget.ImageView
import android.widget.TextView import android.widget.TextView
import android.widget.ViewSwitcher import android.widget.ViewSwitcher
import com.kunzisoft.keepass.R import com.kunzisoft.keepass.R
import com.kunzisoft.keepass.app.database.FileDatabaseHistoryEntity import com.kunzisoft.keepass.model.DatabaseFile
import com.kunzisoft.keepass.utils.FileDatabaseInfo
import com.kunzisoft.keepass.utils.UriUtil
class FileDatabaseHistoryAdapter(private val context: Context) class FileDatabaseHistoryAdapter(context: Context)
: RecyclerView.Adapter<FileDatabaseHistoryAdapter.FileDatabaseHistoryViewHolder>() { : RecyclerView.Adapter<FileDatabaseHistoryAdapter.FileDatabaseHistoryViewHolder>() {
private val inflater: LayoutInflater = LayoutInflater.from(context) private val inflater: LayoutInflater = LayoutInflater.from(context)
private var fileItemOpenListener: ((FileDatabaseHistoryEntity)->Unit)? = null private var fileItemOpenListener: ((DatabaseFile)->Unit)? = null
private var fileSelectClearListener: ((FileDatabaseHistoryEntity)->Boolean)? = null private var fileSelectClearListener: ((DatabaseFile)->Boolean)? = null
private var saveAliasListener: ((FileDatabaseHistoryEntity)->Unit)? = null private var saveAliasListener: ((DatabaseFile)->Unit)? = null
private val listDatabaseFiles = ArrayList<FileDatabaseHistoryEntity>() private val listDatabaseFiles = ArrayList<DatabaseFile>()
private var mExpandedPosition = -1 private var mExpandedPosition = -1
private var mPreviousExpandedPosition = -1 private var mPreviousExpandedPosition = -1
@@ -69,29 +67,28 @@ class FileDatabaseHistoryAdapter(private val context: Context)
override fun onBindViewHolder(holder: FileDatabaseHistoryViewHolder, position: Int) { override fun onBindViewHolder(holder: FileDatabaseHistoryViewHolder, position: Int) {
// Get info from position // Get info from position
val fileHistoryEntity = listDatabaseFiles[position] val databaseFile = listDatabaseFiles[position]
val fileDatabaseInfo = FileDatabaseInfo(context, fileHistoryEntity.databaseUri)
// Click item to open file // Click item to open file
if (fileItemOpenListener != null) if (fileItemOpenListener != null)
holder.fileContainer.setOnClickListener { holder.fileContainer.setOnClickListener {
fileItemOpenListener?.invoke(fileHistoryEntity) fileItemOpenListener?.invoke(databaseFile)
} }
// File alias // File alias
holder.fileAlias.text = fileDatabaseInfo.retrieveDatabaseAlias(fileHistoryEntity.databaseAlias) holder.fileAlias.text = databaseFile.databaseAlias
// File path // File path
holder.filePath.text = UriUtil.decode(fileDatabaseInfo.fileUri?.toString()) holder.filePath.text = databaseFile.databaseDecodedPath
if (fileDatabaseInfo.exists) { if (databaseFile.databaseFileExists) {
holder.fileInformation.clearColorFilter() holder.fileInformation.clearColorFilter()
} else { } else {
holder.fileInformation.setColorFilter(Color.RED, PorterDuff.Mode.MULTIPLY) holder.fileInformation.setColorFilter(Color.RED, PorterDuff.Mode.MULTIPLY)
} }
// Modification // Modification
fileDatabaseInfo.getModificationString()?.let { databaseFile.databaseLastModified?.let {
holder.fileModification.text = it holder.fileModification.text = it
holder.fileModification.visibility = View.VISIBLE holder.fileModification.visibility = View.VISIBLE
} ?: run { } ?: run {
@@ -99,7 +96,7 @@ class FileDatabaseHistoryAdapter(private val context: Context)
} }
// Size // Size
fileDatabaseInfo.getSizeString()?.let { databaseFile.databaseSize?.let {
holder.fileSize.text = it holder.fileSize.text = it
holder.fileSize.visibility = View.VISIBLE holder.fileSize.visibility = View.VISIBLE
} ?: run { } ?: run {
@@ -114,8 +111,8 @@ class FileDatabaseHistoryAdapter(private val context: Context)
// Save alias modification // Save alias modification
holder.fileAliasCloseButton.setOnClickListener { holder.fileAliasCloseButton.setOnClickListener {
// Change the alias // Change the alias
fileHistoryEntity.databaseAlias = holder.fileAliasEdit.text.toString() databaseFile.databaseAlias = holder.fileAliasEdit.text.toString()
saveAliasListener?.invoke(fileHistoryEntity) saveAliasListener?.invoke(databaseFile)
// Finish save mode // Finish save mode
holder.fileMainSwitcher.showPrevious() holder.fileMainSwitcher.showPrevious()
@@ -130,7 +127,7 @@ class FileDatabaseHistoryAdapter(private val context: Context)
} }
holder.fileDeleteButton.setOnClickListener { holder.fileDeleteButton.setOnClickListener {
fileSelectClearListener?.invoke(fileHistoryEntity) fileSelectClearListener?.invoke(databaseFile)
} }
if (isExpanded) { if (isExpanded) {
@@ -160,24 +157,24 @@ class FileDatabaseHistoryAdapter(private val context: Context)
listDatabaseFiles.clear() listDatabaseFiles.clear()
} }
fun addDatabaseFileHistoryList(listFileDatabaseHistoryToAdd: List<FileDatabaseHistoryEntity>) { fun replaceAllDatabaseFileHistoryList(listFileDatabaseHistoryToAdd: List<DatabaseFile>) {
listDatabaseFiles.clear() listDatabaseFiles.clear()
listDatabaseFiles.addAll(listFileDatabaseHistoryToAdd) listDatabaseFiles.addAll(listFileDatabaseHistoryToAdd)
} }
fun deleteDatabaseFileHistory(fileDatabaseHistoryToDelete: FileDatabaseHistoryEntity) { fun deleteDatabaseFileHistory(fileDatabaseHistoryToDelete: DatabaseFile) {
listDatabaseFiles.remove(fileDatabaseHistoryToDelete) listDatabaseFiles.remove(fileDatabaseHistoryToDelete)
} }
fun setOnFileDatabaseHistoryOpenListener(listener : ((FileDatabaseHistoryEntity)->Unit)?) { fun setOnFileDatabaseHistoryOpenListener(listener : ((DatabaseFile)->Unit)?) {
this.fileItemOpenListener = listener this.fileItemOpenListener = listener
} }
fun setOnFileDatabaseHistoryDeleteListener(listener : ((FileDatabaseHistoryEntity)->Boolean)?) { fun setOnFileDatabaseHistoryDeleteListener(listener : ((DatabaseFile)->Boolean)?) {
this.fileSelectClearListener = listener this.fileSelectClearListener = listener
} }
fun setOnSaveAliasListener(listener : ((FileDatabaseHistoryEntity)->Unit)?) { fun setOnSaveAliasListener(listener : ((DatabaseFile)->Unit)?) {
this.saveAliasListener = listener this.saveAliasListener = listener
} }

View File

@@ -71,6 +71,7 @@ class FileDatabaseHistoryAction(applicationContext: Context) {
} }
fun addOrUpdateDatabaseUri(databaseUri: Uri, keyFileUri: Uri? = null) { fun addOrUpdateDatabaseUri(databaseUri: Uri, keyFileUri: Uri? = null) {
// TODO in Thread
addOrUpdateFileDatabaseHistory(FileDatabaseHistoryEntity( addOrUpdateFileDatabaseHistory(FileDatabaseHistoryEntity(
databaseUri.toString(), databaseUri.toString(),
"", "",
@@ -79,7 +80,9 @@ class FileDatabaseHistoryAction(applicationContext: Context) {
), true) ), true)
} }
fun addOrUpdateFileDatabaseHistory(fileDatabaseHistory: FileDatabaseHistoryEntity, unmodifiedAlias: Boolean = false) { fun addOrUpdateFileDatabaseHistory(fileDatabaseHistory: FileDatabaseHistoryEntity,
unmodifiedAlias: Boolean = false,
fileHistoryUpdatedResult: ((FileDatabaseHistoryEntity?) -> Unit)? = null) {
IOActionTask( IOActionTask(
{ {
val fileDatabaseHistoryRetrieve = databaseFileHistoryDao.getByDatabaseUri(fileDatabaseHistory.databaseUri) val fileDatabaseHistoryRetrieve = databaseFileHistoryDao.getByDatabaseUri(fileDatabaseHistory.databaseUri)
@@ -93,6 +96,10 @@ class FileDatabaseHistoryAction(applicationContext: Context) {
} else { } else {
databaseFileHistoryDao.update(fileDatabaseHistory) databaseFileHistoryDao.update(fileDatabaseHistory)
} }
fileDatabaseHistoryRetrieve
},
{
fileHistoryUpdatedResult?.invoke(it)
} }
).execute() ).execute()
} }

View File

@@ -57,6 +57,7 @@ class CreateDatabaseRunnable(context: Context,
super.onFinishRun() super.onFinishRun()
if (result.isSuccess) { if (result.isSuccess) {
// TODO in Thread
// Add database to recent files // Add database to recent files
if (PreferencesUtil.rememberDatabaseLocations(context)) { if (PreferencesUtil.rememberDatabaseLocations(context)) {
FileDatabaseHistoryAction.getInstance(context.applicationContext) FileDatabaseHistoryAction.getInstance(context.applicationContext)

View File

@@ -241,7 +241,7 @@ class ProgressDialogThread(private val activity: FragmentActivity) {
putBoolean(DatabaseTaskNotificationService.MASTER_PASSWORD_CHECKED_KEY, masterPasswordChecked) putBoolean(DatabaseTaskNotificationService.MASTER_PASSWORD_CHECKED_KEY, masterPasswordChecked)
putString(DatabaseTaskNotificationService.MASTER_PASSWORD_KEY, masterPassword) putString(DatabaseTaskNotificationService.MASTER_PASSWORD_KEY, masterPassword)
putBoolean(DatabaseTaskNotificationService.KEY_FILE_CHECKED_KEY, keyFileChecked) putBoolean(DatabaseTaskNotificationService.KEY_FILE_CHECKED_KEY, keyFileChecked)
putParcelable(DatabaseTaskNotificationService.KEY_FILE_KEY, keyFile) putParcelable(DatabaseTaskNotificationService.KEY_FILE_URI_KEY, keyFile)
} }
, ACTION_DATABASE_CREATE_TASK) , ACTION_DATABASE_CREATE_TASK)
} }
@@ -255,7 +255,7 @@ class ProgressDialogThread(private val activity: FragmentActivity) {
start(Bundle().apply { start(Bundle().apply {
putParcelable(DatabaseTaskNotificationService.DATABASE_URI_KEY, databaseUri) putParcelable(DatabaseTaskNotificationService.DATABASE_URI_KEY, databaseUri)
putString(DatabaseTaskNotificationService.MASTER_PASSWORD_KEY, masterPassword) putString(DatabaseTaskNotificationService.MASTER_PASSWORD_KEY, masterPassword)
putParcelable(DatabaseTaskNotificationService.KEY_FILE_KEY, keyFile) putParcelable(DatabaseTaskNotificationService.KEY_FILE_URI_KEY, keyFile)
putBoolean(DatabaseTaskNotificationService.READ_ONLY_KEY, readOnly) putBoolean(DatabaseTaskNotificationService.READ_ONLY_KEY, readOnly)
putParcelable(DatabaseTaskNotificationService.CIPHER_ENTITY_KEY, cipherEntity) putParcelable(DatabaseTaskNotificationService.CIPHER_ENTITY_KEY, cipherEntity)
putBoolean(DatabaseTaskNotificationService.FIX_DUPLICATE_UUID_KEY, fixDuplicateUuid) putBoolean(DatabaseTaskNotificationService.FIX_DUPLICATE_UUID_KEY, fixDuplicateUuid)
@@ -274,7 +274,7 @@ class ProgressDialogThread(private val activity: FragmentActivity) {
putBoolean(DatabaseTaskNotificationService.MASTER_PASSWORD_CHECKED_KEY, masterPasswordChecked) putBoolean(DatabaseTaskNotificationService.MASTER_PASSWORD_CHECKED_KEY, masterPasswordChecked)
putString(DatabaseTaskNotificationService.MASTER_PASSWORD_KEY, masterPassword) putString(DatabaseTaskNotificationService.MASTER_PASSWORD_KEY, masterPassword)
putBoolean(DatabaseTaskNotificationService.KEY_FILE_CHECKED_KEY, keyFileChecked) putBoolean(DatabaseTaskNotificationService.KEY_FILE_CHECKED_KEY, keyFileChecked)
putParcelable(DatabaseTaskNotificationService.KEY_FILE_KEY, keyFile) putParcelable(DatabaseTaskNotificationService.KEY_FILE_URI_KEY, keyFile)
} }
, ACTION_DATABASE_ASSIGN_PASSWORD_TASK) , ACTION_DATABASE_ASSIGN_PASSWORD_TASK)
} }

View File

@@ -0,0 +1,26 @@
package com.kunzisoft.keepass.model
import android.net.Uri
data class DatabaseFile(var databaseUri: Uri? = null,
var keyFileUri: Uri? = null,
var databaseDecodedPath: String? = null,
var databaseAlias: String? = null,
var databaseFileExists: Boolean = false,
var databaseLastModified: String? = null,
var databaseSize: String? = null) {
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (other !is DatabaseFile) return false
if (databaseUri == null) return false
if (databaseUri != other.databaseUri) return false
return true
}
override fun hashCode(): Int {
return databaseUri?.hashCode() ?: 0
}
}

View File

@@ -295,7 +295,7 @@ open class DatabaseTaskNotificationService : LockNotificationService(), Progress
intent?.removeExtra(MASTER_PASSWORD_CHECKED_KEY) intent?.removeExtra(MASTER_PASSWORD_CHECKED_KEY)
intent?.removeExtra(MASTER_PASSWORD_KEY) intent?.removeExtra(MASTER_PASSWORD_KEY)
intent?.removeExtra(KEY_FILE_CHECKED_KEY) intent?.removeExtra(KEY_FILE_CHECKED_KEY)
intent?.removeExtra(KEY_FILE_KEY) intent?.removeExtra(KEY_FILE_URI_KEY)
intent?.removeExtra(READ_ONLY_KEY) intent?.removeExtra(READ_ONLY_KEY)
intent?.removeExtra(CIPHER_ENTITY_KEY) intent?.removeExtra(CIPHER_ENTITY_KEY)
intent?.removeExtra(FIX_DUPLICATE_UUID_KEY) intent?.removeExtra(FIX_DUPLICATE_UUID_KEY)
@@ -380,10 +380,10 @@ open class DatabaseTaskNotificationService : LockNotificationService(), Progress
&& intent.hasExtra(MASTER_PASSWORD_CHECKED_KEY) && intent.hasExtra(MASTER_PASSWORD_CHECKED_KEY)
&& intent.hasExtra(MASTER_PASSWORD_KEY) && intent.hasExtra(MASTER_PASSWORD_KEY)
&& intent.hasExtra(KEY_FILE_CHECKED_KEY) && intent.hasExtra(KEY_FILE_CHECKED_KEY)
&& intent.hasExtra(KEY_FILE_KEY) && intent.hasExtra(KEY_FILE_URI_KEY)
) { ) {
val databaseUri: Uri? = intent.getParcelableExtra(DATABASE_URI_KEY) val databaseUri: Uri? = intent.getParcelableExtra(DATABASE_URI_KEY)
val keyFileUri: Uri? = intent.getParcelableExtra(KEY_FILE_KEY) val keyFileUri: Uri? = intent.getParcelableExtra(KEY_FILE_URI_KEY)
if (databaseUri == null) if (databaseUri == null)
return null return null
@@ -407,14 +407,14 @@ open class DatabaseTaskNotificationService : LockNotificationService(), Progress
if (intent.hasExtra(DATABASE_URI_KEY) if (intent.hasExtra(DATABASE_URI_KEY)
&& intent.hasExtra(MASTER_PASSWORD_KEY) && intent.hasExtra(MASTER_PASSWORD_KEY)
&& intent.hasExtra(KEY_FILE_KEY) && intent.hasExtra(KEY_FILE_URI_KEY)
&& intent.hasExtra(READ_ONLY_KEY) && intent.hasExtra(READ_ONLY_KEY)
&& intent.hasExtra(CIPHER_ENTITY_KEY) && intent.hasExtra(CIPHER_ENTITY_KEY)
&& intent.hasExtra(FIX_DUPLICATE_UUID_KEY) && intent.hasExtra(FIX_DUPLICATE_UUID_KEY)
) { ) {
val databaseUri: Uri? = intent.getParcelableExtra(DATABASE_URI_KEY) val databaseUri: Uri? = intent.getParcelableExtra(DATABASE_URI_KEY)
val masterPassword: String? = intent.getStringExtra(MASTER_PASSWORD_KEY) val masterPassword: String? = intent.getStringExtra(MASTER_PASSWORD_KEY)
val keyFileUri: Uri? = intent.getParcelableExtra(KEY_FILE_KEY) val keyFileUri: Uri? = intent.getParcelableExtra(KEY_FILE_URI_KEY)
val readOnly: Boolean = intent.getBooleanExtra(READ_ONLY_KEY, true) val readOnly: Boolean = intent.getBooleanExtra(READ_ONLY_KEY, true)
val cipherEntity: CipherDatabaseEntity? = intent.getParcelableExtra(CIPHER_ENTITY_KEY) val cipherEntity: CipherDatabaseEntity? = intent.getParcelableExtra(CIPHER_ENTITY_KEY)
@@ -436,7 +436,7 @@ open class DatabaseTaskNotificationService : LockNotificationService(), Progress
result.data = Bundle().apply { result.data = Bundle().apply {
putParcelable(DATABASE_URI_KEY, databaseUri) putParcelable(DATABASE_URI_KEY, databaseUri)
putString(MASTER_PASSWORD_KEY, masterPassword) putString(MASTER_PASSWORD_KEY, masterPassword)
putParcelable(KEY_FILE_KEY, keyFileUri) putParcelable(KEY_FILE_URI_KEY, keyFileUri)
putBoolean(READ_ONLY_KEY, readOnly) putBoolean(READ_ONLY_KEY, readOnly)
putParcelable(CIPHER_ENTITY_KEY, cipherEntity) putParcelable(CIPHER_ENTITY_KEY, cipherEntity)
} }
@@ -451,7 +451,7 @@ open class DatabaseTaskNotificationService : LockNotificationService(), Progress
&& intent.hasExtra(MASTER_PASSWORD_CHECKED_KEY) && intent.hasExtra(MASTER_PASSWORD_CHECKED_KEY)
&& intent.hasExtra(MASTER_PASSWORD_KEY) && intent.hasExtra(MASTER_PASSWORD_KEY)
&& intent.hasExtra(KEY_FILE_CHECKED_KEY) && intent.hasExtra(KEY_FILE_CHECKED_KEY)
&& intent.hasExtra(KEY_FILE_KEY) && intent.hasExtra(KEY_FILE_URI_KEY)
) { ) {
val databaseUri: Uri = intent.getParcelableExtra(DATABASE_URI_KEY) ?: return null val databaseUri: Uri = intent.getParcelableExtra(DATABASE_URI_KEY) ?: return null
AssignPasswordInDatabaseRunnable(this, AssignPasswordInDatabaseRunnable(this,
@@ -460,7 +460,7 @@ open class DatabaseTaskNotificationService : LockNotificationService(), Progress
intent.getBooleanExtra(MASTER_PASSWORD_CHECKED_KEY, false), intent.getBooleanExtra(MASTER_PASSWORD_CHECKED_KEY, false),
intent.getStringExtra(MASTER_PASSWORD_KEY), intent.getStringExtra(MASTER_PASSWORD_KEY),
intent.getBooleanExtra(KEY_FILE_CHECKED_KEY, false), intent.getBooleanExtra(KEY_FILE_CHECKED_KEY, false),
intent.getParcelableExtra(KEY_FILE_KEY) intent.getParcelableExtra(KEY_FILE_URI_KEY)
) )
} else { } else {
null null
@@ -766,7 +766,7 @@ open class DatabaseTaskNotificationService : LockNotificationService(), Progress
const val MASTER_PASSWORD_CHECKED_KEY = "MASTER_PASSWORD_CHECKED_KEY" const val MASTER_PASSWORD_CHECKED_KEY = "MASTER_PASSWORD_CHECKED_KEY"
const val MASTER_PASSWORD_KEY = "MASTER_PASSWORD_KEY" const val MASTER_PASSWORD_KEY = "MASTER_PASSWORD_KEY"
const val KEY_FILE_CHECKED_KEY = "KEY_FILE_CHECKED_KEY" const val KEY_FILE_CHECKED_KEY = "KEY_FILE_CHECKED_KEY"
const val KEY_FILE_KEY = "KEY_FILE_KEY" const val KEY_FILE_URI_KEY = "KEY_FILE_KEY"
const val READ_ONLY_KEY = "READ_ONLY_KEY" const val READ_ONLY_KEY = "READ_ONLY_KEY"
const val CIPHER_ENTITY_KEY = "CIPHER_ENTITY_KEY" const val CIPHER_ENTITY_KEY = "CIPHER_ENTITY_KEY"
const val FIX_DUPLICATE_UUID_KEY = "FIX_DUPLICATE_UUID_KEY" const val FIX_DUPLICATE_UUID_KEY = "FIX_DUPLICATE_UUID_KEY"

View File

@@ -0,0 +1,49 @@
package com.kunzisoft.keepass.viewmodels
import android.app.Application
import android.net.Uri
import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.MutableLiveData
import com.kunzisoft.keepass.app.App
import com.kunzisoft.keepass.app.database.FileDatabaseHistoryAction
import com.kunzisoft.keepass.app.database.IOActionTask
import com.kunzisoft.keepass.model.DatabaseFile
import com.kunzisoft.keepass.utils.UriUtil
class DatabaseFileViewModel(application: Application) : AndroidViewModel(application) {
private var mFileDatabaseHistoryAction: FileDatabaseHistoryAction? = null
init {
mFileDatabaseHistoryAction = FileDatabaseHistoryAction.getInstance(application.applicationContext)
}
val databaseFileLoaded: MutableLiveData<DatabaseFile> by lazy {
MutableLiveData<DatabaseFile>()
}
fun loadDatabaseFile(databaseUri: Uri) {
mFileDatabaseHistoryAction?.getFileDatabaseHistory(databaseUri) { fileDatabaseHistoryEntity ->
IOActionTask (
{
val fileDatabaseInfo = FileDatabaseInfo(
getApplication<App>().applicationContext,
databaseUri
)
DatabaseFile(
databaseUri,
UriUtil.parse(fileDatabaseHistoryEntity?.keyFileUri),
UriUtil.decode(fileDatabaseHistoryEntity?.databaseUri),
fileDatabaseInfo.retrieveDatabaseAlias(fileDatabaseHistoryEntity?.databaseAlias ?: ""),
fileDatabaseInfo.exists,
fileDatabaseInfo.getModificationString(),
fileDatabaseInfo.getSizeString()
)
},
{
databaseFileLoaded.value = it ?: DatabaseFile(databaseUri)
}
).execute()
}
}
}

View File

@@ -0,0 +1,187 @@
package com.kunzisoft.keepass.viewmodels
import android.app.Application
import androidx.lifecycle.*
import com.kunzisoft.keepass.app.App
import com.kunzisoft.keepass.app.database.FileDatabaseHistoryAction
import com.kunzisoft.keepass.app.database.IOActionTask
import com.kunzisoft.keepass.model.DatabaseFile
import com.kunzisoft.keepass.settings.PreferencesUtil
import com.kunzisoft.keepass.utils.UriUtil
class DatabaseFilesViewModel(application: Application) : AndroidViewModel(application) {
private var mFileDatabaseHistoryAction: FileDatabaseHistoryAction? = null
init {
mFileDatabaseHistoryAction = FileDatabaseHistoryAction.getInstance(application.applicationContext)
}
val databaseFilesLoaded: MutableLiveData<DatabaseFileData> by lazy {
MutableLiveData<DatabaseFileData>()
}
fun loadListOfDatabases() {
val databaseFileListLoaded = ArrayList<DatabaseFile>()
mFileDatabaseHistoryAction?.getAllFileDatabaseHistories { databaseFileHistoryList ->
databaseFileHistoryList?.let { historyList ->
IOActionTask({
val context = getApplication<App>().applicationContext
val hideBrokenLocations = PreferencesUtil.hideBrokenLocations(context)
// Show only uri accessible
historyList.forEach { fileDatabaseHistoryEntity ->
val fileDatabaseInfo = FileDatabaseInfo(context, fileDatabaseHistoryEntity.databaseUri)
if (hideBrokenLocations && fileDatabaseInfo.exists
|| !hideBrokenLocations) {
databaseFileListLoaded.add(
DatabaseFile(
UriUtil.parse(fileDatabaseHistoryEntity.databaseUri),
UriUtil.parse(fileDatabaseHistoryEntity.keyFileUri),
UriUtil.decode(fileDatabaseHistoryEntity.databaseUri),
fileDatabaseInfo.retrieveDatabaseAlias(fileDatabaseHistoryEntity.databaseAlias),
fileDatabaseInfo.exists,
fileDatabaseInfo.getModificationString(),
fileDatabaseInfo.getSizeString()
)
)
}
}
}, {
var newValue = databaseFilesLoaded.value
if (newValue == null) {
newValue = DatabaseFileData()
}
newValue.apply {
databaseFileAction = DatabaseFileAction.NONE
databaseFileToActivate = null
databaseFileList.apply {
clear()
addAll(databaseFileListLoaded)
}
}
databaseFilesLoaded.value = newValue
}).execute()
}
}
}
fun addDatabaseFile(databaseFileToAdd: DatabaseFile) {
addOrUpdateDatabaseFile(databaseFileToAdd, DatabaseFileAction.ADD)
}
fun updateDatabaseFile(databaseFileToUpdate: DatabaseFile) {
addOrUpdateDatabaseFile(databaseFileToUpdate, DatabaseFileAction.UPDATE)
}
private fun addOrUpdateDatabaseFile(databaseFileToAddOrUpdate: DatabaseFile,
databaseFileAction: DatabaseFileAction) {
databaseFileToAddOrUpdate.databaseUri?.let { databaseUri ->
mFileDatabaseHistoryAction?.getFileDatabaseHistory(databaseUri) { fileDatabaseHistoryToAddOrUpdate ->
fileDatabaseHistoryToAddOrUpdate?.let {
mFileDatabaseHistoryAction?.addOrUpdateFileDatabaseHistory(fileDatabaseHistoryToAddOrUpdate) { fileHistoryAddedOrUpdated ->
fileHistoryAddedOrUpdated?.let {
IOActionTask (
{
val newValue = databaseFilesLoaded.value
newValue?.apply {
val fileDatabaseInfo = FileDatabaseInfo(getApplication<App>().applicationContext,
fileHistoryAddedOrUpdated.databaseUri)
this.databaseFileAction = databaseFileAction
val databaseFileToActivate =
DatabaseFile(
UriUtil.parse(fileHistoryAddedOrUpdated.databaseUri),
UriUtil.parse(fileHistoryAddedOrUpdated.keyFileUri),
UriUtil.decode(fileHistoryAddedOrUpdated.databaseUri),
fileDatabaseInfo.retrieveDatabaseAlias(fileHistoryAddedOrUpdated.databaseAlias),
fileDatabaseInfo.exists,
fileDatabaseInfo.getModificationString(),
fileDatabaseInfo.getSizeString()
)
when (databaseFileAction) {
DatabaseFileAction.ADD -> {
databaseFileList.add(databaseFileToActivate)
}
DatabaseFileAction.UPDATE -> {
databaseFileList
.find { it.databaseUri == databaseFileToActivate.databaseUri }
?.apply {
keyFileUri = databaseFileToActivate.keyFileUri
databaseAlias = databaseFileToActivate.databaseAlias
databaseFileExists = databaseFileToActivate.databaseFileExists
databaseLastModified = databaseFileToActivate.databaseLastModified
databaseSize = databaseFileToActivate.databaseSize
}
}
else -> {}
}
this.databaseFileToActivate = databaseFileToActivate
}
},
{ databaseFileAddedOrUpdated ->
databaseFileAddedOrUpdated?.let {
databaseFilesLoaded.value = it
}
}
).execute()
}
}
}
}
}
}
fun deleteDatabaseFile(databaseFileToDelete: DatabaseFile) {
databaseFileToDelete.databaseUri?.let { databaseUri ->
mFileDatabaseHistoryAction?.getFileDatabaseHistory(databaseUri) { fileDatabaseHistoryToDelete ->
fileDatabaseHistoryToDelete?.let {
mFileDatabaseHistoryAction?.deleteFileDatabaseHistory(fileDatabaseHistoryToDelete) { fileHistoryDeleted ->
fileHistoryDeleted?.let { _ ->
IOActionTask (
{
val newValue = databaseFilesLoaded.value
newValue?.apply {
databaseFileAction = DatabaseFileAction.DELETE
databaseFileToActivate =
DatabaseFile(
UriUtil.parse(fileHistoryDeleted.databaseUri),
UriUtil.parse(fileHistoryDeleted.keyFileUri),
UriUtil.decode(fileHistoryDeleted.databaseUri),
databaseFileToDelete.databaseAlias
)
databaseFileList.remove(databaseFileToDelete)
}
},
{ databaseFileDeleted ->
databaseFileDeleted?.let {
databaseFilesLoaded.value = it
}
}
).execute()
}
}
}
}
}
}
fun consumeAction() {
databaseFilesLoaded.value?.apply {
databaseFileAction = DatabaseFileAction.NONE
databaseFileToActivate = null
}
}
class DatabaseFileData {
val databaseFileList = ArrayList<DatabaseFile>()
var databaseFileToActivate: DatabaseFile? = null
var databaseFileAction: DatabaseFileAction = DatabaseFileAction.NONE
}
enum class DatabaseFileAction {
NONE, ADD, UPDATE, DELETE
}
}

View File

@@ -17,14 +17,14 @@
* along with KeePassDX. If not, see <http://www.gnu.org/licenses/>. * along with KeePassDX. If not, see <http://www.gnu.org/licenses/>.
* *
*/ */
package com.kunzisoft.keepass.utils package com.kunzisoft.keepass.viewmodels
import android.content.Context import android.content.Context
import android.net.Uri import android.net.Uri
import android.text.format.Formatter import android.text.format.Formatter
import androidx.documentfile.provider.DocumentFile import androidx.documentfile.provider.DocumentFile
import com.kunzisoft.keepass.app.database.FileDatabaseHistoryAction
import com.kunzisoft.keepass.settings.PreferencesUtil import com.kunzisoft.keepass.settings.PreferencesUtil
import com.kunzisoft.keepass.utils.UriUtil
import java.io.Serializable import java.io.Serializable
import java.text.DateFormat import java.text.DateFormat
import java.util.* import java.util.*
@@ -58,18 +58,6 @@ class FileDatabaseInfo : Serializable {
} }
private set private set
var canRead: Boolean = false
get() {
return documentFile?.canRead() ?: field
}
private set
var canWrite: Boolean = false
get() {
return documentFile?.canWrite() ?: field
}
private set
fun getModificationString(): String? { fun getModificationString(): String? {
return documentFile?.lastModified()?.let { return documentFile?.lastModified()?.let {
DateFormat.getDateTimeInstance() DateFormat.getDateTimeInstance()
@@ -83,21 +71,11 @@ class FileDatabaseInfo : Serializable {
} }
} }
fun retrieveDatabaseAlias(alias: String): String { fun retrieveDatabaseAlias(alias: String): String? {
return when { return when {
alias.isNotEmpty() -> alias alias.isNotEmpty() -> alias
PreferencesUtil.isFullFilePathEnable(context) -> fileUri?.path ?: "" PreferencesUtil.isFullFilePathEnable(context) -> fileUri?.path
else -> if (exists) documentFile?.name ?: "" else fileUri?.path ?: "" else -> if (exists) documentFile?.name else fileUri?.path
}
}
fun retrieveDatabaseTitle(titleCallback: (String)->Unit) {
fileUri?.let { fileUri ->
FileDatabaseHistoryAction.getInstance(context.applicationContext)
.getFileDatabaseHistory(fileUri) { fileDatabaseHistoryEntity ->
titleCallback.invoke(retrieveDatabaseAlias(fileDatabaseHistoryEntity?.databaseAlias
?: ""))
}
} }
} }
} }