From 1721912ab8625de5b5c9970050cff6881236834f Mon Sep 17 00:00:00 2001 From: tuancoltech Date: Fri, 10 Nov 2023 21:05:30 +0700 Subject: [PATCH] [bug] Check for note existence before saving to avoid crash: https://github.com/ARK-Builders/ARK-Memo/issues/26 --- .../data/repositories/TextNotesRepo.kt | 2 +- .../data/repositories/TextNotesRepoImpl.kt | 18 +++++++++++--- .../arkmemo/models/SaveNoteResult.kt | 6 +++++ .../ui/fragments/EditTextNotesFragment.kt | 24 ++++++++++++++----- .../arkmemo/ui/viewmodels/NotesViewModel.kt | 21 ++++++++++++++-- app/src/main/res/values/strings.xml | 1 + 6 files changed, 60 insertions(+), 12 deletions(-) create mode 100644 app/src/main/java/dev/arkbuilders/arkmemo/models/SaveNoteResult.kt diff --git a/app/src/main/java/dev/arkbuilders/arkmemo/data/repositories/TextNotesRepo.kt b/app/src/main/java/dev/arkbuilders/arkmemo/data/repositories/TextNotesRepo.kt index fe653de..3640ffb 100644 --- a/app/src/main/java/dev/arkbuilders/arkmemo/data/repositories/TextNotesRepo.kt +++ b/app/src/main/java/dev/arkbuilders/arkmemo/data/repositories/TextNotesRepo.kt @@ -6,7 +6,7 @@ import java.nio.file.Path interface TextNotesRepo { suspend fun init(root: Path, scope: CoroutineScope) - suspend fun save(note: TextNote) + suspend fun save(note: TextNote, callback: SaveNoteCallback) suspend fun delete(note: TextNote): Int suspend fun read(): List diff --git a/app/src/main/java/dev/arkbuilders/arkmemo/data/repositories/TextNotesRepoImpl.kt b/app/src/main/java/dev/arkbuilders/arkmemo/data/repositories/TextNotesRepoImpl.kt index 0477f7c..6131b05 100644 --- a/app/src/main/java/dev/arkbuilders/arkmemo/data/repositories/TextNotesRepoImpl.kt +++ b/app/src/main/java/dev/arkbuilders/arkmemo/data/repositories/TextNotesRepoImpl.kt @@ -11,11 +11,13 @@ import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext import dev.arkbuilders.arkmemo.data.ResourceMeta +import dev.arkbuilders.arkmemo.models.SaveNoteResult import dev.arkbuilders.arkmemo.models.TextNote import java.nio.file.Files import java.nio.file.Path import javax.inject.Inject import kotlin.io.path.deleteIfExists +import kotlin.io.path.exists import kotlin.io.path.extension import kotlin.io.path.fileSize import kotlin.io.path.forEachLine @@ -39,8 +41,8 @@ class TextNotesRepoImpl @Inject constructor(): TextNotesRepo { propertiesStorage = propertiesStorageRepo.provide(RootIndex.provide(root)) } - override suspend fun save(note: TextNote) { - write(note) + override suspend fun save(note: TextNote, callback: SaveNoteCallback) { + write(note, callback) } override suspend fun delete(note: TextNote) = withContext(iODispatcher) { @@ -78,7 +80,8 @@ class TextNotesRepoImpl @Inject constructor(): TextNotesRepo { notes } - private suspend fun write(note: TextNote) = withContext(Dispatchers.IO) { + private suspend fun write(note: TextNote, + saveNoteCallback: SaveNoteCallback) = withContext(Dispatchers.IO) { val tempPath = kotlin.io.path.createTempFile() val lines = note.content.data.split('\n') tempPath.writeLines(lines) @@ -88,6 +91,10 @@ class TextNotesRepoImpl @Inject constructor(): TextNotesRepo { persistNoteProperties(resourceId = id, noteTitle = note.content.title) val resourcePath = root.resolve("$id.$NOTE_EXT") + if (resourcePath.exists()) { + saveNoteCallback.onSaveNote(SaveNoteResult.ERROR_EXISTING) + return@withContext + } renameResourceWithNewResourceMeta( note = note, tempPath = tempPath, @@ -95,6 +102,7 @@ class TextNotesRepoImpl @Inject constructor(): TextNotesRepo { resourceId = id, size = size ) + saveNoteCallback.onSaveNote(SaveNoteResult.SUCCESS) } private suspend fun persistNoteProperties(resourceId: ResourceId, noteTitle: String) { @@ -128,5 +136,9 @@ class TextNotesRepoImpl @Inject constructor(): TextNotesRepo { } } +interface SaveNoteCallback { + fun onSaveNote(result: SaveNoteResult) +} + private const val NOTE_EXT = "note" diff --git a/app/src/main/java/dev/arkbuilders/arkmemo/models/SaveNoteResult.kt b/app/src/main/java/dev/arkbuilders/arkmemo/models/SaveNoteResult.kt new file mode 100644 index 0000000..00309b4 --- /dev/null +++ b/app/src/main/java/dev/arkbuilders/arkmemo/models/SaveNoteResult.kt @@ -0,0 +1,6 @@ +package dev.arkbuilders.arkmemo.models + +enum class SaveNoteResult { + SUCCESS, + ERROR_EXISTING +} \ No newline at end of file diff --git a/app/src/main/java/dev/arkbuilders/arkmemo/ui/fragments/EditTextNotesFragment.kt b/app/src/main/java/dev/arkbuilders/arkmemo/ui/fragments/EditTextNotesFragment.kt index c4c4851..26bf9c7 100644 --- a/app/src/main/java/dev/arkbuilders/arkmemo/ui/fragments/EditTextNotesFragment.kt +++ b/app/src/main/java/dev/arkbuilders/arkmemo/ui/fragments/EditTextNotesFragment.kt @@ -12,6 +12,7 @@ import dagger.hilt.android.AndroidEntryPoint import dev.arkbuilders.arkmemo.R import dev.arkbuilders.arkmemo.ui.viewmodels.NotesViewModel import dev.arkbuilders.arkmemo.databinding.FragmentEditTextNotesBinding +import dev.arkbuilders.arkmemo.models.SaveNoteResult import dev.arkbuilders.arkmemo.models.TextNote import dev.arkbuilders.arkmemo.ui.activities.MainActivity @@ -32,6 +33,7 @@ class EditTextNotesFragment: Fragment(R.layout.fragment_edit_text_notes) { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) notesViewModel.init() + subscribeLiveData() } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { @@ -86,16 +88,26 @@ class EditTextNotesFragment: Fragment(R.layout.fragment_edit_text_notes) { saveNoteButton.setOnClickListener { notesViewModel.onSaveClick(note) { show -> activity.showProgressBar(show) - if (!show) { - Toast.makeText(requireContext(), getString(R.string.ark_memo_note_saved), - Toast.LENGTH_SHORT) - .show() - activity.onBackPressedDispatcher.onBackPressed() - } } } } + private fun subscribeLiveData() { + notesViewModel.getSaveNoteResultLiveData().observe(this) { + if (!isResumed) return@observe + + if (it == SaveNoteResult.SUCCESS) { + Toast.makeText(requireContext(), getString(R.string.ark_memo_note_saved), + Toast.LENGTH_SHORT) + .show() + activity.onBackPressedDispatcher.onBackPressed() + } else { + Toast.makeText(requireContext(), getString(R.string.ark_memo_note_existing), + Toast.LENGTH_SHORT) + .show() + } + } + } companion object{ const val TAG = "Edit Text Notes" diff --git a/app/src/main/java/dev/arkbuilders/arkmemo/ui/viewmodels/NotesViewModel.kt b/app/src/main/java/dev/arkbuilders/arkmemo/ui/viewmodels/NotesViewModel.kt index 27946c5..ee5a44f 100644 --- a/app/src/main/java/dev/arkbuilders/arkmemo/ui/viewmodels/NotesViewModel.kt +++ b/app/src/main/java/dev/arkbuilders/arkmemo/ui/viewmodels/NotesViewModel.kt @@ -1,13 +1,17 @@ package dev.arkbuilders.arkmemo.ui.viewmodels +import androidx.lifecycle.LiveData +import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import dagger.hilt.android.lifecycle.HiltViewModel +import dev.arkbuilders.arkmemo.data.repositories.SaveNoteCallback import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import dev.arkbuilders.arkmemo.data.repositories.TextNotesRepo +import dev.arkbuilders.arkmemo.models.SaveNoteResult import dev.arkbuilders.arkmemo.models.TextNote import dev.arkbuilders.arkmemo.preferences.MemoPreferences import javax.inject.Inject @@ -22,6 +26,7 @@ class NotesViewModel @Inject constructor( private val iODispatcher = Dispatchers.IO private val notes = MutableStateFlow(listOf()) + private val mSaveNoteResultLiveData = MutableLiveData() fun init() { viewModelScope.launch(iODispatcher) { @@ -39,8 +44,16 @@ class NotesViewModel @Inject constructor( showProgress(true) } - textNotesRepo.save(note) - add(note) + textNotesRepo.save(note, object : SaveNoteCallback { + override fun onSaveNote(result: SaveNoteResult) { + if (result == SaveNoteResult.SUCCESS) { + add(note) + } + mSaveNoteResultLiveData.postValue(result) + } + + }) + withContext(Dispatchers.Main) { showProgress(false) } @@ -75,4 +88,8 @@ class NotesViewModel @Inject constructor( notes.remove(note) this.notes.value = notes } + + fun getSaveNoteResultLiveData(): LiveData { + return mSaveNoteResultLiveData + } } \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 0c773d8..e988d24 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -26,5 +26,6 @@ Cancel Are you sure to delete note? Note saved successfully. + Note existing! \ No newline at end of file