From b17237eb6bfdccb65c0cb25c1f423d16c69b567d Mon Sep 17 00:00:00 2001 From: Koitharu Date: Mon, 9 May 2022 13:02:45 +0300 Subject: [PATCH 1/2] Fix favourite categories edit --- .../java/org/koitharu/kotatsu/details/ui/DetailsFragment.kt | 4 ++-- .../kotatsu/favourites/ui/FavouritesContainerFragment.kt | 4 ++-- ...ategoriesDialog.kt => FavouriteCategoriesBottomSheet.kt} | 6 +++--- .../java/org/koitharu/kotatsu/list/ui/MangaListFragment.kt | 4 ++-- .../java/org/koitharu/kotatsu/tracker/ui/FeedViewModel.kt | 3 +++ app/src/main/res/layout/dialog_favorite_categories.xml | 1 + 6 files changed, 13 insertions(+), 9 deletions(-) rename app/src/main/java/org/koitharu/kotatsu/favourites/ui/categories/select/{FavouriteCategoriesDialog.kt => FavouriteCategoriesBottomSheet.kt} (95%) diff --git a/app/src/main/java/org/koitharu/kotatsu/details/ui/DetailsFragment.kt b/app/src/main/java/org/koitharu/kotatsu/details/ui/DetailsFragment.kt index 99c7319e3..817909268 100644 --- a/app/src/main/java/org/koitharu/kotatsu/details/ui/DetailsFragment.kt +++ b/app/src/main/java/org/koitharu/kotatsu/details/ui/DetailsFragment.kt @@ -24,7 +24,7 @@ import org.koitharu.kotatsu.base.ui.BaseFragment import org.koitharu.kotatsu.base.ui.widgets.ChipsView import org.koitharu.kotatsu.core.model.MangaHistory import org.koitharu.kotatsu.databinding.FragmentDetailsBinding -import org.koitharu.kotatsu.favourites.ui.categories.select.FavouriteCategoriesDialog +import org.koitharu.kotatsu.favourites.ui.categories.select.FavouriteCategoriesBottomSheet import org.koitharu.kotatsu.image.ui.ImageActivity import org.koitharu.kotatsu.parsers.model.Manga import org.koitharu.kotatsu.parsers.model.MangaSource @@ -180,7 +180,7 @@ class DetailsFragment : val manga = viewModel.manga.value ?: return when (v.id) { R.id.button_favorite -> { - FavouriteCategoriesDialog.show(childFragmentManager, manga) + FavouriteCategoriesBottomSheet.show(childFragmentManager, manga) } R.id.button_read -> { val chapterId = viewModel.readingHistory.value?.chapterId diff --git a/app/src/main/java/org/koitharu/kotatsu/favourites/ui/FavouritesContainerFragment.kt b/app/src/main/java/org/koitharu/kotatsu/favourites/ui/FavouritesContainerFragment.kt index 61fae0369..065620e40 100644 --- a/app/src/main/java/org/koitharu/kotatsu/favourites/ui/FavouritesContainerFragment.kt +++ b/app/src/main/java/org/koitharu/kotatsu/favourites/ui/FavouritesContainerFragment.kt @@ -147,7 +147,7 @@ class FavouritesContainerFragment : menu.setOnMenuItemClickListener { when (it.itemId) { R.id.action_remove -> editDelegate.deleteCategory(category) - R.id.action_edit -> FavouritesCategoryEditActivity.newIntent(tabView.context, category.id) + R.id.action_edit -> startActivity(FavouritesCategoryEditActivity.newIntent(tabView.context, category.id)) else -> return@setOnMenuItemClickListener false } true @@ -160,7 +160,7 @@ class FavouritesContainerFragment : menu.inflate(R.menu.popup_category_all) menu.setOnMenuItemClickListener { when (it.itemId) { - R.id.action_create -> FavouritesCategoryEditActivity.newIntent(requireContext()) + R.id.action_create -> startActivity(FavouritesCategoryEditActivity.newIntent(requireContext())) R.id.action_hide -> viewModel.setAllCategoriesVisible(false) } true diff --git a/app/src/main/java/org/koitharu/kotatsu/favourites/ui/categories/select/FavouriteCategoriesDialog.kt b/app/src/main/java/org/koitharu/kotatsu/favourites/ui/categories/select/FavouriteCategoriesBottomSheet.kt similarity index 95% rename from app/src/main/java/org/koitharu/kotatsu/favourites/ui/categories/select/FavouriteCategoriesDialog.kt rename to app/src/main/java/org/koitharu/kotatsu/favourites/ui/categories/select/FavouriteCategoriesBottomSheet.kt index 95f733006..9eb9b8d04 100644 --- a/app/src/main/java/org/koitharu/kotatsu/favourites/ui/categories/select/FavouriteCategoriesDialog.kt +++ b/app/src/main/java/org/koitharu/kotatsu/favourites/ui/categories/select/FavouriteCategoriesBottomSheet.kt @@ -24,7 +24,7 @@ import org.koitharu.kotatsu.parsers.model.Manga import org.koitharu.kotatsu.utils.ext.getDisplayMessage import org.koitharu.kotatsu.utils.ext.withArgs -class FavouriteCategoriesDialog : +class FavouriteCategoriesBottomSheet : BaseBottomSheet(), OnListItemClickListener, CategoriesEditDelegate.CategoriesEditCallback, @@ -59,7 +59,7 @@ class FavouriteCategoriesDialog : override fun onMenuItemClick(item: MenuItem): Boolean { return when (item.itemId) { R.id.action_create -> { - FavouritesCategoryEditActivity.newIntent(requireContext()) + startActivity(FavouritesCategoryEditActivity.newIntent(requireContext())) true } else -> false @@ -87,7 +87,7 @@ class FavouriteCategoriesDialog : fun show(fm: FragmentManager, manga: Manga) = Companion.show(fm, listOf(manga)) - fun show(fm: FragmentManager, manga: Collection) = FavouriteCategoriesDialog().withArgs(1) { + fun show(fm: FragmentManager, manga: Collection) = FavouriteCategoriesBottomSheet().withArgs(1) { putParcelableArrayList( KEY_MANGA_LIST, manga.mapTo(ArrayList(manga.size)) { ParcelableManga(it, withChapters = false) } diff --git a/app/src/main/java/org/koitharu/kotatsu/list/ui/MangaListFragment.kt b/app/src/main/java/org/koitharu/kotatsu/list/ui/MangaListFragment.kt index 4b8c2b570..ad7e3ab70 100644 --- a/app/src/main/java/org/koitharu/kotatsu/list/ui/MangaListFragment.kt +++ b/app/src/main/java/org/koitharu/kotatsu/list/ui/MangaListFragment.kt @@ -28,7 +28,7 @@ import org.koitharu.kotatsu.core.prefs.ListMode import org.koitharu.kotatsu.databinding.FragmentListBinding import org.koitharu.kotatsu.details.ui.DetailsActivity import org.koitharu.kotatsu.download.ui.service.DownloadService -import org.koitharu.kotatsu.favourites.ui.categories.select.FavouriteCategoriesDialog +import org.koitharu.kotatsu.favourites.ui.categories.select.FavouriteCategoriesBottomSheet import org.koitharu.kotatsu.list.ui.adapter.MangaListAdapter import org.koitharu.kotatsu.list.ui.adapter.MangaListAdapter.Companion.ITEM_TYPE_MANGA_GRID import org.koitharu.kotatsu.list.ui.adapter.MangaListListener @@ -297,7 +297,7 @@ abstract class MangaListFragment : true } R.id.action_favourite -> { - FavouriteCategoriesDialog.show(childFragmentManager, selectedItems) + FavouriteCategoriesBottomSheet.show(childFragmentManager, selectedItems) mode.finish() true } diff --git a/app/src/main/java/org/koitharu/kotatsu/tracker/ui/FeedViewModel.kt b/app/src/main/java/org/koitharu/kotatsu/tracker/ui/FeedViewModel.kt index 292d2c982..0170ee01d 100644 --- a/app/src/main/java/org/koitharu/kotatsu/tracker/ui/FeedViewModel.kt +++ b/app/src/main/java/org/koitharu/kotatsu/tracker/ui/FeedViewModel.kt @@ -65,6 +65,9 @@ class FeedViewModel( if (loadingJob?.isActive == true) { return } + if (append && !hasNextPage.value) { + return + } loadingJob = launchLoadingJob(Dispatchers.Default) { val offset = if (append) logList.value?.size ?: 0 else 0 val list = repository.getTrackingLog(offset, 20) diff --git a/app/src/main/res/layout/dialog_favorite_categories.xml b/app/src/main/res/layout/dialog_favorite_categories.xml index 0acdd440e..a808907bf 100644 --- a/app/src/main/res/layout/dialog_favorite_categories.xml +++ b/app/src/main/res/layout/dialog_favorite_categories.xml @@ -20,6 +20,7 @@ android:layout_height="wrap_content" android:orientation="vertical" android:overScrollMode="never" + android:paddingBottom="@dimen/list_spacing" android:scrollbars="vertical" app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" tools:listitem="@layout/item_checkable_new" /> From 161bc5f69d9cdefefc030840d550f68c55d81edb Mon Sep 17 00:00:00 2001 From: Koitharu Date: Mon, 9 May 2022 15:27:00 +0300 Subject: [PATCH 2/2] Show stub if favourite categories empty --- .../favourites/data/FavouriteCategoriesDao.kt | 2 +- .../favourites/domain/FavouritesRepository.kt | 10 ++--- .../ui/FavouritesContainerFragment.kt | 38 +++++++++++++++++-- .../FavouritesCategoriesViewModel.kt | 2 +- .../ui/list/FavouritesListViewModel.kt | 4 +- .../res/layout/activity_category_edit.xml | 4 +- .../main/res/layout/fragment_favourites.xml | 6 +++ app/src/main/res/values-ru/strings.xml | 1 + app/src/main/res/values/strings.xml | 1 + 9 files changed, 53 insertions(+), 15 deletions(-) diff --git a/app/src/main/java/org/koitharu/kotatsu/favourites/data/FavouriteCategoriesDao.kt b/app/src/main/java/org/koitharu/kotatsu/favourites/data/FavouriteCategoriesDao.kt index d0ada21da..148dfd820 100644 --- a/app/src/main/java/org/koitharu/kotatsu/favourites/data/FavouriteCategoriesDao.kt +++ b/app/src/main/java/org/koitharu/kotatsu/favourites/data/FavouriteCategoriesDao.kt @@ -16,7 +16,7 @@ abstract class FavouriteCategoriesDao { abstract fun observeAll(): Flow> @Query("SELECT * FROM favourite_categories WHERE category_id = :id") - abstract fun observe(id: Long): Flow + abstract fun observe(id: Long): Flow @Insert(onConflict = OnConflictStrategy.ABORT) abstract suspend fun insert(category: FavouriteCategoryEntity): Long diff --git a/app/src/main/java/org/koitharu/kotatsu/favourites/domain/FavouritesRepository.kt b/app/src/main/java/org/koitharu/kotatsu/favourites/domain/FavouritesRepository.kt index 6e995696b..13a4c92c4 100644 --- a/app/src/main/java/org/koitharu/kotatsu/favourites/domain/FavouritesRepository.kt +++ b/app/src/main/java/org/koitharu/kotatsu/favourites/domain/FavouritesRepository.kt @@ -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 @@ -52,9 +49,9 @@ class FavouritesRepository( }.distinctUntilChanged() } - fun observeCategory(id: Long): Flow { + fun observeCategory(id: Long): Flow { return db.favouriteCategoriesDao.observe(id) - .map { it.toFavouriteCategory() } + .map { it?.toFavouriteCategory() } } fun observeCategories(mangaId: Long): Flow> { @@ -162,6 +159,7 @@ class FavouritesRepository( private fun observeOrder(categoryId: Long): Flow { return db.favouriteCategoriesDao.observe(categoryId) + .filterNotNull() .map { x -> SortOrder(x.order, SortOrder.NEWEST) } .distinctUntilChanged() } diff --git a/app/src/main/java/org/koitharu/kotatsu/favourites/ui/FavouritesContainerFragment.kt b/app/src/main/java/org/koitharu/kotatsu/favourites/ui/FavouritesContainerFragment.kt index 065620e40..8e9d945a0 100644 --- a/app/src/main/java/org/koitharu/kotatsu/favourites/ui/FavouritesContainerFragment.kt +++ b/app/src/main/java/org/koitharu/kotatsu/favourites/ui/FavouritesContainerFragment.kt @@ -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 @@ -17,6 +18,7 @@ import org.koitharu.kotatsu.base.ui.BaseFragment import org.koitharu.kotatsu.base.ui.util.ActionModeListener import org.koitharu.kotatsu.core.model.FavouriteCategory 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(), FavouritesTabLongClickListener, CategoriesEditDelegate.CategoriesEditCallback, - ActionModeListener { + ActionModeListener, + View.OnClickListener { private val viewModel by viewModel() 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) { 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 -> startActivity(FavouritesCategoryEditActivity.newIntent(v.context)) + } + } + override fun onDeleteCategory(category: FavouriteCategory) { viewModel.deleteCategory(category.id) } @@ -168,6 +186,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() diff --git a/app/src/main/java/org/koitharu/kotatsu/favourites/ui/categories/FavouritesCategoriesViewModel.kt b/app/src/main/java/org/koitharu/kotatsu/favourites/ui/categories/FavouritesCategoriesViewModel.kt index 31c1e11de..46dc79586 100644 --- a/app/src/main/java/org/koitharu/kotatsu/favourites/ui/categories/FavouritesCategoriesViewModel.kt +++ b/app/src/main/java/org/koitharu/kotatsu/favourites/ui/categories/FavouritesCategoriesViewModel.kt @@ -30,7 +30,7 @@ class FavouritesCategoriesViewModel( repository.observeCategories(), observeAllCategoriesVisible(), ) { list, showAll -> - mapCategories(list, showAll, showAll) + mapCategories(list, showAll, showAll && list.isNotEmpty()) }.asLiveDataDistinct(viewModelScope.coroutineContext + Dispatchers.Default) fun deleteCategory(id: Long) { diff --git a/app/src/main/java/org/koitharu/kotatsu/favourites/ui/list/FavouritesListViewModel.kt b/app/src/main/java/org/koitharu/kotatsu/favourites/ui/list/FavouritesListViewModel.kt index 06d5bee3d..c2e8c00a1 100644 --- a/app/src/main/java/org/koitharu/kotatsu/favourites/ui/list/FavouritesListViewModel.kt +++ b/app/src/main/java/org/koitharu/kotatsu/favourites/ui/list/FavouritesListViewModel.kt @@ -28,11 +28,11 @@ class FavouritesListViewModel( settings: AppSettings, ) : MangaListViewModel(settings), CountersProvider { - var sortOrder: LiveData = if (categoryId == NO_ID) { + var sortOrder: LiveData = if (categoryId == NO_ID) { MutableLiveData(null) } else { repository.observeCategory(categoryId) - .map { it.order } + .map { it?.order } .asLiveDataDistinct(viewModelScope.coroutineContext + Dispatchers.Default) } diff --git a/app/src/main/res/layout/activity_category_edit.xml b/app/src/main/res/layout/activity_category_edit.xml index e453df674..e8b9d8eab 100644 --- a/app/src/main/res/layout/activity_category_edit.xml +++ b/app/src/main/res/layout/activity_category_edit.xml @@ -34,7 +34,9 @@ android:id="@+id/edit_name" android:layout_width="match_parent" android:layout_height="wrap_content" - android:hint="@string/name" /> + android:hint="@string/name" + android:imeOptions="actionDone" + android:inputType="textCapSentences" /> diff --git a/app/src/main/res/layout/fragment_favourites.xml b/app/src/main/res/layout/fragment_favourites.xml index 0f7e61994..d93d500b3 100644 --- a/app/src/main/res/layout/fragment_favourites.xml +++ b/app/src/main/res/layout/fragment_favourites.xml @@ -17,4 +17,10 @@ android:layout_width="match_parent" android:layout_height="match_parent" /> + + \ No newline at end of file diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index 012bf4aee..0b4fa423e 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -284,4 +284,5 @@ Название Изменить Изменить категорию + Нет категорий избранного \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 2bc68e061..d13563fab 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -287,4 +287,5 @@ Name Edit Edit category + No favourite categories \ No newline at end of file