mirror of
https://github.com/SimpleMobileTools/Simple-Calendar.git
synced 2025-02-17 04:10:45 +01:00
adding endless scrolling to the search results
This commit is contained in:
parent
80234487da
commit
a81bf470c0
@ -34,6 +34,7 @@ import com.simplemobiletools.calendar.pro.helpers.IcsImporter.ImportResult
|
|||||||
import com.simplemobiletools.calendar.pro.jobs.CalDAVUpdateListener
|
import com.simplemobiletools.calendar.pro.jobs.CalDAVUpdateListener
|
||||||
import com.simplemobiletools.calendar.pro.models.Event
|
import com.simplemobiletools.calendar.pro.models.Event
|
||||||
import com.simplemobiletools.calendar.pro.models.ListEvent
|
import com.simplemobiletools.calendar.pro.models.ListEvent
|
||||||
|
import com.simplemobiletools.calendar.pro.models.ListItem
|
||||||
import com.simplemobiletools.commons.dialogs.ConfirmationDialog
|
import com.simplemobiletools.commons.dialogs.ConfirmationDialog
|
||||||
import com.simplemobiletools.commons.dialogs.FilePickerDialog
|
import com.simplemobiletools.commons.dialogs.FilePickerDialog
|
||||||
import com.simplemobiletools.commons.dialogs.RadioGroupDialog
|
import com.simplemobiletools.commons.dialogs.RadioGroupDialog
|
||||||
@ -44,6 +45,8 @@ import com.simplemobiletools.commons.models.FAQItem
|
|||||||
import com.simplemobiletools.commons.models.RadioItem
|
import com.simplemobiletools.commons.models.RadioItem
|
||||||
import com.simplemobiletools.commons.models.Release
|
import com.simplemobiletools.commons.models.Release
|
||||||
import com.simplemobiletools.commons.models.SimpleContact
|
import com.simplemobiletools.commons.models.SimpleContact
|
||||||
|
import com.simplemobiletools.commons.views.MyLinearLayoutManager
|
||||||
|
import com.simplemobiletools.commons.views.MyRecyclerView
|
||||||
import kotlinx.android.synthetic.main.activity_main.*
|
import kotlinx.android.synthetic.main.activity_main.*
|
||||||
import org.joda.time.DateTime
|
import org.joda.time.DateTime
|
||||||
import org.joda.time.DateTimeZone
|
import org.joda.time.DateTimeZone
|
||||||
@ -77,6 +80,12 @@ class MainActivity : SimpleActivity(), RefreshRecyclerViewListener {
|
|||||||
private var mStoredStartWeekWithCurrentDay = false
|
private var mStoredStartWeekWithCurrentDay = false
|
||||||
private var mStoredHighlightWeekendsColor = 0
|
private var mStoredHighlightWeekendsColor = 0
|
||||||
|
|
||||||
|
// search results have endless scrolling, so reaching the top/bottom fetches further results
|
||||||
|
private var minFetchedSearchTS = 0L
|
||||||
|
private var maxFetchedSearchTS = 0L
|
||||||
|
private var searchResultEvents = ArrayList<Event>()
|
||||||
|
private var bottomItemAtRefresh: ListItem? = null
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
setContentView(R.layout.activity_main)
|
setContentView(R.layout.activity_main)
|
||||||
@ -328,6 +337,10 @@ class MainActivity : SimpleActivity(), RefreshRecyclerViewListener {
|
|||||||
|
|
||||||
private fun closeSearch() {
|
private fun closeSearch() {
|
||||||
main_menu.closeSearch()
|
main_menu.closeSearch()
|
||||||
|
minFetchedSearchTS = 0L
|
||||||
|
maxFetchedSearchTS = 0L
|
||||||
|
searchResultEvents.clear()
|
||||||
|
bottomItemAtRefresh = null
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun checkCalDAVUpdateListener() {
|
private fun checkCalDAVUpdateListener() {
|
||||||
@ -1180,35 +1193,19 @@ class MainActivity : SimpleActivity(), RefreshRecyclerViewListener {
|
|||||||
search_holder.fadeIn()
|
search_holder.fadeIn()
|
||||||
} else if (text.isEmpty()) {
|
} else if (text.isEmpty()) {
|
||||||
search_holder.fadeOut()
|
search_holder.fadeOut()
|
||||||
|
search_results_list.adapter = null
|
||||||
}
|
}
|
||||||
|
|
||||||
search_placeholder_2.beVisibleIf(text.length == 1)
|
search_placeholder_2.beVisibleIf(text.length == 1)
|
||||||
if (text.length >= 2) {
|
if (text.length >= 2) {
|
||||||
val minFetchedTS = DateTime().minusMinutes(config.displayPastEvents).seconds()
|
if (search_results_list.adapter == null) {
|
||||||
val maxFetchedTS = DateTime().plusMonths(6).seconds()
|
minFetchedSearchTS = DateTime().minusMinutes(config.displayPastEvents).seconds()
|
||||||
|
maxFetchedSearchTS = DateTime().plusMonths(6).seconds()
|
||||||
|
}
|
||||||
|
|
||||||
eventsHelper.getEvents(minFetchedTS, maxFetchedTS) { events ->
|
eventsHelper.getEvents(minFetchedSearchTS, maxFetchedSearchTS) { events ->
|
||||||
if (text == mLatestSearchQuery) {
|
if (text == mLatestSearchQuery) {
|
||||||
runOnUiThread {
|
showSearchResultEvents(events, INITIAL_EVENTS)
|
||||||
val filtered = events.filter {
|
|
||||||
it.title.contains(text, true) || it.location.contains(text, true) || it.description.contains(text, true)
|
|
||||||
}
|
|
||||||
|
|
||||||
search_results_list.beVisibleIf(filtered.isNotEmpty())
|
|
||||||
search_placeholder.beVisibleIf(filtered.isEmpty())
|
|
||||||
val listItems = getEventListItems(filtered)
|
|
||||||
val eventsAdapter = EventListAdapter(this, listItems, true, this, search_results_list) {
|
|
||||||
hideKeyboard()
|
|
||||||
if (it is ListEvent) {
|
|
||||||
Intent(applicationContext, getActivityToOpen(it.isTask)).apply {
|
|
||||||
putExtra(EVENT_ID, it.id)
|
|
||||||
startActivity(this)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
search_results_list.adapter = eventsAdapter
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (text.length == 1) {
|
} else if (text.length == 1) {
|
||||||
@ -1217,6 +1214,85 @@ class MainActivity : SimpleActivity(), RefreshRecyclerViewListener {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun showSearchResultEvents(events: ArrayList<Event>, updateStatus: Int) {
|
||||||
|
val currentSearchQuery = main_menu.getCurrentQuery()
|
||||||
|
val filtered = events.filter {
|
||||||
|
it.title.contains(currentSearchQuery, true) || it.location.contains(currentSearchQuery, true) || it.description.contains(currentSearchQuery, true)
|
||||||
|
}
|
||||||
|
|
||||||
|
searchResultEvents = filtered.toMutableList() as ArrayList<Event>
|
||||||
|
runOnUiThread {
|
||||||
|
search_results_list.beVisibleIf(filtered.isNotEmpty())
|
||||||
|
search_placeholder.beVisibleIf(filtered.isEmpty())
|
||||||
|
val listItems = getEventListItems(filtered)
|
||||||
|
val currAdapter = search_results_list.adapter
|
||||||
|
if (currAdapter == null) {
|
||||||
|
val eventsAdapter = EventListAdapter(this, listItems, true, this, search_results_list) {
|
||||||
|
hideKeyboard()
|
||||||
|
if (it is ListEvent) {
|
||||||
|
Intent(applicationContext, getActivityToOpen(it.isTask)).apply {
|
||||||
|
putExtra(EVENT_ID, it.id)
|
||||||
|
startActivity(this)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
search_results_list.adapter = eventsAdapter
|
||||||
|
|
||||||
|
search_results_list.endlessScrollListener = object : MyRecyclerView.EndlessScrollListener {
|
||||||
|
override fun updateTop() {
|
||||||
|
fetchPreviousPeriod()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun updateBottom() {
|
||||||
|
fetchNextPeriod()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
(currAdapter as EventListAdapter).updateListItems(listItems)
|
||||||
|
if (updateStatus == UPDATE_TOP) {
|
||||||
|
val item = listItems.indexOfFirst { it == bottomItemAtRefresh }
|
||||||
|
if (item != -1) {
|
||||||
|
search_results_list.scrollToPosition(item)
|
||||||
|
}
|
||||||
|
} else if (updateStatus == UPDATE_BOTTOM) {
|
||||||
|
search_results_list.smoothScrollBy(0, resources.getDimension(R.dimen.endless_scroll_move_height).toInt())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun fetchPreviousPeriod() {
|
||||||
|
val lastPosition = (search_results_list.layoutManager as MyLinearLayoutManager).findLastVisibleItemPosition()
|
||||||
|
bottomItemAtRefresh = (search_results_list.adapter as EventListAdapter).listItems[lastPosition]
|
||||||
|
|
||||||
|
val oldMinFetchedTS = minFetchedSearchTS - 1
|
||||||
|
minFetchedSearchTS -= FETCH_INTERVAL
|
||||||
|
eventsHelper.getEvents(minFetchedSearchTS, oldMinFetchedTS) { events ->
|
||||||
|
events.forEach { event ->
|
||||||
|
if (searchResultEvents.firstOrNull { it.id == event.id && it.startTS == event.startTS } == null) {
|
||||||
|
searchResultEvents.add(0, event)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
showSearchResultEvents(searchResultEvents, UPDATE_TOP)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun fetchNextPeriod() {
|
||||||
|
val oldMaxFetchedTS = maxFetchedSearchTS + 1
|
||||||
|
maxFetchedSearchTS += FETCH_INTERVAL
|
||||||
|
eventsHelper.getEvents(oldMaxFetchedTS, maxFetchedSearchTS) { events ->
|
||||||
|
events.forEach { event ->
|
||||||
|
if (searchResultEvents.firstOrNull { it.id == event.id && it.startTS == event.startTS } == null) {
|
||||||
|
searchResultEvents.add(0, event)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
showSearchResultEvents(searchResultEvents, UPDATE_BOTTOM)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun checkSwipeRefreshAvailability() {
|
private fun checkSwipeRefreshAvailability() {
|
||||||
swipe_refresh_layout.isEnabled = config.caldavSync && config.pullToRefresh && config.storedView != WEEKLY_VIEW
|
swipe_refresh_layout.isEnabled = config.caldavSync && config.pullToRefresh && config.storedView != WEEKLY_VIEW
|
||||||
if (!swipe_refresh_layout.isEnabled) {
|
if (!swipe_refresh_layout.isEnabled) {
|
||||||
|
@ -13,14 +13,12 @@ import com.simplemobiletools.calendar.pro.activities.MainActivity
|
|||||||
import com.simplemobiletools.calendar.pro.activities.SimpleActivity
|
import com.simplemobiletools.calendar.pro.activities.SimpleActivity
|
||||||
import com.simplemobiletools.calendar.pro.adapters.EventListAdapter
|
import com.simplemobiletools.calendar.pro.adapters.EventListAdapter
|
||||||
import com.simplemobiletools.calendar.pro.extensions.*
|
import com.simplemobiletools.calendar.pro.extensions.*
|
||||||
import com.simplemobiletools.calendar.pro.helpers.EVENTS_LIST_VIEW
|
import com.simplemobiletools.calendar.pro.helpers.*
|
||||||
import com.simplemobiletools.calendar.pro.helpers.Formatter
|
|
||||||
import com.simplemobiletools.calendar.pro.models.Event
|
import com.simplemobiletools.calendar.pro.models.Event
|
||||||
import com.simplemobiletools.calendar.pro.models.ListEvent
|
import com.simplemobiletools.calendar.pro.models.ListEvent
|
||||||
import com.simplemobiletools.calendar.pro.models.ListItem
|
import com.simplemobiletools.calendar.pro.models.ListItem
|
||||||
import com.simplemobiletools.calendar.pro.models.ListSectionDay
|
import com.simplemobiletools.calendar.pro.models.ListSectionDay
|
||||||
import com.simplemobiletools.commons.extensions.*
|
import com.simplemobiletools.commons.extensions.*
|
||||||
import com.simplemobiletools.commons.helpers.MONTH_SECONDS
|
|
||||||
import com.simplemobiletools.commons.interfaces.RefreshRecyclerViewListener
|
import com.simplemobiletools.commons.interfaces.RefreshRecyclerViewListener
|
||||||
import com.simplemobiletools.commons.views.MyLinearLayoutManager
|
import com.simplemobiletools.commons.views.MyLinearLayoutManager
|
||||||
import com.simplemobiletools.commons.views.MyRecyclerView
|
import com.simplemobiletools.commons.views.MyRecyclerView
|
||||||
@ -28,11 +26,6 @@ import kotlinx.android.synthetic.main.fragment_event_list.view.*
|
|||||||
import org.joda.time.DateTime
|
import org.joda.time.DateTime
|
||||||
|
|
||||||
class EventListFragment : MyFragmentHolder(), RefreshRecyclerViewListener {
|
class EventListFragment : MyFragmentHolder(), RefreshRecyclerViewListener {
|
||||||
private val NOT_UPDATING = 0
|
|
||||||
private val UPDATE_TOP = 1
|
|
||||||
private val UPDATE_BOTTOM = 2
|
|
||||||
|
|
||||||
private var FETCH_INTERVAL = 3 * MONTH_SECONDS
|
|
||||||
private var MIN_EVENTS_TRESHOLD = 30
|
private var MIN_EVENTS_TRESHOLD = 30
|
||||||
|
|
||||||
private var mEvents = ArrayList<Event>()
|
private var mEvents = ArrayList<Event>()
|
||||||
@ -88,7 +81,7 @@ class EventListFragment : MyFragmentHolder(), RefreshRecyclerViewListener {
|
|||||||
|
|
||||||
requireContext().eventsHelper.getEvents(minFetchedTS, maxFetchedTS) { events ->
|
requireContext().eventsHelper.getEvents(minFetchedTS, maxFetchedTS) { events ->
|
||||||
if (events.size >= MIN_EVENTS_TRESHOLD) {
|
if (events.size >= MIN_EVENTS_TRESHOLD) {
|
||||||
receivedEvents(events, NOT_UPDATING)
|
receivedEvents(events, INITIAL_EVENTS)
|
||||||
} else {
|
} else {
|
||||||
if (!wereInitialEventsAdded) {
|
if (!wereInitialEventsAdded) {
|
||||||
maxFetchedTS += FETCH_INTERVAL
|
maxFetchedTS += FETCH_INTERVAL
|
||||||
@ -96,7 +89,7 @@ class EventListFragment : MyFragmentHolder(), RefreshRecyclerViewListener {
|
|||||||
|
|
||||||
requireContext().eventsHelper.getEvents(minFetchedTS, maxFetchedTS) {
|
requireContext().eventsHelper.getEvents(minFetchedTS, maxFetchedTS) {
|
||||||
mEvents = it
|
mEvents = it
|
||||||
receivedEvents(mEvents, NOT_UPDATING, !wereInitialEventsAdded)
|
receivedEvents(mEvents, INITIAL_EVENTS, !wereInitialEventsAdded)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
wereInitialEventsAdded = true
|
wereInitialEventsAdded = true
|
||||||
|
@ -2,11 +2,18 @@ package com.simplemobiletools.calendar.pro.helpers
|
|||||||
|
|
||||||
import com.simplemobiletools.calendar.pro.activities.EventActivity
|
import com.simplemobiletools.calendar.pro.activities.EventActivity
|
||||||
import com.simplemobiletools.calendar.pro.activities.TaskActivity
|
import com.simplemobiletools.calendar.pro.activities.TaskActivity
|
||||||
|
import com.simplemobiletools.commons.helpers.MONTH_SECONDS
|
||||||
|
|
||||||
const val STORED_LOCALLY_ONLY = 0
|
const val STORED_LOCALLY_ONLY = 0
|
||||||
const val ROW_COUNT = 6
|
const val ROW_COUNT = 6
|
||||||
const val COLUMN_COUNT = 7
|
const val COLUMN_COUNT = 7
|
||||||
const val SCHEDULE_CALDAV_REQUEST_CODE = 10000
|
const val SCHEDULE_CALDAV_REQUEST_CODE = 10000
|
||||||
|
const val FETCH_INTERVAL = 1 * MONTH_SECONDS
|
||||||
|
|
||||||
|
// endless scrolling updating
|
||||||
|
const val INITIAL_EVENTS = 0
|
||||||
|
const val UPDATE_TOP = 1
|
||||||
|
const val UPDATE_BOTTOM = 2
|
||||||
|
|
||||||
const val DAY_CODE = "day_code"
|
const val DAY_CODE = "day_code"
|
||||||
const val YEAR_LABEL = "year"
|
const val YEAR_LABEL = "year"
|
||||||
|
@ -159,6 +159,7 @@
|
|||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:clipToPadding="false"
|
android:clipToPadding="false"
|
||||||
|
android:overScrollMode="never"
|
||||||
android:scrollbars="vertical"
|
android:scrollbars="vertical"
|
||||||
app:layoutManager="com.simplemobiletools.commons.views.MyLinearLayoutManager" />
|
app:layoutManager="com.simplemobiletools.commons.views.MyLinearLayoutManager" />
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user