From 1ce3ef4ea3c55d4a6c4a79f8a6cca58387b240df Mon Sep 17 00:00:00 2001 From: Harsh Shandilya Date: Thu, 27 Aug 2020 14:27:55 +0530 Subject: Expand show hidden folders to also cover files (#1059) * PasswordItem: only strip .gpg suffixes Signed-off-by: Harsh Shandilya * Add preference key and migration for showing all hidden contents Signed-off-by: Harsh Shandilya * Allow showing both hidden files and directories Signed-off-by: Harsh Shandilya * Add tests for hidden folder setting migration Signed-off-by: Harsh Shandilya * Add changelog entry Signed-off-by: Harsh Shandilya * Slightly improve migration logic Skip migration if old key is not found and always delete the previous key even if its set to false. Signed-off-by: Harsh Shandilya * Tweak wording Suggested-by: Fabian Henneke Signed-off-by: Harsh Shandilya * Assert previous key's removal in tests Signed-off-by: Harsh Shandilya --- CHANGELOG.md | 1 + .../java/com/zeapo/pwdstore/MigrationsTest.kt | 26 ++++++++++++++++++++-- app/src/main/java/com/zeapo/pwdstore/Migrations.kt | 10 +++++++++ .../pwdstore/SearchableRepositoryViewModel.kt | 9 ++++---- .../ui/adapters/PasswordItemRecyclerAdapter.kt | 6 ++--- .../java/com/zeapo/pwdstore/utils/PasswordItem.kt | 2 +- .../com/zeapo/pwdstore/utils/PasswordRepository.kt | 6 ++--- .../com/zeapo/pwdstore/utils/PreferenceKeys.kt | 11 +++++++++ app/src/main/res/values-pt-rBR/strings.xml | 2 -- app/src/main/res/values-ru/strings.xml | 2 -- app/src/main/res/values/strings.xml | 4 ++-- app/src/main/res/xml/preference.xml | 2 +- 12 files changed, 60 insertions(+), 21 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c375b7ff..cc7e4a73 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ All notable changes to this project will be documented in this file. - A descriptive error message is shown if no username is specified in the Git server settings - Remove explicit protocol choice from Git server settings, it is now inferred from your URL +- 'Show hidden folders' is now 'Show hidden files and folders' ### Fixed diff --git a/app/src/androidTest/java/com/zeapo/pwdstore/MigrationsTest.kt b/app/src/androidTest/java/com/zeapo/pwdstore/MigrationsTest.kt index c66bb215..5ba1b307 100644 --- a/app/src/androidTest/java/com/zeapo/pwdstore/MigrationsTest.kt +++ b/app/src/androidTest/java/com/zeapo/pwdstore/MigrationsTest.kt @@ -4,6 +4,7 @@ */ @file:Suppress("DEPRECATION") + package com.zeapo.pwdstore import android.content.Context @@ -13,10 +14,10 @@ import com.zeapo.pwdstore.git.config.Protocol import com.zeapo.pwdstore.utils.PreferenceKeys import com.zeapo.pwdstore.utils.getString import com.zeapo.pwdstore.utils.sharedPrefs +import org.junit.Assert.assertEquals +import org.junit.Assert.assertNull import org.junit.Test -import org.junit.Assert.* - class MigrationsTest { private fun checkOldKeysAreRemoved(context: Context) = with(context.sharedPrefs) { @@ -84,4 +85,25 @@ class MigrationsTest { "https://github.com/Android-Password-Store/pass-test" ) } + + @Test + fun verifyHiddenFoldersMigrationIfDisabled() { + val context = Application.instance.applicationContext + context.sharedPrefs.edit { clear() } + runMigrations(context) + assertEquals(true, context.sharedPrefs.getBoolean(PreferenceKeys.SHOW_HIDDEN_FOLDERS, true)) + assertEquals(false, context.sharedPrefs.getBoolean(PreferenceKeys.SHOW_HIDDEN_CONTENTS, false)) + } + + @Test + fun verifyHiddenFoldersMigrationIfEnabled() { + val context = Application.instance.applicationContext + context.sharedPrefs.edit { + clear() + putBoolean(PreferenceKeys.SHOW_HIDDEN_FOLDERS, true) + } + runMigrations(context) + assertEquals(false, context.sharedPrefs.getBoolean(PreferenceKeys.SHOW_HIDDEN_FOLDERS, false)) + assertEquals(true, context.sharedPrefs.getBoolean(PreferenceKeys.SHOW_HIDDEN_CONTENTS, false)) + } } diff --git a/app/src/main/java/com/zeapo/pwdstore/Migrations.kt b/app/src/main/java/com/zeapo/pwdstore/Migrations.kt index 7148ad7e..f7cce784 100644 --- a/app/src/main/java/com/zeapo/pwdstore/Migrations.kt +++ b/app/src/main/java/com/zeapo/pwdstore/Migrations.kt @@ -19,6 +19,7 @@ import java.net.URI fun runMigrations(context: Context) { migrateToGitUrlBasedConfig(context) + migrateToHideAll(context) } private fun migrateToGitUrlBasedConfig(context: Context) { @@ -84,3 +85,12 @@ private fun migrateToGitUrlBasedConfig(context: Context) { e { "Failed to migrate to URL-based Git config, generated URL is invalid" } } } + +private fun migrateToHideAll(context: Context) { + context.sharedPrefs.all[PreferenceKeys.SHOW_HIDDEN_FOLDERS] ?: return + val isHidden = context.sharedPrefs.getBoolean(PreferenceKeys.SHOW_HIDDEN_FOLDERS, false) + context.sharedPrefs.edit { + remove(PreferenceKeys.SHOW_HIDDEN_FOLDERS) + putBoolean(PreferenceKeys.SHOW_HIDDEN_CONTENTS, isHidden) + } +} diff --git a/app/src/main/java/com/zeapo/pwdstore/SearchableRepositoryViewModel.kt b/app/src/main/java/com/zeapo/pwdstore/SearchableRepositoryViewModel.kt index 0509a3dd..6da5de7a 100644 --- a/app/src/main/java/com/zeapo/pwdstore/SearchableRepositoryViewModel.kt +++ b/app/src/main/java/com/zeapo/pwdstore/SearchableRepositoryViewModel.kt @@ -94,7 +94,7 @@ private fun PasswordItem.Companion.makeComparator( PasswordRepository.PasswordSortOrder.FOLDER_FIRST -> compareBy { it.type } // In order to let INDEPENDENT not distinguish between items based on their type, we simply // declare them all equal at this stage. - PasswordRepository.PasswordSortOrder.INDEPENDENT -> Comparator { _, _ -> 0 } + PasswordRepository.PasswordSortOrder.INDEPENDENT -> Comparator { _, _ -> 0 } PasswordRepository.PasswordSortOrder.FILE_FIRST -> compareByDescending { it.type } PasswordRepository.PasswordSortOrder.RECENTLY_USED -> PasswordRepository.PasswordSortOrder.RECENTLY_USED.comparator } @@ -140,8 +140,8 @@ class SearchableRepositoryViewModel(application: Application) : AndroidViewModel private val root get() = PasswordRepository.getRepositoryDirectory() private val settings by lazy { application.sharedPrefs } - private val showHiddenDirs - get() = settings.getBoolean(PreferenceKeys.SHOW_HIDDEN_FOLDERS, false) + private val showHiddenContents + get() = settings.getBoolean(PreferenceKeys.SHOW_HIDDEN_CONTENTS, false) private val defaultSearchMode get() = if (settings.getBoolean(PreferenceKeys.FILTER_RECURSIVELY, true)) { SearchMode.RecursivelyInSubdirectories @@ -254,8 +254,9 @@ class SearchableRepositoryViewModel(application: Application) : AndroidViewModel }.asLiveData(Dispatchers.IO) private fun shouldTake(file: File) = with(file) { + if (showHiddenContents) return true if (isDirectory) { - !isHidden || showHiddenDirs + !isHidden } else { !isHidden && file.extension == "gpg" } diff --git a/app/src/main/java/com/zeapo/pwdstore/ui/adapters/PasswordItemRecyclerAdapter.kt b/app/src/main/java/com/zeapo/pwdstore/ui/adapters/PasswordItemRecyclerAdapter.kt index dc9d0ebd..2915efb4 100644 --- a/app/src/main/java/com/zeapo/pwdstore/ui/adapters/PasswordItemRecyclerAdapter.kt +++ b/app/src/main/java/com/zeapo/pwdstore/ui/adapters/PasswordItemRecyclerAdapter.kt @@ -50,7 +50,7 @@ open class PasswordItemRecyclerAdapter : fun bind(item: PasswordItem) { val settings = itemView.context.sharedPrefs - val showHidden = settings.getBoolean(PreferenceKeys.SHOW_HIDDEN_FOLDERS, false) + val showHidden = settings.getBoolean(PreferenceKeys.SHOW_HIDDEN_CONTENTS, false) val parentPath = item.fullPathToParent.replace("(^/)|(/$)".toRegex(), "") val source = if (parentPath.isNotEmpty()) { "$parentPath\n$item" @@ -62,8 +62,8 @@ open class PasswordItemRecyclerAdapter : name.text = spannable if (item.type == PasswordItem.TYPE_CATEGORY) { folderIndicator.visibility = View.VISIBLE - val children = item.file.listFiles { pathname -> - !(!showHidden && (pathname.isDirectory && pathname.isHidden)) + val children = with(item.file) { + if (showHidden) listFiles() else listFiles { pathname -> pathname.isDirectory && !pathname.isHidden } } ?: emptyArray() val count = children.size childCount.visibility = if (count > 0) View.VISIBLE else View.GONE diff --git a/app/src/main/java/com/zeapo/pwdstore/utils/PasswordItem.kt b/app/src/main/java/com/zeapo/pwdstore/utils/PasswordItem.kt index 016ee1aa..ef31324b 100644 --- a/app/src/main/java/com/zeapo/pwdstore/utils/PasswordItem.kt +++ b/app/src/main/java/com/zeapo/pwdstore/utils/PasswordItem.kt @@ -33,7 +33,7 @@ data class PasswordItem( } override fun toString(): String { - return name.replace(".gpg", "") + return name.replace("\\.gpg$".toRegex(), "") } override fun hashCode(): Int { 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 f0b891fc..73660fca 100644 --- a/app/src/main/java/com/zeapo/pwdstore/utils/PasswordRepository.kt +++ b/app/src/main/java/com/zeapo/pwdstore/utils/PasswordRepository.kt @@ -226,12 +226,10 @@ open class PasswordRepository protected constructor() { // We need to recover the passwords then parse the files val passList = getFilesList(path).also { it.sortBy { f -> f.name } } val passwordList = ArrayList() - val showHiddenDirs = settings.getBoolean(PreferenceKeys.SHOW_HIDDEN_FOLDERS, false) + val showHidden = settings.getBoolean(PreferenceKeys.SHOW_HIDDEN_CONTENTS, false) if (passList.size == 0) return passwordList - if (showHiddenDirs) { - passList.filter { !(it.isFile && it.isHidden) }.toCollection(passList.apply { clear() }) - } else { + if (!showHidden) { passList.filter { !it.isHidden }.toCollection(passList.apply { clear() }) } passList.forEach { file -> diff --git a/app/src/main/java/com/zeapo/pwdstore/utils/PreferenceKeys.kt b/app/src/main/java/com/zeapo/pwdstore/utils/PreferenceKeys.kt index 2bb48201..bcda4505 100644 --- a/app/src/main/java/com/zeapo/pwdstore/utils/PreferenceKeys.kt +++ b/app/src/main/java/com/zeapo/pwdstore/utils/PreferenceKeys.kt @@ -28,16 +28,21 @@ object PreferenceKeys { const val GIT_EXTERNAL = "git_external" const val GIT_EXTERNAL_REPO = "git_external_repo" const val GIT_REMOTE_AUTH = "git_remote_auth" + @Deprecated("Use GIT_REMOTE_URL instead") const val GIT_REMOTE_LOCATION = "git_remote_location" + @Deprecated("Use GIT_REMOTE_URL instead") const val GIT_REMOTE_PORT = "git_remote_port" + @Deprecated("Use GIT_REMOTE_URL instead") const val GIT_REMOTE_PROTOCOL = "git_remote_protocol" const val GIT_DELETE_REPO = "git_delete_repo" + @Deprecated("Use GIT_REMOTE_URL instead") const val GIT_REMOTE_SERVER = "git_remote_server" const val GIT_REMOTE_URL = "git_remote_url" + @Deprecated("Use GIT_REMOTE_URL instead") const val GIT_REMOTE_USERNAME = "git_remote_username" const val GIT_SERVER_INFO = "git_server_info" @@ -55,7 +60,13 @@ object PreferenceKeys { const val REPO_CHANGED = "repo_changed" const val SEARCH_ON_START = "search_on_start" const val SHOW_EXTRA_CONTENT = "show_extra_content" + + @Deprecated( + message = "Use SHOW_HIDDEN_CONTENTS instead", + replaceWith = ReplaceWith("PreferenceKeys.SHOW_HIDDEN_CONTENTS") + ) const val SHOW_HIDDEN_FOLDERS = "show_hidden_folders" + const val SHOW_HIDDEN_CONTENTS = "show_hidden_contents" const val SORT_ORDER = "sort_order" const val SHOW_PASSWORD = "show_password" const val SSH_KEY = "ssh_key" diff --git a/app/src/main/res/values-pt-rBR/strings.xml b/app/src/main/res/values-pt-rBR/strings.xml index 79edf2d9..a7f3e046 100644 --- a/app/src/main/res/values-pt-rBR/strings.xml +++ b/app/src/main/res/values-pt-rBR/strings.xml @@ -269,8 +269,6 @@ O local do armazenamento está em seu cartão SD ou armazenamento interno, mas o aplicativo não tem permissão para acessá-lo. Sua chave pública Erro ao tentar gerar a chave SSH - Mostrar pastas ocultas - Incluir diretórios ocultos na lista de senhas Criar pasta Renomear pasta O nome da categoria não pode ser vazio diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index 596e1c14..3fab8cf9 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -251,8 +251,6 @@ Очистить сохраненный SSH Key идентификатор OpenKystortore Ваш публичный ключ Возникла ошибка при попытке генерации ssh ключа - Показать скрытые папки - Включить скрытые директории в список паролей Создать папку Создать Открыть поиск на старте diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index f27224ff..a6e33047 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -302,8 +302,8 @@ The store location is in your SD Card or Internal storage, but the app does not have permission to access it. Your public key Error while trying to generate the ssh-key - Show hidden folders - Include hidden directories in the password list + Show all files and folders + Include non-password files and directories in the password list Create folder Rename folder Category name can\'t be empty diff --git a/app/src/main/res/xml/preference.xml b/app/src/main/res/xml/preference.xml index 50300b5b..1d82df18 100644 --- a/app/src/main/res/xml/preference.xml +++ b/app/src/main/res/xml/preference.xml @@ -127,7 +127,7 @@ app:title="@string/pref_search_on_start" /> -- cgit v1.2.3