196 lines
7.5 KiB
Kotlin
Raw Normal View History

2024-03-14 22:22:48 -06:00
package com.isolaatti.search.ui
2023-07-15 20:58:57 -06:00
2024-03-29 00:10:55 -06:00
import android.content.Intent
2023-07-15 20:58:57 -06:00
import android.os.Bundle
2024-03-29 00:10:55 -06:00
import android.util.Log
2023-07-15 20:58:57 -06:00
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
2024-03-24 21:06:08 -06:00
import androidx.core.widget.doAfterTextChanged
2023-07-15 20:58:57 -06:00
import androidx.fragment.app.Fragment
2024-03-24 21:06:08 -06:00
import androidx.fragment.app.viewModels
2024-03-29 00:10:55 -06:00
import androidx.lifecycle.Observer
import androidx.navigation.findNavController
import androidx.navigation.fragment.findNavController
2024-03-29 00:10:55 -06:00
import androidx.recyclerview.widget.LinearLayoutManager
import com.google.android.material.carousel.CarouselLayoutManager
import com.google.android.material.carousel.UncontainedCarouselStrategy
import com.google.android.material.chip.Chip
import com.isolaatti.R
2023-07-15 20:58:57 -06:00
import com.isolaatti.databinding.FragmentSearchBinding
import com.isolaatti.posting.posts.viewer.ui.PostViewerActivity
import com.isolaatti.profile.domain.entity.ProfileListItem
import com.isolaatti.profile.profile_listing.ui.ProfileListingFragment
2024-03-29 00:10:55 -06:00
import com.isolaatti.profile.ui.ProfileActivity
import com.isolaatti.search.data.HashtagsDto
import com.isolaatti.search.data.NewestUsersDto
import com.isolaatti.search.data.SearchDto
import com.isolaatti.search.data.SearchHistoryEntity
import com.isolaatti.search.data.SearchResultType
import com.isolaatti.search.presentation.SearchResultsAdapter
2024-03-29 00:10:55 -06:00
import com.isolaatti.search.presentation.SearchSuggestionsAdapter
2024-03-24 21:06:08 -06:00
import com.isolaatti.search.presentation.SearchViewModel
2024-03-29 00:10:55 -06:00
import com.isolaatti.search.presentation.UserCarouselAdapter
import dagger.hilt.android.AndroidEntryPoint
2023-07-15 20:58:57 -06:00
2024-03-29 00:10:55 -06:00
@AndroidEntryPoint
2023-07-15 20:58:57 -06:00
class SearchFragment : Fragment() {
2024-03-29 00:10:55 -06:00
companion object {
const val LOG_TAG = "SearchFragment"
}
2023-07-15 20:58:57 -06:00
lateinit var viewBinding: FragmentSearchBinding
2024-03-24 21:06:08 -06:00
private val viewModel: SearchViewModel by viewModels()
2024-03-29 00:10:55 -06:00
private var searchSuggestionsAdapter: SearchSuggestionsAdapter? = null
private var newestUsersAdapter: UserCarouselAdapter? = null
private var searchResultsAdapter: SearchResultsAdapter? = null
2024-03-29 00:10:55 -06:00
private val searchSuggestionsObserver: Observer<List<SearchHistoryEntity>> = Observer {
searchSuggestionsAdapter?.submitList(it)
}
private val searchResultsObserver: Observer<SearchDto> = Observer {
Log.d(LOG_TAG, it.toString())
searchResultsAdapter?.submitList(it.result)
2024-03-29 00:10:55 -06:00
}
private val trendingHashtagsObserver: Observer<HashtagsDto> = Observer {
Log.d(LOG_TAG, it.toString())
viewBinding.chipGroup.removeAllViews()
it.result.forEach { hashtag ->
viewBinding.chipGroup.addView(Chip(requireContext()).apply {
text = "#$hashtag"
setOnClickListener {
findNavController().navigate(SearchFragmentDirections.actionSearchFragmentToHashtagPostsFragment(hashtag))
2024-03-29 00:10:55 -06:00
}
})
}
}
private val newestUsersObserver: Observer<List<ProfileListItem>> = Observer {
newestUsersAdapter?.submitList(it)
2024-03-29 00:10:55 -06:00
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
viewModel.loadTendingHashtags()
viewModel.loadNewestUsers()
}
2023-07-15 20:58:57 -06:00
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
viewBinding = FragmentSearchBinding.inflate(inflater)
return viewBinding.root
}
2024-03-24 21:06:08 -06:00
2024-03-29 00:10:55 -06:00
private fun showResults(show: Boolean) {
if(show) {
viewBinding.viewAnimator.displayedChild = 1
viewBinding.searchBar.menu.findItem(R.id.close_button)?.setVisible(true)
} else {
viewBinding.viewAnimator.displayedChild = 0
viewModel.searchQuery = ""
viewBinding.searchBar.setText("")
viewBinding.searchBar.menu.findItem(R.id.close_button)?.setVisible(false)
}
}
2024-03-24 21:06:08 -06:00
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
setupListeners()
setupObservers()
2024-03-29 00:10:55 -06:00
searchSuggestionsAdapter = SearchSuggestionsAdapter(
onItemClick = {
viewBinding.searchBar.setText(it.query)
viewModel.searchQuery = it.query
viewBinding.searchView.hide()
viewModel.search()
showResults(true)
},
onItemDeleteClick = {
viewModel.deleteSuggestion(it)
}
)
viewBinding.searchHistoryRecyclerView.apply {
adapter = searchSuggestionsAdapter
layoutManager = LinearLayoutManager(requireContext(), LinearLayoutManager.VERTICAL, false)
}
newestUsersAdapter = UserCarouselAdapter(
onProfileClick = {
ProfileActivity.startActivity(requireContext(), it)
}
)
viewBinding.newUsersRecyclerView.apply {
adapter = newestUsersAdapter
layoutManager = CarouselLayoutManager(UncontainedCarouselStrategy())
}
searchResultsAdapter = SearchResultsAdapter(
onItemClick = {
when(it.type) {
SearchResultType.Profile -> {
it.resourceId.toIntOrNull()?.also { ProfileActivity.startActivity(requireContext(), it) }
}
SearchResultType.Post -> {
it.resourceId.toLongOrNull()?.also { PostViewerActivity.startActivity(requireContext(), it) }
}
SearchResultType.Hashtag -> {
findNavController().navigate(SearchFragmentDirections.actionSearchFragmentToHashtagPostsFragment(it.resourceId))
}
SearchResultType.Unknown -> {}
}
}
)
viewBinding.recyclerViewSearchResults.adapter = searchResultsAdapter
viewBinding.recyclerViewSearchResults.layoutManager = LinearLayoutManager(requireContext(), LinearLayoutManager.VERTICAL, false)
2024-03-24 21:06:08 -06:00
}
private fun setupListeners() {
viewBinding.searchView.editText.doAfterTextChanged { searchText ->
if(searchText != null) {
2024-03-29 00:10:55 -06:00
viewModel.getSuggestions(searchText.toString())
2024-03-24 21:06:08 -06:00
}
}
2024-03-29 00:10:55 -06:00
viewBinding.searchView.editText.setOnEditorActionListener { v, actionId, event ->
Log.d(LOG_TAG, "actionId: $actionId; event: $event")
viewBinding.searchBar.setText(viewBinding.searchView.text)
viewBinding.searchView.hide()
viewModel.search()
showResults(true)
true
}
viewBinding.searchBar.setOnMenuItemClickListener {
if(it.itemId == R.id.close_button) {
showResults(false)
true
} else {
false
2024-03-29 00:10:55 -06:00
}
}
viewBinding.openHashtagsButton.setOnClickListener {
findNavController().navigate(SearchFragmentDirections.actionSearchFragmentToHashtagsFragment())
}
viewBinding.browseProfilesButton.setOnClickListener {
findNavController().navigate(SearchFragmentDirections.actionSearchFragmentToBrowseProfilesFragment())
2024-03-29 00:10:55 -06:00
}
2024-03-24 21:06:08 -06:00
}
private fun setupObservers() {
2024-03-29 00:10:55 -06:00
viewModel.searchSuggestions.observe(viewLifecycleOwner, searchSuggestionsObserver)
viewModel.searchResults.observe(viewLifecycleOwner, searchResultsObserver)
viewModel.trendingHashtags.observe(viewLifecycleOwner, trendingHashtagsObserver)
viewModel.newestUsers.observe(viewLifecycleOwner, newestUsersObserver)
2024-03-24 21:06:08 -06:00
}
2023-07-15 20:58:57 -06:00
}