diff options
Diffstat (limited to 'app')
8 files changed, 61 insertions, 0 deletions
diff --git a/app/src/main/java/com/zeapo/pwdstore/PasswordFragment.kt b/app/src/main/java/com/zeapo/pwdstore/PasswordFragment.kt index 6657afaf..9e50ad2b 100644 --- a/app/src/main/java/com/zeapo/pwdstore/PasswordFragment.kt +++ b/app/src/main/java/com/zeapo/pwdstore/PasswordFragment.kt @@ -16,6 +16,7 @@ import android.view.animation.Animation import android.view.animation.AnimationUtils import androidx.activity.result.contract.ActivityResultContracts.StartActivityForResult import androidx.appcompat.view.ActionMode +import androidx.core.content.edit import androidx.fragment.app.Fragment import androidx.fragment.app.activityViewModels import androidx.recyclerview.widget.DividerItemDecoration @@ -32,6 +33,9 @@ import com.zeapo.pwdstore.ui.adapters.PasswordItemRecyclerAdapter import com.zeapo.pwdstore.ui.dialogs.ItemCreationBottomSheet import com.zeapo.pwdstore.utils.PasswordItem import com.zeapo.pwdstore.utils.PasswordRepository +import com.zeapo.pwdstore.utils.PreferenceKeys +import com.zeapo.pwdstore.utils.base64 +import com.zeapo.pwdstore.utils.getString import com.zeapo.pwdstore.utils.sharedPrefs import com.zeapo.pwdstore.utils.viewBinding import java.io.File @@ -243,6 +247,14 @@ class PasswordFragment : Fragment(R.layout.password_recycler_view) { try { listener = object : OnFragmentInteractionListener { override fun onFragmentInteraction(item: PasswordItem) { + if (settings.getString(PreferenceKeys.SORT_ORDER) == PasswordRepository.PasswordSortOrder.RECENTLY_USED.name) { + //save the time when password was used + val preferences = context.getSharedPreferences("recent_password_history", Context.MODE_PRIVATE) + preferences.edit { + putString(item.file.absolutePath.base64(), System.currentTimeMillis().toString()) + } + } + if (item.type == PasswordItem.TYPE_CATEGORY) { navigateTo(item.file) } else { diff --git a/app/src/main/java/com/zeapo/pwdstore/PasswordStore.kt b/app/src/main/java/com/zeapo/pwdstore/PasswordStore.kt index 3ebd35b8..fe1ab085 100644 --- a/app/src/main/java/com/zeapo/pwdstore/PasswordStore.kt +++ b/app/src/main/java/com/zeapo/pwdstore/PasswordStore.kt @@ -6,6 +6,7 @@ package com.zeapo.pwdstore import android.Manifest import android.annotation.SuppressLint +import android.content.Context import android.content.Intent import android.content.pm.PackageManager import android.content.pm.ShortcutInfo.Builder @@ -63,6 +64,7 @@ import com.zeapo.pwdstore.utils.PasswordRepository.Companion.initialize import com.zeapo.pwdstore.utils.PasswordRepository.Companion.isInitialized import com.zeapo.pwdstore.utils.PasswordRepository.PasswordSortOrder.Companion.getSortOrder import com.zeapo.pwdstore.utils.PreferenceKeys +import com.zeapo.pwdstore.utils.base64 import com.zeapo.pwdstore.utils.commitChange import com.zeapo.pwdstore.utils.contains import com.zeapo.pwdstore.utils.getString @@ -753,6 +755,17 @@ class PasswordStore : AppCompatActivity(R.layout.activity_pwdstore) { !newCategory.isInsideRepository() -> renameCategory(oldCategory, CategoryRenameError.DestinationOutsideRepo) else -> lifecycleScope.launch(Dispatchers.IO) { moveFile(oldCategory.file, newCategory) + + //associate the new category with the last category's timestamp in history + val preference = getSharedPreferences("recent_password_history", Context.MODE_PRIVATE) + val timestamp = preference.getString(oldCategory.file.absolutePath) + if (timestamp != null) { + preference.edit { + remove(oldCategory.file.absolutePath.base64()) + putString(newCategory.absolutePath.base64(), timestamp) + } + } + withContext(Dispatchers.Main) { commitChange( resources.getString(R.string.git_commit_move_text, oldCategory.name, newCategory.name), diff --git a/app/src/main/java/com/zeapo/pwdstore/SearchableRepositoryViewModel.kt b/app/src/main/java/com/zeapo/pwdstore/SearchableRepositoryViewModel.kt index 7ffa71a3..0509a3dd 100644 --- a/app/src/main/java/com/zeapo/pwdstore/SearchableRepositoryViewModel.kt +++ b/app/src/main/java/com/zeapo/pwdstore/SearchableRepositoryViewModel.kt @@ -96,6 +96,7 @@ private fun PasswordItem.Companion.makeComparator( // declare them all equal at this stage. PasswordRepository.PasswordSortOrder.INDEPENDENT -> Comparator<PasswordItem> { _, _ -> 0 } PasswordRepository.PasswordSortOrder.FILE_FIRST -> compareByDescending { it.type } + PasswordRepository.PasswordSortOrder.RECENTLY_USED -> PasswordRepository.PasswordSortOrder.RECENTLY_USED.comparator } .then(compareBy(nullsLast(CaseInsensitiveComparator)) { directoryStructure.getIdentifierFor(it.file) diff --git a/app/src/main/java/com/zeapo/pwdstore/crypto/PasswordCreationActivity.kt b/app/src/main/java/com/zeapo/pwdstore/crypto/PasswordCreationActivity.kt index 1376dd04..c5d3d70a 100644 --- a/app/src/main/java/com/zeapo/pwdstore/crypto/PasswordCreationActivity.kt +++ b/app/src/main/java/com/zeapo/pwdstore/crypto/PasswordCreationActivity.kt @@ -5,6 +5,7 @@ package com.zeapo.pwdstore.crypto +import android.content.Context import android.content.Intent import android.os.Bundle import android.text.InputType @@ -14,6 +15,7 @@ import android.view.View import androidx.activity.result.IntentSenderRequest import androidx.activity.result.contract.ActivityResultContracts.StartActivityForResult import androidx.activity.result.contract.ActivityResultContracts.StartIntentSenderForResult +import androidx.core.content.edit import androidx.core.view.isVisible import androidx.core.widget.doOnTextChanged import androidx.lifecycle.lifecycleScope @@ -30,6 +32,7 @@ import com.zeapo.pwdstore.ui.dialogs.PasswordGeneratorDialogFragment import com.zeapo.pwdstore.ui.dialogs.XkPasswordGeneratorDialogFragment import com.zeapo.pwdstore.utils.PasswordRepository import com.zeapo.pwdstore.utils.PreferenceKeys +import com.zeapo.pwdstore.utils.base64 import com.zeapo.pwdstore.utils.commitChange import com.zeapo.pwdstore.utils.getString import com.zeapo.pwdstore.utils.isInsideRepository @@ -411,6 +414,17 @@ class PasswordCreationActivity : BasePgpActivity(), OpenPgpServiceConnection.OnB return@executeApiAsync } + //associate the new password name with the last name's timestamp in history + val preference = getSharedPreferences("recent_password_history", Context.MODE_PRIVATE) + val oldFilePathHash = "$repoPath/${oldCategory?.trim('/')}/$oldFileName.gpg".base64() + val timestamp = preference.getString(oldFilePathHash) + if (timestamp != null) { + preference.edit { + remove(oldFilePathHash) + putString(file.absolutePath.base64(), timestamp) + } + } + val returnIntent = Intent() returnIntent.putExtra(RETURN_EXTRA_CREATED_FILE, path) returnIntent.putExtra(RETURN_EXTRA_NAME, editName) diff --git a/app/src/main/java/com/zeapo/pwdstore/utils/Extensions.kt b/app/src/main/java/com/zeapo/pwdstore/utils/Extensions.kt index 96bf1b7e..561b8d99 100644 --- a/app/src/main/java/com/zeapo/pwdstore/utils/Extensions.kt +++ b/app/src/main/java/com/zeapo/pwdstore/utils/Extensions.kt @@ -9,6 +9,7 @@ import android.content.Context import android.content.Intent import android.content.SharedPreferences import android.os.Build +import android.util.Base64 import android.util.TypedValue import android.view.View import android.view.autofill.AutofillManager @@ -42,6 +43,10 @@ fun String.splitLines(): Array<String> { return split("\n".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray() } +fun String.base64(): String { + return Base64.encodeToString(encodeToByteArray(), Base64.NO_WRAP) +} + val Context.clipboard get() = getSystemService<ClipboardManager>() fun FragmentActivity.snackbar( diff --git a/app/src/main/java/com/zeapo/pwdstore/utils/PasswordRepository.kt b/app/src/main/java/com/zeapo/pwdstore/utils/PasswordRepository.kt index 8a49f0e3..45453d4f 100644 --- a/app/src/main/java/com/zeapo/pwdstore/utils/PasswordRepository.kt +++ b/app/src/main/java/com/zeapo/pwdstore/utils/PasswordRepository.kt @@ -4,6 +4,7 @@ */ package com.zeapo.pwdstore.utils +import android.content.Context import android.content.SharedPreferences import androidx.core.content.edit import com.zeapo.pwdstore.Application @@ -31,6 +32,18 @@ open class PasswordRepository protected constructor() { p1.name.compareTo(p2.name, ignoreCase = true) }), + RECENTLY_USED(Comparator { p1: PasswordItem, p2: PasswordItem -> + val recentHistory = Application.instance.getSharedPreferences("recent_password_history", Context.MODE_PRIVATE) + val timeP1 = recentHistory.getString(p1.file.absolutePath.base64()) + val timeP2 = recentHistory.getString(p2.file.absolutePath.base64()) + when { + timeP1 != null && timeP2 != null -> timeP2.compareTo(timeP1) + timeP1 != null && timeP2 == null -> return@Comparator -1 + timeP1 == null && timeP2 != null -> return@Comparator 1 + else -> p1.name.compareTo(p2.name, ignoreCase = true) + } + }), + FILE_FIRST(Comparator { p1: PasswordItem, p2: PasswordItem -> (p2.type + p1.name).compareTo(p1.type + p2.name, ignoreCase = true) }); diff --git a/app/src/main/res/values/arrays.xml b/app/src/main/res/values/arrays.xml index 6b5edf6c..2b320f31 100644 --- a/app/src/main/res/values/arrays.xml +++ b/app/src/main/res/values/arrays.xml @@ -8,11 +8,13 @@ <item>@string/pref_folder_first_sort_order</item> <item>@string/pref_file_first_sort_order</item> <item>@string/pref_type_independent_sort_order</item> + <item>@string/pref_recently_used_sort_order</item> </string-array> <string-array name="sort_order_values"> <item>FOLDER_FIRST</item> <item>FILE_FIRST</item> <item>INDEPENDENT</item> + <item>RECENTLY_USED</item> </string-array> <string-array name="capitalization_type_values"> <item>lowercase</item> diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index fe2a3488..ff1d5238 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -140,6 +140,7 @@ <string name="pref_folder_first_sort_order">Folders first</string> <string name="pref_file_first_sort_order">Files first</string> <string name="pref_type_independent_sort_order">Type independent</string> + <string name="pref_recently_used_sort_order">Recently used</string> <string name="pref_autofill_title">Autofill</string> <string name="pref_autofill_enable_title">Enable Autofill</string> <string name="pref_autofill_enable_msg">Tap OK to go to Accessibility settings. There, tap Password Store under Services then tap the switch in the top right to turn it on or off.</string> |