diff --git a/app/src/main/java/ani/dantotsu/connections/anilist/Anilist.kt b/app/src/main/java/ani/dantotsu/connections/anilist/Anilist.kt index fc089716..65fbb3cd 100644 --- a/app/src/main/java/ani/dantotsu/connections/anilist/Anilist.kt +++ b/app/src/main/java/ani/dantotsu/connections/anilist/Anilist.kt @@ -41,20 +41,54 @@ object Anilist { "SCORE_DESC", "POPULARITY_DESC", "TRENDING_DESC", + "START_DATE_DESC", "TITLE_ENGLISH", "TITLE_ENGLISH_DESC", "SCORE" ) + val source = listOf( + "ORIGINAL", + "MANGA", + "LIGHT NOVEL", + "VISUAL NOVEL", + "VIDEO GAME", + "OTHER", + "NOVEL", + "DOUJINSHI", + "ANIME", + "WEB NOVEL", + "LIVE ACTION", + "GAME", + "COMIC", + "MULTIMEDIA PROJECT", + "PICTURE BOOK" + ) + + val animeStatus = listOf( + "FINISHED", + "RELEASING", + "NOT YET RELEASED", + "CANCELLED" + ) + + val mangaStatus = listOf( + "FINISHED", + "RELEASING", + "NOT YET RELEASED", + "HIATUS", + "CANCELLED" + ) + val seasons = listOf( "WINTER", "SPRING", "SUMMER", "FALL" ) - val anime_formats = listOf( + val animeFormats = listOf( "TV", "TV SHORT", "MOVIE", "SPECIAL", "OVA", "ONA", "MUSIC" ) - val manga_formats = listOf( + val mangaFormats = listOf( "MANGA", "NOVEL", "ONE SHOT" ) diff --git a/app/src/main/java/ani/dantotsu/connections/anilist/AnilistQueries.kt b/app/src/main/java/ani/dantotsu/connections/anilist/AnilistQueries.kt index 8e83a9e5..cf9a0ecd 100644 --- a/app/src/main/java/ani/dantotsu/connections/anilist/AnilistQueries.kt +++ b/app/src/main/java/ani/dantotsu/connections/anilist/AnilistQueries.kt @@ -885,18 +885,22 @@ class AnilistQueries { sort: String? = null, genres: MutableList? = null, tags: MutableList? = null, + status: String? = null, + source: String? = null, format: String? = null, + countryOfOrigin: String? = null, isAdult: Boolean = false, onList: Boolean? = null, excludedGenres: MutableList? = null, excludedTags: MutableList? = null, + startYear: Int? = null, seasonYear: Int? = null, season: String? = null, id: Int? = null, hd: Boolean = false, ): SearchResults? { val query = """ -query (${"$"}page: Int = 1, ${"$"}id: Int, ${"$"}type: MediaType, ${"$"}isAdult: Boolean = false, ${"$"}search: String, ${"$"}format: [MediaFormat], ${"$"}status: MediaStatus, ${"$"}countryOfOrigin: CountryCode, ${"$"}source: MediaSource, ${"$"}season: MediaSeason, ${"$"}seasonYear: Int, ${"$"}year: String, ${"$"}onList: Boolean, ${"$"}yearLesser: FuzzyDateInt, ${"$"}yearGreater: FuzzyDateInt, ${"$"}episodeLesser: Int, ${"$"}episodeGreater: Int, ${"$"}durationLesser: Int, ${"$"}durationGreater: Int, ${"$"}chapterLesser: Int, ${"$"}chapterGreater: Int, ${"$"}volumeLesser: Int, ${"$"}volumeGreater: Int, ${"$"}licensedBy: [String], ${"$"}isLicensed: Boolean, ${"$"}genres: [String], ${"$"}excludedGenres: [String], ${"$"}tags: [String], ${"$"}excludedTags: [String], ${"$"}minimumTagRank: Int, ${"$"}sort: [MediaSort] = [POPULARITY_DESC, SCORE_DESC]) { +query (${"$"}page: Int = 1, ${"$"}id: Int, ${"$"}type: MediaType, ${"$"}isAdult: Boolean = false, ${"$"}search: String, ${"$"}format: [MediaFormat], ${"$"}status: MediaStatus, ${"$"}countryOfOrigin: CountryCode, ${"$"}source: MediaSource, ${"$"}season: MediaSeason, ${"$"}seasonYear: Int, ${"$"}year: String, ${"$"}onList: Boolean, ${"$"}yearLesser: FuzzyDateInt, ${"$"}yearGreater: FuzzyDateInt, ${"$"}episodeLesser: Int, ${"$"}episodeGreater: Int, ${"$"}durationLesser: Int, ${"$"}durationGreater: Int, ${"$"}chapterLesser: Int, ${"$"}chapterGreater: Int, ${"$"}volumeLesser: Int, ${"$"}volumeGreater: Int, ${"$"}licensedBy: [String], ${"$"}isLicensed: Boolean, ${"$"}genres: [String], ${"$"}excludedGenres: [String], ${"$"}tags: [String], ${"$"}excludedTags: [String], ${"$"}minimumTagRank: Int, ${"$"}sort: [MediaSort] = [POPULARITY_DESC, SCORE_DESC, START_DATE_DESC]) { Page(page: ${"$"}page, perPage: ${perPage ?: 50}) { pageInfo { total @@ -944,11 +948,15 @@ query (${"$"}page: Int = 1, ${"$"}id: Int, ${"$"}type: MediaType, ${"$"}isAdult: ${if (onList != null) ""","onList":$onList""" else ""} ${if (page != null) ""","page":"$page"""" else ""} ${if (id != null) ""","id":"$id"""" else ""} - ${if (seasonYear != null) ""","seasonYear":"$seasonYear"""" else ""} + ${if (type == "ANIME" && seasonYear != null) ""","seasonYear":"$seasonYear"""" else ""} + ${if (type == "MANGA" && startYear != null) ""","yearGreater":${startYear}0000,"yearLesser":${startYear + 1}0000""" else ""} ${if (season != null) ""","season":"$season"""" else ""} ${if (search != null) ""","search":"$search"""" else ""} + ${if (source != null) ""","source":"$source"""" else ""} ${if (sort != null) ""","sort":"$sort"""" else ""} + ${if (status != null) ""","status":"$status"""" else ""} ${if (format != null) ""","format":"${format.replace(" ", "_")}"""" else ""} + ${if (countryOfOrigin != null) ""","countryOfOrigin":"$countryOfOrigin"""" else ""} ${if (genres?.isNotEmpty() == true) ""","genres":[${genres.joinToString { "\"$it\"" }}]""" else ""} ${ if (excludedGenres?.isNotEmpty() == true) @@ -980,7 +988,6 @@ query (${"$"}page: Int = 1, ${"$"}id: Int, ${"$"}type: MediaType, ${"$"}isAdult: else "" } }""".replace("\n", " ").replace(""" """, "") - val response = executeQuery(query, variables, true)?.data?.page if (response?.media != null) { val responseArray = arrayListOf() @@ -1012,7 +1019,11 @@ query (${"$"}page: Int = 1, ${"$"}id: Int, ${"$"}type: MediaType, ${"$"}isAdult: excludedGenres = excludedGenres, tags = tags, excludedTags = excludedTags, + status = status, + source = source, format = format, + countryOfOrigin = countryOfOrigin, + startYear = startYear, seasonYear = seasonYear, season = season, results = responseArray, diff --git a/app/src/main/java/ani/dantotsu/connections/anilist/AnilistViewModel.kt b/app/src/main/java/ani/dantotsu/connections/anilist/AnilistViewModel.kt index 243e2792..531000c9 100644 --- a/app/src/main/java/ani/dantotsu/connections/anilist/AnilistViewModel.kt +++ b/app/src/main/java/ani/dantotsu/connections/anilist/AnilistViewModel.kt @@ -174,7 +174,10 @@ class AnilistAnimeViewModel : ViewModel() { r.sort, r.genres, r.tags, + r.status, + r.source, r.format, + r.countryOfOrigin, r.isAdult, r.onList ) @@ -276,11 +279,15 @@ class AnilistMangaViewModel : ViewModel() { r.sort, r.genres, r.tags, + r.status, + r.source, r.format, + r.countryOfOrigin, r.isAdult, r.onList, r.excludedGenres, r.excludedTags, + r.startYear, r.seasonYear, r.season ) @@ -336,11 +343,15 @@ class AnilistSearch : ViewModel() { r.sort, r.genres, r.tags, + r.status, + r.source, r.format, + r.countryOfOrigin, r.isAdult, r.onList, r.excludedGenres, r.excludedTags, + r.startYear, r.seasonYear, r.season ) @@ -355,11 +366,15 @@ class AnilistSearch : ViewModel() { r.sort, r.genres, r.tags, + r.status, + r.source, r.format, + r.countryOfOrigin, r.isAdult, r.onList, r.excludedGenres, r.excludedTags, + r.startYear, r.seasonYear, r.season ) diff --git a/app/src/main/java/ani/dantotsu/connections/anilist/SearchResults.kt b/app/src/main/java/ani/dantotsu/connections/anilist/SearchResults.kt index 32bc1757..8458cc7e 100644 --- a/app/src/main/java/ani/dantotsu/connections/anilist/SearchResults.kt +++ b/app/src/main/java/ani/dantotsu/connections/anilist/SearchResults.kt @@ -11,13 +11,17 @@ data class SearchResults( var onList: Boolean? = null, var perPage: Int? = null, var search: String? = null, + var countryOfOrigin :String? = null, var sort: String? = null, var genres: MutableList? = null, var excludedGenres: MutableList? = null, var tags: MutableList? = null, var excludedTags: MutableList? = null, + var status: String? = null, + var source: String? = null, var format: String? = null, var seasonYear: Int? = null, + var startYear: Int? = null, var season: String? = null, var page: Int = 1, var results: MutableList, @@ -37,12 +41,24 @@ data class SearchResults( ) ) } + status?.let { + list.add(SearchChip("STATUS", currContext()!!.getString(R.string.filter_status, it))) + } + source?.let { + list.add(SearchChip("SOURCE", currContext()!!.getString(R.string.filter_source, it))) + } format?.let { list.add(SearchChip("FORMAT", currContext()!!.getString(R.string.filter_format, it))) } + countryOfOrigin?.let { + list.add(SearchChip("COUNTRY", currContext()!!.getString(R.string.filter_country, it))) + } season?.let { list.add(SearchChip("SEASON", it)) } + startYear?.let { + list.add(SearchChip("START_YEAR", it.toString())) + } seasonYear?.let { list.add(SearchChip("SEASON_YEAR", it.toString())) } @@ -74,8 +90,12 @@ data class SearchResults( fun removeChip(chip: SearchChip) { when (chip.type) { "SORT" -> sort = null + "STATUS" -> status = null + "SOURCE" -> source = null "FORMAT" -> format = null + "COUNTRY" -> countryOfOrigin = null "SEASON" -> season = null + "START_YEAR" -> startYear = null "SEASON_YEAR" -> seasonYear = null "GENRE" -> genres?.remove(chip.text) "EXCLUDED_GENRE" -> excludedGenres?.remove(chip.text) diff --git a/app/src/main/java/ani/dantotsu/media/SearchActivity.kt b/app/src/main/java/ani/dantotsu/media/SearchActivity.kt index ca196269..fb685fe9 100644 --- a/app/src/main/java/ani/dantotsu/media/SearchActivity.kt +++ b/app/src/main/java/ani/dantotsu/media/SearchActivity.kt @@ -74,8 +74,12 @@ class SearchActivity : AppCompatActivity() { genres = intent.getStringExtra("genre")?.let { mutableListOf(it) }, tags = intent.getStringExtra("tag")?.let { mutableListOf(it) }, sort = intent.getStringExtra("sortBy"), + status = intent.getStringExtra("status"), + source = intent.getStringExtra("source"), + countryOfOrigin = intent.getStringExtra("country"), season = intent.getStringExtra("season"), - seasonYear = intent.getStringExtra("seasonYear")?.toIntOrNull(), + seasonYear = if (intent.getStringExtra("type") == "ANIME") intent.getStringExtra("seasonYear")?.toIntOrNull() else null, + startYear = if (intent.getStringExtra("type") == "MANGA") intent.getStringExtra("seasonYear")?.toIntOrNull() else null, results = mutableListOf(), hasNextPage = false ) @@ -134,8 +138,12 @@ class SearchActivity : AppCompatActivity() { excludedTags = it.excludedTags tags = it.tags season = it.season + startYear = it.startYear seasonYear = it.seasonYear + status = it.status + source = it.source format = it.format + countryOfOrigin = it.countryOfOrigin page = it.page hasNextPage = it.hasNextPage } diff --git a/app/src/main/java/ani/dantotsu/media/SearchAdapter.kt b/app/src/main/java/ani/dantotsu/media/SearchAdapter.kt index cb590e3a..f04cee00 100644 --- a/app/src/main/java/ani/dantotsu/media/SearchAdapter.kt +++ b/app/src/main/java/ani/dantotsu/media/SearchAdapter.kt @@ -13,6 +13,8 @@ import android.view.animation.AlphaAnimation import android.view.animation.Animation import android.view.inputmethod.EditorInfo import android.view.inputmethod.InputMethodManager +import android.widget.ImageView +import android.widget.PopupMenu import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.content.res.AppCompatResources import androidx.recyclerview.widget.LinearLayoutManager @@ -45,6 +47,19 @@ class SearchAdapter(private val activity: SearchActivity, private val type: Stri private lateinit var searchHistoryAdapter: SearchHistoryAdapter private lateinit var binding: ItemSearchHeaderBinding + private fun updateFilterTextViewDrawable() { + val filterDrawable = when (activity.result.sort) { + Anilist.sortBy[0] -> R.drawable.ic_round_area_chart_24 + Anilist.sortBy[1] -> R.drawable.ic_round_filter_peak_24 + Anilist.sortBy[2] -> R.drawable.ic_round_star_graph_24 + Anilist.sortBy[3] -> R.drawable.ic_round_new_releases_24 + Anilist.sortBy[4] -> R.drawable.ic_round_filter_list_24 + Anilist.sortBy[5] -> R.drawable.ic_round_filter_list_24_reverse + Anilist.sortBy[6] -> R.drawable.ic_round_assist_walker_24 + else -> R.drawable.ic_round_filter_alt_24 + } + binding.filterTextView.setCompoundDrawablesWithIntrinsicBounds(filterDrawable, 0, 0, 0) + } override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): SearchHeaderViewHolder { val binding = ItemSearchHeaderBinding.inflate(LayoutInflater.from(parent.context), parent, false) @@ -93,7 +108,7 @@ class SearchAdapter(private val activity: SearchActivity, private val type: Stri binding.searchAdultCheck.isChecked = adult binding.searchList.isChecked = listOnly == true - binding.searchChipRecycler.adapter = SearchChipAdapter(activity).also { + binding.searchChipRecycler.adapter = SearchChipAdapter(activity, this).also { activity.updateChips = { it.update() } } @@ -103,6 +118,59 @@ class SearchAdapter(private val activity: SearchActivity, private val type: Stri binding.searchFilter.setOnClickListener { SearchFilterBottomDialog.newInstance().show(activity.supportFragmentManager, "dialog") } + binding.searchFilter.setOnLongClickListener { + val popupMenu = PopupMenu(activity, binding.searchFilter) + popupMenu.menuInflater.inflate(R.menu.sortby_filter_menu, popupMenu.menu) + popupMenu.setOnMenuItemClickListener { item -> + when (item.itemId) { + R.id.sort_by_score -> { + activity.result.sort = Anilist.sortBy[0] + activity.updateChips.invoke() + activity.search() + updateFilterTextViewDrawable() + } + R.id.sort_by_popular -> { + activity.result.sort = Anilist.sortBy[1] + activity.updateChips.invoke() + activity.search() + updateFilterTextViewDrawable() + } + R.id.sort_by_trending -> { + activity.result.sort = Anilist.sortBy[2] + activity.updateChips.invoke() + activity.search() + updateFilterTextViewDrawable() + } + R.id.sort_by_recent -> { + activity.result.sort = Anilist.sortBy[3] + activity.updateChips.invoke() + activity.search() + updateFilterTextViewDrawable() + } + R.id.sort_by_a_z -> { + activity.result.sort = Anilist.sortBy[4] + activity.updateChips.invoke() + activity.search() + updateFilterTextViewDrawable() + } + R.id.sort_by_z_a -> { + activity.result.sort = Anilist.sortBy[5] + activity.updateChips.invoke() + activity.search() + updateFilterTextViewDrawable() + } + R.id.sort_by_pure_pain -> { + activity.result.sort = Anilist.sortBy[6] + activity.updateChips.invoke() + activity.search() + updateFilterTextViewDrawable() + } + } + true + } + popupMenu.show() + true + } binding.searchByImage.setOnClickListener { activity.startActivity(Intent(activity, ImageSearchActivity::class.java)) } @@ -257,7 +325,7 @@ class SearchAdapter(private val activity: SearchActivity, private val type: Stri } - class SearchChipAdapter(val activity: SearchActivity) : + class SearchChipAdapter(val activity: SearchActivity, private val searchAdapter: SearchAdapter) : RecyclerView.Adapter() { private var chips = activity.result.toChipList() @@ -274,11 +342,12 @@ class SearchAdapter(private val activity: SearchActivity, private val type: Stri override fun onBindViewHolder(holder: SearchChipViewHolder, position: Int) { val chip = chips[position] holder.binding.root.apply { - text = chip.text + text = chip.text.replace("_", " ") setOnClickListener { activity.result.removeChip(chip) update() activity.search() + searchAdapter.updateFilterTextViewDrawable() } } } @@ -287,6 +356,7 @@ class SearchAdapter(private val activity: SearchActivity, private val type: Stri fun update() { chips = activity.result.toChipList() notifyDataSetChanged() + searchAdapter.updateFilterTextViewDrawable() } override fun getItemCount(): Int = chips.size diff --git a/app/src/main/java/ani/dantotsu/media/SearchFilterBottomDialog.kt b/app/src/main/java/ani/dantotsu/media/SearchFilterBottomDialog.kt index 297f8289..53ee263f 100644 --- a/app/src/main/java/ani/dantotsu/media/SearchFilterBottomDialog.kt +++ b/app/src/main/java/ani/dantotsu/media/SearchFilterBottomDialog.kt @@ -1,11 +1,15 @@ package ani.dantotsu.media +import android.animation.ObjectAnimator import android.os.Bundle import android.view.LayoutInflater import android.view.View import android.view.View.GONE import android.view.ViewGroup +import android.view.animation.AccelerateDecelerateInterpolator +import android.view.animation.AnimationUtils import android.widget.ArrayAdapter +import android.widget.PopupMenu import androidx.recyclerview.widget.GridLayoutManager import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView @@ -17,6 +21,9 @@ import ani.dantotsu.connections.anilist.Anilist import ani.dantotsu.databinding.BottomSheetSearchFilterBinding import ani.dantotsu.databinding.ItemChipBinding import com.google.android.material.chip.Chip +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch import java.util.Calendar class SearchFilterBottomDialog : BottomSheetDialogFragment() { @@ -38,6 +45,54 @@ class SearchFilterBottomDialog : BottomSheetDialogFragment() { private var exGenres = mutableListOf() private var selectedTags = mutableListOf() private var exTags = mutableListOf() + private fun updateChips() { + binding.searchFilterGenres.adapter?.notifyDataSetChanged() + binding.searchFilterTags.adapter?.notifyDataSetChanged() + } + + private fun startBounceZoomAnimation(view: View? = null) { + val targetView = view ?: binding.sortByFilter + val bounceZoomAnimation = AnimationUtils.loadAnimation(requireContext(), R.anim.bounce_zoom) + targetView.startAnimation(bounceZoomAnimation) + } + + private fun setSortByFilterImage() { + val filterDrawable = when (activity.result.sort) { + Anilist.sortBy[0] -> R.drawable.ic_round_area_chart_24 + Anilist.sortBy[1] -> R.drawable.ic_round_filter_peak_24 + Anilist.sortBy[2] -> R.drawable.ic_round_star_graph_24 + Anilist.sortBy[3] -> R.drawable.ic_round_new_releases_24 + Anilist.sortBy[4] -> R.drawable.ic_round_filter_list_24 + Anilist.sortBy[5] -> R.drawable.ic_round_filter_list_24_reverse + Anilist.sortBy[6] -> R.drawable.ic_round_assist_walker_24 + else -> R.drawable.ic_round_filter_alt_24 + } + binding.sortByFilter.setImageResource(filterDrawable) + } + + private fun resetSearchFilter() { + activity.result.sort = null + binding.sortByFilter.setImageResource(R.drawable.ic_round_filter_alt_24) + startBounceZoomAnimation(binding.sortByFilter) + activity.result.countryOfOrigin = null + binding.countryFilter.setImageResource(R.drawable.ic_round_globe_search_googlefonts) + startBounceZoomAnimation(binding.countryFilter) + + selectedGenres.clear() + exGenres.clear() + selectedTags.clear() + exTags.clear() + binding.searchStatus.setText("") + binding.searchSource.setText("") + binding.searchFormat.setText("") + binding.searchSeason.setText("") + binding.searchYear.setText("") + binding.searchStatus.clearFocus() + binding.searchFormat.clearFocus() + binding.searchSeason.clearFocus() + binding.searchYear.clearFocus() + updateChips() + } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { @@ -47,14 +102,149 @@ class SearchFilterBottomDialog : BottomSheetDialogFragment() { exGenres = activity.result.excludedGenres ?: mutableListOf() selectedTags = activity.result.tags ?: mutableListOf() exTags = activity.result.excludedTags ?: mutableListOf() + setSortByFilterImage() + + binding.resetSearchFilter.setOnClickListener { + val rotateAnimation = ObjectAnimator.ofFloat(binding.resetSearchFilter, "rotation", 180f, 540f) + rotateAnimation.duration = 500 + rotateAnimation.interpolator = AccelerateDecelerateInterpolator() + rotateAnimation.start() + resetSearchFilter() + } + + binding.resetSearchFilter.setOnLongClickListener { + val rotateAnimation = ObjectAnimator.ofFloat(binding.resetSearchFilter, "rotation", 180f, 540f) + rotateAnimation.duration = 500 + rotateAnimation.interpolator = AccelerateDecelerateInterpolator() + rotateAnimation.start() + val bounceAnimation = AnimationUtils.loadAnimation(requireContext(), R.anim.bounce_zoom) + + binding.resetSearchFilter.startAnimation(bounceAnimation) + binding.resetSearchFilter.postDelayed({ + resetSearchFilter() + + CoroutineScope(Dispatchers.Main).launch { + activity.result.apply { + status = binding.searchStatus.text.toString().replace(" ", "_").ifBlank { null } + source = binding.searchSource.text.toString().replace(" ", "_").ifBlank { null } + format = binding.searchFormat.text.toString().ifBlank { null } + season = binding.searchSeason.text.toString().ifBlank { null } + startYear = binding.searchYear.text.toString().toIntOrNull() + seasonYear = binding.searchYear.text.toString().toIntOrNull() + sort = activity.result.sort + genres = selectedGenres + tags = selectedTags + excludedGenres = exGenres + excludedTags = exTags + } + activity.updateChips.invoke() + activity.search() + dismiss() + } + }, 500) + true + } + + binding.sortByFilter.setOnClickListener { + val popupMenu = PopupMenu(requireContext(), it) + popupMenu.menuInflater.inflate(R.menu.sortby_filter_menu, popupMenu.menu) + popupMenu.setOnMenuItemClickListener { menuItem -> + when (menuItem.itemId) { + R.id.sort_by_score -> { + activity.result.sort = Anilist.sortBy[0] + binding.sortByFilter.setImageResource(R.drawable.ic_round_area_chart_24) + startBounceZoomAnimation() + } + + R.id.sort_by_popular -> { + activity.result.sort = Anilist.sortBy[1] + binding.sortByFilter.setImageResource(R.drawable.ic_round_filter_peak_24) + startBounceZoomAnimation() + } + + R.id.sort_by_trending -> { + activity.result.sort = Anilist.sortBy[2] + binding.sortByFilter.setImageResource(R.drawable.ic_round_star_graph_24) + startBounceZoomAnimation() + } + + R.id.sort_by_recent -> { + activity.result.sort = Anilist.sortBy[3] + binding.sortByFilter.setImageResource(R.drawable.ic_round_new_releases_24) + startBounceZoomAnimation() + } + + R.id.sort_by_a_z -> { + activity.result.sort = Anilist.sortBy[4] + binding.sortByFilter.setImageResource(R.drawable.ic_round_filter_list_24) + startBounceZoomAnimation() + } + + R.id.sort_by_z_a -> { + activity.result.sort = Anilist.sortBy[5] + binding.sortByFilter.setImageResource(R.drawable.ic_round_filter_list_24_reverse) + startBounceZoomAnimation() + } + + R.id.sort_by_pure_pain -> { + activity.result.sort = Anilist.sortBy[6] + binding.sortByFilter.setImageResource(R.drawable.ic_round_assist_walker_24) + startBounceZoomAnimation() + } + } + true + } + popupMenu.show() + } + + binding.countryFilter.setOnClickListener { + val popupMenu = PopupMenu(requireContext(), it) + popupMenu.menuInflater.inflate(R.menu.country_filter_menu, popupMenu.menu) + popupMenu.setOnMenuItemClickListener { menuItem -> + when (menuItem.itemId) { + R.id.country_global -> { + binding.countryFilter.setImageResource(R.drawable.ic_round_globe_search_googlefonts) + startBounceZoomAnimation(binding.countryFilter) + } + R.id.country_china -> { + activity.result.countryOfOrigin = "CN" + binding.countryFilter.setImageResource(R.drawable.ic_round_globe_china_googlefonts) + startBounceZoomAnimation(binding.countryFilter) + } + R.id.country_south_korea -> { + activity.result.countryOfOrigin = "KR" + binding.countryFilter.setImageResource(R.drawable.ic_round_globe_south_korea_googlefonts) + startBounceZoomAnimation(binding.countryFilter) + } + R.id.country_japan -> { + activity.result.countryOfOrigin = "JP" + binding.countryFilter.setImageResource(R.drawable.ic_round_globe_japan_googlefonts) + startBounceZoomAnimation(binding.countryFilter) + } + R.id.country_taiwan -> { + activity.result.countryOfOrigin = "TW" + binding.countryFilter.setImageResource(R.drawable.ic_round_globe_taiwan_googlefonts) + startBounceZoomAnimation(binding.countryFilter) + } + } + true + } + popupMenu.show() + } binding.searchFilterApply.setOnClickListener { activity.result.apply { + status = binding.searchStatus.text.toString().replace(" ", "_").ifBlank { null } + source = binding.searchSource.text.toString().replace(" ", "_").ifBlank { null } format = binding.searchFormat.text.toString().ifBlank { null } - sort = binding.searchSortBy.text.toString().ifBlank { null } - ?.let { Anilist.sortBy[resources.getStringArray(R.array.sort_by).indexOf(it)] } season = binding.searchSeason.text.toString().ifBlank { null } - seasonYear = binding.searchYear.text.toString().toIntOrNull() + if (activity.result.type == "ANIME") { + seasonYear = binding.searchYear.text.toString().toIntOrNull() + } else { + startYear = binding.searchYear.text.toString().toIntOrNull() + } + sort = activity.result.sort + countryOfOrigin = activity.result.countryOfOrigin genres = selectedGenres tags = selectedTags excludedGenres = exGenres @@ -67,15 +257,22 @@ class SearchFilterBottomDialog : BottomSheetDialogFragment() { binding.searchFilterCancel.setOnClickListener { dismiss() } - - binding.searchSortBy.setText(activity.result.sort?.let { - resources.getStringArray(R.array.sort_by)[Anilist.sortBy.indexOf(it)] - }) - binding.searchSortBy.setAdapter( + val format = if (activity.result.type == "ANIME") Anilist.animeStatus else Anilist.mangaStatus + binding.searchStatus.setText(activity.result.status?.replace("_", " ")) + binding.searchStatus.setAdapter( ArrayAdapter( binding.root.context, R.layout.item_dropdown, - resources.getStringArray(R.array.sort_by) + format + ) + ) + + binding.searchSource.setText(activity.result.source?.replace("_", " ")) + binding.searchSource.setAdapter( + ArrayAdapter( + binding.root.context, + R.layout.item_dropdown, + Anilist.source.toTypedArray() ) ) @@ -84,11 +281,25 @@ class SearchFilterBottomDialog : BottomSheetDialogFragment() { ArrayAdapter( binding.root.context, R.layout.item_dropdown, - (if (activity.result.type == "ANIME") Anilist.anime_formats else Anilist.manga_formats).toTypedArray() + (if (activity.result.type == "ANIME") Anilist.animeFormats else Anilist.mangaFormats).toTypedArray() ) ) - if (activity.result.type == "MANGA") binding.searchSeasonYearCont.visibility = GONE + if (activity.result.type == "ANIME") { + binding.searchYear.setText(activity.result.seasonYear?.toString()) + } else { + binding.searchYear.setText(activity.result.startYear?.toString()) + } + binding.searchYear.setAdapter( + ArrayAdapter( + binding.root.context, + R.layout.item_dropdown, + (1970 until Calendar.getInstance().get(Calendar.YEAR) + 2).map { it.toString() } + .reversed().toTypedArray() + ) + ) + + if (activity.result.type == "MANGA") binding.searchSeasonCont.visibility = GONE else { binding.searchSeason.setText(activity.result.season) binding.searchSeason.setAdapter( @@ -98,16 +309,6 @@ class SearchFilterBottomDialog : BottomSheetDialogFragment() { Anilist.seasons.toTypedArray() ) ) - - binding.searchYear.setText(activity.result.seasonYear?.toString()) - binding.searchYear.setAdapter( - ArrayAdapter( - binding.root.context, - R.layout.item_dropdown, - (1970 until Calendar.getInstance().get(Calendar.YEAR) + 2).map { it.toString() } - .reversed().toTypedArray() - ) - ) } binding.searchFilterGenres.adapter = FilterChipAdapter(Anilist.genres ?: listOf()) { chip -> diff --git a/app/src/main/java/ani/dantotsu/profile/ProfileFragment.kt b/app/src/main/java/ani/dantotsu/profile/ProfileFragment.kt index 6fd425be..f7a04944 100644 --- a/app/src/main/java/ani/dantotsu/profile/ProfileFragment.kt +++ b/app/src/main/java/ani/dantotsu/profile/ProfileFragment.kt @@ -154,22 +154,23 @@ class ProfileFragment : Fragment() { private fun setFavPeople() { if (favStaff.isEmpty()) { binding.profileFavStaffContainer.visibility = View.GONE + } else { + binding.profileFavStaffRecycler.adapter = AuthorAdapter(favStaff) + binding.profileFavStaffRecycler.layoutManager = LinearLayoutManager( + activity, LinearLayoutManager.HORIZONTAL, false + ) + binding.profileFavStaffRecycler.layoutAnimation = LayoutAnimationController(setSlideIn(), 0.25f) } - binding.profileFavStaffRecycler.adapter = AuthorAdapter(favStaff) - binding.profileFavStaffRecycler.layoutManager = LinearLayoutManager( - activity, - LinearLayoutManager.HORIZONTAL, - false - ) + if (favCharacter.isEmpty()) { binding.profileFavCharactersContainer.visibility = View.GONE + } else { + binding.profileFavCharactersRecycler.adapter = CharacterAdapter(favCharacter) + binding.profileFavCharactersRecycler.layoutManager = LinearLayoutManager( + activity, LinearLayoutManager.HORIZONTAL, false + ) + binding.profileFavCharactersRecycler.layoutAnimation = LayoutAnimationController(setSlideIn(), 0.25f) } - binding.profileFavCharactersRecycler.adapter = CharacterAdapter(favCharacter) - binding.profileFavCharactersRecycler.layoutManager = LinearLayoutManager( - activity, - LinearLayoutManager.HORIZONTAL, - false - ) } private fun initRecyclerView( diff --git a/app/src/main/res/drawable/ic_round_area_chart_24.xml b/app/src/main/res/drawable/ic_round_area_chart_24.xml new file mode 100644 index 00000000..b1d6f78c --- /dev/null +++ b/app/src/main/res/drawable/ic_round_area_chart_24.xml @@ -0,0 +1,12 @@ + + + + + diff --git a/app/src/main/res/drawable/ic_round_assist_walker_24.xml b/app/src/main/res/drawable/ic_round_assist_walker_24.xml new file mode 100644 index 00000000..0d38faeb --- /dev/null +++ b/app/src/main/res/drawable/ic_round_assist_walker_24.xml @@ -0,0 +1,16 @@ + + + + + + + diff --git a/app/src/main/res/drawable/ic_round_early_bird_special.xml b/app/src/main/res/drawable/ic_round_early_bird_special.xml deleted file mode 100644 index 4aa4292f..00000000 --- a/app/src/main/res/drawable/ic_round_early_bird_special.xml +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - diff --git a/app/src/main/res/drawable/ic_round_filter_list_24.xml b/app/src/main/res/drawable/ic_round_filter_list_24.xml new file mode 100644 index 00000000..e3dc45c1 --- /dev/null +++ b/app/src/main/res/drawable/ic_round_filter_list_24.xml @@ -0,0 +1,12 @@ + + + + + diff --git a/app/src/main/res/drawable/ic_round_filter_list_24_reverse.xml b/app/src/main/res/drawable/ic_round_filter_list_24_reverse.xml new file mode 100644 index 00000000..ac200103 --- /dev/null +++ b/app/src/main/res/drawable/ic_round_filter_list_24_reverse.xml @@ -0,0 +1,12 @@ + + + + + diff --git a/app/src/main/res/drawable/ic_round_filter_peak_24.xml b/app/src/main/res/drawable/ic_round_filter_peak_24.xml new file mode 100644 index 00000000..061d0ec0 --- /dev/null +++ b/app/src/main/res/drawable/ic_round_filter_peak_24.xml @@ -0,0 +1,12 @@ + + + + + diff --git a/app/src/main/res/drawable/ic_round_globe_china_googlefonts.xml b/app/src/main/res/drawable/ic_round_globe_china_googlefonts.xml new file mode 100644 index 00000000..1a36e8f6 --- /dev/null +++ b/app/src/main/res/drawable/ic_round_globe_china_googlefonts.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_round_globe_japan_googlefonts.xml b/app/src/main/res/drawable/ic_round_globe_japan_googlefonts.xml new file mode 100644 index 00000000..24803edd --- /dev/null +++ b/app/src/main/res/drawable/ic_round_globe_japan_googlefonts.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_round_globe_search_googlefonts.xml b/app/src/main/res/drawable/ic_round_globe_search_googlefonts.xml new file mode 100644 index 00000000..97b82b0e --- /dev/null +++ b/app/src/main/res/drawable/ic_round_globe_search_googlefonts.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_round_globe_south_korea_googlefonts.xml b/app/src/main/res/drawable/ic_round_globe_south_korea_googlefonts.xml new file mode 100644 index 00000000..dff31e26 --- /dev/null +++ b/app/src/main/res/drawable/ic_round_globe_south_korea_googlefonts.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_round_globe_taiwan_googlefonts.xml b/app/src/main/res/drawable/ic_round_globe_taiwan_googlefonts.xml new file mode 100644 index 00000000..52052789 --- /dev/null +++ b/app/src/main/res/drawable/ic_round_globe_taiwan_googlefonts.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_round_reset_star_24.xml b/app/src/main/res/drawable/ic_round_reset_star_24.xml new file mode 100644 index 00000000..00830a3e --- /dev/null +++ b/app/src/main/res/drawable/ic_round_reset_star_24.xml @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_round_star_graph_24.xml b/app/src/main/res/drawable/ic_round_star_graph_24.xml new file mode 100644 index 00000000..590f5f18 --- /dev/null +++ b/app/src/main/res/drawable/ic_round_star_graph_24.xml @@ -0,0 +1,12 @@ + + + + + diff --git a/app/src/main/res/layout/activity_player_settings.xml b/app/src/main/res/layout/activity_player_settings.xml index afbc7ee2..e1503989 100644 --- a/app/src/main/res/layout/activity_player_settings.xml +++ b/app/src/main/res/layout/activity_player_settings.xml @@ -749,7 +749,7 @@ android:layout_height="wrap_content" android:layout_marginBottom="8dp" android:checked="false" - android:drawableStart="@drawable/ic_round_early_bird_special" + android:drawableStart="@drawable/ic_round_assist_walker_24" android:drawablePadding="16dp" android:elegantTextHeight="true" android:fontFamily="@font/poppins_bold" diff --git a/app/src/main/res/layout/activity_reader_settings.xml b/app/src/main/res/layout/activity_reader_settings.xml index 63ce3d08..9e9f1efd 100644 --- a/app/src/main/res/layout/activity_reader_settings.xml +++ b/app/src/main/res/layout/activity_reader_settings.xml @@ -1318,7 +1318,7 @@ android:layout_height="wrap_content" android:layout_marginBottom="8dp" android:checked="false" - android:drawableStart="@drawable/ic_round_early_bird_special" + android:drawableStart="@drawable/ic_round_assist_walker_24" android:drawablePadding="16dp" android:elegantTextHeight="true" android:fontFamily="@font/poppins_bold" diff --git a/app/src/main/res/layout/bottom_sheet_search_filter.xml b/app/src/main/res/layout/bottom_sheet_search_filter.xml index 916a2e72..950141e7 100644 --- a/app/src/main/res/layout/bottom_sheet_search_filter.xml +++ b/app/src/main/res/layout/bottom_sheet_search_filter.xml @@ -1,288 +1,382 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + android:layout_gravity="bottom" + android:orientation="horizontal"> - - - + android:layout_weight="1" + android:fontFamily="@font/poppins_bold" + android:insetTop="0dp" + android:insetBottom="0dp" + android:padding="8dp" + android:text="@string/cancel" + android:textSize="16sp" + app:cornerRadius="16dp" + app:strokeColor="?attr/colorPrimaryContainer" + tools:ignore="SpeakableTextPresentCheck" /> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -