From 93cb8f649e8d1b1746db924d389dfe5b979f6d12 Mon Sep 17 00:00:00 2001 From: Jay Date: Sat, 14 Mar 2020 16:29:12 -0700 Subject: [PATCH] Updates & Fixes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Made manga header in details its own item Pressing the tab icon in library toggles the filters bottom sheet state, no longer just shows it Pressing the tab icon in browse toggles the extensions sheet Better logic in detecting which section of the list library you're in Fixing: • download cache with incorrect casing • "view chapters" from notifcation • Title bar centering • Filtering by tracker --- .../tachiyomi/data/database/models/Chapter.kt | 9 --- .../tachiyomi/data/download/DownloadCache.kt | 4 +- .../data/notification/NotificationReceiver.kt | 6 +- .../tachiyomi/ui/base/CenteredToolbar.kt | 14 ++-- .../ui/base/controller/BaseController.kt | 8 +-- .../ui/catalogue/CatalogueController.kt | 9 +++ .../tachiyomi/ui/library/LibraryController.kt | 22 +++--- .../tachiyomi/ui/library/LibraryHeaderItem.kt | 5 +- .../ui/library/LibraryListController.kt | 50 ++++++++------ .../ui/library/filter/FilterBottomSheet.kt | 8 ++- .../ui/library/filter/FilterTagGroup.kt | 8 ++- .../kanade/tachiyomi/ui/main/MainActivity.kt | 37 +++++----- .../tachiyomi/ui/manga/MangaChapterHolder.kt | 20 ------ .../ui/manga/MangaDetailsController.kt | 67 +++++++++++-------- .../ui/manga/MangaDetailsPresenter.kt | 2 +- .../tachiyomi/ui/manga/MangaHeaderHolder.kt | 8 +-- .../tachiyomi/ui/manga/MangaHeaderItem.kt | 44 ++++++++++++ .../tachiyomi/ui/manga/chapter/ChapterItem.kt | 17 ++--- .../ui/manga/chapter/ChapterMatHolder.kt | 23 +++---- .../ui/manga/chapter/ChaptersAdapter.kt | 9 +-- .../main/res/layout/catalogue_grid_item.xml | 1 - .../main/res/layout/filter_bottom_sheet.xml | 4 +- .../main/res/layout/unread_download_badge.xml | 4 +- app/src/main/res/values/strings.xml | 4 +- 24 files changed, 212 insertions(+), 171 deletions(-) delete mode 100644 app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaChapterHolder.kt create mode 100644 app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaHeaderItem.kt diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/database/models/Chapter.kt b/app/src/main/java/eu/kanade/tachiyomi/data/database/models/Chapter.kt index 133bb520fe..118344ddb7 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/database/models/Chapter.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/database/models/Chapter.kt @@ -24,19 +24,10 @@ interface Chapter : SChapter, Serializable { val isRecognizedNumber: Boolean get() = chapter_number >= 0f - val isHeader: Boolean - get() = id == Long.MIN_VALUE - companion object { fun create(): Chapter = ChapterImpl().apply { chapter_number = -1f } - - fun createHeader(isExpanded: Boolean): Chapter = ChapterImpl().apply { - id = Long.MIN_VALUE - read = isExpanded - manga_id = null - } } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadCache.kt b/app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadCache.kt index a28e6b581a..c8b06d2dbb 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadCache.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadCache.kt @@ -78,7 +78,9 @@ class DownloadCache( checkRenew() val files = mangaFiles[manga.id] ?: return false - return files.any { it in provider.getValidChapterDirNames(chapter) } + return files.any { file -> provider.getValidChapterDirNames(chapter).any { + it.toLowerCase() == file.toLowerCase() + } } } /** diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/notification/NotificationReceiver.kt b/app/src/main/java/eu/kanade/tachiyomi/data/notification/NotificationReceiver.kt index 67c4dad27a..2a02bb2a60 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/notification/NotificationReceiver.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/notification/NotificationReceiver.kt @@ -395,7 +395,7 @@ class NotificationReceiver : BroadcastReceiver() { } /** - * Returns [PendingIntent] that opens the manga info controller. + * Returns [PendingIntent] that opens the manga details controller. * * @param context context of application * @param manga manga of chapter @@ -404,7 +404,7 @@ class NotificationReceiver : BroadcastReceiver() { PendingIntent { val newIntent = Intent(context, MainActivity::class.java).setAction(MainActivity.SHORTCUT_MANGA) - .addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP) + .addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_SINGLE_TOP) .putExtra(MangaDetailsController.MANGA_EXTRA, manga.id) .putExtra("notificationId", manga.id.hashCode()) .putExtra("groupId", groupId) @@ -422,7 +422,7 @@ class NotificationReceiver : BroadcastReceiver() { internal fun openExtensionsPendingActivity(context: Context): PendingIntent { val newIntent = Intent(context, MainActivity::class.java).setAction(MainActivity.SHORTCUT_EXTENSIONS) - .addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP) + .addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_SINGLE_TOP) return PendingIntent.getActivity( context, 0, newIntent, PendingIntent.FLAG_UPDATE_CURRENT ) diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/base/CenteredToolbar.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/base/CenteredToolbar.kt index 61b5e9e3e9..70536b3350 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/base/CenteredToolbar.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/base/CenteredToolbar.kt @@ -21,8 +21,10 @@ class CenteredToolbar@JvmOverloads constructor(context: Context, attrs: Attribut else { toolbar_title.text = context.getString(resId) post { - toolbar_title.text = context.getString(resId) - requestLayout() + if (navigationIcon !is DrawerArrowDrawable) { + toolbar_title.text = context.getString(resId) + requestLayout() + } } super.setTitle(null) } @@ -31,13 +33,15 @@ class CenteredToolbar@JvmOverloads constructor(context: Context, attrs: Attribut override fun setTitle(title: CharSequence?) { if (navigationIcon is DrawerArrowDrawable) { super.setTitle(title) - toolbar_title.text = null + toolbar_title.text = "" } else { toolbar_title.text = title post { - toolbar_title.text = title - requestLayout() + if (navigationIcon !is DrawerArrowDrawable) { + toolbar_title.text = title + requestLayout() + } } super.setTitle(null) } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/base/controller/BaseController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/base/controller/BaseController.kt index 3cb7dc4bca..4fb0ea481a 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/base/controller/BaseController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/base/controller/BaseController.kt @@ -1,18 +1,15 @@ package eu.kanade.tachiyomi.ui.base.controller import android.os.Bundle -import androidx.appcompat.app.AppCompatActivity import android.view.LayoutInflater -import android.view.Menu -import android.view.MenuInflater import android.view.MenuItem import android.view.View import android.view.ViewGroup +import androidx.appcompat.app.AppCompatActivity import com.bluelinelabs.conductor.Controller import com.bluelinelabs.conductor.ControllerChangeHandler import com.bluelinelabs.conductor.ControllerChangeType import com.bluelinelabs.conductor.RestoreViewOnCreateController -import eu.kanade.tachiyomi.util.view.setOnQueryTextChangeListener import kotlinx.android.extensions.LayoutContainer import kotlinx.android.synthetic.* import timber.log.Timber @@ -82,7 +79,8 @@ abstract class BaseController(bundle: Bundle? = null) : RestoreViewOnCreateContr parentController = parentController.parentController } - (activity as? AppCompatActivity)?.supportActionBar?.title = getTitle() + if (router.backstack.lastOrNull()?.controller() == this) + (activity as? AppCompatActivity)?.supportActionBar?.title = getTitle() } private fun Controller.instance(): String { diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/catalogue/CatalogueController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/catalogue/CatalogueController.kt index 4a9882796c..956a87ba7d 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/catalogue/CatalogueController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/catalogue/CatalogueController.kt @@ -164,6 +164,15 @@ class CatalogueController : NucleusController(), } + fun toggleExtensions() { + if (ext_bottom_sheet.sheetBehavior?.state != BottomSheetBehavior.STATE_COLLAPSED) { + ext_bottom_sheet.sheetBehavior?.state = BottomSheetBehavior.STATE_COLLAPSED + } + else { + ext_bottom_sheet.sheetBehavior?.state = BottomSheetBehavior.STATE_EXPANDED + } + } + override fun handleRootBack(): Boolean { if (ext_bottom_sheet.sheetBehavior?.state != BottomSheetBehavior.STATE_COLLAPSED) { ext_bottom_sheet.sheetBehavior?.state = BottomSheetBehavior.STATE_COLLAPSED diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryController.kt index 7773a0cd46..e66356c2bf 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryController.kt @@ -514,13 +514,7 @@ open class LibraryController( when (item.itemId) { R.id.action_search -> expandActionViewFromInteraction = true R.id.action_library_filter -> { - if (bottom_sheet.sheetBehavior?.isHideable == true && - bottom_sheet.sheetBehavior?.state == BottomSheetBehavior.STATE_EXPANDED) - bottom_sheet.sheetBehavior?.state = BottomSheetBehavior.STATE_HIDDEN - else if (bottom_sheet.sheetBehavior?.state != BottomSheetBehavior.STATE_COLLAPSED - && bottom_sheet.sheetBehavior?.skipCollapsed == false) - bottom_sheet.sheetBehavior?.state = BottomSheetBehavior.STATE_COLLAPSED - else bottom_sheet.sheetBehavior?.state = BottomSheetBehavior.STATE_EXPANDED + toggleFilters() } R.id.action_library_display -> { DisplayBottomSheet(this).show() @@ -531,12 +525,14 @@ open class LibraryController( return true } - fun showFiltersBottomSheet() { - if (bottom_sheet.sheetBehavior?.state == BottomSheetBehavior.STATE_HIDDEN) - bottom_sheet.sheetBehavior?.state = - if (bottom_sheet.sheetBehavior?.skipCollapsed == false) - BottomSheetBehavior.STATE_COLLAPSED - else BottomSheetBehavior.STATE_EXPANDED + fun toggleFilters() { + if (bottom_sheet.sheetBehavior?.isHideable == true && + bottom_sheet.sheetBehavior?.state == BottomSheetBehavior.STATE_EXPANDED) + bottom_sheet.sheetBehavior?.state = BottomSheetBehavior.STATE_HIDDEN + else if (bottom_sheet.sheetBehavior?.state != BottomSheetBehavior.STATE_COLLAPSED + && bottom_sheet.sheetBehavior?.skipCollapsed == false) + bottom_sheet.sheetBehavior?.state = BottomSheetBehavior.STATE_COLLAPSED + else bottom_sheet.sheetBehavior?.state = BottomSheetBehavior.STATE_EXPANDED } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryHeaderItem.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryHeaderItem.kt index b676f946a1..217bef7d78 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryHeaderItem.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryHeaderItem.kt @@ -246,6 +246,9 @@ class LibraryHeaderItem(private val categoryF: (Int) -> Category, val catId: Int checkboxImage.setImageDrawable(tintedDrawable) } - + override fun onLongClick(view: View?): Boolean { + super.onLongClick(view) + return false + } } } \ No newline at end of file diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryListController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryListController.kt index 7207b00abd..6eee7949b1 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryListController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryListController.kt @@ -24,6 +24,7 @@ import com.afollestad.materialdialogs.checkbox.checkBoxPrompt import com.afollestad.materialdialogs.checkbox.isCheckPromptChecked import com.bluelinelabs.conductor.ControllerChangeHandler import com.bluelinelabs.conductor.ControllerChangeType +import com.google.android.material.bottomsheet.BottomSheetBehavior import eu.davidea.flexibleadapter.FlexibleAdapter import eu.davidea.flexibleadapter.SelectableAdapter import eu.davidea.flexibleadapter.items.IFlexible @@ -113,13 +114,7 @@ class LibraryListController(bundle: Bundle? = null) : LibraryController(bundle), private var scrollListener = object : RecyclerView.OnScrollListener () { override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) { super.onScrolled(recyclerView, dx, dy) - val position = - (recycler.layoutManager as LinearLayoutManager).findFirstVisibleItemPosition() - val order = when (val item = adapter.getItem(position)) { - is LibraryHeaderItem -> item.category.order - is LibraryItem -> presenter.categories.find { it.id == item.manga.category }?.order - else -> null - } + val order = getCategoryOrder() if (order != null && order != activeCategory) { preferences.lastUsedCategory().set(order) activeCategory = order @@ -163,13 +158,9 @@ class LibraryListController(bundle: Bundle? = null) : LibraryController(bundle), if (startPosX == null) { startPosX = event.rawX startPosY = event.rawY - val position = - (recycler.layoutManager as LinearLayoutManager).findFirstVisibleItemPosition() - val order = when (val item = adapter.getItem(position)) { - is LibraryHeaderItem -> item.category.order - is LibraryItem -> presenter.categories.find { it.id == item.manga.category }?.order - else -> null - } + val position = (recycler.layoutManager as LinearLayoutManager) + .findFirstVisibleItemPosition() + val order = getCategoryOrder() if (order != null) { ogCategory = order var newOffsetN = order + 1 @@ -255,6 +246,26 @@ class LibraryListController(bundle: Bundle? = null) : LibraryController(bundle), } } + private fun getCategoryOrder(): Int? { + val position = + (recycler.layoutManager as LinearLayoutManager).findFirstCompletelyVisibleItemPosition() + var order = when (val item = adapter.getItem(position)) { + is LibraryHeaderItem -> item.category.order + is LibraryItem -> presenter.categories.find { it.id == item.manga.category }?.order + else -> null + } + if (order == null) { + val fPosition = + (recycler.layoutManager as LinearLayoutManager).findFirstVisibleItemPosition() + order = when (val item = adapter.getItem(fPosition)) { + is LibraryHeaderItem -> item.category.order + is LibraryItem -> presenter.categories.find { it.id == item.manga.category }?.order + else -> null + } + } + return order + } + private fun resetScrollingValues() { startPosX = null startPosY = null @@ -448,13 +459,11 @@ class LibraryListController(bundle: Bundle? = null) : LibraryController(bundle), headerPosition, (if (headerPosition == 0) 0 else (-28).dpToPx) + appbarOffset ) - val isCurrentController = router?.backstack?.lastOrNull()?.controller() == - this val headerItem = adapter.getItem(headerPosition) as? LibraryHeaderItem if (headerItem != null) { customTitleSpinner.category_title.text = headerItem.category.name - if (isCurrentController) setTitle() + setTitle() } recycler.suppressLayout(false) } @@ -590,6 +599,7 @@ class LibraryListController(bundle: Bundle? = null) : LibraryController(bundle), */ override fun onItemLongClick(position: Int) { if (recyclerIsScrolling()) return + if (adapter.getItem(position) is LibraryHeaderItem) return createActionModeIfNeeded() when { lastClickPosition == -1 -> setSelection(position) @@ -778,8 +788,10 @@ class LibraryListController(bundle: Bundle? = null) : LibraryController(bundle), override fun onSwipeTop(x: Float, y: Float) { val sheetRect = Rect() activity!!.navigationView.getGlobalVisibleRect(sheetRect) - if (sheetRect.contains(x.toInt(), y.toInt())) - showFiltersBottomSheet() + if (sheetRect.contains(x.toInt(), y.toInt())) { + if (bottom_sheet.sheetBehavior?.state != BottomSheetBehavior.STATE_EXPANDED) + toggleFilters() + } } override fun onSwipeLeft(x: Float, y: Float) = goToNextCategory(x) override fun onSwipeRight(x: Float, y: Float) = goToNextCategory(x) diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/library/filter/FilterBottomSheet.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/library/filter/FilterBottomSheet.kt index 52ae793f51..261e392e4a 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/library/filter/FilterBottomSheet.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/library/filter/FilterBottomSheet.kt @@ -60,11 +60,9 @@ class FilterBottomSheet @JvmOverloads constructor(context: Context, attrs: Attri private val filterItems:MutableList by lazy { val list = mutableListOf() - list.add(downloaded) list.add(unread) + list.add(downloaded) list.add(completed) - //if (Injekt.get().getCategories().executeAsBlocking().isNotEmpty()) - // list.add(categories) if (Injekt.get().hasLoggedServices()) list.add(tracked) list @@ -261,6 +259,8 @@ class FilterBottomSheet @JvmOverloads constructor(context: Context, attrs: Attri if (tracked.isActivated) { filter_layout.addView(trackers) filterItems.add(trackers!!) + trackers?.setState(FILTER_TRACKER) + reSortViews() } } } @@ -293,6 +293,8 @@ class FilterBottomSheet @JvmOverloads constructor(context: Context, attrs: Attri else if (preferences.filterTracked().getOrDefault() != 1 && trackers?.parent != null) { filter_layout.removeView(trackers) + trackers?.reset() + FILTER_TRACKER = "" filterItems.remove(trackers!!) } val hasFilters = hasActiveFilters() diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/library/filter/FilterTagGroup.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/library/filter/FilterTagGroup.kt index 720e613614..955cae809a 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/library/filter/FilterTagGroup.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/library/filter/FilterTagGroup.kt @@ -3,6 +3,7 @@ package eu.kanade.tachiyomi.ui.library.filter import android.content.Context import android.graphics.Color import android.util.AttributeSet +import android.view.View import android.view.ViewGroup import android.widget.LinearLayout import com.f2prateek.rx.preferences.Preference @@ -76,9 +77,10 @@ class FilterTagGroup@JvmOverloads constructor(context: Context, attrs: Attribute toggleButton(index, false) } - fun setState(enabled: Boolean) { - if (enabled) - toggleButton(0, false) + fun setState(text: String) { + val index = buttons.indexOfFirst { it.text == text && it.visibility == View.VISIBLE } + if (index > -1) + toggleButton(index, false) } fun reset() { 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 612d628007..62fbd57542 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 @@ -36,7 +36,6 @@ import com.google.android.material.snackbar.Snackbar import eu.kanade.tachiyomi.BuildConfig import eu.kanade.tachiyomi.Migrations import eu.kanade.tachiyomi.R -import eu.kanade.tachiyomi.data.download.DownloadManager import eu.kanade.tachiyomi.data.download.DownloadService import eu.kanade.tachiyomi.data.download.DownloadServiceListener import eu.kanade.tachiyomi.data.notification.NotificationReceiver @@ -58,6 +57,7 @@ import eu.kanade.tachiyomi.ui.manga.MangaDetailsController import eu.kanade.tachiyomi.ui.recent_updates.RecentChaptersController import eu.kanade.tachiyomi.ui.recently_read.RecentlyReadController import eu.kanade.tachiyomi.ui.security.SecureActivityDelegate +import eu.kanade.tachiyomi.ui.setting.SettingsController import eu.kanade.tachiyomi.ui.setting.SettingsMainController import eu.kanade.tachiyomi.util.system.getResourceColor import eu.kanade.tachiyomi.util.system.launchUI @@ -71,8 +71,6 @@ import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.delay import kotlinx.coroutines.launch import timber.log.Timber -import uy.kohesive.injekt.Injekt -import uy.kohesive.injekt.api.get import uy.kohesive.injekt.injectLazy import java.util.Date import java.util.concurrent.TimeUnit @@ -169,27 +167,27 @@ open class MainActivity : BaseActivity(), DownloadServiceListener { //R.id.nav_settings -> setRoot(SettingsMainController(), id) } } - else if (currentRoot.tag()?.toIntOrNull() == id) { - when (id) { - R.id.nav_recents -> { - if (router.backstack.size > 1) router.popToRoot() - else { + else if (currentRoot.tag()?.toIntOrNull() == id) { + if (router.backstackSize == 1) { + when (id) { + R.id.nav_recents -> { val showRecents = preferences.showRecentUpdates().getOrDefault() if (!showRecents) setRoot(RecentChaptersController(), id) else setRoot(RecentlyReadController(), id) preferences.showRecentUpdates().set(!showRecents) updateRecentsIcon() } - } - R.id.nav_library -> { - if (router.backstack.size > 1) router.popToRoot() - else { - val controller = router.getControllerWithTag(id.toString()) as? - LibraryController - controller?.showFiltersBottomSheet() + R.id.nav_library -> { + val controller = + router.getControllerWithTag(id.toString()) as? LibraryController + controller?.toggleFilters() + } + R.id.nav_catalogues -> { + val controller = + router.getControllerWithTag(id.toString()) as? CatalogueController + controller?.toggleExtensions() } } - R.id.nav_catalogues -> router.popToRoot() } } true @@ -314,9 +312,6 @@ open class MainActivity : BaseActivity(), DownloadServiceListener { } } - toolbar.navigationIcon = if (router.backstackSize > 1) drawerArrow else searchDrawable - (router.backstack.lastOrNull()?.controller() as? BaseController)?.setTitle() - toolbar.setNavigationOnClickListener { val rootSearchController = router.backstack.lastOrNull()?.controller() if (rootSearchController is RootSearchInterface) { @@ -344,6 +339,10 @@ open class MainActivity : BaseActivity(), DownloadServiceListener { syncActivityViewWithController(router.backstack.lastOrNull()?.controller()) + toolbar.navigationIcon = if (router.backstackSize > 1) drawerArrow else searchDrawable + (router.backstack.lastOrNull()?.controller() as? BaseController)?.setTitle() + (router.backstack.lastOrNull()?.controller() as? SettingsController)?.setTitle() + if (savedInstanceState == null) { // Show changelog if needed if (Migrations.upgrade(preferences)) { diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaChapterHolder.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaChapterHolder.kt deleted file mode 100644 index 785c5453ce..0000000000 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaChapterHolder.kt +++ /dev/null @@ -1,20 +0,0 @@ -package eu.kanade.tachiyomi.ui.manga - -import android.view.View -import eu.kanade.tachiyomi.data.database.models.Manga -import eu.kanade.tachiyomi.ui.base.holder.BaseFlexibleViewHolder -import eu.kanade.tachiyomi.ui.manga.chapter.ChapterItem -import eu.kanade.tachiyomi.ui.manga.chapter.ChaptersAdapter - -abstract class MangaChapterHolder( - private val view: View, - private val adapter: ChaptersAdapter -) : BaseFlexibleViewHolder(view, adapter) { - /** - * Method called from [ChaptersAdapter.onBindViewHolder]. It updates the data for this - * holder with the given manga. - * - * @param item the manga item to bind. - */ - abstract fun bind(item: ChapterItem, manga: Manga) -} \ No newline at end of file diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaDetailsController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaDetailsController.kt index a2dade8ec1..21817c09ab 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaDetailsController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaDetailsController.kt @@ -105,7 +105,7 @@ import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.api.get import java.io.File -open class MangaDetailsController : BaseController, +class MangaDetailsController : BaseController, FlexibleAdapter.OnItemClickListener, FlexibleAdapter.OnItemLongClickListener, ActionMode.Callback, @@ -126,6 +126,7 @@ open class MangaDetailsController : BaseController, if (manga != null) { source = Injekt.get().getOrStub(manga.source) } + presenter = MangaDetailsPresenter(this, manga!!, source!!) } constructor(mangaId: Long) : this( @@ -142,15 +143,15 @@ open class MangaDetailsController : BaseController, private var manga: Manga? = null private var source: Source? = null var colorAnimator:ValueAnimator? = null - lateinit var presenter:MangaDetailsPresenter + val presenter:MangaDetailsPresenter var coverColor:Int? = null var toolbarIsColored = false private var snack: Snackbar? = null val fromCatalogue = args.getBoolean(FROM_CATALOGUE_EXTRA, false) var coverDrawable:Drawable? = null - var trackingBottomSheet: TrackingBottomSheet? = null + private var trackingBottomSheet: TrackingBottomSheet? = null + private var startingDLChapterPos:Int? = null - var startingDLChapterPos:Int? = null /** * Adapter containing a list of chapters. */ @@ -178,7 +179,6 @@ open class MangaDetailsController : BaseController, override fun onViewCreated(view: View) { super.onViewCreated(view) coverColor = null - if (!::presenter.isInitialized) presenter = MangaDetailsPresenter(this, manga!!, source!!) // Init RecyclerView and adapter adapter = ChaptersAdapter(this, view.context) @@ -191,7 +191,7 @@ open class MangaDetailsController : BaseController, DividerItemDecoration.VERTICAL ) ) - recycler.setHasFixedSize(false) + recycler.setHasFixedSize(true) adapter?.fastScroller = fast_scroller val attrsArray = intArrayOf(android.R.attr.actionBarSize) val array = view.context.obtainStyledAttributes(attrsArray) @@ -208,7 +208,6 @@ open class MangaDetailsController : BaseController, topMargin = appbarHeight + insets.systemWindowInsetTop bottomMargin = insets.systemWindowInsetBottom } - // offset the recycler by the fab's inset + some inset on top v.updatePaddingRelative(bottom = insets.systemWindowInsetBottom) } @@ -306,6 +305,11 @@ open class MangaDetailsController : BaseController, presenter.isLockedFromSearch = SecureActivityDelegate.shouldBeLocked() presenter.headerItem.isLocked = presenter.isLockedFromSearch presenter.fetchChapters() + val isCurrentController = router?.backstack?.lastOrNull()?.controller() == + this + if (isCurrentController) { + setStatusBarAndToolbar() + } } fun showError(message: String) { @@ -325,10 +329,7 @@ open class MangaDetailsController : BaseController, override fun onChangeStarted(handler: ControllerChangeHandler, type: ControllerChangeType) { super.onChangeStarted(handler, type) if (type == ControllerChangeType.PUSH_ENTER || type == ControllerChangeType.POP_ENTER) { - setStatusBar() - (activity as MainActivity).appbar.setBackgroundColor(Color.TRANSPARENT) - (activity as MainActivity).toolbar.setBackgroundColor(activity?.window?.statusBarColor - ?: Color.TRANSPARENT) + setStatusBarAndToolbar() } else if (type == ControllerChangeType.PUSH_EXIT || type == ControllerChangeType.POP_EXIT) { if (router.backstack.lastOrNull()?.controller() is DialogController) @@ -351,15 +352,9 @@ open class MangaDetailsController : BaseController, } fun updateHeader() { - if (presenter.chapters.isEmpty()) { - adapter?.updateDataSet(listOf(presenter.headerItem)) - } - else { - swipe_refresh?.isRefreshing = presenter.isLoading - adapter?.updateDataSet( - listOf(ChapterItem(presenter.headerItem, presenter.manga)) + presenter.chapters - ) - } + swipe_refresh?.isRefreshing = presenter.isLoading + adapter?.setChapters(presenter.chapters) + addMangaHeader() activity?.invalidateOptionsMenu() } @@ -369,15 +364,15 @@ open class MangaDetailsController : BaseController, launchUI { swipe_refresh?.isRefreshing = true } presenter.fetchChaptersFromSource() } - adapter?.updateDataSet(listOf(presenter.headerItem) + chapters) + adapter?.setChapters(chapters) + addMangaHeader() activity?.invalidateOptionsMenu() } fun refreshAdapter() = adapter?.notifyDataSetChanged() override fun onItemClick(view: View?, position: Int): Boolean { - val chapter = adapter?.getItem(position)?.chapter ?: return false - if (chapter.isHeader) return false + val chapter = (adapter?.getItem(position) as? ChapterItem)?.chapter ?: return false if (actionMode != null) { if (startingDLChapterPos == null) { adapter?.addSelection(position) @@ -410,7 +405,7 @@ open class MangaDetailsController : BaseController, override fun onItemLongClick(position: Int) { val adapter = adapter ?: return - val item = adapter.getItem(position) ?: return + val item = (adapter.getItem(position) as? ChapterItem) ?: return val itemView = getHolder(item)?.itemView ?: return val popup = PopupMenu(itemView.context, itemView, Gravity.END) @@ -709,7 +704,7 @@ open class MangaDetailsController : BaseController, } override fun startDownloadRange(position: Int) { - createActionModeIfNeeded() + if (actionMode == null) createActionModeIfNeeded() onItemClick(null, position) } @@ -743,8 +738,11 @@ open class MangaDetailsController : BaseController, override fun downloadChapter(position: Int) { val view = view ?: return - val chapter = adapter?.getItem(position) ?: return - if (chapter.isHeader) return + val chapter = (adapter?.getItem(position) as? ChapterItem) ?: return + if (actionMode != null) { + onItemClick(null, position) + return + } if (chapter.status != Download.NOT_DOWNLOADED && chapter.status != Download.ERROR) { presenter.deleteChapters(listOf(chapter)) } @@ -970,19 +968,30 @@ open class MangaDetailsController : BaseController, override fun onDestroyActionMode(mode: ActionMode?) { actionMode = null - setStatusBar() + setStatusBarAndToolbar() startingDLChapterPos = null adapter?.mode = SelectableAdapter.Mode.IDLE adapter?.clearSelection() return } - private fun setStatusBar() { + /** + * Called to set the last used catalogue at the top of the view. + */ + private fun addMangaHeader() { + adapter?.removeAllScrollableHeaders() + adapter?.addScrollableHeader(presenter.headerItem) + } + + private fun setStatusBarAndToolbar() { activity?.window?.statusBarColor = if (toolbarIsColored) { val translucentColor = ColorUtils.setAlphaComponent(coverColor ?: Color.TRANSPARENT, 175) (activity as MainActivity).toolbar.setBackgroundColor(translucentColor) translucentColor } else Color.TRANSPARENT + (activity as MainActivity).appbar.setBackgroundColor(Color.TRANSPARENT) + (activity as MainActivity).toolbar.setBackgroundColor(activity?.window?.statusBarColor + ?: Color.TRANSPARENT) } override fun onPrepareActionMode(mode: ActionMode?, menu: Menu?): Boolean { diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaDetailsPresenter.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaDetailsPresenter.kt index 08878bf885..b46d7262e8 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaDetailsPresenter.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaDetailsPresenter.kt @@ -69,7 +69,7 @@ class MangaDetailsPresenter(private val controller: MangaDetailsController, var chapters:List = emptyList() private set - var headerItem = ChapterItem(Chapter.createHeader(controller.fromCatalogue), manga) + var headerItem = MangaHeaderItem(manga, controller.fromCatalogue) fun onCreate() { isLockedFromSearch = SecureActivityDelegate.shouldBeLocked() diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaHeaderHolder.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaHeaderHolder.kt index e855a62933..7bac6c3ebd 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaHeaderHolder.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaHeaderHolder.kt @@ -16,7 +16,7 @@ import eu.kanade.tachiyomi.data.database.models.Manga import eu.kanade.tachiyomi.data.database.models.MangaImpl import eu.kanade.tachiyomi.data.glide.GlideApp import eu.kanade.tachiyomi.source.model.SManga -import eu.kanade.tachiyomi.ui.manga.chapter.ChapterItem +import eu.kanade.tachiyomi.ui.base.holder.BaseFlexibleViewHolder import eu.kanade.tachiyomi.ui.manga.chapter.ChaptersAdapter import eu.kanade.tachiyomi.util.system.getResourceColor import eu.kanade.tachiyomi.util.view.gone @@ -30,7 +30,7 @@ class MangaHeaderHolder( private val view: View, private val adapter: ChaptersAdapter, startExpanded: Boolean -) : MangaChapterHolder(view, adapter) { +) : BaseFlexibleViewHolder(view, adapter) { init { start_reading_button.setOnClickListener { adapter.coverListener.readNextChapter() } @@ -84,8 +84,8 @@ class MangaHeaderHolder( } @SuppressLint("SetTextI18n") - override fun bind(item: ChapterItem, manga: Manga) { - val presenter = adapter.coverListener?.mangaPresenter() ?: return + fun bind(item: MangaHeaderItem, manga: Manga) { + val presenter = adapter.coverListener.mangaPresenter() manga_full_title.text = manga.currentTitle() if (manga.currentGenres().isNullOrBlank().not()) diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaHeaderItem.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaHeaderItem.kt new file mode 100644 index 0000000000..50a66082d9 --- /dev/null +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaHeaderItem.kt @@ -0,0 +1,44 @@ +package eu.kanade.tachiyomi.ui.manga + +import android.view.View +import androidx.recyclerview.widget.RecyclerView +import eu.davidea.flexibleadapter.FlexibleAdapter +import eu.davidea.flexibleadapter.items.AbstractFlexibleItem +import eu.davidea.flexibleadapter.items.IFlexible +import eu.kanade.tachiyomi.R +import eu.kanade.tachiyomi.data.database.models.Manga +import eu.kanade.tachiyomi.ui.manga.chapter.ChaptersAdapter + +class MangaHeaderItem(val manga: Manga, private val startExpanded: Boolean): + AbstractFlexibleItem(){ + + var isLocked = false + + override fun getLayoutRes(): Int { + return R.layout.manga_header_item + } + + override fun isSelectable(): Boolean { + return false + } + + override fun createViewHolder(view: View, adapter: FlexibleAdapter>): MangaHeaderHolder { + return MangaHeaderHolder(view, adapter as ChaptersAdapter, startExpanded) + } + + override fun bindViewHolder(adapter: FlexibleAdapter>, + holder: MangaHeaderHolder, + position: Int, + payloads: MutableList?) { + holder.bind(this, manga) + } + + override fun equals(other: Any?): Boolean { + return (this === other) + } + + override fun hashCode(): Int { + return manga.id!!.hashCode() + } + +} diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChapterItem.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChapterItem.kt index 130894fbf4..d16d7efa77 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChapterItem.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChapterItem.kt @@ -10,11 +10,9 @@ import eu.kanade.tachiyomi.data.database.models.Chapter import eu.kanade.tachiyomi.data.database.models.Manga import eu.kanade.tachiyomi.data.download.model.Download import eu.kanade.tachiyomi.source.model.Page -import eu.kanade.tachiyomi.ui.manga.MangaChapterHolder -import eu.kanade.tachiyomi.ui.manga.MangaHeaderHolder class ChapterItem(val chapter: Chapter, val manga: Manga) : - AbstractFlexibleItem(), + AbstractFlexibleItem(), Chapter by chapter { private var _status: Int = 0 @@ -36,22 +34,19 @@ class ChapterItem(val chapter: Chapter, val manga: Manga) : get() = status == Download.DOWNLOADED override fun getLayoutRes(): Int { - return if (chapter.isHeader) R.layout.manga_header_item - else R.layout.chapters_mat_item + return R.layout.chapters_mat_item } override fun isSelectable(): Boolean { - return !chapter.isHeader + return true } - override fun createViewHolder(view: View, adapter: FlexibleAdapter>): MangaChapterHolder { - return if (chapter.isHeader) MangaHeaderHolder(view, adapter as ChaptersAdapter, - startExpanded = chapter.read) - else ChapterMatHolder(view, adapter as ChaptersAdapter) + override fun createViewHolder(view: View, adapter: FlexibleAdapter>): ChapterMatHolder { + return ChapterMatHolder(view, adapter as ChaptersAdapter) } override fun bindViewHolder(adapter: FlexibleAdapter>, - holder: MangaChapterHolder, + holder: ChapterMatHolder, position: Int, payloads: MutableList?) { holder.bind(this, manga) diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChapterMatHolder.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChapterMatHolder.kt index b4c8fad61e..3ac3dbd09e 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChapterMatHolder.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChapterMatHolder.kt @@ -6,10 +6,10 @@ import androidx.appcompat.widget.PopupMenu import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.data.database.models.Manga import eu.kanade.tachiyomi.data.download.model.Download -import eu.kanade.tachiyomi.ui.manga.MangaChapterHolder +import eu.kanade.tachiyomi.source.LocalSource +import eu.kanade.tachiyomi.ui.base.holder.BaseFlexibleViewHolder import eu.kanade.tachiyomi.util.view.gone -import eu.kanade.tachiyomi.util.view.invisible -import eu.kanade.tachiyomi.util.view.visible +import eu.kanade.tachiyomi.util.view.visibleIf import kotlinx.android.synthetic.main.chapters_mat_item.* import kotlinx.android.synthetic.main.download_button.* import java.util.Date @@ -17,8 +17,9 @@ import java.util.Date class ChapterMatHolder( private val view: View, private val adapter: ChaptersAdapter -) : MangaChapterHolder(view, adapter) { +) : BaseFlexibleViewHolder(view, adapter) { + private var localSource = false init { download_button.setOnClickListener { downloadOrRemoveMenu() } download_button.setOnLongClickListener { @@ -28,7 +29,7 @@ class ChapterMatHolder( } private fun downloadOrRemoveMenu() { - val chapter = adapter.getItem(adapterPosition) ?: return + val chapter = adapter.getItem(adapterPosition) as? ChapterItem ?: return if (chapter.status == Download.NOT_DOWNLOADED || chapter.status == Download.ERROR) { adapter.coverListener.downloadChapter(adapterPosition) } else { @@ -56,7 +57,7 @@ class ChapterMatHolder( } } - override fun bind(item: ChapterItem, manga: Manga) { + fun bind(item: ChapterItem, manga: Manga) { val chapter = item.chapter val isLocked = item.isLocked chapter_title.text = when (manga.displayMode) { @@ -67,12 +68,10 @@ class ChapterMatHolder( else -> chapter.name } - //chapter_menu.visible() - // Set the correct drawable for dropdown and update the tint to match theme. - //chapter_menu.setVectorCompat(R.drawable.ic_more_vert_black_24dp, view.context - // .getResourceColor(R.attr.icon_color)) + localSource = manga.source == LocalSource.ID + download_button.visibleIf(!localSource) - if (isLocked) download_button.invisible() + if (isLocked) download_button.gone() // Set correct text color @@ -110,7 +109,7 @@ class ChapterMatHolder( gone() return } - visible() + download_button.visibleIf(!localSource) setDownloadStatus(status, progress) } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChaptersAdapter.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChaptersAdapter.kt index a317758899..c6168821f2 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChaptersAdapter.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChaptersAdapter.kt @@ -4,22 +4,21 @@ import android.content.Context import android.view.View import androidx.fragment.app.FragmentActivity import eu.davidea.flexibleadapter.FlexibleAdapter +import eu.davidea.flexibleadapter.items.IFlexible import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.data.preference.PreferencesHelper -import eu.kanade.tachiyomi.data.preference.getOrDefault import eu.kanade.tachiyomi.ui.manga.MangaDetailsController import eu.kanade.tachiyomi.ui.manga.MangaDetailsPresenter import eu.kanade.tachiyomi.ui.security.SecureActivityDelegate import eu.kanade.tachiyomi.util.system.getResourceColor import uy.kohesive.injekt.injectLazy -import java.text.DateFormat import java.text.DecimalFormat import java.text.DecimalFormatSymbols class ChaptersAdapter( val controller: MangaDetailsController, context: Context -) : FlexibleAdapter(null, controller, true) { +) : FlexibleAdapter>(null, controller, true) { val preferences: PreferencesHelper by injectLazy() @@ -36,9 +35,7 @@ class ChaptersAdapter( val decimalFormat = DecimalFormat("#.###", DecimalFormatSymbols() .apply { decimalSeparator = '.' }) - val dateFormat: DateFormat = preferences.dateFormat().getOrDefault() - - override fun updateDataSet(items: List?) { + fun setChapters(items: List?) { this.items = items ?: emptyList() super.updateDataSet(items) } diff --git a/app/src/main/res/layout/catalogue_grid_item.xml b/app/src/main/res/layout/catalogue_grid_item.xml index 1277fd6bd9..94bd935885 100644 --- a/app/src/main/res/layout/catalogue_grid_item.xml +++ b/app/src/main/res/layout/catalogue_grid_item.xml @@ -156,6 +156,5 @@ tools:text="Sample artist" /> - \ No newline at end of file diff --git a/app/src/main/res/layout/filter_bottom_sheet.xml b/app/src/main/res/layout/filter_bottom_sheet.xml index 5df715915c..3b6b535112 100644 --- a/app/src/main/res/layout/filter_bottom_sheet.xml +++ b/app/src/main/res/layout/filter_bottom_sheet.xml @@ -30,7 +30,7 @@ android:layout_height="wrap_content" android:layout_marginTop="2dp" android:clipToPadding="false" - android:paddingStart="20dp" + android:paddingStart="10dp" android:paddingTop="8dp" android:paddingEnd="20dp" android:paddingBottom="6dp" @@ -63,7 +63,7 @@ Download Download custom amount Next chapter - First unread chapter - Next 5 chapters + Next unread chapter + Next 5 unread Next 10 chapters Custom range All chapters