This commit is contained in:
Koitharu
2023-08-18 12:59:45 +03:00
parent c77cb4cb3c
commit d54d489494
11 changed files with 65 additions and 42 deletions

View File

@@ -8,6 +8,7 @@ import android.view.ViewGroup
import android.view.ViewParent import android.view.ViewParent
import android.view.inputmethod.InputMethodManager import android.view.inputmethod.InputMethodManager
import android.widget.Checkable import android.widget.Checkable
import android.widget.CompoundButton
import androidx.core.view.children import androidx.core.view.children
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import androidx.viewpager2.widget.ViewPager2 import androidx.viewpager2.widget.ViewPager2

View File

@@ -68,6 +68,14 @@ class MangaSourcesRepository @Inject constructor(
} }
} }
suspend fun setSourcesEnabledExclusive(sources: Set<MangaSource>) {
db.withTransaction {
for (s in remoteSources) {
dao.setEnabled(s.name, s in sources)
}
}
}
suspend fun setSourcesEnabled(sources: Iterable<MangaSource>, isEnabled: Boolean) { suspend fun setSourcesEnabled(sources: Iterable<MangaSource>, isEnabled: Boolean) {
db.withTransaction { db.withTransaction {
for (s in sources) { for (s in sources) {

View File

@@ -28,13 +28,13 @@ import org.koitharu.kotatsu.core.ui.widgets.TipView
import org.koitharu.kotatsu.core.util.ext.addMenuProvider import org.koitharu.kotatsu.core.util.ext.addMenuProvider
import org.koitharu.kotatsu.core.util.ext.observe import org.koitharu.kotatsu.core.util.ext.observe
import org.koitharu.kotatsu.core.util.ext.observeEvent import org.koitharu.kotatsu.core.util.ext.observeEvent
import org.koitharu.kotatsu.core.util.ext.scaleUpActivityOptionsOf
import org.koitharu.kotatsu.databinding.FragmentExploreBinding import org.koitharu.kotatsu.databinding.FragmentExploreBinding
import org.koitharu.kotatsu.details.ui.DetailsActivity import org.koitharu.kotatsu.details.ui.DetailsActivity
import org.koitharu.kotatsu.download.ui.list.DownloadsActivity import org.koitharu.kotatsu.download.ui.list.DownloadsActivity
import org.koitharu.kotatsu.explore.ui.adapter.ExploreAdapter import org.koitharu.kotatsu.explore.ui.adapter.ExploreAdapter
import org.koitharu.kotatsu.explore.ui.adapter.ExploreListEventListener import org.koitharu.kotatsu.explore.ui.adapter.ExploreListEventListener
import org.koitharu.kotatsu.explore.ui.model.MangaSourceItem import org.koitharu.kotatsu.explore.ui.model.MangaSourceItem
import org.koitharu.kotatsu.list.ui.adapter.TypedListSpacingDecoration
import org.koitharu.kotatsu.list.ui.model.ListHeader import org.koitharu.kotatsu.list.ui.model.ListHeader
import org.koitharu.kotatsu.list.ui.model.TipModel import org.koitharu.kotatsu.list.ui.model.TipModel
import org.koitharu.kotatsu.parsers.model.Manga import org.koitharu.kotatsu.parsers.model.Manga
@@ -57,7 +57,6 @@ class ExploreFragment :
private val viewModel by viewModels<ExploreViewModel>() private val viewModel by viewModels<ExploreViewModel>()
private var exploreAdapter: ExploreAdapter? = null private var exploreAdapter: ExploreAdapter? = null
private var paddingHorizontal = 0
override val recyclerView: RecyclerView override val recyclerView: RecyclerView
get() = requireViewBinding().recyclerView get() = requireViewBinding().recyclerView
@@ -75,8 +74,7 @@ class ExploreFragment :
adapter = exploreAdapter adapter = exploreAdapter
setHasFixedSize(true) setHasFixedSize(true)
SpanSizeResolver(this, resources.getDimensionPixelSize(R.dimen.explore_grid_width)).attach() SpanSizeResolver(this, resources.getDimensionPixelSize(R.dimen.explore_grid_width)).attach()
val spacing = resources.getDimensionPixelOffset(R.dimen.list_spacing) addItemDecoration(TypedListSpacingDecoration(context))
paddingHorizontal = spacing
} }
addMenuProvider(ExploreMenuProvider(binding.root.context, viewModel)) addMenuProvider(ExploreMenuProvider(binding.root.context, viewModel))
viewModel.content.observe(viewLifecycleOwner) { viewModel.content.observe(viewLifecycleOwner) {
@@ -97,8 +95,9 @@ class ExploreFragment :
} }
override fun onWindowInsetsChanged(insets: Insets) { override fun onWindowInsetsChanged(insets: Insets) {
requireViewBinding().recyclerView.updatePadding( val rv = requireViewBinding().recyclerView
bottom = insets.bottom, rv.updatePadding(
bottom = insets.bottom + rv.paddingTop,
) )
} }

View File

@@ -204,10 +204,11 @@ abstract class MangaListFragment :
} }
override fun onWindowInsetsChanged(insets: Insets) { override fun onWindowInsetsChanged(insets: Insets) {
requireViewBinding().recyclerView.updatePadding( val rv = requireViewBinding().recyclerView
bottom = insets.bottom, rv.updatePadding(
bottom = insets.bottom + rv.paddingTop,
) )
requireViewBinding().recyclerView.fastScroller.updateLayoutParams<MarginLayoutParams> { rv.fastScroller.updateLayoutParams<MarginLayoutParams> {
bottomMargin = insets.bottom bottomMargin = insets.bottom
} }
if (activity is MainActivity) { if (activity is MainActivity) {

View File

@@ -29,7 +29,10 @@ class TypedListSpacingDecoration(
ListItemType.FILTER_TAG -> outRect.set(0) ListItemType.FILTER_TAG -> outRect.set(0)
ListItemType.HEADER -> outRect.set(spacingList, 0, spacingList, 0) ListItemType.HEADER -> outRect.set(spacingList, 0, spacingList, 0)
ListItemType.MANGA_LIST -> outRect.set(spacingList)
ListItemType.EXPLORE_SOURCE_LIST,
ListItemType.MANGA_LIST -> outRect.set(spacingList, 0, spacingList, 0)
ListItemType.DOWNLOAD, ListItemType.DOWNLOAD,
ListItemType.MANGA_LIST_DETAILED -> outRect.set(spacingList) ListItemType.MANGA_LIST_DETAILED -> outRect.set(spacingList)
@@ -43,7 +46,6 @@ class TypedListSpacingDecoration(
ListItemType.STATE_EMPTY, ListItemType.STATE_EMPTY,
ListItemType.EXPLORE_BUTTONS, ListItemType.EXPLORE_BUTTONS,
ListItemType.EXPLORE_SOURCE_GRID, ListItemType.EXPLORE_SOURCE_GRID,
ListItemType.EXPLORE_SOURCE_LIST,
ListItemType.EXPLORE_SUGGESTION, ListItemType.EXPLORE_SUGGESTION,
ListItemType.MANGA_NESTED_GROUP, ListItemType.MANGA_NESTED_GROUP,
null -> outRect.set(0) null -> outRect.set(0)

View File

@@ -107,6 +107,9 @@ class MultiSearchViewModel @Inject constructor(
@CheckResult @CheckResult
private fun searchImpl(q: String): Flow<List<MultiSearchListModel>> = channelFlow { private fun searchImpl(q: String): Flow<List<MultiSearchListModel>> = channelFlow {
val sources = sourcesRepository.getEnabledSources() val sources = sourcesRepository.getEnabledSources()
if (sources.isEmpty()) {
return@channelFlow
}
val semaphore = Semaphore(MAX_PARALLELISM) val semaphore = Semaphore(MAX_PARALLELISM)
for (source in sources) { for (source in sources) {
launch { launch {

View File

@@ -1,6 +1,5 @@
package org.koitharu.kotatsu.settings.onboard package org.koitharu.kotatsu.settings.onboard
import androidx.annotation.WorkerThread
import androidx.core.os.LocaleListCompat import androidx.core.os.LocaleListCompat
import dagger.hilt.android.lifecycle.HiltViewModel import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
@@ -10,9 +9,11 @@ import org.koitharu.kotatsu.core.ui.BaseViewModel
import org.koitharu.kotatsu.core.util.ext.map import org.koitharu.kotatsu.core.util.ext.map
import org.koitharu.kotatsu.core.util.ext.mapToSet import org.koitharu.kotatsu.core.util.ext.mapToSet
import org.koitharu.kotatsu.explore.data.MangaSourcesRepository import org.koitharu.kotatsu.explore.data.MangaSourcesRepository
import org.koitharu.kotatsu.parsers.model.MangaSource
import org.koitharu.kotatsu.parsers.util.mapNotNullToSet import org.koitharu.kotatsu.parsers.util.mapNotNullToSet
import org.koitharu.kotatsu.parsers.util.toTitleCase import org.koitharu.kotatsu.parsers.util.toTitleCase
import org.koitharu.kotatsu.settings.onboard.model.SourceLocale import org.koitharu.kotatsu.settings.onboard.model.SourceLocale
import java.util.EnumSet
import java.util.Locale import java.util.Locale
import javax.inject.Inject import javax.inject.Inject
@@ -43,8 +44,7 @@ class OnboardViewModel @Inject constructor(
repository.getEnabledSources().mapNotNullToSet { x -> x.locale }, repository.getEnabledSources().mapNotNullToSet { x -> x.locale },
) )
} }
rebuildList() commit()
repository.assimilateNewSources()
} }
} }
@@ -58,15 +58,16 @@ class OnboardViewModel @Inject constructor(
val prevJob = updateJob val prevJob = updateJob
updateJob = launchJob(Dispatchers.Default) { updateJob = launchJob(Dispatchers.Default) {
prevJob.join() prevJob.join()
val sources = allSources.filter { x -> x.locale == key } commit()
repository.setSourcesEnabled(sources, isChecked)
rebuildList()
} }
} }
} }
@WorkerThread private suspend fun commit() {
private fun rebuildList() { val enabledSources = allSources.filterTo(EnumSet.noneOf(MangaSource::class.java)) { x ->
x.locale in selectedLocales
}
repository.setSourcesEnabledExclusive(enabledSources)
list.value = locales.map { (key, srcs) -> list.value = locales.map { (key, srcs) ->
val locale = if (key != null) { val locale = if (key != null) {
Locale(key) Locale(key)

View File

@@ -1,5 +1,6 @@
package org.koitharu.kotatsu.settings.onboard.adapter package org.koitharu.kotatsu.settings.onboard.adapter
import android.widget.CompoundButton
import com.hannesdorfmann.adapterdelegates4.dsl.adapterDelegateViewBinding import com.hannesdorfmann.adapterdelegates4.dsl.adapterDelegateViewBinding
import org.koitharu.kotatsu.R import org.koitharu.kotatsu.R
import org.koitharu.kotatsu.core.util.ext.setChecked import org.koitharu.kotatsu.core.util.ext.setChecked
@@ -13,13 +14,16 @@ fun sourceLocaleAD(
{ inflater, parent -> ItemSourceLocaleBinding.inflate(inflater, parent, false) }, { inflater, parent -> ItemSourceLocaleBinding.inflate(inflater, parent, false) },
) { ) {
binding.switchToggle.setOnCheckedChangeListener { _, isChecked -> val checkedChangeListener = CompoundButton.OnCheckedChangeListener { _, isChecked ->
listener.onItemCheckedChanged(item, isChecked) listener.onItemCheckedChanged(item, isChecked)
} }
binding.switchToggle.setOnCheckedChangeListener(checkedChangeListener)
bind { payloads -> bind { payloads ->
binding.textViewTitle.text = item.title ?: getString(R.string.different_languages) binding.textViewTitle.text = item.title ?: getString(R.string.different_languages)
binding.textViewDescription.textAndVisible = item.summary binding.textViewDescription.textAndVisible = item.summary
binding.switchToggle.setOnCheckedChangeListener(null)
binding.switchToggle.setChecked(item.isChecked, payloads.isNotEmpty()) binding.switchToggle.setChecked(item.isChecked, payloads.isNotEmpty())
binding.switchToggle.setOnCheckedChangeListener(checkedChangeListener)
} }
} }

View File

@@ -7,9 +7,6 @@
android:layout_height="match_parent" android:layout_height="match_parent"
android:clipToPadding="false" android:clipToPadding="false"
android:orientation="vertical" android:orientation="vertical"
android:paddingLeft="@dimen/list_spacing" android:padding="@dimen/list_spacing"
android:paddingTop="@dimen/grid_spacing_outer"
android:paddingRight="@dimen/list_spacing"
android:paddingBottom="@dimen/grid_spacing_outer"
android:scrollbars="vertical" android:scrollbars="vertical"
tools:listitem="@layout/item_explore_source_list" /> tools:listitem="@layout/item_explore_source_list" />

View File

@@ -4,8 +4,8 @@
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:paddingHorizontal="8dp" android:paddingHorizontal="@dimen/list_spacing"
android:paddingVertical="4dp"> android:paddingBottom="@dimen/list_spacing">
<com.google.android.material.button.MaterialButton <com.google.android.material.button.MaterialButton
android:id="@+id/button_local" android:id="@+id/button_local"

View File

@@ -1,34 +1,41 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<LinearLayout <androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="?attr/listPreferredItemHeightSmall" android:layout_height="wrap_content"
android:background="@drawable/list_selector" android:background="@drawable/list_selector"
android:clipChildren="false" android:clipChildren="false">
android:gravity="center_vertical"
android:orientation="horizontal"
android:padding="@dimen/list_spacing">
<com.google.android.material.imageview.ShapeableImageView <com.google.android.material.imageview.ShapeableImageView
android:id="@+id/imageView_icon" android:id="@+id/imageView_icon"
android:layout_width="32dp" android:layout_width="40dp"
android:layout_height="32dp" android:layout_height="40dp"
android:background="?colorControlHighlight" android:layout_marginStart="8dp"
android:labelFor="@id/textView_title" android:layout_marginTop="8dp"
android:scaleType="fitCenter" android:layout_marginBottom="8dp"
app:shapeAppearance="?shapeAppearanceCornerSmall" android:background="?colorSurfaceContainer"
android:scaleType="centerCrop"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:shapeAppearanceOverlay="@style/ShapeAppearanceOverlay.Kotatsu.Cover.Small"
tools:src="@tools:sample/backgrounds/scenic" /> tools:src="@tools:sample/backgrounds/scenic" />
<TextView <TextView
android:id="@+id/textView_title" android:id="@+id/textView_title"
android:layout_width="match_parent" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="16dp" android:layout_marginStart="16dp"
android:layout_marginEnd="8dp"
android:ellipsize="end" android:ellipsize="end"
android:singleLine="true" android:singleLine="true"
android:textAppearance="?attr/textAppearanceBodyMedium" android:textAppearance="?attr/textAppearanceBodyLarge"
tools:text="@tools:sample/lorem[2]" /> app:layout_constraintBottom_toBottomOf="@id/imageView_icon"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/imageView_icon"
app:layout_constraintTop_toTopOf="@+id/imageView_icon"
tools:text="@tools:sample/lorem" />
</LinearLayout> </androidx.constraintlayout.widget.ConstraintLayout>