mirror of
https://github.com/SimpleMobileTools/Simple-Notes.git
synced 2025-03-24 12:30:07 +01:00
Merge branch 'master' into fix-import-dialog
This commit is contained in:
commit
e93fb03484
@ -1,6 +1,12 @@
|
||||
Changelog
|
||||
==========
|
||||
|
||||
Version 6.8.2 *(2021-09-13)*
|
||||
----------------------------
|
||||
|
||||
* Added biometric protection on Android 11+
|
||||
* Fixed a glitch with note content vanishing on export error
|
||||
|
||||
Version 6.8.1 *(2021-08-23)*
|
||||
----------------------------
|
||||
|
||||
|
@ -16,8 +16,8 @@ android {
|
||||
applicationId "com.simplemobiletools.notes.pro"
|
||||
minSdkVersion 21
|
||||
targetSdkVersion 30
|
||||
versionCode 84
|
||||
versionName "6.8.1"
|
||||
versionCode 85
|
||||
versionName "6.8.2"
|
||||
setProperty("archivesBaseName", "notes")
|
||||
}
|
||||
|
||||
@ -56,7 +56,7 @@ android {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation 'com.github.SimpleMobileTools:Simple-Commons:dc3f4b619e'
|
||||
implementation 'com.github.SimpleMobileTools:Simple-Commons:7c0a8d628e'
|
||||
implementation 'androidx.constraintlayout:constraintlayout:2.1.0'
|
||||
implementation 'androidx.documentfile:documentfile:1.0.1'
|
||||
|
||||
|
@ -11,8 +11,6 @@
|
||||
android:name="android.hardware.faketouch"
|
||||
android:required="false" />
|
||||
|
||||
<uses-permission android:name="android.permission.USE_BIOMETRIC" />
|
||||
|
||||
<application
|
||||
android:name=".App"
|
||||
android:allowBackup="true"
|
||||
|
@ -319,8 +319,11 @@ class MainActivity : SimpleActivity() {
|
||||
}
|
||||
|
||||
private fun initViewPager(wantedNoteId: Long? = null) {
|
||||
NotesHelper(this).getNotes {
|
||||
mNotes = it
|
||||
NotesHelper(this).getNotes { notes ->
|
||||
notes.filter { it.shouldBeUnlocked(this) }
|
||||
.forEach(::removeProtection)
|
||||
|
||||
mNotes = notes
|
||||
invalidateOptionsMenu()
|
||||
mCurrentNote = mNotes[0]
|
||||
mAdapter = NotesPagerAdapter(supportFragmentManager, mNotes, this)
|
||||
@ -750,17 +753,19 @@ class MainActivity : SimpleActivity() {
|
||||
|
||||
RadioGroupDialog(this, items) {
|
||||
val syncFile = it as Int == EXPORT_FILE_SYNC
|
||||
tryExportNoteValueToFile(exportPath, textToExport, true) {
|
||||
if (syncFile) {
|
||||
mCurrentNote.path = exportPath
|
||||
mCurrentNote.value = ""
|
||||
} else {
|
||||
mCurrentNote.path = ""
|
||||
mCurrentNote.value = textToExport
|
||||
}
|
||||
tryExportNoteValueToFile(exportPath, textToExport, true) { exportedSuccessfully ->
|
||||
if (exportedSuccessfully) {
|
||||
if (syncFile) {
|
||||
mCurrentNote.path = exportPath
|
||||
mCurrentNote.value = ""
|
||||
} else {
|
||||
mCurrentNote.path = ""
|
||||
mCurrentNote.value = textToExport
|
||||
}
|
||||
|
||||
getPagerAdapter().updateCurrentNoteData(view_pager.currentItem, mCurrentNote.path, mCurrentNote.value)
|
||||
NotesHelper(this).insertOrUpdateNote(mCurrentNote)
|
||||
getPagerAdapter().updateCurrentNoteData(view_pager.currentItem, mCurrentNote.path, mCurrentNote.value)
|
||||
NotesHelper(this).insertOrUpdateNote(mCurrentNote)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -792,23 +797,26 @@ class MainActivity : SimpleActivity() {
|
||||
toast(String.format(getString(R.string.filename_invalid_characters_placeholder, filename)))
|
||||
} else {
|
||||
val noteStoredValue = note.getNoteStoredValue(this) ?: ""
|
||||
tryExportNoteValueToFile(file.absolutePath, note.value, false) {
|
||||
if (syncFile) {
|
||||
note.path = file.absolutePath
|
||||
note.value = ""
|
||||
} else {
|
||||
note.path = ""
|
||||
note.value = noteStoredValue
|
||||
tryExportNoteValueToFile(file.absolutePath, note.value, false) { exportedSuccessfully ->
|
||||
if (exportedSuccessfully) {
|
||||
if (syncFile) {
|
||||
note.path = file.absolutePath
|
||||
note.value = ""
|
||||
} else {
|
||||
note.path = ""
|
||||
note.value = noteStoredValue
|
||||
}
|
||||
|
||||
NotesHelper(this).insertOrUpdateNote(note)
|
||||
}
|
||||
|
||||
NotesHelper(this).insertOrUpdateNote(note)
|
||||
if (mCurrentNote.id == note.id) {
|
||||
mCurrentNote.value = note.value
|
||||
mCurrentNote.path = note.path
|
||||
getPagerAdapter().updateCurrentNoteData(view_pager.currentItem, mCurrentNote.path, mCurrentNote.value)
|
||||
}
|
||||
|
||||
if (!it) {
|
||||
if (!exportedSuccessfully) {
|
||||
failCount++
|
||||
}
|
||||
|
||||
@ -880,7 +888,7 @@ class MainActivity : SimpleActivity() {
|
||||
|
||||
private fun exportNoteValueToUri(uri: Uri, content: String, callback: ((success: Boolean) -> Unit)? = null) {
|
||||
try {
|
||||
val outputStream = contentResolver.openOutputStream(uri, "wt")
|
||||
val outputStream = contentResolver.openOutputStream(uri, "rwt")
|
||||
outputStream!!.bufferedWriter().use { out ->
|
||||
out.write(content)
|
||||
}
|
||||
@ -1087,19 +1095,21 @@ class MainActivity : SimpleActivity() {
|
||||
performSecurityCheck(
|
||||
protectionType = mCurrentNote.protectionType,
|
||||
requiredHash = mCurrentNote.protectionHash,
|
||||
successCallback = { _, _ -> removeProtection() }
|
||||
successCallback = { _, _ -> removeProtection(mCurrentNote) }
|
||||
)
|
||||
}
|
||||
|
||||
private fun removeProtection() {
|
||||
mCurrentNote.protectionHash = ""
|
||||
mCurrentNote.protectionType = PROTECTION_NONE
|
||||
NotesHelper(this).insertOrUpdateNote(mCurrentNote) {
|
||||
getCurrentFragment()?.apply {
|
||||
shouldShowLockedContent = true
|
||||
checkLockState()
|
||||
private fun removeProtection(note: Note) {
|
||||
note.protectionHash = ""
|
||||
note.protectionType = PROTECTION_NONE
|
||||
NotesHelper(this).insertOrUpdateNote(note) {
|
||||
if (note == mCurrentNote) {
|
||||
getCurrentFragment()?.apply {
|
||||
shouldShowLockedContent = true
|
||||
checkLockState()
|
||||
}
|
||||
invalidateOptionsMenu()
|
||||
}
|
||||
invalidateOptionsMenu()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -104,16 +104,18 @@ class WidgetConfigureActivity : SimpleActivity() {
|
||||
|
||||
if (mNotes.size == 1 && note == null) {
|
||||
note = mNotes.first()
|
||||
performSecurityCheck(
|
||||
protectionType = note.protectionType,
|
||||
requiredHash = note.protectionHash,
|
||||
successCallback = { _, _ -> updateCurrentNote(note) },
|
||||
failureCallback = { finish() }
|
||||
)
|
||||
} else {
|
||||
if (note != null) {
|
||||
if (note.shouldBeUnlocked(this)) {
|
||||
updateCurrentNote(note)
|
||||
} else {
|
||||
performSecurityCheck(
|
||||
protectionType = note.protectionType,
|
||||
requiredHash = note.protectionHash,
|
||||
successCallback = { _, _ -> updateCurrentNote(note) },
|
||||
failureCallback = { finish() }
|
||||
)
|
||||
}
|
||||
} else if (note != null) {
|
||||
updateCurrentNote(note)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -127,7 +129,7 @@ class WidgetConfigureActivity : SimpleActivity() {
|
||||
RadioGroupDialog(this, items, mCurrentNoteId.toInt()) {
|
||||
val selectedId = it as Int
|
||||
val note = mNotes.firstOrNull { it.id!!.toInt() == selectedId } ?: return@RadioGroupDialog
|
||||
if (note.protectionType == PROTECTION_NONE) {
|
||||
if (note.protectionType == PROTECTION_NONE || note.shouldBeUnlocked(this)) {
|
||||
updateCurrentNote(note)
|
||||
} else {
|
||||
performSecurityCheck(
|
||||
|
@ -78,11 +78,13 @@ class ChecklistFragment : NoteFragment(), ChecklistItemsListener {
|
||||
items.clear()
|
||||
|
||||
note.value.split("\n").map { it.trim() }.filter { it.isNotBlank() }.forEachIndexed { index, value ->
|
||||
items.add(ChecklistItem(
|
||||
id = index,
|
||||
title = value,
|
||||
isDone = false
|
||||
))
|
||||
items.add(
|
||||
ChecklistItem(
|
||||
id = index,
|
||||
title = value,
|
||||
isDone = false
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
saveChecklist()
|
||||
@ -120,6 +122,10 @@ class ChecklistFragment : NoteFragment(), ChecklistItemsListener {
|
||||
}
|
||||
|
||||
override fun checkLockState() {
|
||||
if (note == null) {
|
||||
return
|
||||
}
|
||||
|
||||
view.apply {
|
||||
checklist_content_holder.beVisibleIf(!note!!.isLocked() || shouldShowLockedContent)
|
||||
checklist_fab.beVisibleIf(!note!!.isLocked() || shouldShowLockedContent)
|
||||
|
@ -176,6 +176,10 @@ class TextFragment : NoteFragment() {
|
||||
fun removeTextWatcher() = view.text_note_view.removeTextChangedListener(textWatcher)
|
||||
|
||||
override fun checkLockState() {
|
||||
if (note == null) {
|
||||
return
|
||||
}
|
||||
|
||||
view.apply {
|
||||
notes_counter.beVisibleIf((!note!!.isLocked() || shouldShowLockedContent) && config!!.showWordCount)
|
||||
notes_scrollview.beVisibleIf(!note!!.isLocked() || shouldShowLockedContent)
|
||||
@ -263,11 +267,13 @@ class TextFragment : NoteFragment() {
|
||||
text.removeSpan(span)
|
||||
}
|
||||
|
||||
Selection.setSelection(text, if (edit.before == null) {
|
||||
start
|
||||
} else {
|
||||
start + edit.before.length
|
||||
})
|
||||
Selection.setSelection(
|
||||
text, if (edit.before == null) {
|
||||
start
|
||||
} else {
|
||||
start + edit.before.length
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
fun redo() {
|
||||
@ -285,11 +291,13 @@ class TextFragment : NoteFragment() {
|
||||
text.removeSpan(o)
|
||||
}
|
||||
|
||||
Selection.setSelection(text, if (edit.after == null) {
|
||||
start
|
||||
} else {
|
||||
start + edit.after.length
|
||||
})
|
||||
Selection.setSelection(
|
||||
text, if (edit.after == null) {
|
||||
start
|
||||
} else {
|
||||
start + edit.after.length
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
fun isUndoAvailable() = textHistory.position > 0
|
||||
|
@ -6,6 +6,8 @@ import androidx.room.ColumnInfo
|
||||
import androidx.room.Entity
|
||||
import androidx.room.Index
|
||||
import androidx.room.PrimaryKey
|
||||
import com.simplemobiletools.commons.extensions.isBiometricIdAvailable
|
||||
import com.simplemobiletools.commons.helpers.PROTECTION_FINGERPRINT
|
||||
import com.simplemobiletools.commons.helpers.PROTECTION_NONE
|
||||
import java.io.File
|
||||
|
||||
@ -17,7 +19,8 @@ data class Note(
|
||||
@ColumnInfo(name = "type") var type: Int,
|
||||
@ColumnInfo(name = "path") var path: String,
|
||||
@ColumnInfo(name = "protection_type") var protectionType: Int,
|
||||
@ColumnInfo(name = "protection_hash") var protectionHash: String) {
|
||||
@ColumnInfo(name = "protection_hash") var protectionHash: String
|
||||
) {
|
||||
|
||||
fun getNoteStoredValue(context: Context): String? {
|
||||
return if (path.isNotEmpty()) {
|
||||
@ -37,4 +40,8 @@ data class Note(
|
||||
}
|
||||
|
||||
fun isLocked() = protectionType != PROTECTION_NONE
|
||||
|
||||
fun shouldBeUnlocked(context: Context): Boolean {
|
||||
return protectionType == PROTECTION_FINGERPRINT && !context.isBiometricIdAvailable()
|
||||
}
|
||||
}
|
||||
|
2
fastlane/metadata/android/en-US/changelogs/85.txt
Normal file
2
fastlane/metadata/android/en-US/changelogs/85.txt
Normal file
@ -0,0 +1,2 @@
|
||||
* Added biometric protection on Android 11+
|
||||
* Fixed a glitch with note content vanishing on export error
|
Loading…
x
Reference in New Issue
Block a user