diff --git a/README.md b/README.md index 7f805fd0..9205d7a2 100644 --- a/README.md +++ b/README.md @@ -4,9 +4,9 @@ NotallyX | Minimalistic note taking app

+ Get it on Google Play IzzyOnDroid F-Droid - JoinTesters

diff --git a/app/src/main/java/com/philkes/notallyx/data/model/BaseNote.kt b/app/src/main/java/com/philkes/notallyx/data/model/BaseNote.kt index fb1b2315..6e76fea5 100644 --- a/app/src/main/java/com/philkes/notallyx/data/model/BaseNote.kt +++ b/app/src/main/java/com/philkes/notallyx/data/model/BaseNote.kt @@ -31,6 +31,50 @@ data class BaseNote( const val COLOR_DEFAULT = "DEFAULT" const val COLOR_NEW = "NEW" } + + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (javaClass != other?.javaClass) return false + + other as BaseNote + + if (id != other.id) return false + if (type != other.type) return false + if (folder != other.folder) return false + if (color != other.color) return false + if (title != other.title) return false + if (pinned != other.pinned) return false + if (timestamp != other.timestamp) return false + if (labels != other.labels) return false + if (body != other.body) return false + if (spans != other.spans) return false + if (items != other.items) return false + if (images != other.images) return false + if (files != other.files) return false + if (audios != other.audios) return false + if (reminders != other.reminders) return false + + return true + } + + override fun hashCode(): Int { + var result = id.hashCode() + result = 31 * result + type.hashCode() + result = 31 * result + folder.hashCode() + result = 31 * result + color.hashCode() + result = 31 * result + title.hashCode() + result = 31 * result + pinned.hashCode() + result = 31 * result + timestamp.hashCode() + result = 31 * result + labels.hashCode() + result = 31 * result + body.hashCode() + result = 31 * result + spans.hashCode() + result = 31 * result + items.hashCode() + result = 31 * result + images.hashCode() + result = 31 * result + files.hashCode() + result = 31 * result + audios.hashCode() + result = 31 * result + reminders.hashCode() + return result + } } fun BaseNote.deepCopy(): BaseNote { diff --git a/app/src/main/java/com/philkes/notallyx/presentation/activity/main/fragment/settings/PreferenceBindingExtensions.kt b/app/src/main/java/com/philkes/notallyx/presentation/activity/main/fragment/settings/PreferenceBindingExtensions.kt index 585682e7..81cf0f08 100644 --- a/app/src/main/java/com/philkes/notallyx/presentation/activity/main/fragment/settings/PreferenceBindingExtensions.kt +++ b/app/src/main/java/com/philkes/notallyx/presentation/activity/main/fragment/settings/PreferenceBindingExtensions.kt @@ -434,6 +434,29 @@ fun PreferenceSeekbarBinding.setup( } } +fun PreferenceSeekbarBinding.setupAutoSaveIdleTime( + preference: IntPreference, + context: Context, + value: Int = preference.value, + onChange: (newValue: Int) -> Unit, +) { + Slider.apply { + setLabelFormatter { sliderValue -> + if (sliderValue == -1f) { + context.getString(R.string.disabled) + } else "${sliderValue.toInt()}s" + } + addOnChangeListener { _, value, _ -> + if (value == -1f) { + setAlpha(0.6f) // Reduce opacity to make it look disabled + } else { + setAlpha(1f) // Restore normal appearance + } + } + } + setup(preference, context, value, onChange) +} + fun PreferenceBinding.setupStartView( preference: StringPreference, value: String, diff --git a/app/src/main/java/com/philkes/notallyx/presentation/activity/main/fragment/settings/SettingsFragment.kt b/app/src/main/java/com/philkes/notallyx/presentation/activity/main/fragment/settings/SettingsFragment.kt index 80bcabf0..fdf7372e 100644 --- a/app/src/main/java/com/philkes/notallyx/presentation/activity/main/fragment/settings/SettingsFragment.kt +++ b/app/src/main/java/com/philkes/notallyx/presentation/activity/main/fragment/settings/SettingsFragment.kt @@ -616,6 +616,12 @@ class SettingsFragment : Fragment() { } } } + binding.AutoSaveAfterIdle.setupAutoSaveIdleTime( + autoSaveAfterIdleTime, + requireContext(), + ) { newValue -> + model.savePreference(autoSaveAfterIdleTime, newValue) + } ClearData.setOnClickListener { MaterialAlertDialogBuilder(requireContext()) .setMessage(R.string.clear_data_message) @@ -689,8 +695,10 @@ class SettingsFragment : Fragment() { .setCancelButton() .show() } + Rate.setOnClickListener { + openLink("https://play.google.com/store/apps/details?id=com.philkes.notallyx") + } SourceCode.setOnClickListener { openLink("https://github.com/PhilKes/NotallyX") } - // TODO: add ColorPickerView Libraries.setOnClickListener { val libraries = arrayOf( diff --git a/app/src/main/java/com/philkes/notallyx/presentation/activity/note/EditActivity.kt b/app/src/main/java/com/philkes/notallyx/presentation/activity/note/EditActivity.kt index 2711645e..36df8880 100644 --- a/app/src/main/java/com/philkes/notallyx/presentation/activity/note/EditActivity.kt +++ b/app/src/main/java/com/philkes/notallyx/presentation/activity/note/EditActivity.kt @@ -8,8 +8,11 @@ import android.graphics.drawable.Drawable import android.net.Uri import android.os.Build import android.os.Bundle +import android.os.Handler +import android.os.Looper import android.provider.Settings import android.text.Editable +import android.util.Log import android.util.TypedValue import android.view.MenuItem import android.view.View @@ -114,12 +117,25 @@ abstract class EditActivity(private val type: Type) : protected var colorInt: Int = -1 protected var inputMethodManager: InputMethodManager? = null + private val autoSaveHandler = Handler(Looper.getMainLooper()) + private val autoSaveRunnable = Runnable { + lifecycleScope.launch(Dispatchers.Main) { + updateModel() + if (notallyModel.isModified()) { + Log.d(TAG, "Auto-saving note...") + saveNote(checkAutoSave = false) + } + } + } + override fun finish() { lifecycleScope.launch(Dispatchers.Main) { if (notallyModel.isEmpty()) { notallyModel.deleteBaseNote(checkAutoSave = false) } else if (notallyModel.isModified()) { saveNote() + } else { + notallyModel.checkBackupOnSave() } super.finish() } @@ -137,9 +153,9 @@ abstract class EditActivity(private val type: Type) : } } - open suspend fun saveNote() { + open suspend fun saveNote(checkAutoSave: Boolean = true) { updateModel() - notallyModel.saveNote() + notallyModel.saveNote(checkAutoSave) WidgetProvider.sendBroadcast(application, longArrayOf(notallyModel.id)) } @@ -193,6 +209,19 @@ abstract class EditActivity(private val type: Type) : } } + override fun onDestroy() { + autoSaveHandler.removeCallbacks(autoSaveRunnable) + super.onDestroy() + } + + protected fun resetIdleTimer() { + autoSaveHandler.removeCallbacks(autoSaveRunnable) + val idleTime = preferences.autoSaveAfterIdleTime.value + if (idleTime > -1) { + autoSaveHandler.postDelayed(autoSaveRunnable, idleTime.toLong() * 1000) + } + } + private fun setupActivityResultLaunchers() { recordAudioActivityResultLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result -> @@ -243,6 +272,7 @@ abstract class EditActivity(private val type: Type) : paddingTop = true, colorInt, ) + resetIdleTimer() } } } @@ -317,6 +347,7 @@ abstract class EditActivity(private val type: Type) : ChangeHistory().apply { canUndo.observe(this@EditActivity) { canUndo -> undo?.isEnabled = canUndo } canRedo.observe(this@EditActivity) { canRedo -> redo?.isEnabled = canRedo } + stackPointer.observe(this@EditActivity) { _ -> resetIdleTimer() } } } @@ -645,6 +676,7 @@ abstract class EditActivity(private val type: Type) : } notallyModel.color = selectedColor setColor() + resetIdleTimer() }, ) { colorToDelete, newColor -> baseModel.changeColor(colorToDelete, newColor) @@ -652,6 +684,7 @@ abstract class EditActivity(private val type: Type) : notallyModel.color = newColor setColor() } + resetIdleTimer() } } } diff --git a/app/src/main/java/com/philkes/notallyx/presentation/viewmodel/NotallyModel.kt b/app/src/main/java/com/philkes/notallyx/presentation/viewmodel/NotallyModel.kt index 45ad195c..bc59fefa 100644 --- a/app/src/main/java/com/philkes/notallyx/presentation/viewmodel/NotallyModel.kt +++ b/app/src/main/java/com/philkes/notallyx/presentation/viewmodel/NotallyModel.kt @@ -40,7 +40,7 @@ import com.philkes.notallyx.presentation.widget.WidgetProvider import com.philkes.notallyx.utils.Cache import com.philkes.notallyx.utils.Event import com.philkes.notallyx.utils.FileError -import com.philkes.notallyx.utils.backup.checkAutoSave +import com.philkes.notallyx.utils.backup.checkBackupOnSave import com.philkes.notallyx.utils.backup.importAudio import com.philkes.notallyx.utils.backup.importFile import com.philkes.notallyx.utils.cancelNoteReminders @@ -268,7 +268,7 @@ class NotallyModel(private val app: Application) : AndroidViewModel(app) { withContext(Dispatchers.IO) { app.deleteAttachments(attachments) } } if (checkAutoSave) { - app.checkAutoSave(preferences, forceFullBackup = true) + app.checkBackupOnSave(preferences, forceFullBackup = true) } } @@ -277,19 +277,26 @@ class NotallyModel(private val app: Application) : AndroidViewModel(app) { this.items.addAll(items) } - suspend fun saveNote(): Long { + suspend fun saveNote(checkBackupOnSave: Boolean = true): Long { return withContext(Dispatchers.IO) { val note = getBaseNote() val id = baseNoteDao.insert(note) - app.checkAutoSave( - preferences, - note = note, - forceFullBackup = originalNote?.attachmentsDifferFrom(note) == true, - ) + if (checkBackupOnSave) { + checkBackupOnSave(note) + } + originalNote = note.deepCopy() return@withContext id } } + suspend fun checkBackupOnSave(note: BaseNote = getBaseNote()) { + app.checkBackupOnSave( + preferences, + note = note, + forceFullBackup = originalNote?.attachmentsDifferFrom(note) == true, + ) + } + fun isEmpty(): Boolean { return title.isEmpty() && body.isEmpty() && diff --git a/app/src/main/java/com/philkes/notallyx/presentation/viewmodel/preference/NotallyXPreferences.kt b/app/src/main/java/com/philkes/notallyx/presentation/viewmodel/preference/NotallyXPreferences.kt index bae06275..037d131b 100644 --- a/app/src/main/java/com/philkes/notallyx/presentation/viewmodel/preference/NotallyXPreferences.kt +++ b/app/src/main/java/com/philkes/notallyx/presentation/viewmodel/preference/NotallyXPreferences.kt @@ -111,6 +111,16 @@ class NotallyXPreferences private constructor(private val context: Context) { ) } + val autoSaveAfterIdleTime = + IntPreference( + "autoSaveAfterIdleTime", + preferences, + 5, + -1, + 20, + R.string.auto_save_after_idle_time, + ) + val biometricLock = createEnumPreference( preferences, @@ -219,6 +229,7 @@ class NotallyXPreferences private constructor(private val context: Context) { periodicBackups, backupPassword, backupOnSave, + autoSaveAfterIdleTime, ) .forEach { it.refresh() } } diff --git a/app/src/main/java/com/philkes/notallyx/utils/backup/ExportExtensions.kt b/app/src/main/java/com/philkes/notallyx/utils/backup/ExportExtensions.kt index 6129cec5..a037e6e4 100644 --- a/app/src/main/java/com/philkes/notallyx/utils/backup/ExportExtensions.kt +++ b/app/src/main/java/com/philkes/notallyx/utils/backup/ExportExtensions.kt @@ -81,6 +81,7 @@ import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import net.lingala.zip4j.ZipFile +import net.lingala.zip4j.exception.ZipException import net.lingala.zip4j.model.ZipParameters import net.lingala.zip4j.model.enums.CompressionLevel import net.lingala.zip4j.model.enums.EncryptionMethod @@ -164,6 +165,9 @@ fun ContextWrapper.autoBackupOnSave(backupPath: String, password: String, savedN backupPath, "Auto backup on note save (${savedNote?.let { "id: '${savedNote.id}, title: '${savedNote.title}'" }}) failed, because auto-backup path '$backupPath' is invalid", ) ?: return + fun log(msg: String? = null, throwable: Throwable? = null) { + logToFile(TAG, folder, NOTALLYX_BACKUP_LOGS_FILE, msg = msg, throwable = throwable) + } try { var backupFile = folder.findFile(ON_SAVE_BACKUP_FILE) if (savedNote == null || backupFile == null || !backupFile.exists()) { @@ -193,16 +197,21 @@ fun ContextWrapper.autoBackupOnSave(backupPath: String, password: String, savedN NotallyDatabase.getCurrentDatabaseFile(this@autoBackupOnSave), ) } - exportToZip(backupFile.uri, files, password) + try { + exportToZip(backupFile.uri, files, password) + } catch (e: ZipException) { + log( + msg = + "Re-creating full backup since existing auto backup ZIP is corrupt: ${e.message}" + ) + backupFile.delete() + autoBackupOnSave(backupPath, password, savedNote) + } } } catch (e: Exception) { - logToFile( - TAG, - folder, - NOTALLYX_BACKUP_LOGS_FILE, - msg = - "Auto backup on note save (${savedNote?.let { "id: '${savedNote.id}, title: '${savedNote.title}'" }}) failed", - throwable = e, + log( + "Auto backup on note save (${savedNote?.let { "id: '${savedNote.id}, title: '${savedNote.title}'" }}) failed", + e, ) tryPostErrorNotification(e) } @@ -224,7 +233,7 @@ private fun ContextWrapper.requireBackupFolder(path: String, msg: String): Docum } } -suspend fun ContextWrapper.checkAutoSave( +suspend fun ContextWrapper.checkBackupOnSave( preferences: NotallyXPreferences, note: BaseNote? = null, forceFullBackup: Boolean = false, @@ -400,6 +409,7 @@ fun ContextWrapper.copyDatabase(): Pair { val database = NotallyDatabase.getDatabase(this, observePreferences = false).value database.checkpoint() val preferences = NotallyXPreferences.getInstance(this) + val databaseFile = NotallyDatabase.getCurrentDatabaseFile(this) return if ( preferences.biometricLock.value == BiometricLock.ENABLED && Build.VERSION.SDK_INT >= Build.VERSION_CODES.M @@ -407,16 +417,11 @@ fun ContextWrapper.copyDatabase(): Pair { val cipher = getInitializedCipherForDecryption(iv = preferences.iv.value!!) val passphrase = cipher.doFinal(preferences.databaseEncryptionKey.value) val decryptedFile = File(cacheDir, DATABASE_NAME) - decryptDatabase( - this, - passphrase, - decryptedFile, - NotallyDatabase.getExternalDatabaseFile(this), - ) + decryptDatabase(this, passphrase, decryptedFile, databaseFile) Pair(database, decryptedFile) } else { val dbFile = File(cacheDir, DATABASE_NAME) - NotallyDatabase.getCurrentDatabaseFile(this).copyTo(dbFile, overwrite = true) + databaseFile.copyTo(dbFile, overwrite = true) Pair(database, dbFile) } } diff --git a/app/src/main/java/com/philkes/notallyx/utils/changehistory/ChangeHistory.kt b/app/src/main/java/com/philkes/notallyx/utils/changehistory/ChangeHistory.kt index ee7518b0..b5a20144 100644 --- a/app/src/main/java/com/philkes/notallyx/utils/changehistory/ChangeHistory.kt +++ b/app/src/main/java/com/philkes/notallyx/utils/changehistory/ChangeHistory.kt @@ -6,7 +6,7 @@ import kotlin.IllegalStateException class ChangeHistory { private val changeStack = ArrayList() - private var stackPointer = NotNullLiveData(-1) + var stackPointer = NotNullLiveData(-1) internal val canUndo = NotNullLiveData(false) internal val canRedo = NotNullLiveData(false) diff --git a/app/src/main/res/layout/fragment_settings.xml b/app/src/main/res/layout/fragment_settings.xml index 36bb1745..452e8fa0 100644 --- a/app/src/main/res/layout/fragment_settings.xml +++ b/app/src/main/res/layout/fragment_settings.xml @@ -30,6 +30,16 @@ android:id="@+id/TextSize" layout="@layout/preference" /> + + + - + + + + + + - - + android:text="@string/libraries" /> Během automatického zálohování došlo k chybě:\n\'%1$s\'\nProsím, zkontrolujte nastavení nebo nahlaste chybu Automatické zálohování NotallyX selhalo Poslední záloha - Automaticky zálohovat při uložení poznámky + Automaticky zálohovat při ukončení poznámky Pokud tuto možnost povolíte, záloha („NotallyX_AutoBackup.zip“) bude automaticky vytvořena ve zvoleném „Adresáři záloh“ pokaždé, když bude poznámka uložena. Mějte na paměti, že to může ovlivnit výkon Frekvence automatického zálohování Adresář pro zálohy diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index 3ee2f345..07e98540 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -22,8 +22,8 @@ Beim autom. Backup ist ein Fehler aufgetreten:\n\'%1$s\'\nÜberprüfe deine Einstellungen oder melde einen Bug NotallyX Auto Backup fehlgeschlagen Letztes Backup - Autom. Backup beim Notiz-Speichern - Ist dies aktiviert, wird jedesmal wenn eine Notiz gespeichert wird autom. ein Backup (\"NotallyX_AutoBackup.zip\") im \"Backups Ordner\" erstellt.\nDies kann die App-Performance beeinträchtigen + Autom. Backup beim Notiz Verlassen + Ist dies aktiviert, wird jedesmal wenn eine Notiz verlassen wird autom. ein Backup (\"NotallyX_AutoBackup.zip\") im \"Backups Ordner\" erstellt.\nDies kann die App-Performance beeinträchtigen Intervall für autom. Backups Backups Ordner Ordner in dem alle autom. Backups erstellt werden diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index 405fac22..e3c4bf1c 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -22,7 +22,7 @@ Ha ocurrido un error durante una copia automática:\n\'%1$s’\nComprueba tus ajustes o informa de un error Falló la copia de seguridad automática de Notallyx Última copia de seguridad - Copia de seguridad automática al guardar una nota + Copia de seguridad automática al salir una nota Al habilitar esta opción, se crea automáticamente una copia de seguridad (\"NotallyX_AutoBackup.zip\") en la \"Directorio de copias de seguridad\" configurada cada vez que se guarda una nota.\nTenga en cuenta que esto puede afectar el rendimiento. Periodo de copia automática Directorio de copias de seguridad diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index 46918625..c2915745 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -22,7 +22,7 @@ Une erreur est survenue lors de la sauvegarde automatique:\n\'%1$s\'\nVeuillez vérifier vos paramètres ou signaler un bug La sauvegarde automatique de NotallyX a échoué Dernière sauvegarde - Sauvegarde automatique après chaque édition + Sauvegarde automatique après avoir quitté la note En activant cette option, une sauvegarde (\"NotallyX_AutoBackup.zip\") est automatiquement créée dans le \"Dossier des sauvegardes\" configuré, à chaque fois qu\'une note est enregistrée.\nAttention, cela pourrait affecter les performances. Dossier des sauvegardes Dossier dans lequel toutes les sauvegardes automatiques seront stockées. diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml index 99b1af0a..c873066b 100644 --- a/app/src/main/res/values-it/strings.xml +++ b/app/src/main/res/values-it/strings.xml @@ -22,7 +22,7 @@ Si é verificato un errore durante il backup automatico:\n\'%1$s\'\nPer favore controlla le tue impostazioni o segnala un bug Backup automatico di NotallyX non riuscito Ultimo backup - Backup automatico al salvataggio della nota + Backup automatico dopo l\'uscita dalla nota Abilitando questa opzione, un backup (NotallyX_AutoBackup.zip) verrà creato automaticamente nella \"Cartella di Backup\" configurata ogni volta che una nota viene salvata.\nTieni presente che questa operazione potrebbe influire sulle prestazioni Frequenza dei backup automatici Cartella backup diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml index d2093de9..77d0c7cf 100644 --- a/app/src/main/res/values-pl/strings.xml +++ b/app/src/main/res/values-pl/strings.xml @@ -22,7 +22,7 @@ Wystąpił błąd podczas tworzenia automatycznej kopii zapasowej:\n„%1$s”\nSprawdź ustawienia lub zgłoś błąd Automatyczna kopia zapasowa NotallyX nie powiodła się Ostatnia kopia zapasowa - Kopia zapasowa po zapisaniu notatki + Kopia zapasowa po wyjściu z notatki Po włączeniu tej opcji kopia zapasowa („NotallyX_AutoBackup.zip”) jest automatycznie tworzona w skonfigurowanym „Folderze kopii zapasowych” za każdym razem, gdy zapisywana jest notatka.\nPamiętaj, że może mieć to wpływ na wydajność Okres tworzenia automatycznych kopii zapasowych Folder kopii zapasowych diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 961ce9f9..5d56ab0a 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -29,6 +29,7 @@ 保存所有自动备份文件的文件夹 你需要重新选择备份文件夹,这样 NotallyX 有写入它的权限。你也可以按:取消“跳过导入备份文件夹的值 先在上方设置备份文件夹 + 在指定的空闲时间后自动保存笔记 将所选项目排到末尾 返回 备份 @@ -37,6 +38,7 @@ 自动备份周期/天 定期备份 启用此选项后将自动在配置的备份文件夹中创建备份文件。如果你启用了节能模式,这可能无法正常工作 + 行为 使用生物识别或PIN解锁应用 已停用生物特征/Pin 锁 未能通过生物特征/PIN验证身份 @@ -158,6 +160,7 @@ 导入备份 如果你的备份文件没有密码保护,只需按下“导入”即可。如有,起输入正确的密码 从其它APP导入笔记 + 导入设置 导入设置 为了导入设置,请选择有效的 NotallyX 设置 JSON 文件 成功地导入了设置 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 27724d95..a8fab153 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -23,13 +23,14 @@ An error occurred during auto backup:\n\'%1$s\'\nPlease check your settings or report a bug NotallyX Auto Backup failed Last Backup - Backup on Note save automatically - By enabling this, a backup (\"NotallyX_AutoBackup.zip\") is automatically created in the configured \"Backups Folder\" whenever a note is saved.\nBe aware this might affect performance + Backup on exit Note automatically + By enabling this, a backup (\"NotallyX_AutoBackup.zip\") is automatically created in the configured \"Backups Folder\" whenever a note is exited.\nBe aware this might affect performance Auto backup period Backups Folder Folder in which all auto backups will be stored in. You need to re-choose your Backups Folder so that NotallyX has permission to write to it.\nYou can also press cancel to skip importing Backups Folder value Set up a Backups Folder above first + Auto save note after specified idle time Sort checked items to the end Back Backup @@ -38,6 +39,7 @@ Auto backup period in days Periodic Backups By enabling this, backups are automatically created in the configured Backups Folder.\nThis may not work if you have power saving mode enabled + Behaviour Lock app with device biometric or PIN Biometric/PIN lock has been disabled Failed to authenticate via Biometric/PIN diff --git a/app/translations.xlsx b/app/translations.xlsx index 9937c8e4..18a9b641 100644 Binary files a/app/translations.xlsx and b/app/translations.xlsx differ diff --git a/fastlane/metadata/android/de-DE/changelogs/7210.txt b/fastlane/metadata/android/de-DE/changelogs/7210.txt new file mode 100644 index 00000000..691a4038 --- /dev/null +++ b/fastlane/metadata/android/de-DE/changelogs/7210.txt @@ -0,0 +1 @@ +* Fix Backup Export wenn Biometrische Sperre aktiv ist \ No newline at end of file diff --git a/fastlane/metadata/android/en-US/changelogs/7210.txt b/fastlane/metadata/android/en-US/changelogs/7210.txt new file mode 100644 index 00000000..abfa5797 --- /dev/null +++ b/fastlane/metadata/android/en-US/changelogs/7210.txt @@ -0,0 +1 @@ +* Fix exporting backups with biometric lock enabled diff --git a/gradle.properties b/gradle.properties index e60310f0..ec34ec4c 100644 --- a/gradle.properties +++ b/gradle.properties @@ -21,5 +21,5 @@ org.gradle.parallel=true android.experimental.enableNewResourceShrinker.preciseShrinking=true android.defaults.buildfeatures.buildconfig=true app.lastVersionName=7.2.0 -app.versionCode=7200 -app.versionName=7.2.0 +app.versionCode=7210 +app.versionName=7.2.1