From b374c363dca9902ed699976066d30f731aec2405 Mon Sep 17 00:00:00 2001 From: ShubertMunthali Date: Tue, 24 Oct 2023 08:22:19 +0200 Subject: [PATCH] Minor fixes --- .../data/repositories/TextNotesRepo.kt | 162 ++++++------------ .../data/viewmodels/EditTextNotesViewModel.kt | 41 ----- .../ui/adapters/TextNotesListAdapter.kt | 2 +- .../ui/dialogs/NoteDeleteDialogFragment.kt | 4 +- .../ui/fragments/EditTextNotesFragment.kt | 8 +- .../arkmemo/ui/fragments/NotesFragment.kt | 9 +- .../viewmodels/NotesViewModel.kt} | 42 ++++- 7 files changed, 96 insertions(+), 172 deletions(-) delete mode 100644 app/src/main/java/space/taran/arkmemo/data/viewmodels/EditTextNotesViewModel.kt rename app/src/main/java/space/taran/arkmemo/{data/viewmodels/TextNotesViewModel.kt => ui/viewmodels/NotesViewModel.kt} (50%) diff --git a/app/src/main/java/space/taran/arkmemo/data/repositories/TextNotesRepo.kt b/app/src/main/java/space/taran/arkmemo/data/repositories/TextNotesRepo.kt index 26f11217..10b9e947 100644 --- a/app/src/main/java/space/taran/arkmemo/data/repositories/TextNotesRepo.kt +++ b/app/src/main/java/space/taran/arkmemo/data/repositories/TextNotesRepo.kt @@ -1,6 +1,7 @@ package space.taran.arkmemo.data.repositories import android.util.Log +import dev.arkbuilders.arklib.ResourceId import dev.arkbuilders.arklib.computeId import dev.arkbuilders.arklib.data.index.RootIndex import dev.arkbuilders.arklib.user.properties.Properties @@ -24,15 +25,13 @@ import kotlin.io.path.extension import kotlin.io.path.fileSize import kotlin.io.path.forEachLine import kotlin.io.path.getLastModifiedTime +import kotlin.io.path.moveTo import kotlin.io.path.name import kotlin.io.path.writeLines @Singleton class TextNotesRepo @Inject constructor() { - private val _textNotes = MutableStateFlow(listOf()) - val textNotes: StateFlow> = _textNotes - private val iODispatcher = Dispatchers.IO private lateinit var propertiesStorage: PropertiesStorage @@ -47,77 +46,61 @@ class TextNotesRepo @Inject constructor() { } suspend fun save(note: TextNote) { - add(note) write(note) } suspend fun delete(note: TextNote) = withContext(iODispatcher) { val path = root.resolve("${note.meta?.name}") - remove(note) delete(path) propertiesStorage.remove(note.meta?.id!!) propertiesStorage.persist() Log.d("text-repo", "${note.meta?.name!!} has been deleted") } - suspend fun read() = withContext(Dispatchers.IO) { + suspend fun read(): List = withContext(Dispatchers.IO) { val notes = mutableListOf() Files.list(root).forEach { path -> if (path.fileName.extension == NOTE_EXT) { - try { - val data = StringBuilder() - path.forEachLine { - data.appendLine(it) - } - val size = path.fileSize() - val id = computeId(size, path) - val meta = ResourceMeta( - id, - path.fileName.name, - path.extension, - path.getLastModifiedTime(), - size - ) - val titles = propertiesStorage.getProperties(id).titles - val content = TextNote.Content(titles.elementAt(0), data.toString()) - val note = TextNote(content, meta) - notes.add(note) - } catch (e: Exception) { - e.printStackTrace() + val data = StringBuilder() + path.forEachLine { + data.appendLine(it) } + val size = path.fileSize() + val id = computeId(size, path) + val meta = ResourceMeta( + id, + path.fileName.name, + path.extension, + path.getLastModifiedTime(), + size + ) + val titles = propertiesStorage.getProperties(id).titles + val content = TextNote.Content(titles.elementAt(0), data.toString()) + val note = TextNote(content, meta) + notes.add(note) } } Log.d("text-repo", "${notes.size} text note resources found") - _textNotes.value = notes + notes } - - private suspend fun write(note: TextNote) { - withContext(Dispatchers.IO) { - val path = root.resolve("${DUMMY_FILENAME}.${NOTE_EXT}") - if (path.exists()) return@withContext - try { - val lines = note.content.data.split(NEWLINE) - path.writeLines(lines) - val size = path.fileSize() - val id = computeId(size, path) - Log.d("text-repo", "initial resource name ${path.name}") - persistNoteProperties(resourceId = id, noteTitle = note.content.title) - - val newPath = root.resolve("$id.$NOTE_EXT") - if (!newPath.exists()) { - renameResourceWithNewResourceMeta( - note = note, - path = path, - newPath = newPath, - resourceId = id, - size = size - ) - } - } catch (e: Exception) { - e.printStackTrace() - } - } + private suspend fun write(note: TextNote) = withContext(Dispatchers.IO) { + val tempPath = kotlin.io.path.createTempFile() + val lines = note.content.data.split('\n') + tempPath.writeLines(lines) + val size = tempPath.fileSize() + val id = computeId(size, tempPath) + Log.d("text-repo", "initial resource name ${tempPath.name}") + persistNoteProperties(resourceId = id, noteTitle = note.content.title) + + val resourcePath = root.resolve("$id.$NOTE_EXT") + renameResourceWithNewResourceMeta( + note = note, + tempPath = tempPath, + resourcePath = resourcePath, + resourceId = id, + size = size + ) } private suspend fun persistNoteProperties(resourceId: ResourceId, noteTitle: String) { @@ -127,76 +110,29 @@ class TextNotesRepo @Inject constructor() { persist() } } + private fun renameResourceWithNewResourceMeta( note: TextNote, - path: Path, - newPath: Path, + tempPath: Path, + resourcePath: Path, resourceId: ResourceId, size: Long ) { - if (path.toFile().renameTo(newPath.toFile())) { - note.meta = ResourceMeta( - id = resourceId, - name = newPath.fileName.name, - extension = newPath.extension, - modified = newPath.getLastModifiedTime(), - size = size - ) - Log.d("notes-repo", "resource renamed to ${newPath.name} successfully") - } else delete(path) - } - val path = root.resolve("${DUMMY_FILENAME}.${NOTE_EXT}") - if (!path.exists()) { - try { - val lines = note.content.data.split(NEWLINE) - path.writeLines(lines) - val size = path.fileSize() - val id = computeId(size, path) - val properties = Properties(setOf(note.content.title), setOf()) - - Log.d("text-repo", "initial resource name ${path.name}") - - propertiesStorage.setProperties(id, properties) - propertiesStorage.persist() - - val newPath = root.resolve("$id.$NOTE_EXT") - if (!newPath.exists()) { - if (path.toFile().renameTo(newPath.toFile())) { - note.meta = ResourceMeta( - id, - newPath.fileName.name, - newPath.extension, - newPath.getLastModifiedTime(), - size - ) - Log.d("notes-repo", "resource renamed to ${newPath.name} successfully") - } else delete(path) - } - } catch (e: Exception) { - e.printStackTrace() - } - } - this.coroutineContext.job + tempPath.moveTo(resourcePath) + note.meta = ResourceMeta( + id = resourceId, + name = resourcePath.fileName.name, + extension = resourcePath.extension, + modified = resourcePath.getLastModifiedTime(), + size = size + ) + Log.d("notes-repo", "resource renamed to ${resourcePath.name} successfully") } private fun delete(path: Path) { path.deleteIfExists() } - - private fun add(note: TextNote) { - val notes = textNotes.value.toMutableList() - notes.add(note) - _textNotes.value = notes - } - - private fun remove(note: TextNote) { - val notes = textNotes.value.toMutableList() - notes.remove(note) - _textNotes.value = notes - } } private const val NOTE_EXT = "note" -private const val DUMMY_FILENAME = "Note" -private const val NEWLINE = "\n" diff --git a/app/src/main/java/space/taran/arkmemo/data/viewmodels/EditTextNotesViewModel.kt b/app/src/main/java/space/taran/arkmemo/data/viewmodels/EditTextNotesViewModel.kt deleted file mode 100644 index 6609ae0a..00000000 --- a/app/src/main/java/space/taran/arkmemo/data/viewmodels/EditTextNotesViewModel.kt +++ /dev/null @@ -1,41 +0,0 @@ -package space.taran.arkmemo.data.viewmodels - -import androidx.lifecycle.ViewModel -import androidx.lifecycle.viewModelScope -import dagger.hilt.android.lifecycle.HiltViewModel -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.launch -import kotlinx.coroutines.withContext -import space.taran.arkmemo.data.repositories.TextNotesRepo -import space.taran.arkmemo.models.TextNote -import space.taran.arkmemo.preferences.MemoPreferences -import javax.inject.Inject - -@HiltViewModel -class EditTextNotesViewModel @Inject constructor(): ViewModel() { - - private val iODispatcher = Dispatchers.IO - - @Inject lateinit var repo: TextNotesRepo - - fun init() { - viewModelScope.launch(iODispatcher) { - repo.init( - MemoPreferences.getInstance().getPath()!!, - viewModelScope - ) - } - } - - fun onSaveClick(note: TextNote, showProgress: (Boolean) -> Unit) { - viewModelScope.launch(iODispatcher) { - withContext(Dispatchers.Main) { - showProgress(true) - } - repo.save(note) - withContext(Dispatchers.Main) { - showProgress(false) - } - } - } -} \ No newline at end of file diff --git a/app/src/main/java/space/taran/arkmemo/ui/adapters/TextNotesListAdapter.kt b/app/src/main/java/space/taran/arkmemo/ui/adapters/TextNotesListAdapter.kt index 1e52eb62..c51c5119 100644 --- a/app/src/main/java/space/taran/arkmemo/ui/adapters/TextNotesListAdapter.kt +++ b/app/src/main/java/space/taran/arkmemo/ui/adapters/TextNotesListAdapter.kt @@ -35,7 +35,7 @@ class TextNotesListAdapter(private val notes: List): RecyclerView.Adap override fun onBindViewHolder(holder: NoteViewHolder, position: Int) { holder.title.text = notes[position].content.title - holder.date.text = notes[position].meta?.modified.toString() + holder.date.text = notes[position].meta?.modified?.toString() ?: "Just now" } override fun getItemCount() = notes.size diff --git a/app/src/main/java/space/taran/arkmemo/ui/dialogs/NoteDeleteDialogFragment.kt b/app/src/main/java/space/taran/arkmemo/ui/dialogs/NoteDeleteDialogFragment.kt index fe9c0c4d..248585d4 100644 --- a/app/src/main/java/space/taran/arkmemo/ui/dialogs/NoteDeleteDialogFragment.kt +++ b/app/src/main/java/space/taran/arkmemo/ui/dialogs/NoteDeleteDialogFragment.kt @@ -7,7 +7,7 @@ import androidx.appcompat.app.AlertDialog import androidx.fragment.app.DialogFragment import space.taran.arkmemo.R import space.taran.arkmemo.models.TextNote -import space.taran.arkmemo.ui.fragments.deleteTextNote +import space.taran.arkmemo.ui.fragments.deleteNote class NoteDeleteDialogFragment: DialogFragment() { @@ -27,7 +27,7 @@ class NoteDeleteDialogFragment: DialogFragment() { } .setPositiveButton(R.string.ark_memo_ok){ dialog, _ -> if(note != null) { - parentFragment?.deleteTextNote(note!!) + parentFragment?.deleteNote(note!!) Toast.makeText( requireContext(), getString(R.string.note_deleted), Toast.LENGTH_SHORT diff --git a/app/src/main/java/space/taran/arkmemo/ui/fragments/EditTextNotesFragment.kt b/app/src/main/java/space/taran/arkmemo/ui/fragments/EditTextNotesFragment.kt index 94880e9f..2abd0067 100644 --- a/app/src/main/java/space/taran/arkmemo/ui/fragments/EditTextNotesFragment.kt +++ b/app/src/main/java/space/taran/arkmemo/ui/fragments/EditTextNotesFragment.kt @@ -10,7 +10,7 @@ import androidx.fragment.app.activityViewModels import by.kirich1409.viewbindingdelegate.viewBinding import dagger.hilt.android.AndroidEntryPoint import space.taran.arkmemo.R -import space.taran.arkmemo.data.viewmodels.EditTextNotesViewModel +import space.taran.arkmemo.ui.viewmodels.NotesViewModel import space.taran.arkmemo.databinding.FragmentEditTextNotesBinding import space.taran.arkmemo.models.TextNote import space.taran.arkmemo.ui.activities.MainActivity @@ -22,7 +22,7 @@ class EditTextNotesFragment: Fragment(R.layout.fragment_edit_text_notes) { requireActivity() as MainActivity } - private val editViewModel: EditTextNotesViewModel by activityViewModels() + private val notesViewModel: NotesViewModel by activityViewModels() private val binding by viewBinding(FragmentEditTextNotesBinding::bind) @@ -31,7 +31,7 @@ class EditTextNotesFragment: Fragment(R.layout.fragment_edit_text_notes) { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - editViewModel.init() + notesViewModel.init() } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { @@ -84,7 +84,7 @@ class EditTextNotesFragment: Fragment(R.layout.fragment_edit_text_notes) { editNote.setText(noteStr) saveNoteButton.setOnClickListener { - editViewModel.onSaveClick(note) { show -> + notesViewModel.onSaveClick(note) { show -> activity.showProgressBar(show) if (!show) { Toast.makeText(requireContext(), getString(R.string.ark_memo_note_saved), diff --git a/app/src/main/java/space/taran/arkmemo/ui/fragments/NotesFragment.kt b/app/src/main/java/space/taran/arkmemo/ui/fragments/NotesFragment.kt index 1b3a7c30..fcb4cfcb 100644 --- a/app/src/main/java/space/taran/arkmemo/ui/fragments/NotesFragment.kt +++ b/app/src/main/java/space/taran/arkmemo/ui/fragments/NotesFragment.kt @@ -6,7 +6,6 @@ import android.widget.Button import android.widget.Toast import androidx.fragment.app.Fragment import androidx.fragment.app.activityViewModels -import androidx.fragment.app.viewModels import androidx.lifecycle.Lifecycle import androidx.lifecycle.lifecycleScope import androidx.lifecycle.repeatOnLifecycle @@ -17,7 +16,7 @@ import com.google.android.material.floatingactionbutton.FloatingActionButton import dagger.hilt.android.AndroidEntryPoint import kotlinx.coroutines.launch import space.taran.arkmemo.R -import space.taran.arkmemo.data.viewmodels.TextNotesViewModel +import space.taran.arkmemo.ui.viewmodels.NotesViewModel import space.taran.arkmemo.databinding.FragmentTextNotesBinding import space.taran.arkmemo.models.TextNote import space.taran.arkmemo.ui.activities.MainActivity @@ -34,7 +33,7 @@ class TextNotesFragment: Fragment(R.layout.fragment_text_notes) { requireActivity() as MainActivity } - private val textNotesViewModel: TextNotesViewModel by activityViewModels() + private val textNotesViewModel: NotesViewModel by activityViewModels() private lateinit var newNoteButton: FloatingActionButton private lateinit var pasteNoteButton: Button @@ -95,7 +94,7 @@ class TextNotesFragment: Fragment(R.layout.fragment_text_notes) { } } -fun Fragment.deleteTextNote(note: TextNote){ - val viewModel: TextNotesViewModel by viewModels() +fun Fragment.deleteNote(note: TextNote){ + val viewModel: NotesViewModel by activityViewModels() viewModel.onDelete(note) } \ No newline at end of file diff --git a/app/src/main/java/space/taran/arkmemo/data/viewmodels/TextNotesViewModel.kt b/app/src/main/java/space/taran/arkmemo/ui/viewmodels/NotesViewModel.kt similarity index 50% rename from app/src/main/java/space/taran/arkmemo/data/viewmodels/TextNotesViewModel.kt rename to app/src/main/java/space/taran/arkmemo/ui/viewmodels/NotesViewModel.kt index b5c1a448..62521089 100644 --- a/app/src/main/java/space/taran/arkmemo/data/viewmodels/TextNotesViewModel.kt +++ b/app/src/main/java/space/taran/arkmemo/ui/viewmodels/NotesViewModel.kt @@ -1,9 +1,10 @@ -package space.taran.arkmemo.data.viewmodels +package space.taran.arkmemo.ui.viewmodels import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import space.taran.arkmemo.data.repositories.TextNotesRepo @@ -12,35 +13,64 @@ import space.taran.arkmemo.preferences.MemoPreferences import javax.inject.Inject @HiltViewModel -class TextNotesViewModel @Inject constructor(): ViewModel() { - - @Inject lateinit var textNotesRepo: TextNotesRepo +class NotesViewModel @Inject constructor( + @Inject var textNotesRepo: TextNotesRepo +): ViewModel() { private val iODispatcher = Dispatchers.IO + private val notes = MutableStateFlow(listOf()) + fun init() { viewModelScope.launch(iODispatcher) { textNotesRepo.init( MemoPreferences.getInstance().getPath()!!, viewModelScope ) - textNotesRepo.read() + notes.value = textNotesRepo.read() + } + } + + fun onSaveClick(note: TextNote, showProgress: (Boolean) -> Unit) { + viewModelScope.launch(iODispatcher) { + withContext(Dispatchers.Main) { + showProgress(true) + + } + textNotesRepo.save(note) + add(note) + withContext(Dispatchers.Main) { + showProgress(false) + } } } fun onDelete(note: TextNote) { viewModelScope.launch(iODispatcher) { + remove(note) textNotesRepo.delete(note) } } fun getTextNotes(emit: (List) -> Unit) { viewModelScope.launch(iODispatcher) { - textNotesRepo.textNotes.collect { + notes.collect { withContext(Dispatchers.Main) { emit(it) } } } } + + private fun add(note: TextNote) { + val notes = this.notes.value.toMutableList() + notes.add(note) + this.notes.value = notes + } + + private fun remove(note: TextNote) { + val notes = this.notes.value.toMutableList() + notes.remove(note) + this.notes.value = notes + } } \ No newline at end of file