From fc0ab3e878f7be597b4b0190e9e45a18242c24a4 Mon Sep 17 00:00:00 2001 From: Jay Date: Sun, 16 Feb 2020 17:02:07 -0800 Subject: [PATCH] Category controller is no longer rx, md2 design (really just google keep) --- .../tachiyomi/ui/catalogue/SourceHolder.kt | 2 +- .../tachiyomi/ui/category/CategoryAdapter.kt | 32 +-- .../ui/category/CategoryController.kt | 267 +++++------------- .../tachiyomi/ui/category/CategoryHolder.kt | 115 +++++++- .../tachiyomi/ui/category/CategoryItem.kt | 6 +- .../ui/category/CategoryPresenter.kt | 98 ++++--- .../tachiyomi/ui/extension/ExtensionHolder.kt | 6 +- .../ui/library/LibraryCategoryAdapter.kt | 6 +- .../ui/library/LibraryCategoryView.kt | 13 +- .../tachiyomi/ui/library/LibraryGridHolder.kt | 43 +-- .../tachiyomi/ui/library/LibraryHolder.kt | 2 +- .../tachiyomi/ui/library/LibraryItem.kt | 1 + .../tachiyomi/ui/library/LibraryListHolder.kt | 12 +- .../kanade/tachiyomi/ui/main/MainActivity.kt | 20 ++ .../tachiyomi/ui/migration/MangaHolder.kt | 9 +- .../ui/migration/MigrationController.kt | 13 +- .../tachiyomi/ui/migration/SourceHolder.kt | 4 +- .../manga/design/MigrationSourceHolder.kt | 6 +- .../res/drawable/bordered_list_selector.xml | 24 ++ app/src/main/res/drawable/rounded_ripple.xml | 38 ++- .../main/res/layout/catalogue_grid_item.xml | 15 +- .../catalogue_main_controller_card_item.xml | 4 +- .../main/res/layout/categories_controller.xml | 21 +- app/src/main/res/layout/categories_item.xml | 88 ++++-- .../main/res/layout/extension_card_item.xml | 6 +- .../main/res/layout/migration_source_item.xml | 2 +- app/src/main/res/values/strings.xml | 7 +- 27 files changed, 454 insertions(+), 406 deletions(-) create mode 100644 app/src/main/res/drawable/bordered_list_selector.xml diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/catalogue/SourceHolder.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/catalogue/SourceHolder.kt index f29fff143c..ebaa1ddcc3 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/catalogue/SourceHolder.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/catalogue/SourceHolder.kt @@ -41,7 +41,7 @@ class SourceHolder(view: View, override val adapter: CatalogueAdapter) : // Set circle letter image. itemView.post { - image.setImageDrawable(image.getRound(source.name.take(1).toUpperCase(), false)) + edit_button.setImageDrawable(edit_button.getRound(source.name.take(1).toUpperCase(), false)) } // If source is login, show only login option diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/category/CategoryAdapter.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/category/CategoryAdapter.kt index 0ad0eb90ce..2525ec7fff 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/category/CategoryAdapter.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/category/CategoryAdapter.kt @@ -13,38 +13,26 @@ class CategoryAdapter(controller: CategoryController) : /** * Listener called when an item of the list is released. */ - val onItemReleaseListener: OnItemReleaseListener = controller - - /** - * Clears the active selections from the list and the model. - */ - override fun clearSelection() { - super.clearSelection() - (0 until itemCount).forEach { getItem(it)?.isSelected = false } - } + val categoryItemListener: CategoryItemListener = controller /** * Clears the active selections from the model. */ - fun clearModelSelection() { - selectedPositions.forEach { getItem(it)?.isSelected = false } - } - - /** - * Toggles the selection of the given position. - * - * @param position The position to toggle. - */ - override fun toggleSelection(position: Int) { - super.toggleSelection(position) - getItem(position)?.isSelected = isSelected(position) + fun resetEditing(position: Int) { + for (i in 0..itemCount) { + getItem(i)?.isEditing = false + } + getItem(position)?.isEditing = true + notifyDataSetChanged() } - interface OnItemReleaseListener { + interface CategoryItemListener { /** * Called when an item of the list is released. */ fun onItemReleased(position: Int) + fun onCategoryRename(position: Int, newName: String): Boolean + fun onItemDelete(position: Int) } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/category/CategoryController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/category/CategoryController.kt index 8f610ec033..853fd404db 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/category/CategoryController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/category/CategoryController.kt @@ -1,46 +1,33 @@ package eu.kanade.tachiyomi.ui.category -import com.google.android.material.snackbar.Snackbar -import androidx.appcompat.app.AppCompatActivity -import androidx.appcompat.view.ActionMode +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.view.WindowManager import androidx.recyclerview.widget.LinearLayoutManager -import androidx.recyclerview.widget.RecyclerView -import android.view.* +import com.afollestad.materialdialogs.MaterialDialog import com.google.android.material.snackbar.BaseTransientBottomBar -import com.jakewharton.rxbinding.view.clicks +import com.google.android.material.snackbar.Snackbar import eu.davidea.flexibleadapter.FlexibleAdapter -import eu.davidea.flexibleadapter.SelectableAdapter import eu.davidea.flexibleadapter.helpers.UndoHelper import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.data.database.models.Category -import eu.kanade.tachiyomi.ui.base.controller.NucleusController +import eu.kanade.tachiyomi.ui.base.controller.BaseController +import eu.kanade.tachiyomi.ui.category.CategoryPresenter.Companion.CREATE_CATEGORY_ORDER import eu.kanade.tachiyomi.ui.main.MainActivity -import eu.kanade.tachiyomi.util.view.doOnApplyWindowInsets -import eu.kanade.tachiyomi.util.view.marginBottom -import eu.kanade.tachiyomi.util.view.snack -import eu.kanade.tachiyomi.util.view.updateLayoutParams -import eu.kanade.tachiyomi.util.view.updatePaddingRelative import eu.kanade.tachiyomi.util.system.toast -import kotlinx.android.synthetic.main.categories_controller.empty_view -import kotlinx.android.synthetic.main.categories_controller.fab -import kotlinx.android.synthetic.main.categories_controller.recycler +import eu.kanade.tachiyomi.util.view.snack +import kotlinx.android.synthetic.main.categories_controller.* /** * Controller to manage the categories for the users' library. */ -class CategoryController : NucleusController(), - ActionMode.Callback, +class CategoryController(bundle: Bundle? = null) : BaseController(bundle), FlexibleAdapter.OnItemClickListener, - FlexibleAdapter.OnItemLongClickListener, - CategoryAdapter.OnItemReleaseListener, + CategoryAdapter.CategoryItemListener, CategoryCreateDialog.Listener, - CategoryRenameDialog.Listener, - UndoHelper.OnActionListener { - - /** - * Object used to show ActionMode toolbar. - */ - private var actionMode: ActionMode? = null + CategoryRenameDialog.Listener { /** * Adapter containing category items. @@ -55,7 +42,7 @@ class CategoryController : NucleusController(), /** * Creates the presenter for this controller. Not to be manually called. */ - override fun createPresenter() = CategoryPresenter() + private val presenter = CategoryPresenter(this) /** * Returns the toolbar title to show when this controller is attached. @@ -89,20 +76,8 @@ class CategoryController : NucleusController(), adapter?.isHandleDragEnabled = true adapter?.isPermanentDelete = false - fab.clicks().subscribeUntilDestroy { - CategoryCreateDialog(this@CategoryController).showDialog(router, null) - } - - val fabBaseMarginBottom = fab?.marginBottom ?: 0 - recycler.doOnApplyWindowInsets { v, insets, padding -> - - fab?.updateLayoutParams { - bottomMargin = fabBaseMarginBottom + insets.systemWindowInsetBottom - } - // offset the recycler by the fab's inset + some inset on top - v.updatePaddingRelative(bottom = padding.bottom + (fab?.marginBottom ?: 0) + - fabBaseMarginBottom + (fab?.height ?: 0)) - } + activity?.window?.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE) + presenter.getCategories() } /** @@ -113,125 +88,35 @@ class CategoryController : NucleusController(), override fun onDestroyView(view: View) { // Manually call callback to delete categories if required snack?.dismiss() + view.clearFocus() + activity?.window?.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN) confirmDelete() snack = null - actionMode = null adapter = null super.onDestroyView(view) } + override fun handleBack(): Boolean { + view?.clearFocus() + confirmDelete() + activity?.window?.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN) + return super.handleBack() + } + /** * Called from the presenter when the categories are updated. * * @param categories The new list of categories to display. */ fun setCategories(categories: List) { - actionMode?.finish() adapter?.updateDataSet(categories) if (categories.isNotEmpty()) { empty_view.hide() - val selected = categories.filter { it.isSelected } - if (selected.isNotEmpty()) { - selected.forEach { onItemLongClick(categories.indexOf(it)) } - } } else { empty_view.show(R.drawable.ic_shape_black_128dp, R.string.information_empty_category) } } - /** - * Called when action mode is first created. The menu supplied will be used to generate action - * buttons for the action mode. - * - * @param mode ActionMode being created. - * @param menu Menu used to populate action buttons. - * @return true if the action mode should be created, false if entering this mode should be - * aborted. - */ - override fun onCreateActionMode(mode: ActionMode, menu: Menu): Boolean { - // Inflate menu. - mode.menuInflater.inflate(R.menu.category_selection, menu) - // Enable adapter multi selection. - adapter?.mode = SelectableAdapter.Mode.MULTI - return true - } - - /** - * Called to refresh an action mode's action menu whenever it is invalidated. - * - * @param mode ActionMode being prepared. - * @param menu Menu used to populate action buttons. - * @return true if the menu or action mode was updated, false otherwise. - */ - override fun onPrepareActionMode(mode: ActionMode, menu: Menu): Boolean { - val adapter = adapter ?: return false - val count = adapter.selectedItemCount - mode.title = resources?.getString(R.string.label_selected, count) - - // Show edit button only when one item is selected - val editItem = mode.menu.findItem(R.id.action_edit) - editItem.isVisible = count == 1 - return true - } - - /** - * Called to report a user click on an action button. - * - * @param mode The current ActionMode. - * @param item The item that was clicked. - * @return true if this callback handled the event, false if the standard MenuItem invocation - * should continue. - */ - override fun onActionItemClicked(mode: ActionMode, item: MenuItem): Boolean { - val adapter = adapter ?: return false - - when (item.itemId) { - R.id.action_delete -> { - adapter.removeItems(adapter.selectedPositions) - snack = - view?.snack(R.string.snack_categories_deleted, Snackbar.LENGTH_INDEFINITE) { - var undoing = false - setAction(R.string.action_undo) { - adapter.restoreDeletedItems() - undoing = true - } - addCallback(object : BaseTransientBottomBar.BaseCallback() { - override fun onDismissed(transientBottomBar: Snackbar?, event: Int) { - super.onDismissed(transientBottomBar, event) - if (!undoing) confirmDelete() - } - }) - } - (activity as? MainActivity)?.setUndoSnackBar(snack) - mode.finish() - } - R.id.action_edit -> { - // Edit selected category - if (adapter.selectedItemCount == 1) { - val position = adapter.selectedPositions.first() - val category = adapter.getItem(position)?.category - if (category != null) { - editCategory(category) - } - } - } - else -> return false - } - return true - } - - /** - * Called when an action mode is about to be exited and destroyed. - * - * @param mode The current ActionMode being destroyed. - */ - override fun onDestroyActionMode(mode: ActionMode) { - // Reset adapter to single selection - adapter?.mode = SelectableAdapter.Mode.IDLE - adapter?.clearSelection() - actionMode = null - } - /** * Called when an item in the list is clicked. * @@ -239,50 +124,45 @@ class CategoryController : NucleusController(), * @return true if this click should enable selection mode. */ override fun onItemClick(view: View?, position: Int): Boolean { - // Check if action mode is initialized and selected item exist. - return if (actionMode != null && position != RecyclerView.NO_POSITION) { - toggleSelection(position) - true - } else { - false - } + adapter?.resetEditing(position) + return true } - /** - * Called when an item in the list is long clicked. - * - * @param position The position of the clicked item. - */ - override fun onItemLongClick(position: Int) { - val activity = activity as? AppCompatActivity ?: return - - // Check if action mode is initialized. - if (actionMode == null) { - // Initialize action mode - actionMode = activity.startSupportActionMode(this) - } - - // Set item as selected - toggleSelection(position) + override fun onCategoryRename(position: Int, newName: String): Boolean { + val category = adapter?.getItem(position)?.category ?: return false + if (category.order == CREATE_CATEGORY_ORDER) + return (presenter.createCategory(newName)) + return (presenter.renameCategory(category, newName)) } - /** - * Toggle the selection state of an item. - * If the item was the last one in the selection and is unselected, the ActionMode is finished. - * - * @param position The position of the item to toggle. - */ - private fun toggleSelection(position: Int) { - val adapter = adapter ?: return - - //Mark the position selected - adapter.toggleSelection(position) - - if (adapter.selectedItemCount == 0) { - actionMode?.finish() - } else { - actionMode?.invalidate() - } + override fun onItemDelete(position: Int) { + MaterialDialog(activity!!) + .title(R.string.confirm_category_deletion) + .message(R.string.confirm_category_deletion_message) + .positiveButton(R.string.action_delete) { + deleteCategory(position) + } + .negativeButton(android.R.string.no) + .show() + } + + private fun deleteCategory(position: Int) { + adapter?.removeItem(position) + snack = + view?.snack(R.string.snack_category_deleted, Snackbar.LENGTH_INDEFINITE) { + var undoing = false + setAction(R.string.action_undo) { + adapter?.restoreDeletedItems() + undoing = true + } + addCallback(object : BaseTransientBottomBar.BaseCallback() { + override fun onDismissed(transientBottomBar: Snackbar?, event: Int) { + super.onDismissed(transientBottomBar, event) + if (!undoing) confirmDelete() + } + }) + } + (activity as? MainActivity)?.setUndoSnackBar(snack) } /** @@ -296,31 +176,10 @@ class CategoryController : NucleusController(), presenter.reorderCategories(categories) } - /** - * Called when the undo action is clicked in the snackbar. - * - * @param action The action performed. - */ - override fun onActionCanceled(action: Int, positions: MutableList?) { - adapter?.restoreDeletedItems() - snack = null - } - - /** - * Called when the time to restore the items expires. - * - * @param action The action performed. - * @param event The event that triggered the action - */ - override fun onActionConfirmed(action: Int, event: Int) { - val adapter = adapter ?: return - presenter.deleteCategories(adapter.deletedItems.map { it.category }) - snack = null - } - fun confirmDelete() { val adapter = adapter ?: return - presenter.deleteCategories(adapter.deletedItems.map { it.category }) + presenter.deleteCategory(adapter.deletedItems.map { it.category }.firstOrNull()) + adapter.confirmDeletion() snack = null } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/category/CategoryHolder.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/category/CategoryHolder.kt index 740a141c0a..0c846ff28a 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/category/CategoryHolder.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/category/CategoryHolder.kt @@ -1,12 +1,21 @@ package eu.kanade.tachiyomi.ui.category +import android.content.Context +import android.graphics.drawable.Drawable +import android.text.InputType import android.view.View +import android.view.WindowManager +import android.view.inputmethod.EditorInfo +import android.view.inputmethod.InputMethodManager +import androidx.core.content.ContextCompat +import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.data.database.models.Category import eu.kanade.tachiyomi.ui.base.holder.BaseFlexibleViewHolder -import eu.kanade.tachiyomi.util.view.getRound -import kotlinx.android.synthetic.main.categories_item.image -import kotlinx.android.synthetic.main.categories_item.reorder -import kotlinx.android.synthetic.main.categories_item.title +import eu.kanade.tachiyomi.ui.category.CategoryPresenter.Companion.CREATE_CATEGORY_ORDER +import eu.kanade.tachiyomi.util.system.getResourceColor +import eu.kanade.tachiyomi.util.view.gone +import eu.kanade.tachiyomi.util.view.visible +import kotlinx.android.synthetic.main.categories_item.* /** * Holder used to display category items. @@ -17,15 +26,14 @@ import kotlinx.android.synthetic.main.categories_item.title class CategoryHolder(view: View, val adapter: CategoryAdapter) : BaseFlexibleViewHolder(view, adapter) { init { - // Create round letter image onclick to simulate long click - image.setOnClickListener { - // Simulate long click on this view to enter selection mode - onLongClick(view) + edit_button.setOnClickListener { + submitChanges() } - - setDragHandleView(reorder) } + var createCategory = false + private var regularDrawable: Drawable? = null + /** * Binds this holder with the given category. * @@ -34,11 +42,90 @@ class CategoryHolder(view: View, val adapter: CategoryAdapter) : BaseFlexibleVie fun bind(category: Category) { // Set capitalized title. title.text = category.name.capitalize() + edit_text.setOnEditorActionListener { _, actionId, _ -> + if (actionId == EditorInfo.IME_ACTION_DONE) { + submitChanges() + } + true + } + createCategory = category.order == CREATE_CATEGORY_ORDER + if (createCategory) { + title.setTextColor(ContextCompat.getColor(itemView.context, R.color.textColorHint)) + regularDrawable = ContextCompat.getDrawable(itemView.context, R.drawable + .ic_add_white_24dp) + edit_button.gone() + image.gone() + edit_text.setText("") + edit_text.hint = title.text + } + else { + title.setTextColor(ContextCompat.getColor(itemView.context, R.color.textColorPrimary)) + regularDrawable = ContextCompat.getDrawable(itemView.context, R.drawable + .ic_reorder_grey_24dp) + edit_button.visible() + image.visible() + edit_text.setText(title.text) + } + + } - // Update circle letter image. - itemView.post { - image.setImageDrawable(image.getRound(category.name.take(1).toUpperCase(),false)) + fun isEditing(editing: Boolean) { + itemView.isActivated = editing + title.visibility = if (editing) View.INVISIBLE else View.VISIBLE + edit_text.visibility = if (!editing) View.INVISIBLE else View.VISIBLE + if (editing) { + edit_text.inputType = InputType.TYPE_TEXT_FLAG_AUTO_CORRECT + edit_text.requestFocus() + edit_text.selectAll() + edit_button.setImageDrawable(ContextCompat.getDrawable(itemView.context, R.drawable.ic_check_white_24dp)) + edit_button.drawable.mutate().setTint(itemView.context.getResourceColor(R.attr.colorAccent)) + showKeyboard() + if (!createCategory) { + reorder.setImageDrawable( + ContextCompat.getDrawable( + itemView.context, R.drawable.ic_delete_white_24dp + ) + ) + reorder.setOnClickListener { + adapter.categoryItemListener.onItemDelete(adapterPosition) + } + } } + else { + if (!createCategory) { + setDragHandleView(reorder) + } + else { + reorder.setOnTouchListener { _, _ -> true} + } + edit_text.clearFocus() + edit_button.setImageDrawable(ContextCompat.getDrawable(itemView.context, R.drawable.ic_edit_white_24dp)) + edit_button.drawable.mutate().setTint(ContextCompat.getColor(itemView.context, R + .color.gray_button)) + reorder.setImageDrawable(regularDrawable) + } + } + + private fun submitChanges() { + if (edit_text.visibility == View.VISIBLE ) { + if (adapter.categoryItemListener + .onCategoryRename(adapterPosition, edit_text.text.toString())) { + isEditing(false) + edit_text.inputType = InputType.TYPE_NULL + if (!createCategory) + title.text = edit_text.text.toString() + } + } + else { + itemView.performClick() + } + } + + private fun showKeyboard() { + val inputMethodManager: InputMethodManager = + itemView.context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager + inputMethodManager.showSoftInput(edit_text, WindowManager.LayoutParams + .SOFT_INPUT_ADJUST_PAN) } /** @@ -48,7 +135,7 @@ class CategoryHolder(view: View, val adapter: CategoryAdapter) : BaseFlexibleVie */ override fun onItemReleased(position: Int) { super.onItemReleased(position) - adapter.onItemReleaseListener.onItemReleased(position) + adapter.categoryItemListener.onItemReleased(position) } } \ No newline at end of file diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/category/CategoryItem.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/category/CategoryItem.kt index 9ea353f92b..f35bdb3627 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/category/CategoryItem.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/category/CategoryItem.kt @@ -7,6 +7,7 @@ import eu.davidea.flexibleadapter.items.AbstractFlexibleItem import eu.davidea.flexibleadapter.items.IFlexible import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.data.database.models.Category +import eu.kanade.tachiyomi.ui.category.CategoryPresenter.Companion.CREATE_CATEGORY_ORDER /** * Category item for a recycler view. @@ -16,7 +17,7 @@ class CategoryItem(val category: Category) : AbstractFlexibleItem>, holder: CategoryHolder, position: Int, payloads: MutableList) { holder.bind(category) + holder.isEditing(isEditing) } /** * Returns true if this item is draggable. */ override fun isDraggable(): Boolean { - return true + return category.order != CREATE_CATEGORY_ORDER && !isEditing } override fun equals(other: Any?): Boolean { diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/category/CategoryPresenter.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/category/CategoryPresenter.kt index 64c7af09a6..ea01818513 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/category/CategoryPresenter.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/category/CategoryPresenter.kt @@ -1,11 +1,13 @@ package eu.kanade.tachiyomi.ui.category -import android.os.Bundle +import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.data.database.DatabaseHelper import eu.kanade.tachiyomi.data.database.models.Category -import eu.kanade.tachiyomi.ui.base.presenter.BasePresenter -import rx.Observable -import rx.android.schedulers.AndroidSchedulers +import eu.kanade.tachiyomi.data.preference.PreferencesHelper +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.GlobalScope +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.api.get @@ -13,27 +15,41 @@ import uy.kohesive.injekt.api.get * Presenter of [CategoryController]. Used to manage the categories of the library. */ class CategoryPresenter( - private val db: DatabaseHelper = Injekt.get() -) : BasePresenter() { + private val controller: CategoryController, + private val db: DatabaseHelper = Injekt.get(), + preferences: PreferencesHelper = Injekt.get() +) { + + private val context = preferences.context /** * List containing categories. */ - private var categories: List = emptyList() + private var categories: MutableList = mutableListOf() /** * Called when the presenter is created. - * - * @param savedState The saved state of this presenter. */ - override fun onCreate(savedState: Bundle?) { - super.onCreate(savedState) - - db.getCategories().asRxObservable() - .doOnNext { categories = it } - .map { it.map(::CategoryItem) } - .observeOn(AndroidSchedulers.mainThread()) - .subscribeLatestCache(CategoryController::setCategories) + fun getCategories() { + if (categories.isNotEmpty()) { + controller.setCategories(categories.map(::CategoryItem)) + } + GlobalScope.launch(Dispatchers.IO) { + categories.clear() + categories.add(newCategory()) + categories.addAll(db.getCategories().executeAsBlocking()) + val catItems = categories.map(::CategoryItem) + withContext(Dispatchers.Main) { + controller.setCategories(catItems) + } + } + } + + private fun newCategory(): Category { + val default = Category.create(context.getString(R.string.create_new_category)) + default.order = CREATE_CATEGORY_ORDER + default.id = Int.MIN_VALUE + return default } /** @@ -41,11 +57,11 @@ class CategoryPresenter( * * @param name The name of the category to create. */ - fun createCategory(name: String) { + fun createCategory(name: String): Boolean { // Do not allow duplicate categories. if (categoryExists(name)) { - Observable.just(Unit).subscribeFirst({ view, _ -> view.onCategoryExistsError() }) - return + controller.onCategoryExistsError() + return false } // Create category. @@ -55,16 +71,25 @@ class CategoryPresenter( cat.order = categories.map { it.order + 1 }.max() ?: 0 // Insert into database. - db.insertCategory(cat).asRxObservable().subscribe() + + db.insertCategory(cat).executeAsBlocking() + val cats = db.getCategories().executeAsBlocking() + val newCat = cats.find { it.name == name } ?: return false + categories.add(1, newCat) + reorderCategories(categories) + return true } /** * Deletes the given categories from the database. * - * @param categories The list of categories to delete. + * @param category The category to delete. */ - fun deleteCategories(categories: List) { - db.deleteCategories(categories).asRxObservable().subscribe() + fun deleteCategory(category: Category?) { + val safeCategory = category ?: return + db.deleteCategory(safeCategory).executeAsBlocking() + categories.remove(safeCategory) + controller.setCategories(categories.map(::CategoryItem)) } /** @@ -74,10 +99,12 @@ class CategoryPresenter( */ fun reorderCategories(categories: List) { categories.forEachIndexed { i, category -> - category.order = i + if (category.order != CREATE_CATEGORY_ORDER) + category.order = i - 1 } - - db.insertCategories(categories).asRxObservable().subscribe() + db.insertCategories(categories.filter { it.order != CREATE_CATEGORY_ORDER }).executeAsBlocking() + this.categories = categories.sortedBy { it.order }.toMutableList() + controller.setCategories(categories.map(::CategoryItem)) } /** @@ -86,22 +113,29 @@ class CategoryPresenter( * @param category The category to rename. * @param name The new name of the category. */ - fun renameCategory(category: Category, name: String) { + fun renameCategory(category: Category, name: String): Boolean { // Do not allow duplicate categories. if (categoryExists(name)) { - Observable.just(Unit).subscribeFirst({ view, _ -> view.onCategoryExistsError() }) - return + controller.onCategoryExistsError() + return false } category.name = name - db.insertCategory(category).asRxObservable().subscribe() + db.insertCategory(category).executeAsBlocking() + categories.find { it.id == category.id }?.name = name + controller.setCategories(categories.map(::CategoryItem)) + return true } /** * Returns true if a category with the given name already exists. */ - fun categoryExists(name: String): Boolean { + private fun categoryExists(name: String): Boolean { return categories.any { it.name.equals(name, true) } } + companion object { + const val CREATE_CATEGORY_ORDER = -2 + } + } \ No newline at end of file diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/extension/ExtensionHolder.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/extension/ExtensionHolder.kt index d3b5aea23c..e7a8127913 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/extension/ExtensionHolder.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/extension/ExtensionHolder.kt @@ -44,13 +44,13 @@ class ExtensionHolder(view: View, override val adapter: ExtensionAdapter) : itemView.context.getString(R.string.ext_untrusted).toUpperCase() } - GlideApp.with(itemView.context).clear(image) + GlideApp.with(itemView.context).clear(edit_button) if (extension is Extension.Available) { GlideApp.with(itemView.context) .load(extension.iconUrl) - .into(image) + .into(edit_button) } else { - extension.getApplicationIcon(itemView.context)?.let { image.setImageDrawable(it) } + extension.getApplicationIcon(itemView.context)?.let { edit_button.setImageDrawable(it) } } bindButton(item) } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryCategoryAdapter.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryCategoryAdapter.kt index 811b69ad49..4a5bae8933 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryCategoryAdapter.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryCategoryAdapter.kt @@ -9,6 +9,8 @@ import eu.kanade.tachiyomi.data.preference.getOrDefault import eu.kanade.tachiyomi.ui.category.CategoryAdapter import eu.kanade.tachiyomi.util.lang.chop import eu.kanade.tachiyomi.util.lang.removeArticles +import eu.kanade.tachiyomi.util.system.launchUI +import kotlinx.coroutines.delay import uy.kohesive.injekt.injectLazy import java.text.SimpleDateFormat import java.util.Calendar @@ -28,9 +30,6 @@ class LibraryCategoryAdapter(val view: LibraryCategoryView) : */ private var mangas: List = emptyList() - val onItemReleaseListener: CategoryAdapter.OnItemReleaseListener = view - - /** * Listener called when an item of the list press start reading. */ @@ -145,5 +144,6 @@ class LibraryCategoryAdapter(val view: LibraryCategoryView) : * Called when an item of the list is released. */ fun startReading(position: Int) + fun onItemReleased(position: Int) } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryCategoryView.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryCategoryView.kt index ded3be3677..517e2faabe 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryCategoryView.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryCategoryView.kt @@ -8,7 +8,6 @@ import android.view.View import androidx.coordinatorlayout.widget.CoordinatorLayout import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView -import androidx.recyclerview.widget.StaggeredGridLayoutManager import eu.davidea.flexibleadapter.FlexibleAdapter import eu.davidea.flexibleadapter.SelectableAdapter import eu.kanade.tachiyomi.R @@ -18,7 +17,6 @@ import eu.kanade.tachiyomi.data.database.models.Manga import eu.kanade.tachiyomi.data.library.LibraryUpdateService import eu.kanade.tachiyomi.data.preference.PreferencesHelper import eu.kanade.tachiyomi.data.preference.getOrDefault -import eu.kanade.tachiyomi.ui.category.CategoryAdapter import eu.kanade.tachiyomi.util.lang.plusAssign import eu.kanade.tachiyomi.util.system.dpToPx import eu.kanade.tachiyomi.util.system.launchUI @@ -40,8 +38,7 @@ class LibraryCategoryView @JvmOverloads constructor(context: Context, attrs: Att FlexibleAdapter.OnItemClickListener, FlexibleAdapter.OnItemLongClickListener, FlexibleAdapter.OnItemMoveListener, - LibraryCategoryAdapter.LibraryListener, - CategoryAdapter.OnItemReleaseListener { + LibraryCategoryAdapter.LibraryListener { /** * Preferences. @@ -209,16 +206,12 @@ class LibraryCategoryView @JvmOverloads constructor(context: Context, attrs: Att * * @param event the event received. */ - fun onNextLibraryManga(event: LibraryMangaEvent) { + private fun onNextLibraryManga(event: LibraryMangaEvent) { // Get the manga list for this category. adapter.isLongPressDragEnabled = canDrag() val mangaForCategory = event.getMangaForCategory(category).orEmpty() - // Update the category with its manga. - // if (!justDraggedAndDropped) - adapter.setItems(mangaForCategory) - // else - // justDraggedAndDropped = false + adapter.setItems(mangaForCategory) swipe_refresh.isEnabled = !preferences.hideCategories().getOrDefault() diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryGridHolder.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryGridHolder.kt index f3e068784e..4f4d9407cc 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryGridHolder.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryGridHolder.kt @@ -31,9 +31,27 @@ class LibraryGridHolder( private val view: View, adapter: LibraryCategoryAdapter, var width:Int, - var fixedSize: Boolean + private var fixedSize: Boolean ) : LibraryHolder(view, adapter) { + init { + play_layout.setOnClickListener { playButtonClicked() } + if (fixedSize) { + title.gone() + subtitle.gone() + } + else { + compact_title.gone() + gradient.gone() + val playLayout = play_layout.layoutParams as FrameLayout.LayoutParams + val buttonLayout = play_button.layoutParams as FrameLayout.LayoutParams + playLayout.gravity = Gravity.BOTTOM or Gravity.END + buttonLayout.gravity = Gravity.BOTTOM or Gravity.END + play_layout.layoutParams = playLayout + play_button.layoutParams = buttonLayout + } + } + /** * Method called from [LibraryCategoryAdapter.onBindViewHolder]. It updates the data for this * holder with the given manga. @@ -44,6 +62,7 @@ class LibraryGridHolder( // Update the title and subtitle of the manga. title.text = item.manga.currentTitle() subtitle.text = item.manga.originalAuthor()?.trim() + if (!fixedSize) { title.viewTreeObserver.addOnPreDrawListener(object : ViewTreeObserver.OnPreDrawListener { override fun onPreDraw(): Boolean { @@ -74,25 +93,13 @@ class LibraryGridHolder( 0 -> if (item.manga.unread > 0) -1 else -2 else -> -2 }, - if (item.manga.source == LocalSource.ID) -2 else item.downloadCount) + when { + item.downloadCount == -1 -> -1 + item.manga.source == LocalSource.ID -> -2 + else -> item.downloadCount + }) play_layout.visibility = if (item.manga.unread > 0 && item.unreadType > -1) View.VISIBLE else View.GONE - play_layout.setOnClickListener { playButtonClicked() } - - if (fixedSize) { - title.gone() - subtitle.gone() - } - else { - compact_title.gone() - gradient.gone() - val playLayout = play_layout.layoutParams as FrameLayout.LayoutParams - val buttonLayout = play_button.layoutParams as FrameLayout.LayoutParams - playLayout.gravity = Gravity.BOTTOM or Gravity.END - buttonLayout.gravity = Gravity.BOTTOM or Gravity.END - play_layout.layoutParams = playLayout - play_button.layoutParams = buttonLayout - } // Update the cover. if (item.manga.thumbnail_url == null) GlideApp.with(view.context).clear(cover_thumbnail) diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryHolder.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryHolder.kt index 7691121905..d2fa4c1f0e 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryHolder.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryHolder.kt @@ -35,7 +35,7 @@ abstract class LibraryHolder( */ override fun onItemReleased(position: Int) { super.onItemReleased(position) - (adapter as? LibraryCategoryAdapter)?.onItemReleaseListener?.onItemReleased(position) + (adapter as? LibraryCategoryAdapter)?.libraryListener?.onItemReleased(position) } protected fun convertColor(color: Int):String { diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryItem.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryItem.kt index 40ca970d36..3b648b8f78 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryItem.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryItem.kt @@ -48,6 +48,7 @@ class LibraryItem(val manga: LibraryManga, private val libraryLayout: Preference val marginParams = card.layoutParams as ConstraintLayout.LayoutParams marginParams.bottomMargin = 6.dpToPx card.layoutParams = marginParams + cover_thumbnail.maxHeight = Integer.MAX_VALUE constraint_layout.minHeight = 0 cover_thumbnail.adjustViewBounds = false cover_thumbnail.layoutParams = FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, coverHeight) diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryListHolder.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryListHolder.kt index d0dfc81710..70dba508a2 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryListHolder.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryListHolder.kt @@ -38,8 +38,16 @@ class LibraryListHolder( title.text = item.manga.currentTitle() badge_view.setUnreadDownload( - if (item.unreadType == 1) item.manga.unread else (item.unreadType - 1), - if (item.manga.source == LocalSource.ID) -2 else item.downloadCount) + when (item.unreadType) { + 1 -> item.manga.unread + 0 -> if (item.manga.unread > 0) -1 else -2 + else -> -2 + }, + when { + item.downloadCount == -1 -> -1 + item.manga.source == LocalSource.ID -> -2 + else -> item.downloadCount + }) subtitle.text = item.manga.originalAuthor()?.trim() subtitle.visibility = if (!item.manga.originalAuthor().isNullOrBlank()) View.VISIBLE diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/main/MainActivity.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/main/MainActivity.kt index a322b459c4..34a41b57a1 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/main/MainActivity.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/main/MainActivity.kt @@ -1,6 +1,7 @@ package eu.kanade.tachiyomi.ui.main import android.app.SearchManager +import android.content.ComponentCallbacks2 import android.content.Intent import android.content.res.Configuration import android.graphics.Color @@ -11,6 +12,7 @@ import android.provider.Settings import android.view.MotionEvent import android.view.View import android.view.ViewGroup +import android.view.WindowManager import android.webkit.WebView import android.widget.FrameLayout import androidx.appcompat.content.res.AppCompatResources @@ -53,8 +55,11 @@ import eu.kanade.tachiyomi.ui.recently_read.RecentlyReadController import eu.kanade.tachiyomi.ui.setting.SettingsMainController import eu.kanade.tachiyomi.util.system.getResourceColor import eu.kanade.tachiyomi.util.system.launchUI +import eu.kanade.tachiyomi.util.view.gone import eu.kanade.tachiyomi.util.view.updateLayoutParams import eu.kanade.tachiyomi.util.view.updatePadding +import eu.kanade.tachiyomi.util.view.updatePaddingRelative +import eu.kanade.tachiyomi.util.view.visible import kotlinx.android.synthetic.main.main_activity.* import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.GlobalScope @@ -166,6 +171,21 @@ open class MainActivity : BaseActivity(), DownloadServiceListener { View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION updateRecentsIcon() + content.viewTreeObserver.addOnGlobalLayoutListener { + val heightDiff: Int = content.rootView.height - content.height + if (heightDiff > 200 && + window.attributes.softInputMode == WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE) { + //keyboard is open, hide layout + navigationView.gone() + } else if (navigationView.visibility == View.GONE) { + //keyboard is hidden, show layout + // use coroutine to delay so the bottom bar doesn't flash on top of the keyboard + launchUI { + navigationView.visible() + } + } + } + content.setOnApplyWindowInsetsListener { v, insets -> // if device doesn't support light nav bar if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) { diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/migration/MangaHolder.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/migration/MangaHolder.kt index 82ac9a4967..bd84561c2e 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/migration/MangaHolder.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/migration/MangaHolder.kt @@ -17,20 +17,13 @@ class MangaHolder( fun bind(item: MangaItem) { // Update the title of the manga. title.text = item.manga.currentTitle() - - // Create thumbnail onclick to simulate long click - cover_thumbnail.setOnClickListener { - // Simulate long click on this view to enter selection mode - onLongClick(itemView) - } + subtitle.text = item.manga.currentAuthor()?.trim() // Update the cover. GlideApp.with(itemView.context).clear(cover_thumbnail) GlideApp.with(itemView.context) .load(item.manga) .diskCacheStrategy(DiskCacheStrategy.RESOURCE) -// .centerCrop() -// .circleCrop() .dontAnimate() .into(cover_thumbnail) } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/migration/MigrationController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/migration/MigrationController.kt index 3c709915de..d39ba258f8 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/migration/MigrationController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/migration/MigrationController.kt @@ -14,10 +14,10 @@ import eu.kanade.tachiyomi.ui.base.controller.NucleusController import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction import eu.kanade.tachiyomi.ui.migration.manga.design.PreMigrationController import eu.kanade.tachiyomi.ui.migration.manga.process.MigrationListController -import eu.kanade.tachiyomi.util.view.RecyclerWindowInsetsListener +import eu.kanade.tachiyomi.ui.migration.manga.process.MigrationProcedureConfig import eu.kanade.tachiyomi.util.system.await import eu.kanade.tachiyomi.util.system.launchUI -import eu.kanade.tachiyomi.ui.migration.manga.process.MigrationProcedureConfig +import eu.kanade.tachiyomi.util.view.RecyclerWindowInsetsListener import kotlinx.android.synthetic.main.migration_controller.* import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext @@ -91,12 +91,17 @@ class MigrationController : NucleusController(), } adapter?.updateDataSet(state.sourcesWithManga) } else { + val switching = title == resources?.getString(R.string.label_migration) title = state.selectedSource.toString() if (adapter !is MangaAdapter) { adapter = MangaAdapter(this) migration_recycler.adapter = adapter } - adapter?.updateDataSet(state.mangaForSource) + adapter?.updateDataSet(state.mangaForSource, true) + /*if (switching) launchUI { + migration_recycler.alpha = 0f + migration_recycler.animate().alpha(1f).setStartDelay(100).setDuration(200).start() + }*/ } } @@ -104,7 +109,7 @@ class MigrationController : NucleusController(), val item = adapter?.getItem(position) ?: return false if (item is MangaItem) { - val controller = SearchController(item.manga) + val controller = PreMigrationController.create(listOf(item.manga.id!!)) controller.targetController = this router.pushController(controller.withFadeTransaction()) diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/migration/SourceHolder.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/migration/SourceHolder.kt index d77d37f96f..959381f0cc 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/migration/SourceHolder.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/migration/SourceHolder.kt @@ -20,7 +20,7 @@ class SourceHolder(view: View, override val adapter: SourceAdapter) : get() = card init { - source_latest.text = "Auto" + source_latest.text = view.context.getString(R.string.action_auto) source_browse.setText(R.string.select) source_browse.setOnClickListener { adapter.selectClickListener?.onSelectClick(adapterPosition) @@ -39,7 +39,7 @@ class SourceHolder(view: View, override val adapter: SourceAdapter) : // Set circle letter image. itemView.post { - image.setImageDrawable(image.getRound(source.name.take(1).toUpperCase(),false)) + edit_button.setImageDrawable(edit_button.getRound(source.name.take(1).toUpperCase(),false)) } } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/migration/manga/design/MigrationSourceHolder.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/migration/manga/design/MigrationSourceHolder.kt index 33417bb578..687eb41687 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/migration/manga/design/MigrationSourceHolder.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/migration/manga/design/MigrationSourceHolder.kt @@ -24,16 +24,16 @@ class MigrationSourceHolder(view: View, val adapter: MigrationSourceAdapter): title.text = sourceName // Update circle letter image. itemView.post { - image.setImageDrawable(image.getRound(source.name.take(1).toUpperCase(),false)) + edit_button.setImageDrawable(edit_button.getRound(source.name.take(1).toUpperCase(),false)) } if(sourceEnabled) { title.alpha = 1.0f - image.alpha = 1.0f + edit_button.alpha = 1.0f title.paintFlags = title.paintFlags and STRIKE_THRU_TEXT_FLAG.inv() } else { title.alpha = DISABLED_ALPHA - image.alpha = DISABLED_ALPHA + edit_button.alpha = DISABLED_ALPHA title.paintFlags = title.paintFlags or STRIKE_THRU_TEXT_FLAG } } diff --git a/app/src/main/res/drawable/bordered_list_selector.xml b/app/src/main/res/drawable/bordered_list_selector.xml new file mode 100644 index 0000000000..7f30001a6c --- /dev/null +++ b/app/src/main/res/drawable/bordered_list_selector.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/rounded_ripple.xml b/app/src/main/res/drawable/rounded_ripple.xml index e581e8ef98..01f8ad0af2 100644 --- a/app/src/main/res/drawable/rounded_ripple.xml +++ b/app/src/main/res/drawable/rounded_ripple.xml @@ -9,26 +9,24 @@ - - - - - - - - - - - - - - + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/catalogue_grid_item.xml b/app/src/main/res/layout/catalogue_grid_item.xml index 2128388604..38d41f2155 100644 --- a/app/src/main/res/layout/catalogue_grid_item.xml +++ b/app/src/main/res/layout/catalogue_grid_item.xml @@ -1,13 +1,7 @@ - - - - - \ No newline at end of file + \ No newline at end of file diff --git a/app/src/main/res/layout/catalogue_main_controller_card_item.xml b/app/src/main/res/layout/catalogue_main_controller_card_item.xml index faf7915d00..84532a8d85 100644 --- a/app/src/main/res/layout/catalogue_main_controller_card_item.xml +++ b/app/src/main/res/layout/catalogue_main_controller_card_item.xml @@ -13,7 +13,7 @@ android:background="?attr/selectable_list_drawable"> diff --git a/app/src/main/res/layout/categories_controller.xml b/app/src/main/res/layout/categories_controller.xml index ad6c6f1f8e..1339f8c0b7 100644 --- a/app/src/main/res/layout/categories_controller.xml +++ b/app/src/main/res/layout/categories_controller.xml @@ -1,9 +1,9 @@ @@ -13,20 +13,13 @@ android:layout_height="match_parent" android:choiceMode="multipleChoice" android:clipToPadding="false" - tools:listitem="@layout/categories_item" - /> - - + tools:listitem="@layout/categories_item" /> + android:visibility="gone" /> diff --git a/app/src/main/res/layout/categories_item.xml b/app/src/main/res/layout/categories_item.xml index cc29883ce8..0b0345af65 100644 --- a/app/src/main/res/layout/categories_item.xml +++ b/app/src/main/res/layout/categories_item.xml @@ -1,40 +1,78 @@ - + android:background="@drawable/bordered_list_selector"> + + android:scaleType="center" + android:tint="?android:attr/textColorPrimary" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent" + app:srcCompat="@drawable/ic_reorder_grey_24dp" /> + + + + + + + + android:textColor="@color/textColorPrimary" + android:textSize="16sp" + app:layout_constraintEnd_toStartOf="@+id/edit_button" + app:layout_constraintStart_toEndOf="@+id/image" + tools:text="Title" /> - - + diff --git a/app/src/main/res/layout/extension_card_item.xml b/app/src/main/res/layout/extension_card_item.xml index 6707a10b82..925d3407bb 100644 --- a/app/src/main/res/layout/extension_card_item.xml +++ b/app/src/main/res/layout/extension_card_item.xml @@ -13,7 +13,7 @@ android:background="?attr/selectable_list_drawable"> Portrait Landscape Default + Create new category Updates Library update frequency @@ -412,6 +413,9 @@ %1$s is already in queue Local Remove from library? + Delete category? + Manga in this category will moved into the + default category. New chapter %d unread @@ -526,7 +530,7 @@ A category with this name already exists! - Categories deleted + Category deleted This will remove the read date of this chapter. Are you sure? @@ -649,5 +653,6 @@ To show this screen again, go to Settings -> Library. Reset Tags Display as + Auto