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
|
2024-03-31 22:50:06 -06:00
|
|
|
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
|
2024-04-03 19:48:01 -06:00
|
|
|
import com.isolaatti.posting.posts.viewer.ui.PostViewerActivity
|
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
|
2024-03-31 22:50:06 -06:00
|
|
|
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
|
2024-03-31 22:50:06 -06:00
|
|
|
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())
|
2024-03-31 22:50:06 -06:00
|
|
|
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 {
|
2024-03-31 22:50:06 -06:00
|
|
|
findNavController().navigate(SearchFragmentDirections.actionSearchFragmentToHashtagPostsFragment(hashtag))
|
2024-03-29 00:10:55 -06:00
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private val newestUsersObserver: Observer<NewestUsersDto> = Observer {
|
|
|
|
|
newestUsersAdapter?.submitList(it.result)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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())
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-31 22:50:06 -06:00
|
|
|
searchResultsAdapter = SearchResultsAdapter(
|
|
|
|
|
onItemClick = {
|
|
|
|
|
when(it.type) {
|
2024-04-03 19:48:01 -06:00
|
|
|
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))
|
|
|
|
|
}
|
2024-03-31 22:50:06 -06:00
|
|
|
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
|
2024-03-31 22:50:06 -06:00
|
|
|
} else {
|
|
|
|
|
false
|
2024-03-29 00:10:55 -06:00
|
|
|
}
|
2024-03-31 22:50:06 -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
|
|
|
}
|