Compare commits

...

9 commits
main ... v7.2.1

Author SHA1 Message Date
PhilKes
e243ed5155 Bump version v7.2.1 2025-03-18 20:51:26 +01:00
Phil
200694d2e2
Merge pull request #465 from PhilKes/translation/update
Update zh-rCN/strings.xml
2025-03-18 18:00:19 +01:00
PhilKes
9ba90e88c4 Update zh-rCN/strings.xml 2025-03-18 17:59:55 +01:00
Phil
3b72ae619e
Merge pull request #464 from PhilKes/fix/export-backup-database
Fix databaseFile path when creating backup
2025-03-18 17:57:48 +01:00
PhilKes
9fe6fb9e5a Fix databaseFile path when creating backup 2025-03-18 13:41:27 +01:00
PhilKes
ebab977d38 Add rate app in About settings 2025-03-16 18:11:32 +01:00
Phil
250a901fce
Merge pull request #458 from PhilKes/feat/auto-save-idle
Add auto-save after user idle time
2025-03-16 18:05:28 +01:00
PhilKes
9d7b3ab6c5 Add auto-save after user idle time 2025-03-16 18:01:13 +01:00
Phil
eda1d8db3e
Add Google Play badge to README.md 2025-03-12 18:17:29 +01:00
22 changed files with 208 additions and 50 deletions

View file

@ -4,9 +4,9 @@
<b>NotallyX | Minimalistic note taking app</b> <b>NotallyX | Minimalistic note taking app</b>
<p> <p>
<center> <center>
<a href='https://play.google.com/store/apps/details?id=com.philkes.notallyx&pcampaignid=pcampaignidMKT-Other-global-all-co-prtnr-py-PartBadge-Mar2515-1'><img alt='Get it on Google Play' src='https://play.google.com/intl/en_us/badges/static/images/badges/en_badge_web_generic.png' height='80'/></a>
<a href="https://f-droid.org/en/packages/com.philkes.notallyx"><img alt='IzzyOnDroid' height='80' src='https://fdroid.gitlab.io/artwork/badge/get-it-on.png' /></a> <a href="https://f-droid.org/en/packages/com.philkes.notallyx"><img alt='IzzyOnDroid' height='80' src='https://fdroid.gitlab.io/artwork/badge/get-it-on.png' /></a>
<a href="https://apt.izzysoft.de/fdroid/index/apk/com.philkes.notallyx"><img alt='F-Droid' height='80' src='https://gitlab.com/IzzyOnDroid/repo/-/raw/master/assets/IzzyOnDroid.png' /></a> <a href="https://apt.izzysoft.de/fdroid/index/apk/com.philkes.notallyx"><img alt='F-Droid' height='80' src='https://gitlab.com/IzzyOnDroid/repo/-/raw/master/assets/IzzyOnDroid.png' /></a>
<a href="https://github.com/PhilKes/NotallyX/issues/120"><img alt="JoinTesters" height="80" src="fastlane/join-testers.png" /></a>
</center> </center>
</p> </p>
</h2> </h2>

View file

@ -31,6 +31,50 @@ data class BaseNote(
const val COLOR_DEFAULT = "DEFAULT" const val COLOR_DEFAULT = "DEFAULT"
const val COLOR_NEW = "NEW" 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 { fun BaseNote.deepCopy(): BaseNote {

View file

@ -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( fun PreferenceBinding.setupStartView(
preference: StringPreference, preference: StringPreference,
value: String, value: String,

View file

@ -616,6 +616,12 @@ class SettingsFragment : Fragment() {
} }
} }
} }
binding.AutoSaveAfterIdle.setupAutoSaveIdleTime(
autoSaveAfterIdleTime,
requireContext(),
) { newValue ->
model.savePreference(autoSaveAfterIdleTime, newValue)
}
ClearData.setOnClickListener { ClearData.setOnClickListener {
MaterialAlertDialogBuilder(requireContext()) MaterialAlertDialogBuilder(requireContext())
.setMessage(R.string.clear_data_message) .setMessage(R.string.clear_data_message)
@ -689,8 +695,10 @@ class SettingsFragment : Fragment() {
.setCancelButton() .setCancelButton()
.show() .show()
} }
Rate.setOnClickListener {
openLink("https://play.google.com/store/apps/details?id=com.philkes.notallyx")
}
SourceCode.setOnClickListener { openLink("https://github.com/PhilKes/NotallyX") } SourceCode.setOnClickListener { openLink("https://github.com/PhilKes/NotallyX") }
// TODO: add ColorPickerView
Libraries.setOnClickListener { Libraries.setOnClickListener {
val libraries = val libraries =
arrayOf( arrayOf(

View file

@ -8,8 +8,11 @@ import android.graphics.drawable.Drawable
import android.net.Uri import android.net.Uri
import android.os.Build import android.os.Build
import android.os.Bundle import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.provider.Settings import android.provider.Settings
import android.text.Editable import android.text.Editable
import android.util.Log
import android.util.TypedValue import android.util.TypedValue
import android.view.MenuItem import android.view.MenuItem
import android.view.View import android.view.View
@ -114,12 +117,25 @@ abstract class EditActivity(private val type: Type) :
protected var colorInt: Int = -1 protected var colorInt: Int = -1
protected var inputMethodManager: InputMethodManager? = null 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() { override fun finish() {
lifecycleScope.launch(Dispatchers.Main) { lifecycleScope.launch(Dispatchers.Main) {
if (notallyModel.isEmpty()) { if (notallyModel.isEmpty()) {
notallyModel.deleteBaseNote(checkAutoSave = false) notallyModel.deleteBaseNote(checkAutoSave = false)
} else if (notallyModel.isModified()) { } else if (notallyModel.isModified()) {
saveNote() saveNote()
} else {
notallyModel.checkBackupOnSave()
} }
super.finish() 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() updateModel()
notallyModel.saveNote() notallyModel.saveNote(checkAutoSave)
WidgetProvider.sendBroadcast(application, longArrayOf(notallyModel.id)) 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() { private fun setupActivityResultLaunchers() {
recordAudioActivityResultLauncher = recordAudioActivityResultLauncher =
registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result -> registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
@ -243,6 +272,7 @@ abstract class EditActivity(private val type: Type) :
paddingTop = true, paddingTop = true,
colorInt, colorInt,
) )
resetIdleTimer()
} }
} }
} }
@ -317,6 +347,7 @@ abstract class EditActivity(private val type: Type) :
ChangeHistory().apply { ChangeHistory().apply {
canUndo.observe(this@EditActivity) { canUndo -> undo?.isEnabled = canUndo } canUndo.observe(this@EditActivity) { canUndo -> undo?.isEnabled = canUndo }
canRedo.observe(this@EditActivity) { canRedo -> redo?.isEnabled = canRedo } 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 notallyModel.color = selectedColor
setColor() setColor()
resetIdleTimer()
}, },
) { colorToDelete, newColor -> ) { colorToDelete, newColor ->
baseModel.changeColor(colorToDelete, newColor) baseModel.changeColor(colorToDelete, newColor)
@ -652,6 +684,7 @@ abstract class EditActivity(private val type: Type) :
notallyModel.color = newColor notallyModel.color = newColor
setColor() setColor()
} }
resetIdleTimer()
} }
} }
} }

View file

@ -40,7 +40,7 @@ import com.philkes.notallyx.presentation.widget.WidgetProvider
import com.philkes.notallyx.utils.Cache import com.philkes.notallyx.utils.Cache
import com.philkes.notallyx.utils.Event import com.philkes.notallyx.utils.Event
import com.philkes.notallyx.utils.FileError 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.importAudio
import com.philkes.notallyx.utils.backup.importFile import com.philkes.notallyx.utils.backup.importFile
import com.philkes.notallyx.utils.cancelNoteReminders import com.philkes.notallyx.utils.cancelNoteReminders
@ -268,7 +268,7 @@ class NotallyModel(private val app: Application) : AndroidViewModel(app) {
withContext(Dispatchers.IO) { app.deleteAttachments(attachments) } withContext(Dispatchers.IO) { app.deleteAttachments(attachments) }
} }
if (checkAutoSave) { if (checkAutoSave) {
app.checkAutoSave(preferences, forceFullBackup = true) app.checkBackupOnSave(preferences, forceFullBackup = true)
} }
} }
@ -277,17 +277,24 @@ class NotallyModel(private val app: Application) : AndroidViewModel(app) {
this.items.addAll(items) this.items.addAll(items)
} }
suspend fun saveNote(): Long { suspend fun saveNote(checkBackupOnSave: Boolean = true): Long {
return withContext(Dispatchers.IO) { return withContext(Dispatchers.IO) {
val note = getBaseNote() val note = getBaseNote()
val id = baseNoteDao.insert(note) val id = baseNoteDao.insert(note)
app.checkAutoSave( if (checkBackupOnSave) {
checkBackupOnSave(note)
}
originalNote = note.deepCopy()
return@withContext id
}
}
suspend fun checkBackupOnSave(note: BaseNote = getBaseNote()) {
app.checkBackupOnSave(
preferences, preferences,
note = note, note = note,
forceFullBackup = originalNote?.attachmentsDifferFrom(note) == true, forceFullBackup = originalNote?.attachmentsDifferFrom(note) == true,
) )
return@withContext id
}
} }
fun isEmpty(): Boolean { fun isEmpty(): Boolean {

View file

@ -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 = val biometricLock =
createEnumPreference( createEnumPreference(
preferences, preferences,
@ -219,6 +229,7 @@ class NotallyXPreferences private constructor(private val context: Context) {
periodicBackups, periodicBackups,
backupPassword, backupPassword,
backupOnSave, backupOnSave,
autoSaveAfterIdleTime,
) )
.forEach { it.refresh() } .forEach { it.refresh() }
} }

View file

@ -81,6 +81,7 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import net.lingala.zip4j.ZipFile import net.lingala.zip4j.ZipFile
import net.lingala.zip4j.exception.ZipException
import net.lingala.zip4j.model.ZipParameters import net.lingala.zip4j.model.ZipParameters
import net.lingala.zip4j.model.enums.CompressionLevel import net.lingala.zip4j.model.enums.CompressionLevel
import net.lingala.zip4j.model.enums.EncryptionMethod import net.lingala.zip4j.model.enums.EncryptionMethod
@ -164,6 +165,9 @@ fun ContextWrapper.autoBackupOnSave(backupPath: String, password: String, savedN
backupPath, backupPath,
"Auto backup on note save (${savedNote?.let { "id: '${savedNote.id}, title: '${savedNote.title}'" }}) failed, because auto-backup path '$backupPath' is invalid", "Auto backup on note save (${savedNote?.let { "id: '${savedNote.id}, title: '${savedNote.title}'" }}) failed, because auto-backup path '$backupPath' is invalid",
) ?: return ) ?: return
fun log(msg: String? = null, throwable: Throwable? = null) {
logToFile(TAG, folder, NOTALLYX_BACKUP_LOGS_FILE, msg = msg, throwable = throwable)
}
try { try {
var backupFile = folder.findFile(ON_SAVE_BACKUP_FILE) var backupFile = folder.findFile(ON_SAVE_BACKUP_FILE)
if (savedNote == null || backupFile == null || !backupFile.exists()) { if (savedNote == null || backupFile == null || !backupFile.exists()) {
@ -193,16 +197,21 @@ fun ContextWrapper.autoBackupOnSave(backupPath: String, password: String, savedN
NotallyDatabase.getCurrentDatabaseFile(this@autoBackupOnSave), NotallyDatabase.getCurrentDatabaseFile(this@autoBackupOnSave),
) )
} }
try {
exportToZip(backupFile.uri, files, password) 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) { } catch (e: Exception) {
logToFile( log(
TAG,
folder,
NOTALLYX_BACKUP_LOGS_FILE,
msg =
"Auto backup on note save (${savedNote?.let { "id: '${savedNote.id}, title: '${savedNote.title}'" }}) failed", "Auto backup on note save (${savedNote?.let { "id: '${savedNote.id}, title: '${savedNote.title}'" }}) failed",
throwable = e, e,
) )
tryPostErrorNotification(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, preferences: NotallyXPreferences,
note: BaseNote? = null, note: BaseNote? = null,
forceFullBackup: Boolean = false, forceFullBackup: Boolean = false,
@ -400,6 +409,7 @@ fun ContextWrapper.copyDatabase(): Pair<NotallyDatabase, File> {
val database = NotallyDatabase.getDatabase(this, observePreferences = false).value val database = NotallyDatabase.getDatabase(this, observePreferences = false).value
database.checkpoint() database.checkpoint()
val preferences = NotallyXPreferences.getInstance(this) val preferences = NotallyXPreferences.getInstance(this)
val databaseFile = NotallyDatabase.getCurrentDatabaseFile(this)
return if ( return if (
preferences.biometricLock.value == BiometricLock.ENABLED && preferences.biometricLock.value == BiometricLock.ENABLED &&
Build.VERSION.SDK_INT >= Build.VERSION_CODES.M Build.VERSION.SDK_INT >= Build.VERSION_CODES.M
@ -407,16 +417,11 @@ fun ContextWrapper.copyDatabase(): Pair<NotallyDatabase, File> {
val cipher = getInitializedCipherForDecryption(iv = preferences.iv.value!!) val cipher = getInitializedCipherForDecryption(iv = preferences.iv.value!!)
val passphrase = cipher.doFinal(preferences.databaseEncryptionKey.value) val passphrase = cipher.doFinal(preferences.databaseEncryptionKey.value)
val decryptedFile = File(cacheDir, DATABASE_NAME) val decryptedFile = File(cacheDir, DATABASE_NAME)
decryptDatabase( decryptDatabase(this, passphrase, decryptedFile, databaseFile)
this,
passphrase,
decryptedFile,
NotallyDatabase.getExternalDatabaseFile(this),
)
Pair(database, decryptedFile) Pair(database, decryptedFile)
} else { } else {
val dbFile = File(cacheDir, DATABASE_NAME) val dbFile = File(cacheDir, DATABASE_NAME)
NotallyDatabase.getCurrentDatabaseFile(this).copyTo(dbFile, overwrite = true) databaseFile.copyTo(dbFile, overwrite = true)
Pair(database, dbFile) Pair(database, dbFile)
} }
} }

View file

@ -6,7 +6,7 @@ import kotlin.IllegalStateException
class ChangeHistory { class ChangeHistory {
private val changeStack = ArrayList<Change>() private val changeStack = ArrayList<Change>()
private var stackPointer = NotNullLiveData(-1) var stackPointer = NotNullLiveData(-1)
internal val canUndo = NotNullLiveData(false) internal val canUndo = NotNullLiveData(false)
internal val canRedo = NotNullLiveData(false) internal val canRedo = NotNullLiveData(false)

View file

@ -30,6 +30,16 @@
android:id="@+id/TextSize" android:id="@+id/TextSize"
layout="@layout/preference" /> layout="@layout/preference" />
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="?android:attr/listDivider" />
<TextView
style="@style/PreferenceHeader"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/behaviour" />
<include <include
android:id="@+id/NotesSortOrder" android:id="@+id/NotesSortOrder"
@ -39,11 +49,14 @@
android:id="@+id/CheckedListItemSorting" android:id="@+id/CheckedListItemSorting"
layout="@layout/preference" /> layout="@layout/preference" />
<include <include
android:id="@+id/StartView" android:id="@+id/StartView"
layout="@layout/preference" /> layout="@layout/preference" />
<include
android:id="@+id/AutoSaveAfterIdle"
layout="@layout/preference_seekbar" />
<View <View
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="1dp" android:layout_height="1dp"
@ -221,6 +234,20 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/send_feedback" /> android:text="@string/send_feedback" />
<TextView
android:id="@+id/Rate"
style="@style/Preference"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/rate" />
<TextView
android:id="@+id/Donate"
style="@style/Preference"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/donate" />
<TextView <TextView
android:id="@+id/SourceCode" android:id="@+id/SourceCode"
style="@style/Preference" style="@style/Preference"
@ -235,13 +262,6 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/libraries" /> android:text="@string/libraries" />
<TextView
android:id="@+id/Donate"
style="@style/Preference"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/donate" />
<TextView <TextView
android:id="@+id/VersionText" android:id="@+id/VersionText"
android:layout_width="match_parent" android:layout_width="match_parent"

View file

@ -23,7 +23,7 @@
<string name="auto_backup_error_message">Během automatického zálohování došlo k chybě:\n\'%1$s\'\nProsím, zkontrolujte nastavení nebo nahlaste chybu</string> <string name="auto_backup_error_message">Během automatického zálohování došlo k chybě:\n\'%1$s\'\nProsím, zkontrolujte nastavení nebo nahlaste chybu</string>
<string name="auto_backup_failed">Automatické zálohování NotallyX selhalo</string> <string name="auto_backup_failed">Automatické zálohování NotallyX selhalo</string>
<string name="auto_backup_last">Poslední záloha</string> <string name="auto_backup_last">Poslední záloha</string>
<string name="auto_backup_on_save">Automaticky zálohovat při uložení poznámky</string> <string name="auto_backup_on_save">Automaticky zálohovat při ukončení poznámky</string>
<string name="auto_backup_on_save_hint">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</string> <string name="auto_backup_on_save_hint">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</string>
<string name="auto_backup_period">Frekvence automatického zálohování</string> <string name="auto_backup_period">Frekvence automatického zálohování</string>
<string name="auto_backups_folder">Adresář pro zálohy</string> <string name="auto_backups_folder">Adresář pro zálohy</string>

View file

@ -22,8 +22,8 @@
<string name="auto_backup_error_message">Beim autom. Backup ist ein Fehler aufgetreten:\n\'%1$s\'\nÜberprüfe deine Einstellungen oder melde einen Bug</string> <string name="auto_backup_error_message">Beim autom. Backup ist ein Fehler aufgetreten:\n\'%1$s\'\nÜberprüfe deine Einstellungen oder melde einen Bug</string>
<string name="auto_backup_failed">NotallyX Auto Backup fehlgeschlagen</string> <string name="auto_backup_failed">NotallyX Auto Backup fehlgeschlagen</string>
<string name="auto_backup_last">Letztes Backup</string> <string name="auto_backup_last">Letztes Backup</string>
<string name="auto_backup_on_save">Autom. Backup beim Notiz-Speichern</string> <string name="auto_backup_on_save">Autom. Backup beim Notiz Verlassen</string>
<string name="auto_backup_on_save_hint">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</string> <string name="auto_backup_on_save_hint">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</string>
<string name="auto_backup_period">Intervall für autom. Backups</string> <string name="auto_backup_period">Intervall für autom. Backups</string>
<string name="auto_backups_folder">Backups Ordner</string> <string name="auto_backups_folder">Backups Ordner</string>
<string name="auto_backups_folder_hint">Ordner in dem alle autom. Backups erstellt werden</string> <string name="auto_backups_folder_hint">Ordner in dem alle autom. Backups erstellt werden</string>

View file

@ -22,7 +22,7 @@
<string name="auto_backup_error_message">Ha ocurrido un error durante una copia automática:\n\'%1$s\nComprueba tus ajustes o informa de un error</string> <string name="auto_backup_error_message">Ha ocurrido un error durante una copia automática:\n\'%1$s\nComprueba tus ajustes o informa de un error</string>
<string name="auto_backup_failed">Falló la copia de seguridad automática de Notallyx</string> <string name="auto_backup_failed">Falló la copia de seguridad automática de Notallyx</string>
<string name="auto_backup_last">Última copia de seguridad</string> <string name="auto_backup_last">Última copia de seguridad</string>
<string name="auto_backup_on_save">Copia de seguridad automática al guardar una nota</string> <string name="auto_backup_on_save">Copia de seguridad automática al salir una nota</string>
<string name="auto_backup_on_save_hint">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.</string> <string name="auto_backup_on_save_hint">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.</string>
<string name="auto_backup_period">Periodo de copia automática</string> <string name="auto_backup_period">Periodo de copia automática</string>
<string name="auto_backups_folder">Directorio de copias de seguridad</string> <string name="auto_backups_folder">Directorio de copias de seguridad</string>

View file

@ -22,7 +22,7 @@
<string name="auto_backup_error_message">Une erreur est survenue lors de la sauvegarde automatique:\n\'%1$s\'\nVeuillez vérifier vos paramètres ou signaler un bug</string> <string name="auto_backup_error_message">Une erreur est survenue lors de la sauvegarde automatique:\n\'%1$s\'\nVeuillez vérifier vos paramètres ou signaler un bug</string>
<string name="auto_backup_failed">La sauvegarde automatique de NotallyX a échoué </string> <string name="auto_backup_failed">La sauvegarde automatique de NotallyX a échoué </string>
<string name="auto_backup_last">Dernière sauvegarde</string> <string name="auto_backup_last">Dernière sauvegarde</string>
<string name="auto_backup_on_save">Sauvegarde automatique après chaque édition</string> <string name="auto_backup_on_save">Sauvegarde automatique après avoir quitté la note</string>
<string name="auto_backup_on_save_hint">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.</string> <string name="auto_backup_on_save_hint">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.</string>
<string name="auto_backups_folder">Dossier des sauvegardes</string> <string name="auto_backups_folder">Dossier des sauvegardes</string>
<string name="auto_backups_folder_hint">Dossier dans lequel toutes les sauvegardes automatiques seront stockées.</string> <string name="auto_backups_folder_hint">Dossier dans lequel toutes les sauvegardes automatiques seront stockées.</string>

View file

@ -22,7 +22,7 @@
<string name="auto_backup_error_message">Si é verificato un errore durante il backup automatico:\n\'%1$s\'\nPer favore controlla le tue impostazioni o segnala un bug</string> <string name="auto_backup_error_message">Si é verificato un errore durante il backup automatico:\n\'%1$s\'\nPer favore controlla le tue impostazioni o segnala un bug</string>
<string name="auto_backup_failed">Backup automatico di NotallyX non riuscito</string> <string name="auto_backup_failed">Backup automatico di NotallyX non riuscito</string>
<string name="auto_backup_last">Ultimo backup</string> <string name="auto_backup_last">Ultimo backup</string>
<string name="auto_backup_on_save">Backup automatico al salvataggio della nota</string> <string name="auto_backup_on_save">Backup automatico dopo l\'uscita dalla nota</string>
<string name="auto_backup_on_save_hint">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</string> <string name="auto_backup_on_save_hint">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</string>
<string name="auto_backup_period">Frequenza dei backup automatici</string> <string name="auto_backup_period">Frequenza dei backup automatici</string>
<string name="auto_backups_folder">Cartella backup</string> <string name="auto_backups_folder">Cartella backup</string>

View file

@ -22,7 +22,7 @@
<string name="auto_backup_error_message">Wystąpił błąd podczas tworzenia automatycznej kopii zapasowej:\n„%1$s”\nSprawdź ustawienia lub zgłoś błąd</string> <string name="auto_backup_error_message">Wystąpił błąd podczas tworzenia automatycznej kopii zapasowej:\n„%1$s”\nSprawdź ustawienia lub zgłoś błąd</string>
<string name="auto_backup_failed">Automatyczna kopia zapasowa NotallyX nie powiodła się</string> <string name="auto_backup_failed">Automatyczna kopia zapasowa NotallyX nie powiodła się</string>
<string name="auto_backup_last">Ostatnia kopia zapasowa</string> <string name="auto_backup_last">Ostatnia kopia zapasowa</string>
<string name="auto_backup_on_save">Kopia zapasowa po zapisaniu notatki</string> <string name="auto_backup_on_save">Kopia zapasowa po wyjściu z notatki</string>
<string name="auto_backup_on_save_hint">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ść</string> <string name="auto_backup_on_save_hint">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ść</string>
<string name="auto_backup_period">Okres tworzenia automatycznych kopii zapasowych</string> <string name="auto_backup_period">Okres tworzenia automatycznych kopii zapasowych</string>
<string name="auto_backups_folder">Folder kopii zapasowych</string> <string name="auto_backups_folder">Folder kopii zapasowych</string>

View file

@ -29,6 +29,7 @@
<string name="auto_backups_folder_hint">保存所有自动备份文件的文件夹</string> <string name="auto_backups_folder_hint">保存所有自动备份文件的文件夹</string>
<string name="auto_backups_folder_rechoose">你需要重新选择备份文件夹,这样 NotallyX 有写入它的权限。你也可以按:取消“跳过导入备份文件夹的值</string> <string name="auto_backups_folder_rechoose">你需要重新选择备份文件夹,这样 NotallyX 有写入它的权限。你也可以按:取消“跳过导入备份文件夹的值</string>
<string name="auto_backups_folder_set">先在上方设置备份文件夹</string> <string name="auto_backups_folder_set">先在上方设置备份文件夹</string>
<string name="auto_save_after_idle_time">在指定的空闲时间后自动保存笔记</string>
<string name="auto_sort_by_checked">将所选项目排到末尾</string> <string name="auto_sort_by_checked">将所选项目排到末尾</string>
<string name="back">返回</string> <string name="back">返回</string>
<string name="backup">备份</string> <string name="backup">备份</string>
@ -37,6 +38,7 @@
<string name="backup_period_days">自动备份周期/天</string> <string name="backup_period_days">自动备份周期/天</string>
<string name="backup_periodic">定期备份</string> <string name="backup_periodic">定期备份</string>
<string name="backup_periodic_hint">启用此选项后将自动在配置的备份文件夹中创建备份文件。如果你启用了节能模式,这可能无法正常工作</string> <string name="backup_periodic_hint">启用此选项后将自动在配置的备份文件夹中创建备份文件。如果你启用了节能模式,这可能无法正常工作</string>
<string name="behaviour">行为</string>
<string name="biometric_lock">使用生物识别或PIN解锁应用</string> <string name="biometric_lock">使用生物识别或PIN解锁应用</string>
<string name="biometrics_disable_success">已停用生物特征/Pin 锁</string> <string name="biometrics_disable_success">已停用生物特征/Pin 锁</string>
<string name="biometrics_failure">未能通过生物特征/PIN验证身份</string> <string name="biometrics_failure">未能通过生物特征/PIN验证身份</string>
@ -158,6 +160,7 @@
<string name="import_backup">导入备份</string> <string name="import_backup">导入备份</string>
<string name="import_backup_password_hint">如果你的备份文件没有密码保护,只需按下“导入”即可。如有,起输入正确的密码</string> <string name="import_backup_password_hint">如果你的备份文件没有密码保护,只需按下“导入”即可。如有,起输入正确的密码</string>
<string name="import_other">从其它APP导入笔记</string> <string name="import_other">从其它APP导入笔记</string>
<string name="import_settings">导入设置</string>
<string name="import_settings_failure">导入设置</string> <string name="import_settings_failure">导入设置</string>
<string name="import_settings_message">为了导入设置,请选择有效的 NotallyX 设置 JSON 文件</string> <string name="import_settings_message">为了导入设置,请选择有效的 NotallyX 设置 JSON 文件</string>
<string name="import_settings_success">成功地导入了设置</string> <string name="import_settings_success">成功地导入了设置</string>

View file

@ -23,13 +23,14 @@
<string name="auto_backup_error_message">An error occurred during auto backup:\n\'%1$s\'\nPlease check your settings or report a bug</string> <string name="auto_backup_error_message">An error occurred during auto backup:\n\'%1$s\'\nPlease check your settings or report a bug</string>
<string name="auto_backup_failed">NotallyX Auto Backup failed</string> <string name="auto_backup_failed">NotallyX Auto Backup failed</string>
<string name="auto_backup_last">Last Backup</string> <string name="auto_backup_last">Last Backup</string>
<string name="auto_backup_on_save">Backup on Note save automatically</string> <string name="auto_backup_on_save">Backup on exit Note automatically</string>
<string name="auto_backup_on_save_hint">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</string> <string name="auto_backup_on_save_hint">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</string>
<string name="auto_backup_period">Auto backup period</string> <string name="auto_backup_period">Auto backup period</string>
<string name="auto_backups_folder">Backups Folder</string> <string name="auto_backups_folder">Backups Folder</string>
<string name="auto_backups_folder_hint">Folder in which all auto backups will be stored in.</string> <string name="auto_backups_folder_hint">Folder in which all auto backups will be stored in.</string>
<string name="auto_backups_folder_rechoose">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</string> <string name="auto_backups_folder_rechoose">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</string>
<string name="auto_backups_folder_set">Set up a Backups Folder above first</string> <string name="auto_backups_folder_set">Set up a Backups Folder above first</string>
<string name="auto_save_after_idle_time">Auto save note after specified idle time</string>
<string name="auto_sort_by_checked">Sort checked items to the end</string> <string name="auto_sort_by_checked">Sort checked items to the end</string>
<string name="back">Back</string> <string name="back">Back</string>
<string name="backup">Backup</string> <string name="backup">Backup</string>
@ -38,6 +39,7 @@
<string name="backup_period_days">Auto backup period in days</string> <string name="backup_period_days">Auto backup period in days</string>
<string name="backup_periodic">Periodic Backups</string> <string name="backup_periodic">Periodic Backups</string>
<string name="backup_periodic_hint">By enabling this, backups are automatically created in the configured Backups Folder.\nThis may not work if you have power saving mode enabled</string> <string name="backup_periodic_hint">By enabling this, backups are automatically created in the configured Backups Folder.\nThis may not work if you have power saving mode enabled</string>
<string name="behaviour">Behaviour</string>
<string name="biometric_lock">Lock app with device biometric or PIN</string> <string name="biometric_lock">Lock app with device biometric or PIN</string>
<string name="biometrics_disable_success">Biometric/PIN lock has been disabled</string> <string name="biometrics_disable_success">Biometric/PIN lock has been disabled</string>
<string name="biometrics_failure">Failed to authenticate via Biometric/PIN</string> <string name="biometrics_failure">Failed to authenticate via Biometric/PIN</string>

Binary file not shown.

View file

@ -0,0 +1 @@
* Fix Backup Export wenn Biometrische Sperre aktiv ist

View file

@ -0,0 +1 @@
* Fix exporting backups with biometric lock enabled

View file

@ -21,5 +21,5 @@ org.gradle.parallel=true
android.experimental.enableNewResourceShrinker.preciseShrinking=true android.experimental.enableNewResourceShrinker.preciseShrinking=true
android.defaults.buildfeatures.buildconfig=true android.defaults.buildfeatures.buildconfig=true
app.lastVersionName=7.2.0 app.lastVersionName=7.2.0
app.versionCode=7200 app.versionCode=7210
app.versionName=7.2.0 app.versionName=7.2.1