conventionschedule-android/app/src/main/java/com/adlerosn/brasilfurfest/schedule/SearchFilterActivity.kt

177 lines
7.4 KiB
Kotlin

package com.adlerosn.brasilfurfest.schedule
import android.os.Bundle
import androidx.annotation.StringRes
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity
import androidx.recyclerview.widget.LinearLayoutManager
import android.text.Editable
import android.text.TextWatcher
import com.adlerosn.brasilfurfest.R
import com.adlerosn.brasilfurfest.helper.*
import com.adlerosn.brasilfurfest.helper.observables.Observer
import com.adlerosn.brasilfurfest.schedule.managers.ScheduleManagerGetter
import com.adlerosn.brasilfurfest.schedule.abstractDataTypes.convention.FilterableNamedColoredAttribute
import com.adlerosn.brasilfurfest.schedule.abstractDataTypes.convention.Place
import com.adlerosn.brasilfurfest.schedule.abstractDataTypes.convention.Tag
import com.adlerosn.brasilfurfest.schedule.abstractDataTypes.dataholder.PeekableEvent
import com.adlerosn.brasilfurfest.schedule.adapters.FilterCriteriaRecyclerViewAdapter
import com.adlerosn.brasilfurfest.schedule.adapters.PeekableEventRecyclerViewAdapter
import com.adlerosn.brasilfurfest.schedule.adapters.TagTripleListAdapter
import kotlinx.android.synthetic.main.activity_search_filter.*
import org.jetbrains.anko.doAsync
import org.jetbrains.anko.uiThread
class SearchFilterActivity : AppCompatActivity() {
val tags = mutableListOf<Tag>()
val places = mutableListOf<Place>()
var query = ""
val scheduleManager = ScheduleManagerGetter[this]
lateinit var filteredEventsListAdapter: PeekableEventRecyclerViewAdapter
lateinit var filterTagsListAdapter: FilterCriteriaRecyclerViewAdapter<Tag>
lateinit var filterPlacesListAdapter: FilterCriteriaRecyclerViewAdapter<Place>
lateinit var everyPeekableEvent: List<PeekableEvent>
val observer = Observer { _, _: Any? ->
runOnUiThread {
updateView()
}
}
private val nullPair = Pair(null, nullFun)
override fun onCreate(savedInstanceState: Bundle?) {
ActivitiesForFragments[this.javaClass.simpleName] = this
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_search_filter)
resourcesAliased = this.resources
scheduleManager.addObserver(observer)
queryText.addTextChangedListener(object: TextWatcher{
override fun afterTextChanged(s: Editable?) {
query = s.toString()
updateView()
}
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {}
})
val rl = recyclerList!!
val fct = filterCriteriaTags!!
val fcp = filterCriteriaPlaces!!
filteredEventsListAdapter = PeekableEventRecyclerViewAdapter(mutableListOf(), scheduleManager, this) {updateView()}
filterTagsListAdapter = FilterCriteriaRecyclerViewAdapter( listOf() ) { callAddTags() }
filterPlacesListAdapter = FilterCriteriaRecyclerViewAdapter( listOf() ) { callAddPlaces() }
rl.adapter = filteredEventsListAdapter
rl.layoutManager = LinearLayoutManager(this@SearchFilterActivity)
everyPeekableEvent = (
scheduleManager.convention.events.map { PeekableEvent(it) } +
scheduleManager.attendeeFavorites.toList().filter { it.isCustom }.map { PeekableEvent(it) }
).sortedWith(compareBy(
{ it.timeRange.start.timeInMillis },
{ it.timeRange.finish.timeInMillis },
{ it.title.solved }
))
fct.adapter = filterTagsListAdapter
fct.layoutManager = LinearLayoutManager(this@SearchFilterActivity, LinearLayoutManager.HORIZONTAL, false)
fcp.adapter = filterPlacesListAdapter
fcp.layoutManager = LinearLayoutManager(this@SearchFilterActivity, LinearLayoutManager.HORIZONTAL, false)
updateView()
}
override fun onBackPressed() {
scheduleManager.deleteObserver(observer)
super.onBackPressed()
}
private fun <T: FilterableNamedColoredAttribute> callAddSomething(
wholeCollection: Collection<T>,
currentCollection: MutableCollection<T>,
@StringRes dialogTitleResource: Int
){
doAsync {
val placeChoices = wholeCollection.filterNot {
it in currentCollection
}.map {
Triple(it.names.solved!!, it.color, { currentCollection.add(it) })
}
uiThread {
val choicesAdapted = TagTripleListAdapter(placeChoices)
AlertDialog.Builder(this@SearchFilterActivity)
.setTitle(dialogTitleResource)
.setAdapter(choicesAdapted) { dialog, which: Int ->
placeChoices[which].third()
dialog.dismiss()
updateView()
}
.show()
}
}
}
fun callAddPlaces() = callAddSomething(
scheduleManager.convention.places,
places,
R.string.schedule_event_key_places
)
fun callAddTags() = callAddSomething(
scheduleManager.convention.tags,
tags,
R.string.schedule_event_key_categories
)
fun <T: FilterableNamedColoredAttribute> updateFilterItemView(
wholeCollection: Collection<T>,
currentCollection: MutableCollection<T>,
adapter: FilterCriteriaRecyclerViewAdapter<T>
){
doAsync {
val hasPlusButtons = currentCollection.size < wholeCollection.size
val plusButtons = if (hasPlusButtons) listOf(nullPair) else listOf()
val filterableChoices = currentCollection.map {
Pair(it) { currentCollection.remove(it); updateView() }
}.let {
when (it.size) {
0 -> plusButtons
1 -> plusButtons+it
else -> plusButtons+it+plusButtons
}
}
uiThread {
adapter.onDataChanged(filterableChoices)
}
}
}
fun updateView() {
updateFilterItemView(
scheduleManager.convention.tags,
tags,
filterTagsListAdapter
)
updateFilterItemView(
scheduleManager.convention.places,
places,
filterPlacesListAdapter
)
doAsync {
val toRemoveByName = if (query.isEmpty()) listOf() else
everyPeekableEvent.filter {
(query.toLowerCase() !in it.title.solved?.toLowerCase()?:"")
&&
(query.toLowerCase() !in it.subtitles?.solved?.toLowerCase()?:"")
&&
(query.toLowerCase() !in it.descriptions?.solved?.toLowerCase()?:"")
}
val toRemoveByTag = if(tags.isEmpty()) listOf() else
everyPeekableEvent.filter { event ->
!tags.any { event.tags?.contains(it) ?: false }
}
val toRemoveByPlace = if(places.isEmpty()) listOf() else
everyPeekableEvent.filter { event ->
!places.any { event.places?.contains(it) ?: false }
}
val toDisplay = everyPeekableEvent - (toRemoveByName+toRemoveByTag+toRemoveByPlace).toSet()
filteredEventsListAdapter.onDataChanged(toDisplay)
}
}
}