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