mirror of
https://github.com/PhilKes/NotallyX.git
synced 2025-06-29 20:59:54 +00:00
Compare commits
9 commits
Author | SHA1 | Date | |
---|---|---|---|
|
e243ed5155 | ||
|
200694d2e2 | ||
|
9ba90e88c4 | ||
|
3b72ae619e | ||
|
9fe6fb9e5a | ||
|
ebab977d38 | ||
|
250a901fce | ||
|
9d7b3ab6c5 | ||
|
eda1d8db3e |
22 changed files with 208 additions and 50 deletions
|
@ -4,9 +4,9 @@
|
|||
<b>NotallyX | Minimalistic note taking app</b>
|
||||
<p>
|
||||
<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://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>
|
||||
</p>
|
||||
</h2>
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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() &&
|
||||
|
|
|
@ -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() }
|
||||
}
|
||||
|
|
|
@ -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<NotallyDatabase, File> {
|
|||
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<NotallyDatabase, File> {
|
|||
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)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@ import kotlin.IllegalStateException
|
|||
|
||||
class ChangeHistory {
|
||||
private val changeStack = ArrayList<Change>()
|
||||
private var stackPointer = NotNullLiveData(-1)
|
||||
var stackPointer = NotNullLiveData(-1)
|
||||
|
||||
internal val canUndo = NotNullLiveData(false)
|
||||
internal val canRedo = NotNullLiveData(false)
|
||||
|
|
|
@ -30,6 +30,16 @@
|
|||
android:id="@+id/TextSize"
|
||||
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
|
||||
android:id="@+id/NotesSortOrder"
|
||||
|
@ -39,11 +49,14 @@
|
|||
android:id="@+id/CheckedListItemSorting"
|
||||
layout="@layout/preference" />
|
||||
|
||||
|
||||
<include
|
||||
android:id="@+id/StartView"
|
||||
layout="@layout/preference" />
|
||||
|
||||
<include
|
||||
android:id="@+id/AutoSaveAfterIdle"
|
||||
layout="@layout/preference_seekbar" />
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
|
@ -220,6 +233,20 @@
|
|||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
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
|
||||
android:id="@+id/SourceCode"
|
||||
|
@ -229,18 +256,11 @@
|
|||
android:text="@string/source_code" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/Libraries"
|
||||
style="@style/Preference"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/libraries" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/Donate"
|
||||
android:id="@+id/Libraries"
|
||||
style="@style/Preference"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/donate" />
|
||||
android:text="@string/libraries" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/VersionText"
|
||||
|
|
|
@ -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_failed">Automatické zálohování NotallyX selhalo</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_period">Frekvence automatického zálohování</string>
|
||||
<string name="auto_backups_folder">Adresář pro zálohy</string>
|
||||
|
|
|
@ -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_failed">NotallyX Auto Backup fehlgeschlagen</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_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">Autom. Backup beim Notiz Verlassen</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_backups_folder">Backups Ordner</string>
|
||||
<string name="auto_backups_folder_hint">Ordner in dem alle autom. Backups erstellt werden</string>
|
||||
|
|
|
@ -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_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_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_period">Periodo de copia automática</string>
|
||||
<string name="auto_backups_folder">Directorio de copias de seguridad</string>
|
||||
|
|
|
@ -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_failed">La sauvegarde automatique de NotallyX a échoué </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_backups_folder">Dossier des sauvegardes</string>
|
||||
<string name="auto_backups_folder_hint">Dossier dans lequel toutes les sauvegardes automatiques seront stockées.</string>
|
||||
|
|
|
@ -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_failed">Backup automatico di NotallyX non riuscito</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_period">Frequenza dei backup automatici</string>
|
||||
<string name="auto_backups_folder">Cartella backup</string>
|
||||
|
|
|
@ -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_failed">Automatyczna kopia zapasowa NotallyX nie powiodła się</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_period">Okres tworzenia automatycznych kopii zapasowych</string>
|
||||
<string name="auto_backups_folder">Folder kopii zapasowych</string>
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
<string name="auto_backups_folder_hint">保存所有自动备份文件的文件夹</string>
|
||||
<string name="auto_backups_folder_rechoose">你需要重新选择备份文件夹,这样 NotallyX 有写入它的权限。你也可以按:取消“跳过导入备份文件夹的值</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="back">返回</string>
|
||||
<string name="backup">备份</string>
|
||||
|
@ -37,6 +38,7 @@
|
|||
<string name="backup_period_days">自动备份周期/天</string>
|
||||
<string name="backup_periodic">定期备份</string>
|
||||
<string name="backup_periodic_hint">启用此选项后将自动在配置的备份文件夹中创建备份文件。如果你启用了节能模式,这可能无法正常工作</string>
|
||||
<string name="behaviour">行为</string>
|
||||
<string name="biometric_lock">使用生物识别或PIN解锁应用</string>
|
||||
<string name="biometrics_disable_success">已停用生物特征/Pin 锁</string>
|
||||
<string name="biometrics_failure">未能通过生物特征/PIN验证身份</string>
|
||||
|
@ -158,6 +160,7 @@
|
|||
<string name="import_backup">导入备份</string>
|
||||
<string name="import_backup_password_hint">如果你的备份文件没有密码保护,只需按下“导入”即可。如有,起输入正确的密码</string>
|
||||
<string name="import_other">从其它APP导入笔记</string>
|
||||
<string name="import_settings">导入设置</string>
|
||||
<string name="import_settings_failure">导入设置</string>
|
||||
<string name="import_settings_message">为了导入设置,请选择有效的 NotallyX 设置 JSON 文件</string>
|
||||
<string name="import_settings_success">成功地导入了设置</string>
|
||||
|
|
|
@ -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_failed">NotallyX Auto Backup failed</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_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">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 exited.\nBe aware this might affect performance</string>
|
||||
<string name="auto_backup_period">Auto backup period</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_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_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="back">Back</string>
|
||||
<string name="backup">Backup</string>
|
||||
|
@ -38,6 +39,7 @@
|
|||
<string name="backup_period_days">Auto backup period in days</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="behaviour">Behaviour</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_failure">Failed to authenticate via Biometric/PIN</string>
|
||||
|
|
Binary file not shown.
1
fastlane/metadata/android/de-DE/changelogs/7210.txt
Normal file
1
fastlane/metadata/android/de-DE/changelogs/7210.txt
Normal file
|
@ -0,0 +1 @@
|
|||
* Fix Backup Export wenn Biometrische Sperre aktiv ist
|
1
fastlane/metadata/android/en-US/changelogs/7210.txt
Normal file
1
fastlane/metadata/android/en-US/changelogs/7210.txt
Normal file
|
@ -0,0 +1 @@
|
|||
* Fix exporting backups with biometric lock enabled
|
|
@ -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
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue