Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
10c03ff01a | ||
|
|
e85b9db118 | ||
|
|
f6b0a7c780 |
4
.github/ISSUE_TEMPLATE/report_issue.yml
vendored
4
.github/ISSUE_TEMPLATE/report_issue.yml
vendored
@@ -44,7 +44,7 @@ body:
|
||||
label: Kotatsu version
|
||||
description: You can find your Kotatsu version in **Settings → About**.
|
||||
placeholder: |
|
||||
Example: "3.2.2"
|
||||
Example: "3.2.3"
|
||||
validations:
|
||||
required: true
|
||||
|
||||
@@ -87,7 +87,7 @@ body:
|
||||
required: true
|
||||
- label: If this is an issue with a source, I should be opening an issue in the [parsers repository](https://github.com/nv95/kotatsu-parsers/issues/new).
|
||||
required: true
|
||||
- label: I have updated the app to version **[3.2.2](https://github.com/nv95/Kotatsu/releases/latest)**.
|
||||
- label: I have updated the app to version **[3.2.3](https://github.com/nv95/Kotatsu/releases/latest)**.
|
||||
required: true
|
||||
- label: I will fill out all of the requested information in this form.
|
||||
required: true
|
||||
2
.github/ISSUE_TEMPLATE/request_feature.yml
vendored
2
.github/ISSUE_TEMPLATE/request_feature.yml
vendored
@@ -33,7 +33,7 @@ body:
|
||||
required: true
|
||||
- label: If this is an issue with a source, I should be opening an issue in the [parsers repository](https://github.com/nv95/kotatsu-parsers/issues/new).
|
||||
required: true
|
||||
- label: I have updated the app to version **[3.2.2](https://github.com/nv95/Kotatsu/releases/latest)**.
|
||||
- label: I have updated the app to version **[3.2.3](https://github.com/nv95/Kotatsu/releases/latest)**.
|
||||
required: true
|
||||
- label: I will fill out all of the requested information in this form.
|
||||
required: true
|
||||
@@ -14,8 +14,8 @@ android {
|
||||
applicationId 'org.koitharu.kotatsu'
|
||||
minSdkVersion 21
|
||||
targetSdkVersion 32
|
||||
versionCode 406
|
||||
versionName '3.2.2'
|
||||
versionCode 407
|
||||
versionName '3.2.3'
|
||||
generatedDensities = []
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
|
||||
@@ -65,7 +65,7 @@ android {
|
||||
}
|
||||
dependencies {
|
||||
implementation fileTree(dir: 'libs', include: ['*.jar', '*.aar'])
|
||||
implementation('com.github.nv95:kotatsu-parsers:b495e5e457') {
|
||||
implementation('com.github.nv95:kotatsu-parsers:05a93e2380') {
|
||||
exclude group: 'org.json', module: 'json'
|
||||
}
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ abstract class FavouriteCategoriesDao {
|
||||
abstract fun observeAll(): Flow<List<FavouriteCategoryEntity>>
|
||||
|
||||
@Query("SELECT * FROM favourite_categories WHERE category_id = :id")
|
||||
abstract fun observe(id: Long): Flow<FavouriteCategoryEntity>
|
||||
abstract fun observe(id: Long): Flow<FavouriteCategoryEntity?>
|
||||
|
||||
@Insert(onConflict = OnConflictStrategy.ABORT)
|
||||
abstract suspend fun insert(category: FavouriteCategoryEntity): Long
|
||||
|
||||
@@ -1,10 +1,7 @@
|
||||
package org.koitharu.kotatsu.favourites.domain
|
||||
|
||||
import androidx.room.withTransaction
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||
import kotlinx.coroutines.flow.flatMapLatest
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.flow.*
|
||||
import org.koitharu.kotatsu.core.db.MangaDatabase
|
||||
import org.koitharu.kotatsu.core.db.entity.*
|
||||
import org.koitharu.kotatsu.core.model.FavouriteCategory
|
||||
@@ -48,6 +45,11 @@ class FavouritesRepository(private val db: MangaDatabase) {
|
||||
}.distinctUntilChanged()
|
||||
}
|
||||
|
||||
fun observeCategory(id: Long): Flow<FavouriteCategory?> {
|
||||
return db.favouriteCategoriesDao.observe(id)
|
||||
.map { it?.toFavouriteCategory() }
|
||||
}
|
||||
|
||||
fun observeCategories(mangaId: Long): Flow<List<FavouriteCategory>> {
|
||||
return db.favouritesDao.observe(mangaId).map { entity ->
|
||||
entity?.categories?.map { it.toFavouriteCategory() }.orEmpty()
|
||||
@@ -121,6 +123,7 @@ class FavouritesRepository(private val db: MangaDatabase) {
|
||||
|
||||
private fun observeOrder(categoryId: Long): Flow<SortOrder> {
|
||||
return db.favouriteCategoriesDao.observe(categoryId)
|
||||
.filterNotNull()
|
||||
.map { x -> SortOrder(x.order, SortOrder.NEWEST) }
|
||||
.distinctUntilChanged()
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import androidx.appcompat.view.ActionMode
|
||||
import androidx.appcompat.widget.PopupMenu
|
||||
import androidx.core.graphics.Insets
|
||||
import androidx.core.view.children
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.core.view.updateLayoutParams
|
||||
import androidx.core.view.updatePadding
|
||||
import com.google.android.material.snackbar.Snackbar
|
||||
@@ -18,6 +19,7 @@ import org.koitharu.kotatsu.base.ui.util.ActionModeListener
|
||||
import org.koitharu.kotatsu.core.model.FavouriteCategory
|
||||
import org.koitharu.kotatsu.core.ui.titleRes
|
||||
import org.koitharu.kotatsu.databinding.FragmentFavouritesBinding
|
||||
import org.koitharu.kotatsu.databinding.ItemEmptyStateBinding
|
||||
import org.koitharu.kotatsu.favourites.ui.categories.CategoriesActivity
|
||||
import org.koitharu.kotatsu.favourites.ui.categories.CategoriesEditDelegate
|
||||
import org.koitharu.kotatsu.favourites.ui.categories.FavouritesCategoriesViewModel
|
||||
@@ -31,13 +33,15 @@ class FavouritesContainerFragment :
|
||||
BaseFragment<FragmentFavouritesBinding>(),
|
||||
FavouritesTabLongClickListener,
|
||||
CategoriesEditDelegate.CategoriesEditCallback,
|
||||
ActionModeListener {
|
||||
ActionModeListener,
|
||||
View.OnClickListener {
|
||||
|
||||
private val viewModel by viewModel<FavouritesCategoriesViewModel>()
|
||||
private val editDelegate by lazy(LazyThreadSafetyMode.NONE) {
|
||||
CategoriesEditDelegate(requireContext(), this)
|
||||
}
|
||||
private var pagerAdapter: FavouritesPagerAdapter? = null
|
||||
private var stubBinding: ItemEmptyStateBinding? = null
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
@@ -52,9 +56,7 @@ class FavouritesContainerFragment :
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
val adapter = FavouritesPagerAdapter(this, this)
|
||||
viewModel.visibleCategories.value?.let {
|
||||
adapter.replaceData(it)
|
||||
}
|
||||
viewModel.visibleCategories.value?.let(::onCategoriesChanged)
|
||||
binding.pager.adapter = adapter
|
||||
pagerAdapter = adapter
|
||||
TabLayoutMediator(binding.tabs, binding.pager, adapter).attach()
|
||||
@@ -66,6 +68,7 @@ class FavouritesContainerFragment :
|
||||
|
||||
override fun onDestroyView() {
|
||||
pagerAdapter = null
|
||||
stubBinding = null
|
||||
super.onDestroyView()
|
||||
}
|
||||
|
||||
@@ -101,6 +104,15 @@ class FavouritesContainerFragment :
|
||||
|
||||
private fun onCategoriesChanged(categories: List<CategoryListModel>) {
|
||||
pagerAdapter?.replaceData(categories)
|
||||
if (categories.isEmpty()) {
|
||||
binding.pager.isVisible = false
|
||||
binding.tabs.isVisible = false
|
||||
showStub()
|
||||
} else {
|
||||
binding.pager.isVisible = true
|
||||
binding.tabs.isVisible = true
|
||||
(stubBinding?.root ?: binding.stubEmptyState).isVisible = false
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
|
||||
@@ -130,6 +142,12 @@ class FavouritesContainerFragment :
|
||||
return true
|
||||
}
|
||||
|
||||
override fun onClick(v: View) {
|
||||
when (v.id) {
|
||||
R.id.button_retry -> editDelegate.createCategory()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDeleteCategory(category: FavouriteCategory) {
|
||||
viewModel.deleteCategory(category.id)
|
||||
}
|
||||
@@ -193,6 +211,18 @@ class FavouritesContainerFragment :
|
||||
menu.show()
|
||||
}
|
||||
|
||||
private fun showStub() {
|
||||
val stub = stubBinding ?: ItemEmptyStateBinding.bind(binding.stubEmptyState.inflate())
|
||||
stub.root.isVisible = true
|
||||
stub.icon.setImageResource(R.drawable.ic_heart_outline)
|
||||
stub.textPrimary.setText(R.string.text_empty_holder_primary)
|
||||
stub.textSecondary.setText(R.string.empty_favourite_categories)
|
||||
stub.buttonRetry.setText(R.string.add)
|
||||
stub.buttonRetry.isVisible = true
|
||||
stub.buttonRetry.setOnClickListener(this)
|
||||
stubBinding = stub
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
fun newInstance() = FavouritesContainerFragment()
|
||||
|
||||
@@ -31,7 +31,7 @@ class FavouritesCategoriesViewModel(
|
||||
repository.observeCategories(),
|
||||
observeAllCategoriesVisible(),
|
||||
) { list, showAll ->
|
||||
mapCategories(list, showAll, showAll)
|
||||
mapCategories(list, showAll, showAll && list.isNotEmpty())
|
||||
}.asLiveDataDistinct(viewModelScope.coroutineContext + Dispatchers.Default)
|
||||
|
||||
fun createCategory(name: String) {
|
||||
|
||||
@@ -1,9 +1,13 @@
|
||||
package org.koitharu.kotatsu.favourites.ui.list
|
||||
|
||||
import androidx.lifecycle.LiveData
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import androidx.recyclerview.widget.RecyclerView.NO_ID
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.catch
|
||||
import kotlinx.coroutines.flow.combine
|
||||
import kotlinx.coroutines.flow.map
|
||||
import org.koitharu.kotatsu.R
|
||||
import org.koitharu.kotatsu.core.prefs.AppSettings
|
||||
import org.koitharu.kotatsu.favourites.domain.FavouritesRepository
|
||||
@@ -24,6 +28,14 @@ class FavouritesListViewModel(
|
||||
settings: AppSettings,
|
||||
) : MangaListViewModel(settings), CountersProvider {
|
||||
|
||||
var sortOrder: LiveData<SortOrder?> = if (categoryId == NO_ID) {
|
||||
MutableLiveData(null)
|
||||
} else {
|
||||
repository.observeCategory(categoryId)
|
||||
.map { it?.order }
|
||||
.asLiveDataDistinct(viewModelScope.coroutineContext + Dispatchers.Default)
|
||||
}
|
||||
|
||||
override val content = combine(
|
||||
if (categoryId == 0L) {
|
||||
repository.observeAll(SortOrder.NEWEST)
|
||||
|
||||
@@ -17,4 +17,10 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" />
|
||||
|
||||
<ViewStub
|
||||
android:id="@+id/stub_empty_state"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout="@layout/item_empty_state" />
|
||||
|
||||
</LinearLayout>
|
||||
@@ -278,4 +278,5 @@
|
||||
<string name="chapters_will_removed_background">Главы будут удалены в фоновом режиме. Это может занять какое-то время</string>
|
||||
<string name="hide">Скрыть</string>
|
||||
<string name="new_sources_text">Доступны новые источники манги</string>
|
||||
<string name="empty_favourite_categories">Нет категорий избранного</string>
|
||||
</resources>
|
||||
@@ -281,4 +281,5 @@
|
||||
<string name="chapters_will_removed_background">Chapters will be removed in the background. It can take some time</string>
|
||||
<string name="hide">Hide</string>
|
||||
<string name="new_sources_text">New manga sources are available</string>
|
||||
<string name="empty_favourite_categories">No favourite categories</string>
|
||||
</resources>
|
||||
Reference in New Issue
Block a user