From cfb42f02f5ce7cb9c58e757007e7258e9db0559f Mon Sep 17 00:00:00 2001 From: Diogenes Molinares Date: Thu, 20 Aug 2020 13:53:34 +0200 Subject: Sort by recently used (#1031) * Sort passwords by recently used * reformat * modified CHANGELOG.md * restore format CHANGELOG.md * added new sharedPreferences file to manage recent password history * associate timestamp when rename category * associate timestamp when rename password * reformat * Update CHANGELOG.md Co-authored-by: Fabian Henneke * Update app/src/main/java/com/zeapo/pwdstore/PasswordFragment.kt Co-authored-by: Fabian Henneke * Update app/src/main/java/com/zeapo/pwdstore/PasswordFragment.kt Co-authored-by: Fabian Henneke * use kotlin edit extension * Add changelog entry correctly Signed-off-by: Harsh Shandilya * Save paths as Base64 hashes Signed-off-by: Harsh Shandilya * Missed it Signed-off-by: Harsh Shandilya Co-authored-by: Fabian Henneke Co-authored-by: Harsh Shandilya --- app/src/main/java/com/zeapo/pwdstore/PasswordFragment.kt | 12 ++++++++++++ app/src/main/java/com/zeapo/pwdstore/PasswordStore.kt | 13 +++++++++++++ .../com/zeapo/pwdstore/SearchableRepositoryViewModel.kt | 1 + .../com/zeapo/pwdstore/crypto/PasswordCreationActivity.kt | 14 ++++++++++++++ app/src/main/java/com/zeapo/pwdstore/utils/Extensions.kt | 5 +++++ .../java/com/zeapo/pwdstore/utils/PasswordRepository.kt | 13 +++++++++++++ 6 files changed, 58 insertions(+) (limited to 'app/src/main/java/com/zeapo') 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 { _, _ -> 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 { return split("\n".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray() } +fun String.base64(): String { + return Base64.encodeToString(encodeToByteArray(), Base64.NO_WRAP) +} + val Context.clipboard get() = getSystemService() 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) }); -- cgit v1.2.3