Improve ui

This commit is contained in:
Koitharu
2023-07-26 15:27:43 +03:00
parent 01c23bc3b8
commit 61a7f1c830
28 changed files with 238 additions and 76 deletions

View File

@@ -135,8 +135,7 @@
android:windowSoftInputMode="adjustResize" />
<activity
android:name="org.koitharu.kotatsu.favourites.ui.categories.FavouriteCategoriesActivity"
android:label="@string/favourites"
android:windowSoftInputMode="stateAlwaysHidden" />
android:label="@string/manage_categories" />
<activity
android:name="org.koitharu.kotatsu.widget.shelf.ShelfConfigActivity"
android:exported="true"

View File

@@ -12,6 +12,7 @@ import androidx.core.view.children
import androidx.recyclerview.widget.RecyclerView
import androidx.viewpager2.widget.ViewPager2
import com.google.android.material.slider.Slider
import com.google.android.material.tabs.TabLayout
import kotlin.math.roundToInt
fun View.hideKeyboard() {
@@ -147,3 +148,9 @@ var View.isRtl: Boolean
set(value) {
layoutDirection = if (value) View.LAYOUT_DIRECTION_RTL else View.LAYOUT_DIRECTION_LTR
}
fun TabLayout.setTabsEnabled(enabled: Boolean) {
for (i in 0 until tabCount) {
getTabAt(i)?.view?.isEnabled = enabled
}
}

View File

@@ -143,14 +143,6 @@ class FavouritesRepository @Inject constructor(
db.favouriteCategoriesDao.updateTracking(id, isTrackingEnabled)
}
suspend fun removeCategory(id: Long) {
db.withTransaction {
db.favouriteCategoriesDao.delete(id)
db.favouritesDao.deleteAll(id)
}
channels.deleteChannel(id)
}
suspend fun removeCategories(ids: Collection<Long>) {
db.withTransaction {
for (id in ids) {

View File

@@ -7,7 +7,6 @@ import androidx.recyclerview.widget.RecyclerView
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import org.koitharu.kotatsu.R
import org.koitharu.kotatsu.core.ui.list.ListSelectionController
import org.koitharu.kotatsu.favourites.ui.categories.edit.FavouritesCategoryEditActivity
import com.google.android.material.R as materialR
class CategoriesSelectionCallback(
@@ -25,21 +24,44 @@ class CategoriesSelectionCallback(
}
override fun onPrepareActionMode(controller: ListSelectionController, mode: ActionMode, menu: Menu): Boolean {
val isOneItem = controller.count == 1
menu.findItem(R.id.action_edit)?.isVisible = isOneItem
val categories = viewModel.getCategories(controller.peekCheckedIds())
var canShow = categories.isNotEmpty()
var canHide = canShow
for (cat in categories) {
if (cat.isVisibleInLibrary) {
canShow = false
} else {
canHide = false
}
}
menu.findItem(R.id.action_show)?.isVisible = canShow
menu.findItem(R.id.action_hide)?.isVisible = canHide
mode.title = controller.count.toString()
return true
}
override fun onActionItemClicked(controller: ListSelectionController, mode: ActionMode, item: MenuItem): Boolean {
return when (item.itemId) {
R.id.action_edit -> {
/*R.id.action_view -> {
val id = controller.peekCheckedIds().singleOrNull() ?: return false
val context = recyclerView.context
val intent = FavouritesCategoryEditActivity.newIntent(context, id)
val category = viewModel.getCategory(id) ?: return false
val intent = FavouritesActivity.newIntent(context, category)
context.startActivity(intent)
mode.finish()
true
}*/
R.id.action_show -> {
viewModel.setIsVisible(controller.snapshot(), true)
mode.finish()
true
}
R.id.action_hide -> {
viewModel.setIsVisible(controller.snapshot(), false)
mode.finish()
true
}
R.id.action_remove -> {

View File

@@ -20,9 +20,7 @@ import org.koitharu.kotatsu.core.ui.BaseActivity
import org.koitharu.kotatsu.core.ui.list.ListSelectionController
import org.koitharu.kotatsu.core.util.ext.observe
import org.koitharu.kotatsu.core.util.ext.observeEvent
import org.koitharu.kotatsu.core.util.ext.scaleUpActivityOptionsOf
import org.koitharu.kotatsu.databinding.ActivityCategoriesBinding
import org.koitharu.kotatsu.favourites.ui.FavouritesActivity
import org.koitharu.kotatsu.favourites.ui.categories.adapter.CategoriesAdapter
import org.koitharu.kotatsu.favourites.ui.categories.edit.FavouritesCategoryEditActivity
import org.koitharu.kotatsu.list.ui.adapter.ListStateHolderListener
@@ -66,7 +64,7 @@ class FavouriteCategoriesActivity :
attachToRecyclerView(viewBinding.recyclerView)
}
viewModel.detalizedCategories.observe(this, ::onCategoriesChanged)
viewModel.categories.observe(this, ::onCategoriesChanged)
viewModel.onError.observeEvent(this, SnackbarErrorObserver(viewBinding.recyclerView, null))
}
@@ -80,9 +78,8 @@ class FavouriteCategoriesActivity :
if (selectionController.onItemClick(item.id)) {
return
}
val intent = FavouritesActivity.newIntent(this, item)
val options = scaleUpActivityOptionsOf(view)
startActivity(intent, options)
val intent = FavouritesCategoryEditActivity.newIntent(view.context, item.id)
startActivity(intent)
}
override fun onItemLongClick(item: FavouriteCategory, view: View): Boolean {

View File

@@ -9,6 +9,7 @@ import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.plus
import org.koitharu.kotatsu.R
import org.koitharu.kotatsu.core.model.FavouriteCategory
import org.koitharu.kotatsu.core.prefs.AppSettings
import org.koitharu.kotatsu.core.ui.BaseViewModel
import org.koitharu.kotatsu.core.util.ext.requireValue
@@ -27,7 +28,7 @@ class FavouritesCategoriesViewModel @Inject constructor(
private var reorderJob: Job? = null
val detalizedCategories = repository.observeCategoriesWithCovers()
val categories = repository.observeCategoriesWithCovers()
.map { list ->
list.map { (category, covers) ->
CategoryListModel(
@@ -47,14 +48,8 @@ class FavouritesCategoriesViewModel @Inject constructor(
}
}.stateIn(viewModelScope + Dispatchers.Default, SharingStarted.Eagerly, listOf(LoadingState))
fun deleteCategory(id: Long) {
launchJob {
repository.removeCategory(id)
}
}
fun deleteCategories(ids: Set<Long>) {
launchJob {
launchJob(Dispatchers.Default) {
repository.removeCategories(ids)
}
}
@@ -63,13 +58,13 @@ class FavouritesCategoriesViewModel @Inject constructor(
settings.isAllFavouritesVisible = isVisible
}
fun isEmpty(): Boolean = detalizedCategories.value.none { it is CategoryListModel }
fun isEmpty(): Boolean = categories.value.none { it is CategoryListModel }
fun reorderCategories(oldPos: Int, newPos: Int) {
val prevJob = reorderJob
reorderJob = launchJob(Dispatchers.Default) {
prevJob?.join()
val items = detalizedCategories.requireValue()
val items = categories.requireValue()
val ids = items.mapNotNullTo(ArrayList(items.size)) {
(it as? CategoryListModel)?.category?.id
}
@@ -78,4 +73,19 @@ class FavouritesCategoriesViewModel @Inject constructor(
repository.reorderCategories(ids)
}
}
fun setIsVisible(ids: Set<Long>, isVisible: Boolean) {
launchJob(Dispatchers.Default) {
for (id in ids) {
repository.updateCategory(id, isVisible)
}
}
}
fun getCategories(ids: Set<Long>): ArrayList<FavouriteCategory> {
val items = categories.requireValue()
return items.mapNotNullTo(ArrayList(ids.size)) { item ->
(item as? CategoryListModel)?.category?.takeIf { it.id in ids }
}
}
}

View File

@@ -35,8 +35,8 @@ fun categoryAD(
{ inflater, parent -> ItemCategoryBinding.inflate(inflater, parent, false) },
) {
val eventListener = object : OnClickListener, OnLongClickListener, OnTouchListener {
override fun onClick(v: View) = clickListener.onItemClick(item.category, binding.imageViewCover1)
override fun onLongClick(v: View) = clickListener.onItemLongClick(item.category, binding.imageViewCover1)
override fun onClick(v: View) = clickListener.onItemClick(item.category, itemView)
override fun onLongClick(v: View) = clickListener.onItemLongClick(item.category, itemView)
override fun onTouch(v: View?, event: MotionEvent): Boolean = event.actionMasked == MotionEvent.ACTION_DOWN &&
clickListener.onDragHandleTouch(this@adapterDelegateViewBinding)
}

View File

@@ -1,22 +1,38 @@
package org.koitharu.kotatsu.favourites.ui.container
import android.annotation.SuppressLint
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.ViewStub
import androidx.appcompat.view.ActionMode
import androidx.core.graphics.Insets
import androidx.core.view.isGone
import androidx.core.view.isVisible
import androidx.core.view.updatePadding
import androidx.fragment.app.viewModels
import coil.ImageLoader
import dagger.hilt.android.AndroidEntryPoint
import org.koitharu.kotatsu.R
import org.koitharu.kotatsu.core.ui.BaseFragment
import org.koitharu.kotatsu.core.ui.util.ActionModeListener
import org.koitharu.kotatsu.core.util.ext.addMenuProvider
import org.koitharu.kotatsu.core.util.ext.enqueueWith
import org.koitharu.kotatsu.core.util.ext.newImageRequest
import org.koitharu.kotatsu.core.util.ext.observe
import org.koitharu.kotatsu.core.util.ext.setTabsEnabled
import org.koitharu.kotatsu.core.util.ext.setTextAndVisible
import org.koitharu.kotatsu.databinding.FragmentFavouritesContainerBinding
import org.koitharu.kotatsu.databinding.ItemEmptyStateBinding
import org.koitharu.kotatsu.favourites.ui.categories.FavouriteCategoriesActivity
import javax.inject.Inject
@AndroidEntryPoint
class FavouritesContainerFragment : BaseFragment<FragmentFavouritesContainerBinding>(), ActionModeListener {
class FavouritesContainerFragment : BaseFragment<FragmentFavouritesContainerBinding>(), ActionModeListener,
ViewStub.OnInflateListener, View.OnClickListener {
@Inject
lateinit var coil: ImageLoader
private val viewModel: FavouritesContainerViewModel by viewModels()
@@ -31,8 +47,10 @@ class FavouritesContainerFragment : BaseFragment<FragmentFavouritesContainerBind
binding.pager.adapter = adapter
binding.tabs.setupWithViewPager(binding.pager)
binding.pager.offscreenPageLimit = 1
binding.stubEmpty.setOnInflateListener(this)
actionModeDelegate.addListener(this)
viewModel.categories.observe(viewLifecycleOwner, adapter)
viewModel.isEmpty.observe(viewLifecycleOwner, ::onEmptyStateChanged)
addMenuProvider(FavouritesContainerMenuProvider(binding.root.context))
}
@@ -48,19 +66,42 @@ class FavouritesContainerFragment : BaseFragment<FragmentFavouritesContainerBind
)
}
@SuppressLint("ClickableViewAccessibility")
override fun onActionModeStarted(mode: ActionMode) {
viewBinding?.run {
pager.isUserInputEnabled = false
tabs.isEnabled = false
tabs.setTabsEnabled(false)
}
}
@SuppressLint("ClickableViewAccessibility")
override fun onActionModeFinished(mode: ActionMode) {
viewBinding?.run {
pager.isUserInputEnabled = true
tabs.isEnabled = true
tabs.setTabsEnabled(true)
}
}
override fun onInflate(stub: ViewStub?, inflated: View) {
val stubBinding = ItemEmptyStateBinding.bind(inflated)
stubBinding.icon.newImageRequest(viewLifecycleOwner, R.drawable.ic_empty_favourites)?.enqueueWith(coil)
stubBinding.textPrimary.setText(R.string.text_empty_holder_primary)
stubBinding.textSecondary.setTextAndVisible(R.string.empty_favourite_categories)
stubBinding.buttonRetry.setTextAndVisible(R.string.manage)
stubBinding.buttonRetry.setOnClickListener(this)
}
override fun onClick(v: View) {
when (v.id) {
R.id.button_retry -> startActivity(
FavouriteCategoriesActivity.newIntent(v.context),
)
}
}
private fun onEmptyStateChanged(isEmpty: Boolean) {
viewBinding?.run {
pager.isGone = isEmpty
tabs.isGone = isEmpty
stubEmpty.isVisible = isEmpty
}
}
}

View File

@@ -5,6 +5,8 @@ import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.filterNotNull
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.plus
import org.koitharu.kotatsu.core.ui.BaseViewModel
@@ -17,8 +19,15 @@ class FavouritesContainerViewModel @Inject constructor(
favouritesRepository: FavouritesRepository,
) : BaseViewModel() {
val categories = favouritesRepository.observeCategoriesForLibrary()
private val categoriesStateFlow = favouritesRepository.observeCategoriesForLibrary()
.stateIn(viewModelScope + Dispatchers.Default, SharingStarted.Eagerly, null)
val categories = categoriesStateFlow.filterNotNull()
.mapItems { FavouriteTabModel(it.id, it.title) }
.distinctUntilChanged()
.stateIn(viewModelScope + Dispatchers.Default, SharingStarted.Eagerly, emptyList())
val isEmpty = categoriesStateFlow.map {
it?.isEmpty() == true
}.stateIn(viewModelScope + Dispatchers.Default, SharingStarted.Eagerly, false)
}

View File

@@ -16,8 +16,12 @@ class FilterAdapter(
) : BaseListAdapter<ListModel>(), FastScroller.SectionIndexer {
init {
delegatesManager.addDelegate(filterSortDelegate(listener)).addDelegate(filterTagDelegate(listener))
.addDelegate(listHeaderAD(null)).addDelegate(loadingStateAD()).addDelegate(loadingFooterAD())
delegatesManager
.addDelegate(ITEM_TYPE_SORT, filterSortDelegate(listener))
.addDelegate(ITEM_TYPE_TAG, filterTagDelegate(listener))
.addDelegate(ITEM_TYPE_HEADER, listHeaderAD(listener))
.addDelegate(loadingStateAD())
.addDelegate(loadingFooterAD())
.addDelegate(filterErrorDelegate())
differ.addListListener(listListener)
}
@@ -32,4 +36,11 @@ class FilterAdapter(
}
return null
}
companion object {
const val ITEM_TYPE_SORT = 0
const val ITEM_TYPE_TAG = 1
const val ITEM_TYPE_HEADER = 2
}
}

View File

@@ -1,5 +1,6 @@
package org.koitharu.kotatsu.filter.ui
import android.view.View
import androidx.annotation.WorkerThread
import androidx.lifecycle.SavedStateHandle
import dagger.hilt.android.ViewModelLifecycle
@@ -95,6 +96,10 @@ class FilterCoordinator @Inject constructor(
}
}
override fun onListHeaderClick(item: ListHeader, view: View) {
reset()
}
fun observeAvailableTags(): Flow<Set<MangaTag>?> = flow {
if (!availableTagsDeferred.isCompleted) {
emit(emptySet())
@@ -208,7 +213,7 @@ class FilterCoordinator @Inject constructor(
}
}
if (allTags.isLoading || allTags.isError || tags.isNotEmpty()) {
list.add(ListHeader(R.string.genres, 0, null))
list.add(ListHeader(R.string.genres, if (state.tags.isEmpty()) 0 else R.string.reset, null))
tags.mapTo(list) {
FilterItem.Tag(it, isChecked = it in state.tags)
}

View File

@@ -0,0 +1,28 @@
package org.koitharu.kotatsu.filter.ui
import android.content.Context
import android.graphics.Rect
import android.view.View
import androidx.recyclerview.widget.RecyclerView
import org.koitharu.kotatsu.R
class FilterItemDecoration(
context: Context,
) : RecyclerView.ItemDecoration() {
private val spacing = context.resources.getDimensionPixelOffset(R.dimen.list_spacing)
override fun getItemOffsets(
outRect: Rect,
view: View,
parent: RecyclerView,
state: RecyclerView.State
) {
val itemType = parent.getChildViewHolder(view)?.itemViewType ?: -1
if (itemType == FilterAdapter.ITEM_TYPE_HEADER) {
outRect.set(spacing, 0, spacing, 0)
} else {
outRect.set(0, 0, 0, 0)
}
}
}

View File

@@ -32,6 +32,7 @@ class FilterSheetFragment :
val adapter = FilterAdapter(filter, this)
binding.recyclerView.adapter = adapter
filter.filterItems.observe(viewLifecycleOwner, adapter)
binding.recyclerView.addItemDecoration(FilterItemDecoration(binding.root.context))
if (dialog == null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
binding.recyclerView.scrollIndicators = 0

View File

@@ -1,8 +1,9 @@
package org.koitharu.kotatsu.filter.ui
import org.koitharu.kotatsu.filter.ui.model.FilterItem
import org.koitharu.kotatsu.list.ui.adapter.ListHeaderClickListener
interface OnFilterChangedListener {
interface OnFilterChangedListener : ListHeaderClickListener {
fun onSortItemClick(item: FilterItem.Sort)

View File

@@ -309,7 +309,7 @@ abstract class MangaListFragment :
}
override fun onSelectionChanged(controller: ListSelectionController, count: Int) {
requireViewBinding().recyclerView.invalidateItemDecorations()
viewBinding?.recyclerView?.invalidateItemDecorations()
}
override fun onFastScrollStart(fastScroller: FastScroller) {

View File

@@ -1,7 +1,8 @@
package org.koitharu.kotatsu.list.ui.adapter
import androidx.core.view.isInvisible
import androidx.core.view.isVisible
import com.hannesdorfmann.adapterdelegates4.dsl.adapterDelegateViewBinding
import org.koitharu.kotatsu.core.util.ext.setTextAndVisible
import org.koitharu.kotatsu.databinding.ItemHeaderButtonBinding
import org.koitharu.kotatsu.list.ui.model.ListHeader
import org.koitharu.kotatsu.list.ui.model.ListModel
@@ -19,6 +20,12 @@ fun listHeaderAD(
bind {
binding.textViewTitle.text = item.getText(context)
binding.buttonMore.setTextAndVisible(item.buttonTextRes)
if (item.buttonTextRes == 0) {
binding.buttonMore.isInvisible = true
binding.buttonMore.text = null
} else {
binding.buttonMore.setText(item.buttonTextRes)
binding.buttonMore.isVisible = true
}
}
}

View File

@@ -5,6 +5,7 @@ import android.text.method.LinkMovementMethod
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.core.graphics.Insets
import androidx.core.view.isVisible
import androidx.fragment.app.viewModels
@@ -120,11 +121,11 @@ class PreviewFragment : BaseFragment<FragmentPreviewBinding>(), View.OnClickList
}
private fun onDescriptionChanged(description: CharSequence?) {
val tv = requireViewBinding().textViewDescription
if (description.isNullOrBlank()) {
tv.setText(R.string.no_description)
} else {
tv.text = description
val tv = viewBinding?.textViewDescription ?: return
when {
description == null -> tv.setText(R.string.loading_)
description.isBlank() -> tv.setText(R.string.no_description)
else -> tv.setText(description, TextView.BufferType.NORMAL)
}
}

View File

@@ -12,6 +12,7 @@ import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.distinctUntilChangedBy
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.stateIn
@@ -49,6 +50,8 @@ class PreviewViewModel @Inject constructor(
emit(description.parseAsHtml().filterSpans().sanitize())
emit(description.parseAsHtml(imageGetter = imageGetter).filterSpans())
}
}.combine(isLoading) { desc, loading ->
if (loading) null else desc ?: ""
}.stateIn(viewModelScope + Dispatchers.Default, SharingStarted.WhileSubscribed(5000), null)
val tagsChips = manga.map {

View File

@@ -62,7 +62,7 @@ class MangaListActivity :
finishAfterTransition()
return
}
viewBinding.chipSort?.setOnClickListener(this)
viewBinding.buttonOrder?.setOnClickListener(this)
title = if (source == MangaSource.LOCAL) getString(R.string.local_storage) else source.title
initList(source, tags)
}
@@ -80,7 +80,7 @@ class MangaListActivity :
override fun onClick(v: View) {
when (v.id) {
R.id.chip_sort -> FilterSheetFragment.show(supportFragmentManager)
R.id.button_order -> FilterSheetFragment.show(supportFragmentManager)
}
}
@@ -127,7 +127,7 @@ class MangaListActivity :
}
}
val filter = filterOwner.filter
val chipSort = viewBinding.chipSort
val chipSort = viewBinding.buttonOrder
if (chipSort != null) {
filter.header.observe(this) {
chipSort.setTextAndVisible(it.sortOrder?.titleRes ?: 0)

View File

@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<vector
xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:tint="?attr/colorControlNormal"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="#000000"
android:pathData="M2,5.27L3.28,4L20,20.72L18.73,22L15.65,18.92C14.5,19.3 13.28,19.5 12,19.5C7,19.5 2.73,16.39 1,12C1.69,10.24 2.79,8.69 4.19,7.46L2,5.27M12,9A3,3 0 0,1 15,12C15,12.35 14.94,12.69 14.83,13L11,9.17C11.31,9.06 11.65,9 12,9M12,4.5C17,4.5 21.27,7.61 23,12C22.18,14.08 20.79,15.88 19,17.19L17.58,15.76C18.94,14.82 20.06,13.54 20.82,12C19.17,8.64 15.76,6.5 12,6.5C10.91,6.5 9.84,6.68 8.84,7L7.3,5.47C8.74,4.85 10.33,4.5 12,4.5M3.18,12C4.83,15.36 8.24,17.5 12,17.5C12.69,17.5 13.37,17.43 14,17.29L11.72,15C10.29,14.85 9.15,13.71 9,12.28L5.6,8.87C4.61,9.72 3.78,10.78 3.18,12Z" />
</vector>

View File

@@ -2,6 +2,7 @@
<androidx.coordinatorlayout.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
@@ -50,7 +51,8 @@
android:paddingVertical="@dimen/list_spacing"
android:scrollbars="vertical"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior" />
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior"
tools:listitem="@layout/item_category" />
<com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
android:id="@+id/fab_add"

View File

@@ -29,19 +29,14 @@
app:layout_collapseMode="parallax"
tools:ignore="RtlSymmetry">
<com.google.android.material.chip.Chip
style="@style/Widget.Material3.Chip.Assist"
android:id="@+id/chip_sort"
<com.google.android.material.button.MaterialButton
android:id="@+id/button_order"
style="@style/Widget.Kotatsu.Button.More"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone"
app:chipBackgroundColor="?attr/colorSurfaceContainerHigh"
app:chipIcon="@drawable/ic_sort"
app:chipIconEnabled="true"
app:closeIcon="@drawable/ic_expand_more"
app:closeIconEnabled="true"
app:layout_collapseMode="pin"
tools:text="@string/popular"
android:visibility="invisible"
app:icon="@drawable/ic_reorder"
tools:text="@string/manage"
tools:visibility="visible" />
</LinearLayout>

View File

@@ -2,6 +2,7 @@
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
@@ -16,6 +17,14 @@
<org.koitharu.kotatsu.core.ui.widgets.EnhancedViewPager
android:id="@+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent" />
android:layout_height="match_parent"
tools:visibility="gone" />
<ViewStub
android:id="@+id/stub_empty"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout="@layout/item_empty_state"
tools:visibility="visible" />
</LinearLayout>

View File

@@ -124,7 +124,6 @@
android:id="@+id/imageView_handle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="?selectableItemBackgroundBorderless"
android:contentDescription="@string/reorder"
android:padding="@dimen/margin_normal"
android:src="@drawable/ic_reorder_handle"

View File

@@ -4,6 +4,7 @@
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:baselineAligned="true"
android:orientation="horizontal">
<TextView
@@ -22,6 +23,8 @@
style="@style/Widget.Kotatsu.Button.More"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/manage" />
android:visibility="invisible"
tools:text="@string/manage"
tools:visibility="visible" />
</LinearLayout>

View File

@@ -4,9 +4,15 @@
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/action_edit"
android:icon="@drawable/ic_edit"
android:title="@string/edit"
android:id="@+id/action_show"
android:icon="@drawable/ic_eye"
android:title="@string/show"
app:showAsAction="ifRoom" />
<item
android:id="@+id/action_hide"
android:icon="@drawable/ic_eye_off"
android:title="@string/hide"
app:showAsAction="ifRoom" />
<item
@@ -15,4 +21,4 @@
android:title="@string/remove"
app:showAsAction="ifRoom" />
</menu>
</menu>

View File

@@ -5,7 +5,7 @@
<item
android:id="@+id/action_manage"
android:orderInCategory="48"
android:title="@string/manage_favourites"
android:title="@string/manage_categories"
android:titleCondensed="@string/manage" />
</menu>

View File

@@ -460,10 +460,12 @@
<string name="background">Background</string>
<string name="data_not_restored">Data was not restored</string>
<string name="data_not_restored_text">Make sure you have selected the correct backup file</string>
<string name="manage_favourites">Manage favourites</string>
<string name="manage_categories">Manage categories</string>
<string name="suggestions_wifi_only_summary">Do not update suggestions using metered network connections</string>
<string name="tracker_wifi_only_summary">Do not check for new chapters using metered network connections</string>
<string name="search_hint">Enter manga title, genre or source name</string>
<string name="progress">Progress</string>
<string name="order_added">Added</string>
<string name="view_list">View list</string>
<string name="show">Show</string>
</resources>