Skip to content

feat: add Event Types Chips #1565

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 2 commits into from
Apr 11, 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
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import com.github.jasminb.jsonapi.annotations.Type
data class EventType(
@Id(LongIdHandler::class)
@PrimaryKey
val id: Long?,
val name: String?,
val slug: String?
val id: Long,
val name: String,
val slug: String
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why? These values will never be null?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes JSON-API id's can never be null and neither can name or slug

)
Original file line number Diff line number Diff line change
@@ -1,97 +1,81 @@
package org.fossasia.openevent.general.search

import android.content.res.ColorStateList
import android.os.Bundle
import android.view.LayoutInflater
import android.view.MenuItem
import android.view.View
import android.view.ViewGroup
import android.widget.CompoundButton
import androidx.core.content.ContextCompat
import androidx.core.view.children
import android.content.res.ColorStateList
import androidx.core.view.isVisible
import androidx.fragment.app.Fragment
import androidx.lifecycle.Observer
import androidx.navigation.Navigation
import androidx.navigation.fragment.navArgs
import androidx.recyclerview.widget.LinearLayoutManager
import com.google.android.material.chip.Chip
import kotlinx.android.synthetic.main.fragment_search_results.view.searchRootLayout
import kotlinx.android.synthetic.main.fragment_search_results.view.eventsRecycler
import kotlinx.android.synthetic.main.fragment_search_results.view.shimmerSearch
import kotlinx.android.synthetic.main.content_no_internet.view.retry
import kotlinx.android.synthetic.main.content_no_internet.view.noInternetCard
import kotlinx.android.synthetic.main.fragment_search_results.view.noSearchResults
import kotlinx.android.synthetic.main.content_no_internet.view.retry
import kotlinx.android.synthetic.main.fragment_search_results.view.chipGroup
import kotlinx.android.synthetic.main.fragment_search_results.view.todayChip
import kotlinx.android.synthetic.main.fragment_search_results.view.tomorrowChip
import kotlinx.android.synthetic.main.fragment_search_results.view.weekendChip
import kotlinx.android.synthetic.main.fragment_search_results.view.monthChip
import kotlinx.android.synthetic.main.fragment_search_results.view.chipGroupLayout
import kotlinx.android.synthetic.main.fragment_search_results.view.eventsRecycler
import kotlinx.android.synthetic.main.fragment_search_results.view.noSearchResults
import kotlinx.android.synthetic.main.fragment_search_results.view.searchRootLayout
import kotlinx.android.synthetic.main.fragment_search_results.view.shimmerSearch
import org.fossasia.openevent.general.R
import org.fossasia.openevent.general.common.EventClickListener
import org.fossasia.openevent.general.common.FavoriteFabClickListener
import org.fossasia.openevent.general.di.Scopes
import org.fossasia.openevent.general.event.Event
import org.fossasia.openevent.general.common.EventClickListener
import org.fossasia.openevent.general.event.EventDetailsFragmentArgs
import org.fossasia.openevent.general.common.FavoriteFabClickListener
import org.fossasia.openevent.general.event.types.EventType
import org.fossasia.openevent.general.favorite.FavoriteEventsRecyclerAdapter
import org.fossasia.openevent.general.utils.Utils.getAnimFade
import org.fossasia.openevent.general.utils.Utils.setToolbar
import org.fossasia.openevent.general.utils.extensions.nonNull
import org.jetbrains.anko.design.longSnackbar
import org.koin.android.ext.android.inject
import org.koin.androidx.scope.ext.android.bindScope
import org.koin.androidx.scope.ext.android.getOrCreateScope
import org.koin.androidx.viewmodel.ext.android.viewModel
import timber.log.Timber
import org.fossasia.openevent.general.utils.Utils.setToolbar
import org.jetbrains.anko.design.longSnackbar
import androidx.appcompat.view.ContextThemeWrapper

class SearchResultsFragment : Fragment(), CompoundButton.OnCheckedChangeListener {

class SearchResultsFragment : Fragment() {
private lateinit var rootView: View
private val searchViewModel by viewModel<SearchViewModel>()
private val safeArgs: SearchResultsFragmentArgs by navArgs()
private val favoriteEventsRecyclerAdapter: FavoriteEventsRecyclerAdapter by inject(
scope = getOrCreateScope(Scopes.SEARCH_RESULTS_FRAGMENT.toString())
)

private lateinit var days: Array<String>
private lateinit var eventDate: String
private lateinit var eventType: String
private var eventTypesList: List<EventType>? = arrayListOf()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
bindScope(getOrCreateScope(Scopes.SEARCH_RESULTS_FRAGMENT.toString()))

days = resources.getStringArray(R.array.days)
eventDate = safeArgs.date
eventType = safeArgs.type

performSearch(safeArgs)
searchViewModel.loadEventTypes()
searchViewModel.eventTypes
.nonNull()
.observe(this, Observer { list ->
eventTypesList = list
})
}

override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
rootView = inflater.inflate(R.layout.fragment_search_results, container, false)

val selectedChip = when (safeArgs.date) {
getString(R.string.today) -> rootView.todayChip
getString(R.string.tomorrow) -> rootView.tomorrowChip
getString(R.string.weekend) -> rootView.weekendChip
getString(R.string.month) -> rootView.monthChip
else -> null
}
selectedChip?.apply {
isChecked = true
chipBackgroundColor = ColorStateList.valueOf(ContextCompat.getColor(requireContext(), R.color.colorPrimary))
}

rootView.chipGroup.setOnCheckedChangeListener { chipGroup, id ->

chipGroup.children.forEach { chip ->
if (chip is Chip) {
if (chip.id != chipGroup.checkedChipId) {
chip.chipBackgroundColor =
ColorStateList.valueOf(ContextCompat.getColor(requireContext(), R.color.grey))
chip.isClickable = true
} else {
chip.isClickable = false
chip.chipBackgroundColor =
ColorStateList.valueOf(ContextCompat.getColor(requireContext(), R.color.colorPrimary))
rootView.noSearchResults.isVisible = false
favoriteEventsRecyclerAdapter.submitList(null)
performSearch(safeArgs, chip.text.toString())
}
}
}
}
setChips(safeArgs.date, safeArgs.type)
setToolbar(activity, getString(R.string.search_results))
setHasOptionsMenu(true)

Expand Down Expand Up @@ -149,19 +133,68 @@ class SearchResultsFragment : Fragment() {
return rootView
}

private fun setChips(date: String = eventDate, type: String = eventType) {
if (rootView.chipGroup.childCount>0) {
rootView.chipGroup.removeAllViews()
}
when {
date != getString(R.string.anytime) && type != getString(R.string.anything) -> {
addchips(date, true)
addchips(type, true)
addchips("Clear All", false)
}
date != getString(R.string.anytime) && type == getString(R.string.anything) -> {
addchips(date, true)
searchViewModel.eventTypes
.nonNull()
.observe(this, Observer { list ->
list.forEach {
addchips(it.name, false)
}
})
}
date == getString(R.string.anytime) && type != getString(R.string.anything) -> {
addchips(type, true)
days.forEach {
addchips(it, false)
}
}
else -> {
days.forEach {
addchips(it, false)
}
}
}
}

private fun addchips(name: String, checked: Boolean) {
val newContext = ContextThemeWrapper(context, R.style.CustomChipChoice)
val chip = Chip(newContext)
chip.text = name
chip.isCheckable = true
chip.isChecked = checked
chip.isClickable = true
if (checked) {
chip.chipBackgroundColor =
ColorStateList.valueOf(ContextCompat.getColor(requireContext(), R.color.colorPrimary))
}
chip.setOnCheckedChangeListener(this)
rootView.chipGroup.addView(chip)
}

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val eventClickListener: EventClickListener = object : EventClickListener {
override fun onClick(eventID: Long) { EventDetailsFragmentArgs.Builder()
.setEventId(eventID)
.build()
.toBundle()
.also { bundle ->
Navigation.findNavController(view).navigate(R.id.eventDetailsFragment, bundle, getAnimFade())
}
override fun onClick(eventID: Long) {
EventDetailsFragmentArgs.Builder()
.setEventId(eventID)
.build()
.toBundle()
.also { bundle ->
Navigation.findNavController(view).navigate(R.id.eventDetailsFragment, bundle, getAnimFade())
}
}
}

val favFabClickListener: FavoriteFabClickListener = object : FavoriteFabClickListener {
override fun onClick(event: Event, itemPosition: Int) {
searchViewModel.setFavorite(event.id, !event.favorite)
Expand All @@ -176,11 +209,11 @@ class SearchResultsFragment : Fragment() {
}
}

private fun performSearch(args: SearchResultsFragmentArgs, eventDate: String = "") {
private fun performSearch(args: SearchResultsFragmentArgs) {
val query = args.query
val location = args.location
val type = args.type
val date = if (eventDate.isNotEmpty()) eventDate else args.date
val type = eventType
val date = eventDate
searchViewModel.searchEvent = query
searchViewModel.loadEvents(location, date, type)
}
Expand All @@ -203,4 +236,36 @@ class SearchResultsFragment : Fragment() {
else -> super.onOptionsItemSelected(item)
}
}
override fun onCheckedChanged(buttonView: CompoundButton?, isChecked: Boolean) {
if (isChecked) {
if (buttonView?.text == "Clear All") {
eventDate = getString(R.string.anytime)
eventType = getString(R.string.anything)
rootView.noSearchResults.isVisible = false
favoriteEventsRecyclerAdapter.submitList(null)
performSearch(safeArgs)
setChips()
}
days.forEach {
if (it == buttonView?.text) {
eventDate = it
setChips(date = it)
rootView.noSearchResults.isVisible = false
favoriteEventsRecyclerAdapter.submitList(null)
performSearch(safeArgs)
return@forEach
}
}
eventTypesList?.forEach {
if (it.name == buttonView?.text) {
eventType = it.name
setChips(type = it.name)
rootView.noSearchResults.isVisible = false
favoriteEventsRecyclerAdapter.submitList(null)
performSearch(safeArgs)
return@forEach
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ 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
Expand All @@ -19,9 +18,8 @@ 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()
private val eventTypesList: MutableList<String> = arrayListOf("Anything")

override fun onCreateView(
inflater: LayoutInflater,
Expand All @@ -40,7 +38,7 @@ class SearchTypeFragment : Fragment() {
.nonNull()
.observe(this, Observer { list ->
list.forEach {
eventTypesList.add(it.name ?: "")
eventTypesList.add(it.name)
}
adapter.notifyDataSetChanged()
})
Expand Down
36 changes: 3 additions & 33 deletions app/src/main/res/layout/fragment_search_results.xml
Original file line number Diff line number Diff line change
Expand Up @@ -48,39 +48,9 @@
android:layout_height="wrap_content">

<com.google.android.material.chip.ChipGroup
android:layout_width="wrap_content"
android:id="@+id/chipGroup"
app:singleSelection="true"
android:layout_height="wrap_content">

<com.google.android.material.chip.Chip
style="@style/CustomChipChoice"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/todayChip"
android:text="@string/today" />

<com.google.android.material.chip.Chip
style="@style/CustomChipChoice"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/tomorrowChip"
android:text="@string/tomorrow" />

<com.google.android.material.chip.Chip
style="@style/CustomChipChoice"
android:layout_width="wrap_content"
android:id="@+id/weekendChip"
android:layout_height="wrap_content"
android:text="@string/weekend" />

<com.google.android.material.chip.Chip
style="@style/CustomChipChoice"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/monthChip"
android:text="@string/month" />
</com.google.android.material.chip.ChipGroup>
android:layout_width="wrap_content"
android:id="@+id/chipGroup"
android:layout_height="wrap_content" />
</HorizontalScrollView>

<com.facebook.shimmer.ShimmerFrameLayout
Expand Down
9 changes: 9 additions & 0 deletions app/src/main/res/values/arrays.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<array name="days">
<item>@string/today</item>
<item>@string/tomorrow</item>
<item>@string/weekend</item>
<item>@string/month</item>
</array>
</resources>
4 changes: 3 additions & 1 deletion app/src/main/res/values/styles.xml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
<item name="colorSecondary">@color/colorSecondary</item>
<item name="colorSecondaryVariant">@color/colorSecondaryVariant</item>
<item name="materialButtonStyle">@style/AppTheme.MaterialButton</item>
<item name="chipStyle">@style/CustomChipChoice</item>
</style>

<style name="AppTheme.NoActionBar">
Expand All @@ -35,8 +36,9 @@
<item name="android:enabled">false</item>
</style>

<style name="CustomChipChoice" parent="@style/Widget.MaterialComponents.Chip.Choice">
<style name="CustomChipChoice" parent="@style/Widget.MaterialComponents.Chip.Filter">
<item name="chipBackgroundColor">@color/grey</item>
<item name="checkedIcon">@drawable/ic_baseline_tick</item>
<item name="android:textColor">@color/text_color_chip_state_list</item>
</style>

Expand Down