Skip to content

feat: add event types for search #1521

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 7, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 10 additions & 2 deletions app/src/main/java/org/fossasia/openevent/general/di/Modules.kt
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ import org.fossasia.openevent.general.event.EventsListAdapter
import org.fossasia.openevent.general.event.EventsViewModel
import org.fossasia.openevent.general.event.topic.EventTopic
import org.fossasia.openevent.general.event.topic.EventTopicApi
import org.fossasia.openevent.general.event.types.EventType
import org.fossasia.openevent.general.event.types.EventTypesApi
import org.fossasia.openevent.general.event.topic.SimilarEventsViewModel
import org.fossasia.openevent.general.favorite.FavoriteEventsRecyclerAdapter
import org.fossasia.openevent.general.favorite.FavoriteEventsViewModel
Expand All @@ -59,6 +61,7 @@ import org.fossasia.openevent.general.search.GeoLocationViewModel
import org.fossasia.openevent.general.search.SearchLocationViewModel
import org.fossasia.openevent.general.search.SearchViewModel
import org.fossasia.openevent.general.search.LocationService
import org.fossasia.openevent.general.search.SearchTypeViewModel
import org.fossasia.openevent.general.search.LocationServiceImpl
import org.fossasia.openevent.general.settings.SettingsViewModel
import org.fossasia.openevent.general.social.SocialLink
Expand Down Expand Up @@ -118,11 +121,15 @@ val apiModule = module {
val retrofit: Retrofit = get()
retrofit.create(PaypalApi::class.java)
}
single {
val retrofit: Retrofit = get()
retrofit.create(EventTypesApi::class.java)
}

factory { AuthHolder(get()) }
factory { AuthService(get(), get(), get()) }

factory { EventService(get(), get(), get(), get()) }
factory { EventService(get(), get(), get(), get(), get()) }
factory { TicketService(get(), get()) }
factory { SocialLinksService(get(), get()) }
factory { AttendeeService(get(), get(), get()) }
Expand All @@ -139,6 +146,7 @@ val viewModelModule = module {
viewModel { SearchViewModel(get(), get(), get(), get()) }
viewModel { AttendeeViewModel(get(), get(), get(), get(), get(), get(), get()) }
viewModel { SearchLocationViewModel(get()) }
viewModel { SearchTypeViewModel(get()) }
viewModel { TicketsViewModel(get(), get(), get(), get()) }
viewModel { AboutEventViewModel(get(), get()) }
viewModel { SocialLinksViewModel(get(), get()) }
Expand Down Expand Up @@ -188,7 +196,7 @@ val networkModule = module {
SignUp::class.java, Ticket::class.java, SocialLink::class.java, EventId::class.java,
EventTopic::class.java, Attendee::class.java, TicketId::class.java, Order::class.java,
AttendeeId::class.java, Charge::class.java, Paypal::class.java, ConfirmOrder::class.java,
CustomForm::class.java))
CustomForm::class.java, EventType::class.java))
.addConverterFactory(JacksonConverterFactory.create(objectMapper))
.baseUrl(baseUrl)
.build()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,17 @@ import io.reactivex.Single
import org.fossasia.openevent.general.event.topic.EventTopic
import org.fossasia.openevent.general.event.topic.EventTopicApi
import org.fossasia.openevent.general.event.topic.EventTopicsDao
import org.fossasia.openevent.general.event.types.EventType
import org.fossasia.openevent.general.event.types.EventTypesApi

import java.util.Locale.filter

class EventService(
private val eventApi: EventApi,
private val eventDao: EventDao,
private val eventTopicApi: EventTopicApi,
private val eventTopicsDao: EventTopicsDao
private val eventTopicsDao: EventTopicsDao,
private val eventTypesApi: EventTypesApi
) {

fun getEvents(): Flowable<List<Event>> {
Expand Down Expand Up @@ -44,6 +48,10 @@ class EventService(
return eventTopicsDao.getAllEventTopics()
}

fun getEventTypes(): Single<List<EventType>> {
return eventTypesApi.getEventTypes()
}

fun getSearchEvents(eventName: String): Single<List<Event>> {
return eventApi.searchEvents("name", eventName).flatMap { apiList ->
var eventIds = apiList.map { it.id }.toList()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package org.fossasia.openevent.general.event.types

import androidx.room.Entity
import androidx.room.PrimaryKey
import com.github.jasminb.jsonapi.LongIdHandler
import com.github.jasminb.jsonapi.annotations.Id
import com.github.jasminb.jsonapi.annotations.Type

@Type("event-type")
@Entity
data class EventType(
@Id(LongIdHandler::class)
@PrimaryKey
val id: Long?,
val name: String?,
val slug: String?
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package org.fossasia.openevent.general.event.types

import io.reactivex.Single
import retrofit2.http.GET

interface EventTypesApi {

@GET("event-types?sort=name")
fun getEventTypes(): Single<List<EventType>>
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import androidx.navigation.Navigation.findNavController
import kotlinx.android.synthetic.main.fragment_search.view.fabSearch
import kotlinx.android.synthetic.main.fragment_search.view.locationTextView
import kotlinx.android.synthetic.main.fragment_search.view.timeTextView
import kotlinx.android.synthetic.main.fragment_search.view.eventTypeTextView
import org.fossasia.openevent.general.R
import org.fossasia.openevent.general.utils.nullToEmpty
import org.koin.androidx.viewmodel.ext.android.viewModel
Expand Down Expand Up @@ -73,6 +74,8 @@ class SearchFragment : Fragment() {
rootView.timeTextView.text = time
}
}
val type = safeArgs?.stringSavedType
rootView.eventTypeTextView.text = if (type.isNullOrBlank()) getString(R.string.anything) else type

searchViewModel.loadSavedLocation()
rootView.locationTextView.text = searchViewModel.savedLocation
Expand All @@ -87,6 +90,16 @@ class SearchFragment : Fragment() {
}
}

rootView.eventTypeTextView.setOnClickListener {
SearchLocationFragmentArgs.Builder()
.setFromSearchFragment(true)
.build()
.toBundle()
.also { bundle ->
Navigation.findNavController(rootView).navigate(R.id.searchTypeFragment, bundle, getAnimSlide())
}
}

return rootView
}

Expand Down Expand Up @@ -117,6 +130,7 @@ class SearchFragment : Fragment() {
.setQuery(query)
.setLocation(rootView.locationTextView.text.toString().nullToEmpty())
.setDate((safeArgs?.stringSavedDate ?: getString(R.string.anytime)).nullToEmpty())
.setType((safeArgs?.stringSavedType ?: getString(R.string.anything)).nullToEmpty())
.build()
.toBundle()
.also { bundle ->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -195,9 +195,10 @@ class SearchResultsFragment : Fragment() {
private fun performSearch(args: SearchResultsFragmentArgs, eventDate: String = "") {
val query = args.query
val location = args.location
val type = args.type
val date = if (eventDate.isNotEmpty()) eventDate else args.date
searchViewModel.searchEvent = query
searchViewModel.loadEvents(location, date)
searchViewModel.loadEvents(location, date, type)
}

private fun showNoSearchResults(events: List<Event>) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package org.fossasia.openevent.general.search

import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ArrayAdapter
import androidx.fragment.app.Fragment
import androidx.lifecycle.Observer
import androidx.navigation.NavOptions
import androidx.navigation.Navigation
import androidx.navigation.fragment.navArgs
import kotlinx.android.synthetic.main.fragment_search_type.view.eventTypesLv
import org.fossasia.openevent.general.R
import org.fossasia.openevent.general.utils.Utils.setToolbar
import org.fossasia.openevent.general.utils.extensions.nonNull
import org.koin.androidx.viewmodel.ext.android.viewModel

class SearchTypeFragment : Fragment() {
private val searchTypeViewModel by viewModel<SearchTypeViewModel>()
private val safeArgs: SearchTypeFragmentArgs by navArgs()
private lateinit var rootView: View
private val eventTypesList: MutableList<String> = ArrayList()

override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
rootView = inflater.inflate(R.layout.fragment_search_type, container, false)
setToolbar(activity, "", hasUpEnabled = true)
setHasOptionsMenu(true)
searchTypeViewModel.loadEventTypes()
val adapter = ArrayAdapter(context, R.layout.event_type_list, eventTypesList)
rootView.eventTypesLv.adapter = adapter

searchTypeViewModel.eventLocations
.nonNull()
.observe(this, Observer { list ->
list.forEach {
eventTypesList.add(it.name ?: "")
}
adapter.notifyDataSetChanged()
})
rootView.eventTypesLv.setOnItemClickListener { parent, view, position, id ->
redirectToSearch(eventTypesList[position])
}
return rootView
}

private fun redirectToSearch(type: String) {
val args = SearchFragmentArgs.Builder().setStringSavedType(type).build().toBundle()
val navOptions = NavOptions.Builder().setPopUpTo(R.id.eventsFragment, false).build()
Navigation.findNavController(rootView).navigate(R.id.searchFragment, args, navOptions)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package org.fossasia.openevent.general.search

import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.CompositeDisposable
import io.reactivex.schedulers.Schedulers
import org.fossasia.openevent.general.event.EventService
import org.fossasia.openevent.general.event.types.EventType
import timber.log.Timber

class SearchTypeViewModel(
private val eventService: EventService
) : ViewModel() {

private val compositeDisposable = CompositeDisposable()
private val mutableEventLocations = MutableLiveData<List<EventType>>()
val eventLocations: LiveData<List<EventType>> = mutableEventLocations

fun loadEventTypes() {
compositeDisposable.add(eventService.getEventTypes()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe({
mutableEventLocations.value = it
}, {
Timber.e(it, "Error fetching events types")
})
)
}

override fun onCleared() {
super.onCleared()
compositeDisposable.clear()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ class SearchViewModel(
savedLocation = preference.getString(SAVED_LOCATION)
}

fun loadEvents(location: String, time: String) {
fun loadEvents(location: String, time: String, type: String) {
if (mutableEvents.value != null) {
mutableShowShimmerResults.value = false
mutableShowNoInternetError.value = false
Expand All @@ -68,6 +68,17 @@ class SearchViewModel(
| 'op':'ilike',
| 'val':'%$searchEvent%'
|}]""".trimMargin().replace("'", "'")
time == "Anytime" && type == "Anything" -> """[{
| 'and':[{
| 'name':'location-name',
| 'op':'ilike',
| 'val':'%$location%'
| }, {
| 'name':'name',
| 'op':'ilike',
| 'val':'%$searchEvent%'
| }]
|}]""".trimMargin().replace("'", "\"")
time == "Anytime" -> """[{
| 'and':[{
| 'name':'location-name',
Expand All @@ -77,6 +88,14 @@ class SearchViewModel(
| 'name':'name',
| 'op':'ilike',
| 'val':'%$searchEvent%'
| }, {
| 'name':'event-type',
| 'op':'has',
| 'val': {
| 'name':'name',
| 'op':'eq',
| 'val':'$type'
| }
| }]
|}]""".trimMargin().replace("'", "\"")
time == "Today" -> """[{
Expand All @@ -96,6 +115,14 @@ class SearchViewModel(
| 'name':'starts-at',
| 'op':'lt',
| 'val':'$savedNextDate%'
| }, {
| 'name':'event-type',
| 'op':'has',
| 'val': {
| 'name':'name',
| 'op':'eq',
| 'val':'$type'
| }
| }]
|}]""".trimMargin().replace("'", "\"")
time == "Tomorrow" -> """[{
Expand All @@ -115,6 +142,14 @@ class SearchViewModel(
| 'name':'starts-at',
| 'op':'lt',
| 'val':'$savedNextToNextDate%'
| }, {
| 'name':'event-type',
| 'op':'has',
| 'val': {
| 'name':'name',
| 'op':'eq',
| 'val':'$type'
| }
| }]
|}]""".trimMargin().replace("'", "\"")
time == "This weekend" -> """[{
Expand All @@ -134,6 +169,14 @@ class SearchViewModel(
| 'name':'starts-at',
| 'op':'lt',
| 'val':'$savedWeekendNextDate%'
| }, {
| 'name':'event-type',
| 'op':'has',
| 'val': {
| 'name':'name',
| 'op':'eq',
| 'val':'$type'
| }
| }]
|}]""".trimMargin().replace("'", "\"")
time == "In the next month" -> """[{
Expand All @@ -153,6 +196,14 @@ class SearchViewModel(
| 'name':'starts-at',
| 'op':'lt',
| 'val':'$savedNextToNextMonth%'
| }, {
| 'name':'event-type',
| 'op':'has',
| 'val': {
| 'name':'name',
| 'op':'eq',
| 'val':'$type'
| }
| }]
|}]""".trimMargin().replace("'", "\"")
else -> """[{
Expand All @@ -172,6 +223,14 @@ class SearchViewModel(
| 'name':'starts-at',
| 'op':'lt',
| 'val':'$savedNextDate%'
| }, {
| 'name':'event-type',
| 'op':'has',
| 'val': {
| 'name':'name',
| 'op':'eq',
| 'val':'$type'
| }
| }]
|}]""".trimMargin().replace("'", "\"")
}
Expand Down
15 changes: 15 additions & 0 deletions app/src/main/res/layout/event_type_list.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<CheckedTextView
android:id="@+id/text1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingStart="@dimen/layout_margin_large"
android:paddingTop="@dimen/layout_margin_large"
android:paddingBottom="@dimen/layout_margin_large"
android:gravity="center_vertical"
android:text="@string/anytime"
android:background="?attr/selectableItemBackground"
android:textColor="@color/black"
android:textSize="@dimen/text_size_expanded_title"
android:paddingLeft="@dimen/layout_margin_large"
xmlns:android="http://schemas.android.com/apk/res/android" />
Loading