Open Library display options in main library settings

Also converting more rxprefs to flow prefs
This commit is contained in:
Jays2Kings 2021-04-16 15:03:24 -04:00
parent 91743c056d
commit 5d2a0feb5f
15 changed files with 129 additions and 72 deletions

View File

@ -192,7 +192,7 @@ class PreferencesHelper(val context: Context) {
fun lastVersionCode() = rxPrefs.getInteger("last_version_code", 0) fun lastVersionCode() = rxPrefs.getInteger("last_version_code", 0)
fun browseAsList() = rxPrefs.getBoolean(Keys.catalogueAsList, false) fun browseAsList() = flowPrefs.getBoolean(Keys.catalogueAsList, false)
fun enabledLanguages() = flowPrefs.getStringSet(Keys.enabledLanguages, setOf("en", Locale.getDefault().language)) fun enabledLanguages() = flowPrefs.getStringSet(Keys.enabledLanguages, setOf("en", Locale.getDefault().language))
@ -240,11 +240,11 @@ class PreferencesHelper(val context: Context) {
fun libraryUpdatePrioritization() = rxPrefs.getInteger(Keys.libraryUpdatePrioritization, 0) fun libraryUpdatePrioritization() = rxPrefs.getInteger(Keys.libraryUpdatePrioritization, 0)
fun libraryLayout() = rxPrefs.getInteger(Keys.libraryLayout, 2) fun libraryLayout() = flowPrefs.getInt(Keys.libraryLayout, 2)
fun gridSize() = rxPrefs.getInteger(Keys.gridSize, 2) fun gridSize() = flowPrefs.getInt(Keys.gridSize, 2)
fun uniformGrid() = rxPrefs.getBoolean(Keys.uniformGrid, true) fun uniformGrid() = flowPrefs.getBoolean(Keys.uniformGrid, true)
fun chaptersDescAsDefault() = rxPrefs.getBoolean("chapters_desc_as_default", true) fun chaptersDescAsDefault() = rxPrefs.getBoolean("chapters_desc_as_default", true)
@ -329,7 +329,7 @@ class PreferencesHelper(val context: Context) {
fun lastAppCheck() = flowPrefs.getLong("last_app_check", 0) fun lastAppCheck() = flowPrefs.getLong("last_app_check", 0)
fun unreadBadgeType() = rxPrefs.getInteger("unread_badge_type", 2) fun unreadBadgeType() = flowPrefs.getInt("unread_badge_type", 2)
fun hideStartReadingButton() = rxPrefs.getBoolean("hide_reading_button", false) fun hideStartReadingButton() = rxPrefs.getBoolean("hide_reading_button", false)

View File

@ -104,6 +104,9 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job import kotlinx.coroutines.Job
import kotlinx.coroutines.cancel import kotlinx.coroutines.cancel
import kotlinx.coroutines.delay import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.drop
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get import uy.kohesive.injekt.api.get
import kotlin.math.abs import kotlin.math.abs
@ -143,7 +146,7 @@ class LibraryController(
*/ */
private var actionMode: ActionMode? = null private var actionMode: ActionMode? = null
private var libraryLayout: Int = preferences.libraryLayout().getOrDefault() private var libraryLayout: Int = preferences.libraryLayout().get()
var singleCategory: Boolean = false var singleCategory: Boolean = false
private set private set
@ -469,6 +472,7 @@ class LibraryController(
} }
setupFilterSheet() setupFilterSheet()
setUpHopper() setUpHopper()
setPreferenceFlows()
elevateAppBar = elevateAppBar =
scrollViewWith( scrollViewWith(
@ -497,8 +501,24 @@ class LibraryController(
updateHopperY() updateHopperY()
} }
} }
binding.swipeRefresh.setOnRefreshListener { setSwipeRefresh()
binding.swipeRefresh.isRefreshing = false
if (selectedMangas.isNotEmpty()) {
createActionModeIfNeeded()
}
presenter.onRestore()
if (presenter.libraryItems.isNotEmpty()) {
presenter.restoreLibrary()
} else {
binding.recyclerLayout.alpha = 0f
presenter.getLibrary()
}
}
private fun setSwipeRefresh() = with(binding.swipeRefresh) {
setOnRefreshListener {
isRefreshing = false
if (!LibraryUpdateService.isRunning()) { if (!LibraryUpdateService.isRunning()) {
when { when {
!presenter.showAllCategories && presenter.groupType == BY_DEFAULT -> { !presenter.showAllCategories && presenter.groupType == BY_DEFAULT -> {
@ -514,11 +534,11 @@ class LibraryController(
.negativeButton(android.R.string.cancel) .negativeButton(android.R.string.cancel)
.listItemsSingleChoice( .listItemsSingleChoice(
items = listOf( items = listOf(
view.context.getString( context.getString(
R.string.top_category, R.string.top_category,
presenter.allCategories.first().name presenter.allCategories.first().name
), ),
view.context.getString( context.getString(
R.string.categories_in_global_update R.string.categories_in_global_update
) )
), ),
@ -540,18 +560,6 @@ class LibraryController(
} }
} }
} }
if (selectedMangas.isNotEmpty()) {
createActionModeIfNeeded()
}
presenter.onRestore()
if (presenter.libraryItems.isNotEmpty()) {
presenter.restoreLibrary()
} else {
binding.recyclerLayout.alpha = 0f
presenter.getLibrary()
}
} }
private fun setupFilterSheet() { private fun setupFilterSheet() {
@ -786,7 +794,7 @@ class LibraryController(
end = 0 end = 0
) )
} else { } else {
binding.libraryGridRecycler.recycler.columnWidth = when (preferences.gridSize().getOrDefault()) { binding.libraryGridRecycler.recycler.columnWidth = when (preferences.gridSize().get()) {
1 -> 1f 1 -> 1f
2 -> 1.25f 2 -> 1.25f
3 -> 1.66f 3 -> 1.66f
@ -800,6 +808,17 @@ class LibraryController(
} }
} }
private fun setPreferenceFlows() {
listOf(preferences.libraryLayout(), preferences.uniformGrid(), preferences.gridSize(), preferences.unreadBadgeType()).forEach {
it.asFlow()
.drop(1)
.onEach {
reattachAdapter()
}
.launchIn(scope)
}
}
override fun onChangeStarted(handler: ControllerChangeHandler, type: ControllerChangeType) { override fun onChangeStarted(handler: ControllerChangeHandler, type: ControllerChangeType) {
super.onChangeStarted(handler, type) super.onChangeStarted(handler, type)
if (type.isEnter) { if (type.isEnter) {
@ -1049,7 +1068,7 @@ class LibraryController(
} }
fun reattachAdapter() { fun reattachAdapter() {
libraryLayout = preferences.libraryLayout().getOrDefault() libraryLayout = preferences.libraryLayout().get()
setRecyclerLayout() setRecyclerLayout()
val position = val position =
(binding.libraryGridRecycler.recycler.layoutManager as LinearLayoutManager).findFirstVisibleItemPosition() (binding.libraryGridRecycler.recycler.layoutManager as LinearLayoutManager).findFirstVisibleItemPosition()

View File

@ -37,10 +37,10 @@ class LibraryItem(
var unreadType = 2 var unreadType = 2
private val uniformSize: Boolean private val uniformSize: Boolean
get() = preferences.uniformGrid().getOrDefault() get() = preferences.uniformGrid().get()
private val libraryLayout: Int private val libraryLayout: Int
get() = preferences.libraryLayout().getOrDefault() get() = preferences.libraryLayout().get()
val hideReadingButton: Boolean val hideReadingButton: Boolean
get() = preferences.hideStartReadingButton().getOrDefault() get() = preferences.hideStartReadingButton().getOrDefault()

View File

@ -325,7 +325,7 @@ class LibraryPresenter(
} }
private fun setUnreadBadge(itemList: List<LibraryItem>) { private fun setUnreadBadge(itemList: List<LibraryItem>) {
val unreadType = preferences.unreadBadgeType().getOrDefault() val unreadType = preferences.unreadBadgeType().get()
for (item in itemList) { for (item in itemList) {
item.unreadType = unreadType item.unreadType = unreadType
} }

View File

@ -12,13 +12,11 @@ class LibraryBadgesView @JvmOverloads constructor(context: Context, attrs: Attri
override fun inflateBinding() = LibraryBadgesLayoutBinding.bind(this) override fun inflateBinding() = LibraryBadgesLayoutBinding.bind(this)
override fun initGeneralPreferences() { override fun initGeneralPreferences() {
binding.unreadBadgeGroup.bindToPreference(preferences.unreadBadgeType()) { binding.unreadBadgeGroup.bindToPreference(preferences.unreadBadgeType()) {
controller.presenter.requestUnreadBadgesUpdate() controller?.presenter?.requestUnreadBadgesUpdate()
}
binding.hideReading.bindToPreference(preferences.hideStartReadingButton()) {
controller.reattachAdapter()
} }
binding.hideReading.bindToPreference(preferences.hideStartReadingButton())
binding.downloadBadge.bindToPreference(preferences.downloadBadge()) { binding.downloadBadge.bindToPreference(preferences.downloadBadge()) {
controller.presenter.requestDownloadBadgesUpdate() controller?.presenter?.requestDownloadBadgesUpdate()
} }
} }
} }

View File

@ -26,12 +26,12 @@ class LibraryCategoryView @JvmOverloads constructor(context: Context, attrs: Att
override fun initGeneralPreferences() { override fun initGeneralPreferences() {
with(binding) { with(binding) {
showAll.bindToPreference(preferences.showAllCategories()) { showAll.bindToPreference(preferences.showAllCategories()) {
controller.presenter.getLibrary() controller?.presenter?.getLibrary()
binding.categoryShow.isEnabled = it binding.categoryShow.isEnabled = it
} }
categoryShow.isEnabled = showAll.isChecked categoryShow.isEnabled = showAll.isChecked
categoryShow.bindToPreference(preferences.showCategoryInTitle()) { categoryShow.bindToPreference(preferences.showCategoryInTitle()) {
controller.showMiniBar() controller?.showMiniBar()
} }
val hideHopper = min( val hideHopper = min(
2, 2,
@ -42,15 +42,15 @@ class LibraryCategoryView @JvmOverloads constructor(context: Context, attrs: Att
hideHopperSpinner.onItemSelectedListener = { hideHopperSpinner.onItemSelectedListener = {
preferences.hideHopper().set(it == 2) preferences.hideHopper().set(it == 2)
preferences.autohideHopper().set(it == 1) preferences.autohideHopper().set(it == 1)
controller.hideHopper(it == 2) controller?.hideHopper(it == 2)
controller.resetHopperY() controller?.resetHopperY()
} }
addCategoriesButton.setOnClickListener { addCategoriesButton.setOnClickListener {
controller.showCategoriesController() controller?.showCategoriesController()
} }
expandCollapseCategories.setOnClickListener { expandCollapseCategories.setOnClickListener {
controller.binding.filterBottomSheet.root controller?.binding?.filterBottomSheet?.root
.onGroupClicked(FilterBottomSheet.ACTION_EXPAND_COLLAPSE_ALL) ?.onGroupClicked?.invoke(FilterBottomSheet.ACTION_EXPAND_COLLAPSE_ALL)
} }
hopperLongPress.bindToPreference(preferences.hopperLongPressAction()) hopperLongPress.bindToPreference(preferences.hopperLongPressAction())

View File

@ -11,14 +11,8 @@ class LibraryDisplayView @JvmOverloads constructor(context: Context, attrs: Attr
override fun inflateBinding() = LibraryDisplayLayoutBinding.bind(this) override fun inflateBinding() = LibraryDisplayLayoutBinding.bind(this)
override fun initGeneralPreferences() { override fun initGeneralPreferences() {
binding.displayGroup.bindToPreference(preferences.libraryLayout()) { binding.displayGroup.bindToPreference(preferences.libraryLayout())
controller.reattachAdapter() binding.uniformGrid.bindToPreference(preferences.uniformGrid())
} binding.gridSizeToggleGroup.bindToPreference(preferences.gridSize())
binding.uniformGrid.bindToPreference(preferences.uniformGrid()) {
controller.reattachAdapter()
}
binding.gridSizeToggleGroup.bindToPreference(preferences.gridSize()) {
controller.reattachAdapter()
}
} }
} }

View File

@ -3,6 +3,8 @@ package eu.kanade.tachiyomi.ui.library.display
import android.view.View import android.view.View
import android.view.View.inflate import android.view.View.inflate
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import androidx.core.view.isVisible
import com.bluelinelabs.conductor.Controller
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.preference.PreferencesHelper import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.data.preference.getOrDefault import eu.kanade.tachiyomi.data.preference.getOrDefault
@ -15,7 +17,7 @@ import eu.kanade.tachiyomi.widget.TabbedBottomSheetDialog
import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get import uy.kohesive.injekt.api.get
open class TabbedLibraryDisplaySheet(val controller: LibraryController) : open class TabbedLibraryDisplaySheet(val controller: Controller) :
TabbedBottomSheetDialog(controller.activity!!) { TabbedBottomSheetDialog(controller.activity!!) {
private val displayView: LibraryDisplayView = inflate(controller.activity!!, R.layout.library_display_layout, null) as LibraryDisplayView private val displayView: LibraryDisplayView = inflate(controller.activity!!, R.layout.library_display_layout, null) as LibraryDisplayView
@ -23,10 +25,12 @@ open class TabbedLibraryDisplaySheet(val controller: LibraryController) :
private val categoryView: LibraryCategoryView = inflate(controller.activity!!, R.layout.library_category_layout, null) as LibraryCategoryView private val categoryView: LibraryCategoryView = inflate(controller.activity!!, R.layout.library_category_layout, null) as LibraryCategoryView
init { init {
displayView.controller = controller (controller as? LibraryController)?.let { libraryController ->
badgesView.controller = controller displayView.controller = libraryController
categoryView.controller = controller badgesView.controller = libraryController
binding.menu.visible() categoryView.controller = libraryController
}
binding.menu.isVisible = controller !is SettingsLibraryController
binding.menu.compatToolTipText = context.getString(R.string.more_library_settings) binding.menu.compatToolTipText = context.getString(R.string.more_library_settings)
binding.menu.setImageDrawable( binding.menu.setImageDrawable(
ContextCompat.getDrawable( ContextCompat.getDrawable(
@ -39,11 +43,16 @@ open class TabbedLibraryDisplaySheet(val controller: LibraryController) :
dismiss() dismiss()
} }
setExpandText( if (controller is LibraryController) {
!controller.singleCategory && controller.presenter.showAllCategories, setExpandText(
Injekt.get<PreferencesHelper>().collapsedCategories().getOrDefault().isNotEmpty(), !controller.singleCategory && controller.presenter.showAllCategories,
false Injekt.get<PreferencesHelper>().collapsedCategories().getOrDefault().isNotEmpty(),
) false
)
} else {
setExpandText(showExpanded = false, allExpanded = false)
categoryView.binding.addCategoriesButton.isVisible = false
}
} }
fun setExpandText(showExpanded: Boolean, allExpanded: Boolean, animated: Boolean = true) { fun setExpandText(showExpanded: Boolean, allExpanded: Boolean, animated: Boolean = true) {
@ -53,7 +62,7 @@ open class TabbedLibraryDisplaySheet(val controller: LibraryController) :
override fun dismiss() { override fun dismiss() {
super.dismiss() super.dismiss()
controller.displaySheet = null (controller as? LibraryController)?.displaySheet = null
} }
override fun getTabViews(): List<View> = listOf( override fun getTabViews(): List<View> = listOf(

View File

@ -7,6 +7,7 @@ import eu.kanade.tachiyomi.data.database.DatabaseHelper
import eu.kanade.tachiyomi.data.database.models.Category import eu.kanade.tachiyomi.data.database.models.Category
import eu.kanade.tachiyomi.data.library.LibraryUpdateJob import eu.kanade.tachiyomi.data.library.LibraryUpdateJob
import eu.kanade.tachiyomi.ui.category.CategoryController import eu.kanade.tachiyomi.ui.category.CategoryController
import eu.kanade.tachiyomi.ui.library.display.TabbedLibraryDisplaySheet
import eu.kanade.tachiyomi.util.view.withFadeTransaction import eu.kanade.tachiyomi.util.view.withFadeTransaction
import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get import uy.kohesive.injekt.api.get
@ -26,6 +27,17 @@ class SettingsLibraryController : SettingsController() {
summaryRes = R.string.when_sorting_ignore_articles summaryRes = R.string.when_sorting_ignore_articles
defaultValue = false defaultValue = false
} }
preference {
key = "library_display_options"
isPersistent = false
titleRes = R.string.display_options
summaryRes = R.string.can_be_found_in_library_filters
onClick {
TabbedLibraryDisplaySheet(this@SettingsLibraryController).show()
}
}
} }
val dbCategories = db.getCategories().executeAsBlocking() val dbCategories = db.getCategories().executeAsBlocking()
@ -34,6 +46,7 @@ class SettingsLibraryController : SettingsController() {
titleRes = R.string.categories titleRes = R.string.categories
preference { preference {
key = "edit_categories" key = "edit_categories"
isPersistent = false
val catCount = db.getCategories().executeAsBlocking().size val catCount = db.getCategories().executeAsBlocking().size
titleRes = if (catCount > 0) R.string.edit_categories else R.string.add_categories titleRes = if (catCount > 0) R.string.edit_categories else R.string.add_categories
if (catCount > 0) summary = context.resources.getQuantityString(R.plurals.category_plural, catCount, catCount) if (catCount > 0) summary = context.resources.getQuantityString(R.plurals.category_plural, catCount, catCount)

View File

@ -18,7 +18,6 @@ import eu.davidea.flexibleadapter.items.IFlexible
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.database.models.Manga import eu.kanade.tachiyomi.data.database.models.Manga
import eu.kanade.tachiyomi.data.preference.PreferencesHelper import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.data.preference.getOrDefault
import eu.kanade.tachiyomi.databinding.BrowseSourceControllerBinding import eu.kanade.tachiyomi.databinding.BrowseSourceControllerBinding
import eu.kanade.tachiyomi.source.CatalogueSource import eu.kanade.tachiyomi.source.CatalogueSource
import eu.kanade.tachiyomi.source.LocalSource import eu.kanade.tachiyomi.source.LocalSource
@ -168,7 +167,7 @@ open class BrowseSourceController(bundle: Bundle) :
} }
} else { } else {
(binding.catalogueView.inflate(R.layout.manga_recycler_autofit) as AutofitRecyclerView).apply { (binding.catalogueView.inflate(R.layout.manga_recycler_autofit) as AutofitRecyclerView).apply {
columnWidth = when (preferences.gridSize().getOrDefault()) { columnWidth = when (preferences.gridSize().get()) {
1 -> 1f 1 -> 1f
2 -> 1.25f 2 -> 1.25f
3 -> 1.66f 3 -> 1.66f

View File

@ -8,13 +8,12 @@ import android.widget.ImageView
import androidx.constraintlayout.widget.ConstraintLayout import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import com.f2prateek.rx.preferences.Preference import com.tfcporciuncula.flow.Preference
import eu.davidea.flexibleadapter.FlexibleAdapter import eu.davidea.flexibleadapter.FlexibleAdapter
import eu.davidea.flexibleadapter.items.AbstractFlexibleItem import eu.davidea.flexibleadapter.items.AbstractFlexibleItem
import eu.davidea.flexibleadapter.items.IFlexible import eu.davidea.flexibleadapter.items.IFlexible
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.database.models.Manga import eu.kanade.tachiyomi.data.database.models.Manga
import eu.kanade.tachiyomi.data.preference.getOrDefault
import eu.kanade.tachiyomi.databinding.MangaGridItemBinding import eu.kanade.tachiyomi.databinding.MangaGridItemBinding
import eu.kanade.tachiyomi.util.system.dpToPx import eu.kanade.tachiyomi.util.system.dpToPx
import eu.kanade.tachiyomi.util.view.updateLayoutParams import eu.kanade.tachiyomi.util.view.updateLayoutParams
@ -28,7 +27,7 @@ class BrowseSourceItem(
AbstractFlexibleItem<BrowseSourceHolder>() { AbstractFlexibleItem<BrowseSourceHolder>() {
override fun getLayoutRes(): Int { override fun getLayoutRes(): Int {
return if (catalogueAsList.getOrDefault()) { return if (catalogueAsList.get()) {
R.layout.manga_list_item R.layout.manga_list_item
} else { } else {
R.layout.manga_grid_item R.layout.manga_grid_item
@ -37,8 +36,8 @@ class BrowseSourceItem(
override fun createViewHolder(view: View, adapter: FlexibleAdapter<IFlexible<RecyclerView.ViewHolder>>): BrowseSourceHolder { override fun createViewHolder(view: View, adapter: FlexibleAdapter<IFlexible<RecyclerView.ViewHolder>>): BrowseSourceHolder {
val parent = adapter.recyclerView val parent = adapter.recyclerView
return if (parent is AutofitRecyclerView && !catalogueAsList.getOrDefault()) { return if (parent is AutofitRecyclerView && !catalogueAsList.get()) {
val listType = catalogueListType.getOrDefault() val listType = catalogueListType.get()
view.apply { view.apply {
val binding = MangaGridItemBinding.bind(this) val binding = MangaGridItemBinding.bind(this)
val coverHeight = (parent.itemWidth / 3 * 4f).toInt() val coverHeight = (parent.itemWidth / 3 * 4f).toInt()

View File

@ -28,6 +28,12 @@ import eu.kanade.tachiyomi.ui.source.filter.TextItem
import eu.kanade.tachiyomi.ui.source.filter.TextSectionItem import eu.kanade.tachiyomi.ui.source.filter.TextSectionItem
import eu.kanade.tachiyomi.ui.source.filter.TriStateItem import eu.kanade.tachiyomi.ui.source.filter.TriStateItem
import eu.kanade.tachiyomi.ui.source.filter.TriStateSectionItem import eu.kanade.tachiyomi.ui.source.filter.TriStateSectionItem
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.cancel
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import rx.Observable import rx.Observable
import rx.Subscription import rx.Subscription
import rx.android.schedulers.AndroidSchedulers import rx.android.schedulers.AndroidSchedulers
@ -109,6 +115,8 @@ open class BrowseSourcePresenter(
*/ */
private var initializerSubscription: Subscription? = null private var initializerSubscription: Subscription? = null
private var scope = CoroutineScope(Job() + Dispatchers.IO)
override fun onCreate(savedState: Bundle?) { override fun onCreate(savedState: Bundle?) {
super.onCreate(savedState) super.onCreate(savedState)
@ -118,14 +126,18 @@ open class BrowseSourcePresenter(
query = savedState.getString(::query.name, "") query = savedState.getString(::query.name, "")
} }
add( prefs.browseAsList().asFlow()
prefs.browseAsList().asObservable() .onEach { setDisplayMode(it) }
.subscribe { setDisplayMode(it) } .launchIn(scope)
)
restartPager() restartPager()
} }
override fun onDestroy() {
super.onDestroy()
scope.cancel()
}
override fun onSave(state: Bundle) { override fun onSave(state: Bundle) {
state.putString(::query.name, query) state.putString(::query.name, query)
super.onSave(state) super.onSave(state)

View File

@ -87,6 +87,18 @@ fun RadioGroup.bindToPreference(pref: Preference<Int>, block: (() -> Unit)? = nu
} }
} }
/**
* Binds a radio group with a int preference.
*/
fun RadioGroup.bindToPreference(pref: com.tfcporciuncula.flow.Preference<Int>, block: (() -> Unit)? = null) {
(getChildAt(pref.get()) as RadioButton).isChecked = true
setOnCheckedChangeListener { _, checkedId ->
val index = indexOfChild(findViewById(checkedId))
pref.set(index)
block?.invoke()
}
}
/** /**
* Binds a spinner to an int preference with an optional offset for the value. * Binds a spinner to an int preference with an optional offset for the value.
*/ */

View File

@ -13,7 +13,8 @@ import uy.kohesive.injekt.injectLazy
abstract class BaseTabbedScrollView<VB : ViewBinding> @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) : abstract class BaseTabbedScrollView<VB : ViewBinding> @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) :
NestedScrollView(context, attrs) { NestedScrollView(context, attrs) {
protected lateinit var binding: VB lateinit var binding: VB
private set
init { init {
clipToPadding = false clipToPadding = false
} }
@ -32,7 +33,7 @@ abstract class BaseTabbedScrollView<VB : ViewBinding> @JvmOverloads constructor(
abstract class BaseLibraryDisplayView<VB : ViewBinding> @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) : abstract class BaseLibraryDisplayView<VB : ViewBinding> @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) :
BaseTabbedScrollView<VB>(context, attrs) { BaseTabbedScrollView<VB>(context, attrs) {
lateinit var controller: LibraryController var controller: LibraryController? = null
} }
abstract class BaseReaderSettingsView<VB : ViewBinding> @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) : abstract class BaseReaderSettingsView<VB : ViewBinding> @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) :

View File

@ -146,6 +146,7 @@
<!-- Library Display --> <!-- Library Display -->
<string name="display_options">Display options</string> <string name="display_options">Display options</string>
<string name="can_be_found_in_library_filters">Can also be found by expanding library filters</string>
<string name="list">List</string> <string name="list">List</string>
<string name="comfortable_grid">Comfortable Grid</string> <string name="comfortable_grid">Comfortable Grid</string>
<string name="compact_grid">Compact Grid</string> <string name="compact_grid">Compact Grid</string>