From b26b5dc1c32d3580ea33011bd62ee896b417d7e8 Mon Sep 17 00:00:00 2001 From: Yogesh Choudhary Paliyal Date: Fri, 3 Sep 2021 22:39:20 +0530 Subject: [PATCH] New Feature -> Auto backup whenever there is changes in accounts :D Added Chinese (Simplified) --- app/build.gradle | 16 +++- app/src/main/AndroidManifest.xml | 13 ++- .../yogeshpaliyal/keypass/MyApplication.kt | 16 +++- .../com/yogeshpaliyal/keypass/db/DbDao.kt | 8 +- .../keypass/ui/backup/BackupActivity.kt | 89 ++++++++++--------- .../keypass/ui/detail/DetailActivity.kt | 27 ++---- .../keypass/ui/detail/DetailViewModel.kt | 40 ++++++++- .../keypass/utils/BackupUtils.kt | 44 ++++++++- .../keypass/utils/SharedPreferenceUtils.kt | 11 +++ .../keypass/worker/AutoBackupWorker.kt | 42 +++++++++ .../keypass/worker/MyWorkManager.kt | 19 ++++ app/src/main/res/values-hi/string.xml | 5 ++ app/src/main/res/values-zh-rCN/strings.xml | 5 ++ app/src/main/res/values/strings.xml | 1 + .../main/res/values/strings_no_translate.xml | 2 + app/src/main/res/xml/backup_preferences.xml | 33 ++++--- .../android/en-US/changelogs/1308.txt | 1 + .../android/en-US/changelogs/1309.txt | 2 + whatsnew/whatsnew-en-US | 3 +- 19 files changed, 283 insertions(+), 94 deletions(-) create mode 100644 app/src/main/java/com/yogeshpaliyal/keypass/worker/AutoBackupWorker.kt create mode 100644 app/src/main/java/com/yogeshpaliyal/keypass/worker/MyWorkManager.kt create mode 100644 fastlane/metadata/android/en-US/changelogs/1308.txt create mode 100644 fastlane/metadata/android/en-US/changelogs/1309.txt diff --git a/app/build.gradle b/app/build.gradle index eaca6a22..ebb456fb 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -20,8 +20,8 @@ android { applicationId appPackageId minSdkVersion 22 targetSdkVersion 30 - versionCode 1308 - versionName "1.3.8" + versionCode 1309 + versionName "1.3.9" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } @@ -79,7 +79,7 @@ dependencies { implementation 'com.google.android.material:material:1.4.0' implementation 'androidx.constraintlayout:constraintlayout:2.1.0' implementation 'androidx.preference:preference-ktx:1.1.1' - + testImplementation 'junit:junit:4.13.2' androidTestImplementation 'androidx.test.ext:junit:1.1.3' androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0' @@ -112,15 +112,23 @@ dependencies { implementation "androidx.preference:preference-ktx:1.1.1" + implementation "androidx.work:work-runtime-ktx:2.6.0" + + + //Androidx Security implementation "androidx.security:security-crypto:1.1.0-alpha03" - implementation 'com.google.code.gson:gson:2.8.6' + implementation 'com.google.code.gson:gson:2.8.8' // dependency injection implementation("com.google.dagger:hilt-android:$hilt_version") kapt("com.google.dagger:hilt-android-compiler:$hilt_version") + implementation("androidx.hilt:hilt-work:1.0.0") + // When using Kotlin. + kapt("androidx.hilt:hilt-compiler:1.0.0") + } diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 5b0b8449..681f30f6 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -1,5 +1,6 @@ - + @@ -34,6 +34,15 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/yogeshpaliyal/keypass/MyApplication.kt b/app/src/main/java/com/yogeshpaliyal/keypass/MyApplication.kt index 01528bfc..e0d31c77 100644 --- a/app/src/main/java/com/yogeshpaliyal/keypass/MyApplication.kt +++ b/app/src/main/java/com/yogeshpaliyal/keypass/MyApplication.kt @@ -1,7 +1,10 @@ package com.yogeshpaliyal.keypass import android.app.Application +import androidx.hilt.work.HiltWorkerFactory +import androidx.work.Configuration import dagger.hilt.android.HiltAndroidApp +import javax.inject.Inject /* * @author Yogesh Paliyal @@ -10,14 +13,25 @@ import dagger.hilt.android.HiltAndroidApp * created on 22-01-2021 22:41 */ @HiltAndroidApp -class MyApplication : Application() { +class MyApplication : Application(), Configuration.Provider { companion object { lateinit var instance: MyApplication } + @Inject + lateinit var workerFactory: HiltWorkerFactory + override fun onCreate() { super.onCreate() instance = this } + + override fun getWorkManagerConfiguration(): Configuration { + return Configuration.Builder() + .setMinimumLoggingLevel(android.util.Log.INFO) + .setWorkerFactory(workerFactory) + .build() + } + } diff --git a/app/src/main/java/com/yogeshpaliyal/keypass/db/DbDao.kt b/app/src/main/java/com/yogeshpaliyal/keypass/db/DbDao.kt index 87b5ab62..b4c7201b 100644 --- a/app/src/main/java/com/yogeshpaliyal/keypass/db/DbDao.kt +++ b/app/src/main/java/com/yogeshpaliyal/keypass/db/DbDao.kt @@ -1,10 +1,7 @@ package com.yogeshpaliyal.keypass.db import androidx.lifecycle.LiveData -import androidx.room.Dao -import androidx.room.Insert -import androidx.room.OnConflictStrategy -import androidx.room.Query +import androidx.room.* import com.yogeshpaliyal.keypass.data.AccountModel import kotlinx.coroutines.flow.Flow @@ -41,4 +38,7 @@ abstract class DbDao { @Query("DELETE from account WHERE id = :id") abstract fun deleteAccount(id: Long?) + + @Delete + abstract fun deleteAccount(accountModel: AccountModel) } diff --git a/app/src/main/java/com/yogeshpaliyal/keypass/ui/backup/BackupActivity.kt b/app/src/main/java/com/yogeshpaliyal/keypass/ui/backup/BackupActivity.kt index bf32d3e0..cb725907 100644 --- a/app/src/main/java/com/yogeshpaliyal/keypass/ui/backup/BackupActivity.kt +++ b/app/src/main/java/com/yogeshpaliyal/keypass/ui/backup/BackupActivity.kt @@ -10,6 +10,7 @@ import androidx.core.content.ContextCompat import androidx.documentfile.provider.DocumentFile import androidx.lifecycle.lifecycleScope import androidx.preference.Preference +import androidx.preference.PreferenceCategory import androidx.preference.PreferenceFragmentCompat import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.yogeshpaliyal.keypass.AppDatabase @@ -80,6 +81,7 @@ class BackupActivity : AppCompatActivity() { if (it.canUserAccessBackupDirectory(sp)) { val selectedDirectory = Uri.parse(getBackupDirectory(sp)) backup(selectedDirectory) + } } } @@ -98,20 +100,60 @@ class BackupActivity : AppCompatActivity() { } updateItems() } + getString(R.string.settings_override_auto_backup) -> { + sp.apply { + setOverrideAutoBackup(overrideAutoBackup().not()) + } + updateItems() + } } return super.onPreferenceTreeClick(preference) } + fun backup(selectedDirectory: Uri){ + lifecycleScope.launch { + context.backupAccounts(sp, appDb,selectedDirectory)?.let { keyPair -> + if (keyPair.first) { + val binding = LayoutBackupKeypharseBinding.inflate(layoutInflater) + binding.txtCode.text = getOrCreateBackupKey(sp).second + binding.txtCode.setOnClickListener { + val clipboard = + ContextCompat.getSystemService( + requireContext(), + ClipboardManager::class.java + ) + val clip = ClipData.newPlainText("KeyPass", binding.txtCode.text) + clipboard?.setPrimaryClip(clip) + Toast.makeText(context, getString(R.string.copied_to_clipboard), Toast.LENGTH_SHORT).show() + } + MaterialAlertDialogBuilder(requireContext()).setView(binding.root) + .setPositiveButton( + getString(R.string.yes) + ) { dialog, which -> + dialog?.dismiss() + }.show() + } else { + Toast.makeText(context, getString(R.string.backup_completed), Toast.LENGTH_SHORT).show() + } + } + } + updateItems() + } + private fun updateItems() { val isBackupEnabled = context.canUserAccessBackupDirectory(sp) val isAutoBackupEnabled = sp.isAutoBackupEnabled() findPreference(getString(R.string.settings_start_backup))?.isVisible = isBackupEnabled.not() + findPreference(getString(R.string.settings_stop_backup))?.isVisible = isBackupEnabled findPreference(getString(R.string.settings_auto_backup))?.isVisible = isBackupEnabled findPreference(getString(R.string.settings_auto_backup))?.summary = if(isAutoBackupEnabled) getString(R.string.enabled) else getString(R.string.disabled) + findPreference(getString(R.string.settings_cat_auto_backup))?.isVisible = isBackupEnabled && isAutoBackupEnabled + + findPreference(getString(R.string.settings_override_auto_backup))?.summary = if(sp.overrideAutoBackup()) getString(R.string.enabled) else getString(R.string.disabled) findPreference(getString(R.string.settings_create_backup))?.isVisible = isBackupEnabled findPreference(getString(R.string.settings_create_backup))?.summary = getString(R.string.last_backup_date, getBackupTime(sp).formatCalendar("dd MMM yyyy hh:mm aa")) @@ -156,50 +198,7 @@ class BackupActivity : AppCompatActivity() { } } - private fun backup(selectedDirectory: Uri) { - val keyPair = getOrCreateBackupKey(sp) - - val tempFile = DocumentFile.fromTreeUri(requireContext(), selectedDirectory)?.createFile( - "*/*", - "key_pass_backup_${System.currentTimeMillis()}.keypass" - ) - - lifecycleScope.launch { - context?.contentResolver?.let { - appDb.createBackup( - keyPair.second, - it, - tempFile?.uri - ) - setBackupTime(sp, System.currentTimeMillis()) - if (keyPair.first) { - val binding = LayoutBackupKeypharseBinding.inflate(layoutInflater) - binding.txtCode.text = getOrCreateBackupKey(sp).second - binding.txtCode.setOnClickListener { - val clipboard = - ContextCompat.getSystemService( - requireContext(), - ClipboardManager::class.java - ) - val clip = ClipData.newPlainText("KeyPass", binding.txtCode.text) - clipboard?.setPrimaryClip(clip) - Toast.makeText(context, getString(R.string.copied_to_clipboard), Toast.LENGTH_SHORT).show() - } - MaterialAlertDialogBuilder(requireContext()).setView(binding.root) - .setPositiveButton( - getString(R.string.yes) - ) { dialog, which -> - dialog?.dismiss() - }.show() - } else { - Toast.makeText(context, getString(R.string.backup_completed), Toast.LENGTH_SHORT).show() - } - } - - updateItems() - } - } private fun changeBackupFolder() { startBackup() @@ -213,6 +212,10 @@ class BackupActivity : AppCompatActivity() { clearBackupKey(sp) setBackupDirectory(sp, "") setBackupTime(sp, -1) + sp.apply { + setOverrideAutoBackup(false) + setAutoBackupEnabled(false) + } updateItems() } } diff --git a/app/src/main/java/com/yogeshpaliyal/keypass/ui/detail/DetailActivity.kt b/app/src/main/java/com/yogeshpaliyal/keypass/ui/detail/DetailActivity.kt index d2d83272..ba64df2f 100644 --- a/app/src/main/java/com/yogeshpaliyal/keypass/ui/detail/DetailActivity.kt +++ b/app/src/main/java/com/yogeshpaliyal/keypass/ui/detail/DetailActivity.kt @@ -7,17 +7,11 @@ import android.view.Menu import androidx.activity.viewModels import androidx.appcompat.app.AppCompatActivity import androidx.lifecycle.Observer -import androidx.lifecycle.lifecycleScope import com.google.android.material.dialog.MaterialAlertDialogBuilder -import com.yogeshpaliyal.keypass.AppDatabase import com.yogeshpaliyal.keypass.R import com.yogeshpaliyal.keypass.databinding.FragmentDetailBinding import com.yogeshpaliyal.keypass.utils.PasswordGenerator import dagger.hilt.android.AndroidEntryPoint -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.launch -import kotlinx.coroutines.withContext -import javax.inject.Inject /* * @author Yogesh Paliyal @@ -30,9 +24,6 @@ class DetailActivity : AppCompatActivity() { lateinit var binding: FragmentDetailBinding - @Inject - lateinit var appDb: AppDatabase - companion object { private const val ARG_ACCOUNT_ID = "ARG_ACCOUNT_ID" @@ -90,14 +81,8 @@ class DetailActivity : AppCompatActivity() { } binding.btnSave.setOnClickListener { - lifecycleScope.launch(Dispatchers.IO) { - val model = mViewModel.accountModel.value - if (model != null) { - appDb.getDao().insertOrUpdateAccount(model) - } - withContext(Dispatchers.Main) { - onBackPressed() - } + mViewModel.insertOrUpdate { + onBackPressed() } } } @@ -110,11 +95,9 @@ class DetailActivity : AppCompatActivity() { getString(R.string.delete) ) { dialog, which -> dialog?.dismiss() - lifecycleScope.launch(Dispatchers.IO) { - if (accountId > 0L) { - appDb.getDao().deleteAccount(accountId) - } - withContext(Dispatchers.Main) { + + if (accountId > 0L) { + mViewModel.deleteAccount { onBackPressed() } } diff --git a/app/src/main/java/com/yogeshpaliyal/keypass/ui/detail/DetailViewModel.kt b/app/src/main/java/com/yogeshpaliyal/keypass/ui/detail/DetailViewModel.kt index b8d4fcc5..8134b203 100644 --- a/app/src/main/java/com/yogeshpaliyal/keypass/ui/detail/DetailViewModel.kt +++ b/app/src/main/java/com/yogeshpaliyal/keypass/ui/detail/DetailViewModel.kt @@ -1,14 +1,18 @@ package com.yogeshpaliyal.keypass.ui.detail import android.app.Application +import android.content.SharedPreferences import androidx.lifecycle.AndroidViewModel +import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData import androidx.lifecycle.viewModelScope import com.yogeshpaliyal.keypass.AppDatabase import com.yogeshpaliyal.keypass.data.AccountModel +import com.yogeshpaliyal.keypass.worker.executeAutoBackup import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext import javax.inject.Inject /* @@ -18,16 +22,44 @@ import javax.inject.Inject * created on 31-01-2021 11:52 */ @HiltViewModel -class DetailViewModel @Inject constructor(application: Application, val appDb: AppDatabase) : AndroidViewModel(application) { +class DetailViewModel @Inject constructor(val app: Application, val appDb: AppDatabase,val sp: SharedPreferences) : AndroidViewModel(app) { - val accountModel by lazy { MutableLiveData() } + private val _accountModel by lazy { MutableLiveData() } + val accountModel : LiveData = _accountModel fun loadAccount(accountId: Long?) { - viewModelScope.launch(Dispatchers.IO) { - accountModel.postValue( + _accountModel.postValue( appDb.getDao().getAccount(accountId) ?: AccountModel() ) } } + + fun deleteAccount(onExecCompleted : ()->Unit){ + viewModelScope.launch { + accountModel.value?.let { + withContext(Dispatchers.IO) { + appDb.getDao().deleteAccount(it) + } + autoBackup() + onExecCompleted() + } + } + } + + fun insertOrUpdate(onExecCompleted : ()->Unit){ + viewModelScope.launch { + accountModel.value?.let { + withContext(Dispatchers.IO) { + appDb.getDao().insertOrUpdateAccount(it) + autoBackup() + } + } + onExecCompleted() + } + } + + private fun autoBackup(){ + app.executeAutoBackup(sp) + } } diff --git a/app/src/main/java/com/yogeshpaliyal/keypass/utils/BackupUtils.kt b/app/src/main/java/com/yogeshpaliyal/keypass/utils/BackupUtils.kt index cda3731d..e3f9e539 100644 --- a/app/src/main/java/com/yogeshpaliyal/keypass/utils/BackupUtils.kt +++ b/app/src/main/java/com/yogeshpaliyal/keypass/utils/BackupUtils.kt @@ -5,6 +5,8 @@ import android.content.SharedPreferences import android.net.Uri import android.text.TextUtils import androidx.documentfile.provider.DocumentFile +import com.yogeshpaliyal.keypass.AppDatabase +import com.yogeshpaliyal.keypass.db_helper.createBackup import java.security.SecureRandom /* @@ -21,9 +23,9 @@ fun getRandomString(sizeOfRandomString: Int): String { val sb = StringBuilder(sizeOfRandomString) for (i in 0 until sizeOfRandomString) sb.append( ALLOWED_CHARACTERS[ - random.nextInt( - ALLOWED_CHARACTERS.length - ) + random.nextInt( + ALLOWED_CHARACTERS.length + ) ] ) return sb.toString() @@ -36,6 +38,42 @@ fun Context?.canUserAccessBackupDirectory(sp: SharedPreferences): Boolean { return backupDirectory != null && backupDirectory.exists() && backupDirectory.canRead() && backupDirectory.canWrite() } + +/** + * @return Pair (Boolean to check if backup is for first time, is backup is for first time show user alert to save encryption key) + * Second Value contains the encryption key + */ +suspend fun Context?.backupAccounts( + sp: SharedPreferences, + appDb: AppDatabase, + selectedDirectory: Uri, fileName: String? = null +): Pair? { + + this ?: return null + + val keyPair = getOrCreateBackupKey(sp) + + val fileName = (fileName ?: "key_pass_backup_${System.currentTimeMillis()}")+".keypass" + + + val directory = DocumentFile.fromTreeUri(this, selectedDirectory) + var docFile = directory?.findFile(fileName) + if (docFile == null) + docFile = DocumentFile.fromTreeUri(this, selectedDirectory)?.createFile( + "*/*", + fileName) + + + val response = appDb.createBackup( + keyPair.second, + contentResolver, + docFile?.uri + ) + setBackupTime(sp, System.currentTimeMillis()) + + return keyPair +} + private fun getUri(string: String?): Uri? { val uri = string return if (TextUtils.isEmpty(uri)) { diff --git a/app/src/main/java/com/yogeshpaliyal/keypass/utils/SharedPreferenceUtils.kt b/app/src/main/java/com/yogeshpaliyal/keypass/utils/SharedPreferenceUtils.kt index 7aa7f10a..1cf21a25 100644 --- a/app/src/main/java/com/yogeshpaliyal/keypass/utils/SharedPreferenceUtils.kt +++ b/app/src/main/java/com/yogeshpaliyal/keypass/utils/SharedPreferenceUtils.kt @@ -55,6 +55,16 @@ fun SharedPreferences?.isAutoBackupEnabled(): Boolean { return this?.getBoolean(AUTO_BACKUP, false) ?: false } +fun SharedPreferences?.overrideAutoBackup(): Boolean { + return this?.getBoolean(OVERRIDE_AUTO_BACKUP, false) ?: false +} + +fun SharedPreferences?.setOverrideAutoBackup(value: Boolean) { + this?.edit { + putBoolean(OVERRIDE_AUTO_BACKUP, value) + } +} + fun SharedPreferences?.setAutoBackupEnabled(value: Boolean) { this?.edit { putBoolean(AUTO_BACKUP, value) @@ -69,3 +79,4 @@ private const val BACKUP_KEY = "backup_key" private const val BACKUP_DIRECTORY = "backup_directory" private const val BACKUP_DATE_TIME = "backup_date_time" private const val AUTO_BACKUP = "auto_backup" +private const val OVERRIDE_AUTO_BACKUP = "override_auto_backup" diff --git a/app/src/main/java/com/yogeshpaliyal/keypass/worker/AutoBackupWorker.kt b/app/src/main/java/com/yogeshpaliyal/keypass/worker/AutoBackupWorker.kt new file mode 100644 index 00000000..e3df6674 --- /dev/null +++ b/app/src/main/java/com/yogeshpaliyal/keypass/worker/AutoBackupWorker.kt @@ -0,0 +1,42 @@ +package com.yogeshpaliyal.keypass.worker + +import android.content.Context +import android.content.SharedPreferences +import android.net.Uri +import androidx.hilt.work.HiltWorker +import androidx.work.CoroutineWorker +import androidx.work.WorkerParameters +import com.yogeshpaliyal.keypass.AppDatabase +import com.yogeshpaliyal.keypass.utils.backupAccounts +import com.yogeshpaliyal.keypass.utils.canUserAccessBackupDirectory +import com.yogeshpaliyal.keypass.utils.getBackupDirectory +import com.yogeshpaliyal.keypass.utils.overrideAutoBackup +import dagger.assisted.Assisted +import dagger.assisted.AssistedInject +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.withContext + +@HiltWorker +class AutoBackupWorker @AssistedInject constructor( + @Assisted val appContext: Context, @Assisted params: WorkerParameters, + val appDatabase: AppDatabase, + val sp: SharedPreferences +) : + CoroutineWorker(appContext, params) { + override suspend fun doWork(): Result { + return withContext(Dispatchers.IO) { + + if (appContext.canUserAccessBackupDirectory(sp)) { + val selectedDirectory = Uri.parse(getBackupDirectory(sp)) + appContext.backupAccounts( + sp, + appDatabase, + selectedDirectory, + if (sp.overrideAutoBackup()) "key_pass_auto_backup" else null + ) + } + + Result.success() + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/yogeshpaliyal/keypass/worker/MyWorkManager.kt b/app/src/main/java/com/yogeshpaliyal/keypass/worker/MyWorkManager.kt new file mode 100644 index 00000000..190ca623 --- /dev/null +++ b/app/src/main/java/com/yogeshpaliyal/keypass/worker/MyWorkManager.kt @@ -0,0 +1,19 @@ +package com.yogeshpaliyal.keypass.worker + +import android.content.Context +import android.content.SharedPreferences +import androidx.work.ExistingWorkPolicy +import androidx.work.OneTimeWorkRequestBuilder +import androidx.work.WorkManager +import com.yogeshpaliyal.keypass.utils.isAutoBackupEnabled + +fun Context?.executeAutoBackup(sp: SharedPreferences){ + this ?: return + + if (sp.isAutoBackupEnabled()) { + val work = OneTimeWorkRequestBuilder().build() + + WorkManager.getInstance(this.applicationContext) + .enqueueUniqueWork("AutoBackupWorker", ExistingWorkPolicy.KEEP, work) + } +} \ No newline at end of file diff --git a/app/src/main/res/values-hi/string.xml b/app/src/main/res/values-hi/string.xml index b2d8a95b..79ff8634 100644 --- a/app/src/main/res/values-hi/string.xml +++ b/app/src/main/res/values-hi/string.xml @@ -59,4 +59,9 @@ टैग अल्पविराम से अलग (वैकल्पिक) वेबसाइट यूआरएल (वैकल्पिक) नोट्स (वैकल्पिक) + + ऑटो बैकअप + अक्षम + सक्रिय + ऑटो बैकअप फ़ाइल को ओवरराइड करें \ No newline at end of file diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 03e4c15f..20490283 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -59,4 +59,9 @@ 标签(选填) 网站(选填) 附注(选填) + + 自动备份 + 已禁用 + 启用 + 覆盖自动备份文件 \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index fb656ae8..dbaaca86 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -62,4 +62,5 @@ Auto Backup Disabled Enabled + Override Auto Backup File \ No newline at end of file diff --git a/app/src/main/res/values/strings_no_translate.xml b/app/src/main/res/values/strings_no_translate.xml index de83d1bc..74cfd201 100644 --- a/app/src/main/res/values/strings_no_translate.xml +++ b/app/src/main/res/values/strings_no_translate.xml @@ -10,5 +10,7 @@ backup_folder stop_backup auto_backup + cat_auto_backup + override_auto_backup \ No newline at end of file diff --git a/app/src/main/res/xml/backup_preferences.xml b/app/src/main/res/xml/backup_preferences.xml index f22c7864..b2ce7ac7 100644 --- a/app/src/main/res/xml/backup_preferences.xml +++ b/app/src/main/res/xml/backup_preferences.xml @@ -3,39 +3,52 @@ - + + app:title="@string/turn_on_backup" /> + tools:summary="Last backup : 7m" /> + tools:summary="@string/backup" /> + tools:summary="@string/disabled" /> + + + + + + + + + app:summary="@string/verify_keyphrase_message" + app:title="@string/verify_keyphrase" /> + app:key="@string/settings_stop_backup" + app:title="@string/turn_off_backup" /> \ No newline at end of file diff --git a/fastlane/metadata/android/en-US/changelogs/1308.txt b/fastlane/metadata/android/en-US/changelogs/1308.txt new file mode 100644 index 00000000..9d124829 --- /dev/null +++ b/fastlane/metadata/android/en-US/changelogs/1308.txt @@ -0,0 +1 @@ +Fixed crash for some devices when creating backup \ No newline at end of file diff --git a/fastlane/metadata/android/en-US/changelogs/1309.txt b/fastlane/metadata/android/en-US/changelogs/1309.txt new file mode 100644 index 00000000..d1ccbff1 --- /dev/null +++ b/fastlane/metadata/android/en-US/changelogs/1309.txt @@ -0,0 +1,2 @@ +New Feature -> Auto backup whenever there is changes in accounts :D +Added Chinese (Simplified) \ No newline at end of file diff --git a/whatsnew/whatsnew-en-US b/whatsnew/whatsnew-en-US index 9d124829..d1ccbff1 100644 --- a/whatsnew/whatsnew-en-US +++ b/whatsnew/whatsnew-en-US @@ -1 +1,2 @@ -Fixed crash for some devices when creating backup \ No newline at end of file +New Feature -> Auto backup whenever there is changes in accounts :D +Added Chinese (Simplified) \ No newline at end of file