diff --git a/app/src/main/java/com/philkes/notallyx/data/dao/BaseNoteDao.kt b/app/src/main/java/com/philkes/notallyx/data/dao/BaseNoteDao.kt index f77d9cd4..4571ec34 100644 --- a/app/src/main/java/com/philkes/notallyx/data/dao/BaseNoteDao.kt +++ b/app/src/main/java/com/philkes/notallyx/data/dao/BaseNoteDao.kt @@ -162,7 +162,9 @@ interface BaseNoteDao { ) fun getAllRemindersAsync(): LiveData> - @Query("SELECT * FROM BaseNote WHERE reminders IS NOT NULL AND reminders != '[]'") + @Query( + "SELECT * FROM BaseNote WHERE reminders IS NOT NULL AND reminders != '[]' AND folder = 'NOTES'" + ) fun getAllBaseNotesWithReminders(): LiveData> @Query("SELECT id FROM BaseNote WHERE folder = 'DELETED'") diff --git a/app/src/main/java/com/philkes/notallyx/presentation/activity/main/fragment/NotallyFragment.kt b/app/src/main/java/com/philkes/notallyx/presentation/activity/main/fragment/NotallyFragment.kt index 556c68c2..618c027e 100644 --- a/app/src/main/java/com/philkes/notallyx/presentation/activity/main/fragment/NotallyFragment.kt +++ b/app/src/main/java/com/philkes/notallyx/presentation/activity/main/fragment/NotallyFragment.kt @@ -16,6 +16,7 @@ import androidx.lifecycle.LiveData import androidx.navigation.findNavController import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView +import androidx.recyclerview.widget.SortedListAdapterCallback import androidx.recyclerview.widget.StaggeredGridLayoutManager import com.google.android.material.snackbar.Snackbar import com.philkes.notallyx.R @@ -41,6 +42,7 @@ import com.philkes.notallyx.presentation.movedToResId import com.philkes.notallyx.presentation.showKeyboard import com.philkes.notallyx.presentation.view.main.BaseNoteAdapter import com.philkes.notallyx.presentation.view.main.BaseNoteVHPreferences +import com.philkes.notallyx.presentation.view.main.createCallback import com.philkes.notallyx.presentation.view.misc.ItemListener import com.philkes.notallyx.presentation.viewmodel.BaseNoteModel import com.philkes.notallyx.presentation.viewmodel.preference.NotesView @@ -261,7 +263,7 @@ abstract class NotallyFragment : Fragment(), ItemListener { BaseNoteAdapter( model.actionMode.selectedIds, dateFormat.value, - notesSorting.value, + notesAdapterSortCallback(), BaseNoteVHPreferences( textSizeOverview.value, maxItems.value, @@ -269,6 +271,7 @@ abstract class NotallyFragment : Fragment(), ItemListener { maxTitle.value, labelTagsHiddenInOverview.value, imagesHiddenInOverview.value, + notesSorting.value.sortedBy, ), model.imageRoot, this@NotallyFragment, @@ -296,6 +299,11 @@ abstract class NotallyFragment : Fragment(), ItemListener { } } + protected open fun notesAdapterSortCallback(): + (BaseNoteAdapter) -> SortedListAdapterCallback = { adapter -> + model.preferences.notesSorting.value.createCallback(adapter) + } + private fun setupObserver() { getObservable().observe(viewLifecycleOwner) { list -> notesAdapter?.submitList(list) diff --git a/app/src/main/java/com/philkes/notallyx/presentation/activity/main/fragment/RemindersFragment.kt b/app/src/main/java/com/philkes/notallyx/presentation/activity/main/fragment/RemindersFragment.kt index b2f60fd6..6f6d1030 100644 --- a/app/src/main/java/com/philkes/notallyx/presentation/activity/main/fragment/RemindersFragment.kt +++ b/app/src/main/java/com/philkes/notallyx/presentation/activity/main/fragment/RemindersFragment.kt @@ -4,15 +4,21 @@ import android.os.Bundle import android.view.View import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData +import androidx.recyclerview.widget.SortedListAdapterCallback import com.philkes.notallyx.R import com.philkes.notallyx.data.model.BaseNote import com.philkes.notallyx.data.model.Item import com.philkes.notallyx.data.model.hasAnyUpcomingNotifications +import com.philkes.notallyx.presentation.view.main.BaseNoteAdapter +import com.philkes.notallyx.presentation.view.main.sorting.BaseNoteLastNotificationSort +import com.philkes.notallyx.presentation.view.main.sorting.BaseNoteMostRecentNotificationSort +import com.philkes.notallyx.presentation.view.main.sorting.BaseNoteNextNotificationSort +import com.philkes.notallyx.presentation.viewmodel.preference.SortDirection class RemindersFragment : NotallyFragment() { private val currentReminderNotes = MutableLiveData>() private val allReminderNotes: LiveData> by lazy { model.reminderNotes!! } - private var filterMode = FilterOptions.ALL + private var filterMode = FilterOptions.UPCOMING override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) @@ -21,7 +27,7 @@ class RemindersFragment : NotallyFragment() { allReminderNotes.observe(viewLifecycleOwner) { _ -> applyFilter(filterMode) } binding?.ReminderFilter?.setOnCheckedStateChangeListener { _, checkedIds -> if (checkedIds.isEmpty()) { - binding?.ReminderFilter?.check(R.id.all) + binding?.ReminderFilter?.check(R.id.upcoming) return@setOnCheckedStateChangeListener } filterMode = @@ -38,6 +44,15 @@ class RemindersFragment : NotallyFragment() { override fun getObservable(): LiveData> = currentReminderNotes + override fun notesAdapterSortCallback(): (BaseNoteAdapter) -> SortedListAdapterCallback = + { adapter -> + when (filterMode) { + FilterOptions.UPCOMING -> BaseNoteNextNotificationSort(adapter, SortDirection.ASC) + FilterOptions.ELAPSED -> BaseNoteLastNotificationSort(adapter, SortDirection.DESC) + FilterOptions.ALL -> BaseNoteMostRecentNotificationSort(adapter, SortDirection.DESC) + } + } + fun applyFilter(filterOptions: FilterOptions) { val items: List = allReminderNotes.value ?: return val filteredList: List = @@ -53,11 +68,12 @@ class RemindersFragment : NotallyFragment() { } } currentReminderNotes.value = filteredList + notesAdapter?.setNotesSortCallback(notesAdapterSortCallback()) } } enum class FilterOptions { - ALL, UPCOMING, ELAPSED, + ALL, } diff --git a/app/src/main/java/com/philkes/notallyx/presentation/activity/note/PickNoteActivity.kt b/app/src/main/java/com/philkes/notallyx/presentation/activity/note/PickNoteActivity.kt index 03025bf5..f18e7b2f 100644 --- a/app/src/main/java/com/philkes/notallyx/presentation/activity/note/PickNoteActivity.kt +++ b/app/src/main/java/com/philkes/notallyx/presentation/activity/note/PickNoteActivity.kt @@ -18,6 +18,7 @@ import com.philkes.notallyx.databinding.ActivityPickNoteBinding import com.philkes.notallyx.presentation.activity.LockedActivity import com.philkes.notallyx.presentation.view.main.BaseNoteAdapter import com.philkes.notallyx.presentation.view.main.BaseNoteVHPreferences +import com.philkes.notallyx.presentation.view.main.createCallback import com.philkes.notallyx.presentation.view.misc.ItemListener import com.philkes.notallyx.presentation.viewmodel.BaseNoteModel import com.philkes.notallyx.presentation.viewmodel.preference.NotallyXPreferences @@ -50,7 +51,7 @@ open class PickNoteActivity : LockedActivity(), ItemLis BaseNoteAdapter( Collections.emptySet(), dateFormat.value, - notesSorting.value, + { adapter -> notesSorting.value.createCallback(adapter) }, BaseNoteVHPreferences( textSizeOverview.value, maxItems.value, @@ -58,6 +59,7 @@ open class PickNoteActivity : LockedActivity(), ItemLis maxTitle.value, labelTagsHiddenInOverview.value, imagesHiddenInOverview.value, + notesSorting.value.sortedBy, ), application.getCurrentImagesDirectory(), this@PickNoteActivity, diff --git a/app/src/main/java/com/philkes/notallyx/presentation/view/main/BaseNoteAdapter.kt b/app/src/main/java/com/philkes/notallyx/presentation/view/main/BaseNoteAdapter.kt index 7cdbd2b2..fb4350bb 100644 --- a/app/src/main/java/com/philkes/notallyx/presentation/view/main/BaseNoteAdapter.kt +++ b/app/src/main/java/com/philkes/notallyx/presentation/view/main/BaseNoteAdapter.kt @@ -23,7 +23,7 @@ import java.io.File class BaseNoteAdapter( private val selectedIds: Set, private val dateFormat: DateFormat, - private var notesSort: NotesSort, + private var notesSortCallback: (adapter: BaseNoteAdapter) -> SortedListAdapterCallback, private val preferences: BaseNoteVHPreferences, private val imageRoot: File?, private val listener: ItemListener, @@ -31,7 +31,7 @@ class BaseNoteAdapter( private var searchKeyword: String = "" - private var list = SortedList(Item::class.java, notesSort.createCallback()) + private var list = SortedList(Item::class.java, notesSortCallback(this)) override fun getItemViewType(position: Int): Int { return when (list[position]) { @@ -50,7 +50,7 @@ class BaseNoteAdapter( is BaseNote -> { (holder as BaseNoteVH).apply { setSearchKeyword(searchKeyword) - bind(item, imageRoot, selectedIds.contains(item.id), notesSort.sortedBy) + bind(item, imageRoot, selectedIds.contains(item.id), preferences.sortedBy) } } } @@ -119,8 +119,14 @@ class BaseNoteAdapter( } fun setNotesSort(notesSort: NotesSort) { - this.notesSort = notesSort - replaceSortCallback(notesSort.createCallback()) + setNotesSortCallback { adapter -> notesSort.createCallback(adapter) } + } + + fun setNotesSortCallback( + notesSortCallback: (adapter: BaseNoteAdapter) -> SortedListAdapterCallback + ) { + this.notesSortCallback = notesSortCallback + replaceSortCallback(this.notesSortCallback(this)) } fun getItem(position: Int): Item? { @@ -134,16 +140,6 @@ class BaseNoteAdapter( list.replaceAll(items) } - private fun NotesSort.createCallback() = - when (sortedBy) { - NotesSortBy.TITLE -> BaseNoteTitleSort(this@BaseNoteAdapter, sortDirection) - NotesSortBy.MODIFIED_DATE -> - BaseNoteModifiedDateSort(this@BaseNoteAdapter, sortDirection) - NotesSortBy.CREATION_DATE -> - BaseNoteCreationDateSort(this@BaseNoteAdapter, sortDirection) - NotesSortBy.COLOR -> BaseNoteColorSort(this@BaseNoteAdapter, sortDirection) - } - private fun replaceSortCallback(sortCallback: SortedListAdapterCallback) { val mutableList = mutableListOf() for (i in 0 until list.size()) { @@ -167,3 +163,11 @@ class BaseNoteAdapter( return mutableList.toList() } } + +fun NotesSort.createCallback(adapter: RecyclerView.Adapter<*>?) = + when (sortedBy) { + NotesSortBy.TITLE -> BaseNoteTitleSort(adapter, sortDirection) + NotesSortBy.MODIFIED_DATE -> BaseNoteModifiedDateSort(adapter, sortDirection) + NotesSortBy.CREATION_DATE -> BaseNoteCreationDateSort(adapter, sortDirection) + NotesSortBy.COLOR -> BaseNoteColorSort(adapter, sortDirection) + } diff --git a/app/src/main/java/com/philkes/notallyx/presentation/view/main/BaseNoteVH.kt b/app/src/main/java/com/philkes/notallyx/presentation/view/main/BaseNoteVH.kt index a49e3c10..d0c1fa39 100644 --- a/app/src/main/java/com/philkes/notallyx/presentation/view/main/BaseNoteVH.kt +++ b/app/src/main/java/com/philkes/notallyx/presentation/view/main/BaseNoteVH.kt @@ -51,6 +51,7 @@ data class BaseNoteVHPreferences( val maxTitleLines: Int, val hideLabels: Boolean, val hideImages: Boolean, + val sortedBy: NotesSortBy, ) class BaseNoteVH( diff --git a/app/src/main/java/com/philkes/notallyx/presentation/view/main/sorting/BaseNoteLastNotificationSort.kt b/app/src/main/java/com/philkes/notallyx/presentation/view/main/sorting/BaseNoteLastNotificationSort.kt new file mode 100644 index 00000000..34af99a7 --- /dev/null +++ b/app/src/main/java/com/philkes/notallyx/presentation/view/main/sorting/BaseNoteLastNotificationSort.kt @@ -0,0 +1,41 @@ +package com.philkes.notallyx.presentation.view.main.sorting + +import androidx.recyclerview.widget.RecyclerView +import com.philkes.notallyx.data.model.BaseNote +import com.philkes.notallyx.data.model.findLastNotificationDate +import com.philkes.notallyx.presentation.viewmodel.preference.SortDirection + +class BaseNoteLastNotificationSort( + adapter: RecyclerView.Adapter<*>?, + sortDirection: SortDirection, +) : ItemSort(adapter, sortDirection) { + + override fun compare(note1: BaseNote, note2: BaseNote, sortDirection: SortDirection): Int { + val sort = note1.compareLastNotification(note2) + return if (sortDirection == SortDirection.ASC) sort else -1 * sort + } +} + +fun BaseNote.compareLastNotification(other: BaseNote): Int { + if (other.reminders.isEmpty() && reminders.isNotEmpty()) { + return 1 + } + if (other.reminders.isNotEmpty() && reminders.isEmpty()) { + return -1 + } + if (other.reminders.isEmpty() && reminders.isEmpty()) { + return 0 + } + val lastNotification = reminders.findLastNotificationDate() + val otherLastNotification = other.reminders.findLastNotificationDate() + if (lastNotification == null && otherLastNotification != null) { + return -1 + } + if (lastNotification != null && otherLastNotification == null) { + return 1 + } + if (lastNotification == null && otherLastNotification == null) { + return 0 + } + return lastNotification!!.compareTo(otherLastNotification!!) +} diff --git a/app/src/main/java/com/philkes/notallyx/presentation/view/main/sorting/BaseNoteMostRecentNotificationSort.kt b/app/src/main/java/com/philkes/notallyx/presentation/view/main/sorting/BaseNoteMostRecentNotificationSort.kt new file mode 100644 index 00000000..461e6a0c --- /dev/null +++ b/app/src/main/java/com/philkes/notallyx/presentation/view/main/sorting/BaseNoteMostRecentNotificationSort.kt @@ -0,0 +1,18 @@ +package com.philkes.notallyx.presentation.view.main.sorting + +import androidx.recyclerview.widget.RecyclerView +import com.philkes.notallyx.data.model.BaseNote +import com.philkes.notallyx.presentation.viewmodel.preference.SortDirection + +class BaseNoteMostRecentNotificationSort( + adapter: RecyclerView.Adapter<*>?, + sortDirection: SortDirection, +) : ItemSort(adapter, sortDirection) { + + override fun compare(note1: BaseNote, note2: BaseNote, sortDirection: SortDirection): Int { + val sort = + note1.compareNextNotification(note2).takeIf { it != 0 } + ?: note1.compareLastNotification(note2) + return if (sortDirection == SortDirection.ASC) sort else -1 * sort + } +} diff --git a/app/src/main/java/com/philkes/notallyx/presentation/view/main/sorting/BaseNoteNextNotificationSort.kt b/app/src/main/java/com/philkes/notallyx/presentation/view/main/sorting/BaseNoteNextNotificationSort.kt new file mode 100644 index 00000000..dd931e5d --- /dev/null +++ b/app/src/main/java/com/philkes/notallyx/presentation/view/main/sorting/BaseNoteNextNotificationSort.kt @@ -0,0 +1,41 @@ +package com.philkes.notallyx.presentation.view.main.sorting + +import androidx.recyclerview.widget.RecyclerView +import com.philkes.notallyx.data.model.BaseNote +import com.philkes.notallyx.data.model.findNextNotificationDate +import com.philkes.notallyx.presentation.viewmodel.preference.SortDirection + +class BaseNoteNextNotificationSort( + adapter: RecyclerView.Adapter<*>?, + sortDirection: SortDirection, +) : ItemSort(adapter, sortDirection) { + + override fun compare(note1: BaseNote, note2: BaseNote, sortDirection: SortDirection): Int { + val sort = note1.compareNextNotification(note2) + return if (sortDirection == SortDirection.ASC) sort else -1 * sort + } +} + +fun BaseNote.compareNextNotification(other: BaseNote): Int { + if (other.reminders.isEmpty() && reminders.isNotEmpty()) { + return 1 + } + if (other.reminders.isNotEmpty() && reminders.isEmpty()) { + return -1 + } + if (other.reminders.isEmpty() && reminders.isEmpty()) { + return 0 + } + val nextNotification = reminders.findNextNotificationDate() + val otherNextNotification = other.reminders.findNextNotificationDate() + if (nextNotification == null && otherNextNotification != null) { + return -1 + } + if (nextNotification != null && otherNextNotification == null) { + return 1 + } + if (nextNotification == null && otherNextNotification == null) { + return 0 + } + return nextNotification!!.compareTo(otherNextNotification!!) +} diff --git a/app/src/main/res/layout/fragment_notes.xml b/app/src/main/res/layout/fragment_notes.xml index a0928108..b1c89386 100644 --- a/app/src/main/res/layout/fragment_notes.xml +++ b/app/src/main/res/layout/fragment_notes.xml @@ -78,12 +78,12 @@ > + android:text="@string/upcoming" /> + android:text="@string/all" />