komikku/app/src/main/java/exh/recs/batch/RecommendationSearchBottomSheetDialog.kt
Tim Schneeberger 9a31ffcc41
feat(recommendation): batch processing for recommendations & sort by relevancy (jobobby04/TachiyomiSY#1383)
* refactor: use NoResultsException

* refactor: cleanup RecommendationPagingSources

* refactor: turn wake/wifi lock functions into reusable extensions

* feat: implement batch recommendation (initial version)

* fix: serialization issues

* fix: wrong source id

* refactor: increase performance using virtual paging

* refactor: update string

* refactor: handle 404 of MD source correctly

* style: add newline

* refactor: create universal throttle manager

* refactor: throttle requests

* chore: remove unused strings

* feat: rank recommendations by match count

* feat: add badges indicating match count to batch recommendations

* fix: handle rec search with no results

* fix: validate flags in pre-search bottom sheet

* feat: implement 'hide library entries' for recommendation search using custom SmartSearchEngine for library items

* style: run spotless

* fix: cancel button

* fix: racing condition causing loss of state

* Avoid runBlocking in a property getter

* Remove unnecessary `synchronized`

* Fixes screen staying on in library tab. (jobobby04/TachiyomiSY#1451)

(cherry picked from commit 254980695bc39fe064e7aeb181ecdbf70c1eff95)

---------

Co-authored-by: Cuong-Tran <cuongtran.tm@gmail.com>
Co-authored-by: NGB-Was-Taken <76197326+NGB-Was-Taken@users.noreply.github.com>
2025-06-12 15:19:34 +07:00

65 lines
2.7 KiB
Kotlin

package exh.recs.batch
import android.view.LayoutInflater
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.viewinterop.AndroidView
import eu.kanade.presentation.components.AdaptiveSheet
import eu.kanade.tachiyomi.databinding.RecommendationSearchBottomSheetBinding
import tachiyomi.domain.UnsortedPreferences
import uy.kohesive.injekt.injectLazy
@Composable
fun RecommendationSearchBottomSheetDialog(
onDismissRequest: () -> Unit,
onSearchRequest: () -> Unit,
) {
val state = remember { RecommendationSearchBottomSheetDialogState(onSearchRequest) }
AdaptiveSheet(onDismissRequest = onDismissRequest) {
AndroidView(
factory = { factoryContext ->
val binding = RecommendationSearchBottomSheetBinding.inflate(LayoutInflater.from(factoryContext))
state.initPreferences(binding)
binding.root
},
modifier = Modifier.fillMaxWidth(),
)
}
}
class RecommendationSearchBottomSheetDialogState(private val onSearchRequest: () -> Unit) {
private val preferences: UnsortedPreferences by injectLazy()
fun initPreferences(binding: RecommendationSearchBottomSheetBinding) {
val flags = preferences.recommendationSearchFlags().get()
binding.recSources.isChecked = SearchFlags.hasIncludeSources(flags)
binding.recTrackers.isChecked = SearchFlags.hasIncludeTrackers(flags)
binding.recHideLibraryEntries.isChecked = SearchFlags.hasHideLibraryResults(flags)
binding.recSources.setOnCheckedChangeListener { _, _ -> setFlags(binding) }
binding.recTrackers.setOnCheckedChangeListener { _, _ -> setFlags(binding) }
binding.recHideLibraryEntries.setOnCheckedChangeListener { _, _ -> setFlags(binding) }
binding.recSearchBtn.setOnClickListener { _ -> onSearchRequest() }
validate(binding)
}
private fun setFlags(binding: RecommendationSearchBottomSheetBinding) {
var flags = 0
if (binding.recSources.isChecked) flags = flags or SearchFlags.INCLUDE_SOURCES
if (binding.recTrackers.isChecked) flags = flags or SearchFlags.INCLUDE_TRACKERS
if (binding.recHideLibraryEntries.isChecked) flags = flags or SearchFlags.HIDE_LIBRARY_RESULTS
preferences.recommendationSearchFlags().set(flags)
validate(binding)
}
private fun validate(binding: RecommendationSearchBottomSheetBinding) {
// Only enable search button if at least one of the checkboxes is checked
binding.recSearchBtn.isEnabled = binding.recSources.isChecked || binding.recTrackers.isChecked
}
}