Skip to content

feat: Improve Search Section #1950

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
Jun 18, 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 @@ -63,7 +63,7 @@ class MainActivity : AppCompatActivity() {
val hostFragment = supportFragmentManager.findFragmentById(R.id.frameContainer)
if (hostFragment is NavHostFragment) {
val currentFragment = hostFragment.childFragmentManager.fragments.first()
if (currentFragment is ScrollToTop) currentFragment.scrollToTop()
if (currentFragment is BottomIconDoubleClick) currentFragment.doubleClick()
}
}
}
Expand Down Expand Up @@ -122,8 +122,8 @@ class MainActivity : AppCompatActivity() {
}
}

interface ScrollToTop {
fun scrollToTop()
interface BottomIconDoubleClick {
fun doubleClick()
}

interface ComplexBackPressFragment {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import kotlinx.android.synthetic.main.fragment_events.view.scrollView
import kotlinx.android.synthetic.main.fragment_events.view.notification
import kotlinx.android.synthetic.main.fragment_events.view.swiperefresh
import org.fossasia.openevent.general.R
import org.fossasia.openevent.general.ScrollToTop
import org.fossasia.openevent.general.BottomIconDoubleClick
import org.fossasia.openevent.general.common.EventClickListener
import org.fossasia.openevent.general.common.FavoriteFabClickListener
import org.fossasia.openevent.general.data.Preference
Expand All @@ -39,7 +39,7 @@ import org.jetbrains.anko.design.longSnackbar

const val BEEN_TO_WELCOME_SCREEN = "beenToWelcomeScreen"

class EventsFragment : Fragment(), ScrollToTop {
class EventsFragment : Fragment(), BottomIconDoubleClick {
private val eventsViewModel by viewModel<EventsViewModel>()
private lateinit var rootView: View
private val preference = Preference()
Expand Down Expand Up @@ -226,5 +226,5 @@ class EventsFragment : Fragment(), ScrollToTop {
super.onStop()
}

override fun scrollToTop() = rootView.scrollView.smoothScrollTo(0, 0)
override fun doubleClick() = rootView.scrollView.smoothScrollTo(0, 0)
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import kotlinx.android.synthetic.main.fragment_favorite.view.monthChip
import kotlinx.android.synthetic.main.fragment_favorite.view.likesNumber
import kotlinx.android.synthetic.main.fragment_favorite.view.scrollView
import org.fossasia.openevent.general.R
import org.fossasia.openevent.general.ScrollToTop
import org.fossasia.openevent.general.BottomIconDoubleClick
import org.fossasia.openevent.general.event.Event
import org.fossasia.openevent.general.common.EventClickListener
import org.fossasia.openevent.general.common.FavoriteFabClickListener
Expand All @@ -37,7 +37,7 @@ import org.fossasia.openevent.general.utils.extensions.setStartPostponedEnterTra
import org.jetbrains.anko.design.longSnackbar
import org.jetbrains.anko.design.snackbar

class FavoriteFragment : Fragment(), ScrollToTop {
class FavoriteFragment : Fragment(), BottomIconDoubleClick {
private val favoriteEventViewModel by viewModel<FavoriteEventsViewModel>()
private lateinit var rootView: View
private val favoriteEventsRecyclerAdapter = FavoriteEventsRecyclerAdapter()
Expand Down Expand Up @@ -140,7 +140,7 @@ class FavoriteFragment : Fragment(), ScrollToTop {
setToolbar(activity, show = false)
}

override fun scrollToTop() = rootView.scrollView.smoothScrollTo(0, 0)
override fun doubleClick() = rootView.scrollView.smoothScrollTo(0, 0)

private fun showEmptyMessage(itemCount: Int) {
rootView.noLikedLL.isVisible = (itemCount == 0)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import kotlinx.android.synthetic.main.fragment_orders_under_user.view.scrollView
import kotlinx.android.synthetic.main.fragment_orders_under_user.view.pastEvent
import kotlinx.android.synthetic.main.fragment_orders_under_user.view.ticketsNumber
import org.fossasia.openevent.general.R
import org.fossasia.openevent.general.ScrollToTop
import org.fossasia.openevent.general.BottomIconDoubleClick
import org.fossasia.openevent.general.event.EventUtils
import org.fossasia.openevent.general.utils.Utils
import org.fossasia.openevent.general.utils.extensions.nonNull
Expand All @@ -30,7 +30,7 @@ import org.jetbrains.anko.design.longSnackbar

const val ORDERS_FRAGMENT = "ordersFragment"

class OrdersUnderUserFragment : Fragment(), ScrollToTop {
class OrdersUnderUserFragment : Fragment(), BottomIconDoubleClick {

private lateinit var rootView: View
private val ordersUnderUserVM by viewModel<OrdersUnderUserViewModel>()
Expand Down Expand Up @@ -128,7 +128,7 @@ class OrdersUnderUserFragment : Fragment(), ScrollToTop {
.actionOrderUserToAuth(getString(R.string.log_in_first), ORDERS_FRAGMENT))
}

override fun scrollToTop() = rootView.scrollView.smoothScrollTo(0, 0)
override fun doubleClick() = rootView.scrollView.smoothScrollTo(0, 0)

override fun onOptionsItemSelected(item: MenuItem): Boolean {
return when (item.itemId) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,10 @@ package org.fossasia.openevent.general.search

import android.os.Bundle
import android.view.LayoutInflater
import android.view.Menu
import android.view.MenuInflater
import android.view.MenuItem
import android.view.View
import android.view.ViewGroup
import android.widget.RadioButton
import androidx.core.widget.NestedScrollView
import androidx.fragment.app.Fragment
import androidx.navigation.Navigation.findNavController
import androidx.navigation.fragment.navArgs
Expand All @@ -20,6 +18,10 @@ import kotlinx.android.synthetic.main.fragment_search_filter.view.radioGroup
import kotlinx.android.synthetic.main.fragment_search_filter.view.tvSelectCategory
import kotlinx.android.synthetic.main.fragment_search_filter.view.tvSelectDate
import kotlinx.android.synthetic.main.fragment_search_filter.view.tvSelectLocation
import kotlinx.android.synthetic.main.fragment_search_filter.view.toolbar
import kotlinx.android.synthetic.main.fragment_search_filter.view.toolbarLayout
import kotlinx.android.synthetic.main.fragment_search_filter.view.tick
import kotlinx.android.synthetic.main.fragment_search_filter.view.scrollView
import org.fossasia.openevent.general.R
import org.fossasia.openevent.general.utils.Utils.setToolbar
import org.koin.androidx.viewmodel.ext.android.viewModel
Expand All @@ -40,9 +42,8 @@ class SearchFilterFragment : Fragment() {
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
setToolbar(activity)
setHasOptionsMenu(true)
rootView = inflater.inflate(R.layout.fragment_search_filter, container, false)
setupToolbar()
setFilterParams()
setFilters()
setSortByRadioGroup()
Expand All @@ -67,31 +68,28 @@ class SearchFilterFragment : Fragment() {
}
}

override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
inflater.inflate(R.menu.search_filter, menu)
super.onCreateOptionsMenu(menu, inflater)
}

override fun onOptionsItemSelected(item: MenuItem): Boolean {
return when (item.itemId) {
android.R.id.home -> {
activity?.onBackPressed()
true
}
R.id.filter_set -> {
findNavController(rootView).navigate(SearchFilterFragmentDirections.actionSearchFilterToSearchResults(
date = selectedTime,
freeEvents = rootView.freeStuffCheckBox.isChecked,
location = selectedLocation,
type = selectedCategory,
query = safeArgs.query,
sort = sortBy,
sessionsAndSpeakers = rootView.sessionsAndSpeakerCheckBox.isChecked,
callForSpeakers = rootView.callForSpeakerCheckBox.isChecked
))
true
}
else -> super.onOptionsItemSelected(item)
private fun setupToolbar() {
setToolbar(activity, show = false)
rootView.toolbar.setNavigationOnClickListener {
activity?.onBackPressed()
}
rootView.tick.setOnClickListener {
findNavController(rootView).navigate(SearchFilterFragmentDirections.actionSearchFilterToSearchResults(
date = selectedTime,
freeEvents = rootView.freeStuffCheckBox.isChecked,
location = selectedLocation,
type = selectedCategory,
query = safeArgs.query,
sort = sortBy,
sessionsAndSpeakers = rootView.sessionsAndSpeakerCheckBox.isChecked,
callForSpeakers = rootView.callForSpeakerCheckBox.isChecked
))
}
rootView.scrollView.setOnScrollChangeListener { _: NestedScrollView?, _: Int, scrollY: Int, _: Int, _: Int ->
if (scrollY > 0)
rootView.toolbarLayout.elevation = resources.getDimension(R.dimen.custom_toolbar_elevation)
else
rootView.toolbarLayout.elevation = 0F
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,48 +1,53 @@
package org.fossasia.openevent.general.search

import android.content.res.Configuration
import android.os.Bundle
import android.view.KeyEvent
import android.view.LayoutInflater
import android.view.Menu
import android.view.MenuInflater
import android.view.MenuItem
import android.view.View
import android.view.ViewGroup
import androidx.appcompat.widget.SearchView
import android.view.inputmethod.EditorInfo
import androidx.core.view.isVisible
import androidx.fragment.app.Fragment
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 kotlinx.android.synthetic.main.fragment_search.view.searchText
import kotlinx.android.synthetic.main.fragment_search.view.searchInfoContainer
import kotlinx.android.synthetic.main.fragment_search.view.toolbar
import kotlinx.android.synthetic.main.fragment_search.view.backgroundImage
import org.fossasia.openevent.general.R
import org.fossasia.openevent.general.utils.nullToEmpty
import org.koin.androidx.viewmodel.ext.android.viewModel
import androidx.navigation.Navigation.findNavController
import org.fossasia.openevent.general.MainActivity
import com.squareup.picasso.Picasso
import org.fossasia.openevent.general.BottomIconDoubleClick
import org.fossasia.openevent.general.ComplexBackPressFragment
import org.fossasia.openevent.general.event.EventUtils.getFormattedDate
import org.fossasia.openevent.general.event.EventUtils.getFormattedDateWithoutYear
import org.fossasia.openevent.general.utils.Utils.hideSoftKeyboard
import org.threeten.bp.LocalDate
import org.threeten.bp.ZoneId
import org.threeten.bp.format.DateTimeFormatter
import org.threeten.bp.format.DateTimeParseException
import java.util.Calendar
import org.fossasia.openevent.general.utils.Utils.setToolbar
import org.fossasia.openevent.general.utils.Utils.showSoftKeyboard

const val SEARCH_FRAGMENT = "SearchFragment"

class SearchFragment : Fragment() {
class SearchFragment : Fragment(), ComplexBackPressFragment, BottomIconDoubleClick {
private val searchViewModel by viewModel<SearchViewModel>()
private lateinit var rootView: View
private lateinit var searchView: SearchView

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

setToolbar(activity, getString(R.string.search), false)
setHasOptionsMenu(true)
setToolbar()

rootView.timeTextView.setOnClickListener {
findNavController(rootView).navigate(SearchFragmentDirections.actionSearchToSearchTime(
Expand Down Expand Up @@ -84,68 +89,89 @@ class SearchFragment : Fragment() {
))
}

if (searchViewModel.isQuerying)
startQuerying()
else
stopQuerying()

return rootView
}

override fun onOptionsItemSelected(item: MenuItem): Boolean {
return when (item.itemId) {
R.id.search_item -> {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
rootView.fabSearch.setOnClickListener {
makeSearch()
}
rootView.searchText.setOnClickListener {
if (!searchViewModel.isQuerying)
startQuerying()
}
rootView.searchText.setOnEditorActionListener { v, actionId, event ->
if (actionId == EditorInfo.IME_ACTION_SEARCH ||
actionId == EditorInfo.IME_ACTION_DONE ||
event.action == KeyEvent.ACTION_DOWN &&
event.keyCode == KeyEvent.KEYCODE_ENTER) {
makeSearch()
true
} else {
false
}

else -> super.onOptionsItemSelected(item)
}
}

override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
inflater.inflate(R.menu.search, menu)
super.onCreateOptionsMenu(menu, inflater)
override fun handleBackPress() {
if (searchViewModel.isQuerying)
stopQuerying()
else
findNavController(rootView).popBackStack()
}

override fun onPrepareOptionsMenu(menu: Menu) {
val searchItem = menu.findItem(R.id.search_item)
val thisActivity = activity
if (thisActivity is MainActivity) searchView = SearchView(thisActivity.supportActionBar?.themedContext)
searchView.maxWidth = Int.MAX_VALUE
searchItem.actionView = searchView
val queryListener = object : SearchView.OnQueryTextListener {
override fun onQueryTextSubmit(query: String): Boolean {
findNavController(rootView).navigate(SearchFragmentDirections.actionSearchToSearchResults(
query = query,
location = rootView.locationTextView.text.toString().nullToEmpty(),
date = (searchViewModel.savedTime ?: getString(R.string.anytime)).nullToEmpty(),
type = (searchViewModel.savedType ?: getString(R.string.anything)).nullToEmpty()
))
return false
}
override fun doubleClick() {
startQuerying()
}

override fun onQueryTextChange(newText: String): Boolean {
return false
}
}
searchView.setOnQueryTextListener(queryListener)
rootView.fabSearch.setOnClickListener {
queryListener.onQueryTextSubmit(searchView.query.toString())
private fun setToolbar() {
setToolbar(activity, show = false)
rootView.toolbar.setNavigationOnClickListener {
if (searchViewModel.isQuerying)
stopQuerying()
else
startQuerying()
}
}

if (searchViewModel.isQuerying) {
searchItem.expandActionView()
searchView.setQuery(searchViewModel.searchViewQuery, false)
searchView.clearFocus()
}
super.onPrepareOptionsMenu(menu)
private fun makeSearch() {
searchViewModel.isQuerying = false
findNavController(rootView).navigate(SearchFragmentDirections.actionSearchToSearchResults(
query = rootView.searchText.text.toString(),
location = rootView.locationTextView.text.toString().nullToEmpty(),
date = (searchViewModel.savedTime ?: getString(R.string.anytime)).nullToEmpty(),
type = (searchViewModel.savedType ?: getString(R.string.anything)).nullToEmpty()
))
rootView.searchText.setText("")
}

override fun onDestroyView() {
super.onDestroyView()
searchViewModel.isQuerying = !searchView.isIconified
searchViewModel.searchViewQuery = searchView.query.toString()
searchView.isSaveEnabled = false
private fun startQuerying() {
searchViewModel.isQuerying = true
rootView.searchInfoContainer.isVisible = false
Picasso.get()
.load(R.color.colorPrimary)
.placeholder(R.color.colorPrimary)
.into(rootView.backgroundImage)
rootView.toolbar.navigationIcon = resources.getDrawable(R.drawable.ic_arrow_back_white_cct)
rootView.searchText.requestFocus()
showSoftKeyboard(context, rootView)
}

override fun onDestroy() {
super.onDestroy()
if (this::searchView.isInitialized)
searchView.setOnQueryTextListener(null)
private fun stopQuerying() {
searchViewModel.isQuerying = false
rootView.searchInfoContainer.isVisible = true
val background = if (resources.configuration.orientation == Configuration.ORIENTATION_LANDSCAPE)
R.drawable.background_fragment else R.drawable.background_fragment_search
Picasso.get()
.load(background)
.placeholder(background)
.into(rootView.backgroundImage)
rootView.toolbar.navigationIcon = resources.getDrawable(R.drawable.ic_search_white)
hideSoftKeyboard(context, rootView)
}
}
Loading