diff --git a/app/src/main/java/org/koitharu/kotatsu/library/LibraryModule.kt b/app/src/main/java/org/koitharu/kotatsu/library/LibraryModule.kt index 972752aa7..514abcfea 100644 --- a/app/src/main/java/org/koitharu/kotatsu/library/LibraryModule.kt +++ b/app/src/main/java/org/koitharu/kotatsu/library/LibraryModule.kt @@ -4,7 +4,7 @@ import org.koin.androidx.viewmodel.dsl.viewModel import org.koin.dsl.module import org.koitharu.kotatsu.library.domain.LibraryRepository import org.koitharu.kotatsu.library.ui.LibraryViewModel -import org.koitharu.kotatsu.library.ui.config.LibraryCategoriesConfigViewModel +import org.koitharu.kotatsu.library.ui.config.categories.LibraryCategoriesConfigViewModel val libraryModule get() = module { diff --git a/app/src/main/java/org/koitharu/kotatsu/library/ui/LibraryMenuProvider.kt b/app/src/main/java/org/koitharu/kotatsu/library/ui/LibraryMenuProvider.kt index 0bce5a7bf..c7947ebf7 100644 --- a/app/src/main/java/org/koitharu/kotatsu/library/ui/LibraryMenuProvider.kt +++ b/app/src/main/java/org/koitharu/kotatsu/library/ui/LibraryMenuProvider.kt @@ -6,14 +6,15 @@ import android.view.MenuInflater import android.view.MenuItem import androidx.core.view.MenuProvider import androidx.fragment.app.FragmentManager +import com.google.android.material.R as materialR import com.google.android.material.dialog.MaterialAlertDialogBuilder -import org.koitharu.kotatsu.R -import org.koitharu.kotatsu.base.ui.dialog.RememberSelectionDialogListener -import org.koitharu.kotatsu.library.ui.config.LibraryCategoriesConfigSheet -import org.koitharu.kotatsu.utils.ext.startOfDay import java.util.* import java.util.concurrent.TimeUnit -import com.google.android.material.R as materialR +import org.koitharu.kotatsu.R +import org.koitharu.kotatsu.base.ui.dialog.RememberSelectionDialogListener +import org.koitharu.kotatsu.library.ui.config.categories.LibraryCategoriesConfigSheet +import org.koitharu.kotatsu.library.ui.config.size.LibrarySizeBottomSheet +import org.koitharu.kotatsu.utils.ext.startOfDay class LibraryMenuProvider( private val context: Context, @@ -31,6 +32,10 @@ class LibraryMenuProvider( showClearHistoryDialog() true } + R.id.action_grid_size -> { + LibrarySizeBottomSheet.show(fragmentManager) + true + } R.id.action_categories -> { LibraryCategoriesConfigSheet.show(fragmentManager) true @@ -64,4 +69,4 @@ class LibraryMenuProvider( viewModel.clearHistory(minDate) }.show() } -} \ No newline at end of file +} diff --git a/app/src/main/java/org/koitharu/kotatsu/library/ui/config/LibraryCategoriesConfigAdapter.kt b/app/src/main/java/org/koitharu/kotatsu/library/ui/config/categories/LibraryCategoriesConfigAdapter.kt similarity index 94% rename from app/src/main/java/org/koitharu/kotatsu/library/ui/config/LibraryCategoriesConfigAdapter.kt rename to app/src/main/java/org/koitharu/kotatsu/library/ui/config/categories/LibraryCategoriesConfigAdapter.kt index 0abdc7535..7610bf597 100644 --- a/app/src/main/java/org/koitharu/kotatsu/library/ui/config/LibraryCategoriesConfigAdapter.kt +++ b/app/src/main/java/org/koitharu/kotatsu/library/ui/config/categories/LibraryCategoriesConfigAdapter.kt @@ -1,4 +1,4 @@ -package org.koitharu.kotatsu.library.ui.config +package org.koitharu.kotatsu.library.ui.config.categories import androidx.recyclerview.widget.DiffUtil import com.hannesdorfmann.adapterdelegates4.AsyncListDifferDelegationAdapter @@ -29,4 +29,4 @@ class LibraryCategoriesConfigAdapter( } else Unit } } -} \ No newline at end of file +} diff --git a/app/src/main/java/org/koitharu/kotatsu/library/ui/config/LibraryCategoriesConfigSheet.kt b/app/src/main/java/org/koitharu/kotatsu/library/ui/config/categories/LibraryCategoriesConfigSheet.kt similarity index 90% rename from app/src/main/java/org/koitharu/kotatsu/library/ui/config/LibraryCategoriesConfigSheet.kt rename to app/src/main/java/org/koitharu/kotatsu/library/ui/config/categories/LibraryCategoriesConfigSheet.kt index a7d793ea3..67c4b9f01 100644 --- a/app/src/main/java/org/koitharu/kotatsu/library/ui/config/LibraryCategoriesConfigSheet.kt +++ b/app/src/main/java/org/koitharu/kotatsu/library/ui/config/categories/LibraryCategoriesConfigSheet.kt @@ -1,4 +1,4 @@ -package org.koitharu.kotatsu.library.ui.config +package org.koitharu.kotatsu.library.ui.config.categories import android.os.Bundle import android.view.LayoutInflater @@ -14,7 +14,9 @@ import org.koitharu.kotatsu.core.model.FavouriteCategory import org.koitharu.kotatsu.databinding.SheetBaseBinding import org.koitharu.kotatsu.utils.BottomSheetToolbarController -class LibraryCategoriesConfigSheet : BaseBottomSheet(), OnListItemClickListener, +class LibraryCategoriesConfigSheet : + BaseBottomSheet(), + OnListItemClickListener, View.OnClickListener { private val viewModel by viewModel() @@ -53,4 +55,4 @@ class LibraryCategoriesConfigSheet : BaseBottomSheet(), OnList fun show(fm: FragmentManager) = LibraryCategoriesConfigSheet().show(fm, TAG) } -} \ No newline at end of file +} diff --git a/app/src/main/java/org/koitharu/kotatsu/library/ui/config/LibraryCategoriesConfigViewModel.kt b/app/src/main/java/org/koitharu/kotatsu/library/ui/config/categories/LibraryCategoriesConfigViewModel.kt similarity index 93% rename from app/src/main/java/org/koitharu/kotatsu/library/ui/config/LibraryCategoriesConfigViewModel.kt rename to app/src/main/java/org/koitharu/kotatsu/library/ui/config/categories/LibraryCategoriesConfigViewModel.kt index 88217c8b2..10259ed90 100644 --- a/app/src/main/java/org/koitharu/kotatsu/library/ui/config/LibraryCategoriesConfigViewModel.kt +++ b/app/src/main/java/org/koitharu/kotatsu/library/ui/config/categories/LibraryCategoriesConfigViewModel.kt @@ -1,4 +1,4 @@ -package org.koitharu.kotatsu.library.ui.config +package org.koitharu.kotatsu.library.ui.config.categories import androidx.lifecycle.viewModelScope import kotlinx.coroutines.Dispatchers @@ -24,4 +24,4 @@ class LibraryCategoriesConfigViewModel( favouritesRepository.updateCategory(category.id, !category.isVisibleInLibrary) } } -} \ No newline at end of file +} diff --git a/app/src/main/java/org/koitharu/kotatsu/library/ui/config/LibraryCategoryAD.kt b/app/src/main/java/org/koitharu/kotatsu/library/ui/config/categories/LibraryCategoryAD.kt similarity index 88% rename from app/src/main/java/org/koitharu/kotatsu/library/ui/config/LibraryCategoryAD.kt rename to app/src/main/java/org/koitharu/kotatsu/library/ui/config/categories/LibraryCategoryAD.kt index 01987d6b1..a482bc11a 100644 --- a/app/src/main/java/org/koitharu/kotatsu/library/ui/config/LibraryCategoryAD.kt +++ b/app/src/main/java/org/koitharu/kotatsu/library/ui/config/categories/LibraryCategoryAD.kt @@ -1,4 +1,4 @@ -package org.koitharu.kotatsu.library.ui.config +package org.koitharu.kotatsu.library.ui.config.categories import com.hannesdorfmann.adapterdelegates4.dsl.adapterDelegateViewBinding import org.koitharu.kotatsu.base.ui.list.AdapterDelegateClickListenerAdapter @@ -9,9 +9,8 @@ import org.koitharu.kotatsu.databinding.ItemCategoryCheckableMultipleBinding fun libraryCategoryAD( listener: OnListItemClickListener, ) = adapterDelegateViewBinding( - { layoutInflater, parent -> ItemCategoryCheckableMultipleBinding.inflate(layoutInflater, parent, false) } + { layoutInflater, parent -> ItemCategoryCheckableMultipleBinding.inflate(layoutInflater, parent, false) }, ) { - val eventListener = AdapterDelegateClickListenerAdapter(this, listener) itemView.setOnClickListener(eventListener) @@ -19,4 +18,4 @@ fun libraryCategoryAD( binding.root.text = item.title binding.root.isChecked = item.isVisibleInLibrary } -} \ No newline at end of file +} diff --git a/app/src/main/java/org/koitharu/kotatsu/library/ui/config/size/LibrarySizeBottomSheet.kt b/app/src/main/java/org/koitharu/kotatsu/library/ui/config/size/LibrarySizeBottomSheet.kt new file mode 100644 index 000000000..a761181f7 --- /dev/null +++ b/app/src/main/java/org/koitharu/kotatsu/library/ui/config/size/LibrarySizeBottomSheet.kt @@ -0,0 +1,63 @@ +package org.koitharu.kotatsu.library.ui.config.size + +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.fragment.app.FragmentManager +import com.google.android.material.slider.LabelFormatter +import com.google.android.material.slider.Slider +import org.koin.android.ext.android.inject +import org.koitharu.kotatsu.R +import org.koitharu.kotatsu.base.ui.BaseBottomSheet +import org.koitharu.kotatsu.core.prefs.AppSettings +import org.koitharu.kotatsu.databinding.SheetLibrarySizeBinding +import org.koitharu.kotatsu.utils.ext.setValueRounded +import org.koitharu.kotatsu.utils.progress.IntPercentLabelFormatter + +class LibrarySizeBottomSheet : + BaseBottomSheet(), + Slider.OnChangeListener, + View.OnClickListener { + + private val settings by inject(mode = LazyThreadSafetyMode.NONE) + private var labelFormatter: LabelFormatter? = null + + override fun onInflateView(inflater: LayoutInflater, container: ViewGroup?): SheetLibrarySizeBinding { + return SheetLibrarySizeBinding.inflate(inflater, container, false) + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + labelFormatter = IntPercentLabelFormatter(view.context) + binding.sliderGrid.addOnChangeListener(this) + binding.buttonSmall.setOnClickListener(this) + binding.buttonLarge.setOnClickListener(this) + + binding.sliderGrid.setValueRounded(settings.gridSize.toFloat()) + } + + override fun onDestroyView() { + labelFormatter = null + super.onDestroyView() + } + + override fun onValueChange(slider: Slider, value: Float, fromUser: Boolean) { + settings.gridSize = value.toInt() + binding.textViewLabel.text = labelFormatter?.getFormattedValue(value) + } + + override fun onClick(v: View) { + when (v.id) { + R.id.button_small -> binding.sliderGrid.value -= binding.sliderGrid.stepSize + R.id.button_large -> binding.sliderGrid.value += binding.sliderGrid.stepSize + } + } + + companion object { + + private const val TAG = "LibrarySizeBottomSheet" + + fun show(fm: FragmentManager) = LibrarySizeBottomSheet().show(fm, TAG) + } +} diff --git a/app/src/main/java/org/koitharu/kotatsu/list/ui/ItemSizeResolver.kt b/app/src/main/java/org/koitharu/kotatsu/list/ui/ItemSizeResolver.kt index bd406a658..443f7021d 100644 --- a/app/src/main/java/org/koitharu/kotatsu/list/ui/ItemSizeResolver.kt +++ b/app/src/main/java/org/koitharu/kotatsu/list/ui/ItemSizeResolver.kt @@ -1,15 +1,85 @@ package org.koitharu.kotatsu.list.ui +import android.content.SharedPreferences import android.content.res.Resources +import android.view.View +import android.widget.TextView +import androidx.annotation.StyleRes +import androidx.core.view.updateLayoutParams +import androidx.lifecycle.DefaultLifecycleObserver +import androidx.lifecycle.LifecycleOwner +import kotlin.math.roundToInt import org.koitharu.kotatsu.R import org.koitharu.kotatsu.core.prefs.AppSettings -import kotlin.math.roundToInt -class ItemSizeResolver(resources: Resources, settings: AppSettings) { +class ItemSizeResolver(resources: Resources, private val settings: AppSettings) { - private val scaleFactor = settings.gridSize / 100f private val gridWidth = resources.getDimension(R.dimen.preferred_grid_width) + private val scaleFactor: Float + get() = settings.gridSize / 100f val cellWidth: Int get() = (gridWidth * scaleFactor).roundToInt() -} \ No newline at end of file + + fun attachToView(lifecycleOwner: LifecycleOwner, view: View, textView: TextView?) { + val observer = SizeObserver(view, textView) + view.addOnAttachStateChangeListener(observer) + lifecycleOwner.lifecycle.addObserver(observer) + if (view.isAttachedToWindow) { + observer.update() + } + } + + private inner class SizeObserver( + private val view: View, + private val textView: TextView?, + ) : DefaultLifecycleObserver, SharedPreferences.OnSharedPreferenceChangeListener, View.OnAttachStateChangeListener { + + private val widthThreshold = view.resources.getDimensionPixelSize(R.dimen.small_grid_width) + + @StyleRes + private var prevTextAppearance = 0 + + override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences?, key: String?) { + if (key == AppSettings.KEY_GRID_SIZE) { + update() + } + } + + override fun onViewAttachedToWindow(v: View?) { + settings.subscribe(this) + update() + } + + override fun onViewDetachedFromWindow(v: View?) { + settings.unsubscribe(this) + } + + override fun onDestroy(owner: LifecycleOwner) { + super.onDestroy(owner) + settings.unsubscribe(this) + view.removeOnAttachStateChangeListener(this) + } + + fun update() { + val newWidth = cellWidth + textView?.adjustTextAppearance(newWidth) + view.updateLayoutParams { + width = newWidth + } + } + + private fun TextView.adjustTextAppearance(width: Int) { + val textAppearanceResId = if (width < widthThreshold) { + R.style.TextAppearance_Kotatsu_GridTitle_Small + } else { + R.style.TextAppearance_Kotatsu_GridTitle + } + if (textAppearanceResId != prevTextAppearance) { + prevTextAppearance = textAppearanceResId + setTextAppearance(textAppearanceResId) + requestLayout() + } + } + } +} diff --git a/app/src/main/java/org/koitharu/kotatsu/list/ui/ListModeSelectDialog.kt b/app/src/main/java/org/koitharu/kotatsu/list/ui/ListModeSelectDialog.kt index a7ae219e8..dfbefb02d 100644 --- a/app/src/main/java/org/koitharu/kotatsu/list/ui/ListModeSelectDialog.kt +++ b/app/src/main/java/org/koitharu/kotatsu/list/ui/ListModeSelectDialog.kt @@ -18,14 +18,16 @@ import org.koitharu.kotatsu.databinding.DialogListModeBinding import org.koitharu.kotatsu.utils.ext.setValueRounded import org.koitharu.kotatsu.utils.progress.IntPercentLabelFormatter -class ListModeSelectDialog : AlertDialogFragment(), - CheckableButtonGroup.OnCheckedChangeListener, Slider.OnSliderTouchListener { +class ListModeSelectDialog : + AlertDialogFragment(), + CheckableButtonGroup.OnCheckedChangeListener, + Slider.OnChangeListener { private val settings by inject(mode = LazyThreadSafetyMode.NONE) override fun onInflateView( inflater: LayoutInflater, - container: ViewGroup? + container: ViewGroup?, ) = DialogListModeBinding.inflate(inflater, container, false) override fun onBuildDialog(builder: MaterialAlertDialogBuilder) { @@ -45,7 +47,7 @@ class ListModeSelectDialog : AlertDialogFragment(), binding.sliderGrid.setLabelFormatter(IntPercentLabelFormatter(view.context)) binding.sliderGrid.setValueRounded(settings.gridSize.toFloat()) - binding.sliderGrid.addOnSliderTouchListener(this) + binding.sliderGrid.addOnChangeListener(this) binding.checkableGroup.onCheckedChangeListener = this } @@ -62,10 +64,10 @@ class ListModeSelectDialog : AlertDialogFragment(), settings.listMode = mode } - override fun onStartTrackingTouch(slider: Slider) = Unit - - override fun onStopTrackingTouch(slider: Slider) { - settings.gridSize = slider.value.toInt() + override fun onValueChange(slider: Slider, value: Float, fromUser: Boolean) { + if (fromUser) { + settings.gridSize = value.toInt() + } } companion object { @@ -74,4 +76,4 @@ class ListModeSelectDialog : AlertDialogFragment(), fun show(fm: FragmentManager) = ListModeSelectDialog().show(fm, TAG) } -} \ No newline at end of file +} diff --git a/app/src/main/java/org/koitharu/kotatsu/list/ui/adapter/MangaGridItemAD.kt b/app/src/main/java/org/koitharu/kotatsu/list/ui/adapter/MangaGridItemAD.kt index 75676e5bf..61328e10e 100644 --- a/app/src/main/java/org/koitharu/kotatsu/list/ui/adapter/MangaGridItemAD.kt +++ b/app/src/main/java/org/koitharu/kotatsu/list/ui/adapter/MangaGridItemAD.kt @@ -1,6 +1,5 @@ package org.koitharu.kotatsu.list.ui.adapter -import androidx.core.view.updateLayoutParams import androidx.lifecycle.LifecycleOwner import coil.ImageLoader import com.google.android.material.badge.BadgeDrawable @@ -24,9 +23,8 @@ fun mangaGridItemAD( clickListener: OnListItemClickListener, sizeResolver: ItemSizeResolver?, ) = adapterDelegateViewBinding( - { inflater, parent -> ItemMangaGridBinding.inflate(inflater, parent, false) } + { inflater, parent -> ItemMangaGridBinding.inflate(inflater, parent, false) }, ) { - var badge: BadgeDrawable? = null itemView.setOnClickListener { @@ -35,11 +33,7 @@ fun mangaGridItemAD( itemView.setOnLongClickListener { clickListener.onItemLongClick(item.manga, it) } - if (sizeResolver != null) { - itemView.updateLayoutParams { - width = sizeResolver.cellWidth - } - } + sizeResolver?.attachToView(lifecycleOwner, itemView, binding.textViewTitle) bind { payloads -> binding.textViewTitle.text = item.title @@ -62,4 +56,4 @@ fun mangaGridItemAD( badge = null binding.imageViewCover.disposeImageRequest() } -} \ No newline at end of file +} diff --git a/app/src/main/java/org/koitharu/kotatsu/utils/progress/IntPercentLabelFormatter.kt b/app/src/main/java/org/koitharu/kotatsu/utils/progress/IntPercentLabelFormatter.kt index 5456ae5b0..d9f4ff533 100644 --- a/app/src/main/java/org/koitharu/kotatsu/utils/progress/IntPercentLabelFormatter.kt +++ b/app/src/main/java/org/koitharu/kotatsu/utils/progress/IntPercentLabelFormatter.kt @@ -9,4 +9,4 @@ class IntPercentLabelFormatter(context: Context) : LabelFormatter { private val pattern = context.getString(R.string.percent_string_pattern) override fun getFormattedValue(value: Float) = pattern.format(value.toInt().toString()) -} \ No newline at end of file +} diff --git a/app/src/main/res/drawable/ic_size_large.xml b/app/src/main/res/drawable/ic_size_large.xml new file mode 100644 index 000000000..feb4a5b73 --- /dev/null +++ b/app/src/main/res/drawable/ic_size_large.xml @@ -0,0 +1,12 @@ + + + + diff --git a/app/src/main/res/drawable/ic_size_small.xml b/app/src/main/res/drawable/ic_size_small.xml new file mode 100644 index 000000000..4d4a819be --- /dev/null +++ b/app/src/main/res/drawable/ic_size_small.xml @@ -0,0 +1,12 @@ + + + + diff --git a/app/src/main/res/layout/sheet_library_size.xml b/app/src/main/res/layout/sheet_library_size.xml new file mode 100644 index 000000000..9d6f52186 --- /dev/null +++ b/app/src/main/res/layout/sheet_library_size.xml @@ -0,0 +1,83 @@ + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/menu/opt_library.xml b/app/src/main/res/menu/opt_library.xml index a8f3ed456..dd0b59de8 100644 --- a/app/src/main/res/menu/opt_library.xml +++ b/app/src/main/res/menu/opt_library.xml @@ -10,10 +10,16 @@ android:title="@string/categories_" app:showAsAction="never" /> + + - \ No newline at end of file + diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml index e6099a290..883339de0 100644 --- a/app/src/main/res/values/dimens.xml +++ b/app/src/main/res/values/dimens.xml @@ -17,6 +17,7 @@ 4dp 48dp 120dp + 92dp 48dp 36dp 48dp @@ -59,4 +60,4 @@ 6dp 6dp - \ No newline at end of file + diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index ac32429e6..e2a792737 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -198,6 +198,15 @@ ?attr/colorPrimary + +