Lotta stuff for new manga controller

Added pages left for chapters db, shown in the new chapters item
Added new manga controller everywhere
Added Fetching to the manga controller
Added Manhua and Comics to filters, manhua and comics are now LTR by default
This commit is contained in:
Jay 2020-03-02 02:18:48 -08:00
parent c2b1c3f63f
commit c3620b74f1
68 changed files with 703 additions and 404 deletions

View File

@ -18,7 +18,7 @@ class DbOpenCallback : SupportSQLiteOpenHelper.Callback(DATABASE_VERSION) {
/**
* Version of the database.
*/
const val DATABASE_VERSION = 10
const val DATABASE_VERSION = 11
}
override fun onCreate(db: SupportSQLiteDatabase) = with(db) {
@ -73,6 +73,9 @@ class DbOpenCallback : SupportSQLiteOpenHelper.Callback(DATABASE_VERSION) {
if (oldVersion < 10) {
db.execSQL(CategoryTable.addMangaOrder)
}
if (oldVersion < 11) {
db.execSQL(ChapterTable.pagesLeftQuery)
}
}
override fun onConfigure(db: SupportSQLiteDatabase) {

View File

@ -19,6 +19,7 @@ import eu.kanade.tachiyomi.data.database.tables.ChapterTable.COL_ID
import eu.kanade.tachiyomi.data.database.tables.ChapterTable.COL_LAST_PAGE_READ
import eu.kanade.tachiyomi.data.database.tables.ChapterTable.COL_MANGA_ID
import eu.kanade.tachiyomi.data.database.tables.ChapterTable.COL_NAME
import eu.kanade.tachiyomi.data.database.tables.ChapterTable.COL_PAGES_LEFT
import eu.kanade.tachiyomi.data.database.tables.ChapterTable.COL_READ
import eu.kanade.tachiyomi.data.database.tables.ChapterTable.COL_SCANLATOR
import eu.kanade.tachiyomi.data.database.tables.ChapterTable.COL_SOURCE_ORDER
@ -54,6 +55,7 @@ class ChapterPutResolver : DefaultPutResolver<Chapter>() {
put(COL_DATE_FETCH, obj.date_fetch)
put(COL_DATE_UPLOAD, obj.date_upload)
put(COL_LAST_PAGE_READ, obj.last_page_read)
put(COL_PAGES_LEFT, obj.pages_left)
put(COL_CHAPTER_NUMBER, obj.chapter_number)
put(COL_SOURCE_ORDER, obj.source_order)
}
@ -72,6 +74,7 @@ class ChapterGetResolver : DefaultGetResolver<Chapter>() {
date_fetch = cursor.getLong(cursor.getColumnIndex(COL_DATE_FETCH))
date_upload = cursor.getLong(cursor.getColumnIndex(COL_DATE_UPLOAD))
last_page_read = cursor.getInt(cursor.getColumnIndex(COL_LAST_PAGE_READ))
pages_left = cursor.getInt(cursor.getColumnIndex(COL_PAGES_LEFT))
chapter_number = cursor.getFloat(cursor.getColumnIndex(COL_CHAPTER_NUMBER))
source_order = cursor.getInt(cursor.getColumnIndex(COL_SOURCE_ORDER))
}

View File

@ -15,6 +15,8 @@ interface Chapter : SChapter, Serializable {
var last_page_read: Int
var pages_left: Int
var date_fetch: Long
var source_order: Int
@ -22,10 +24,18 @@ 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 createH(): Chapter = ChapterImpl().apply {
id = Long.MIN_VALUE
manga_id = null
}
}
}

View File

@ -18,6 +18,8 @@ class ChapterImpl : Chapter {
override var last_page_read: Int = 0
override var pages_left: Int = 0
override var date_fetch: Long = 0
override var date_upload: Long = 0

View File

@ -35,14 +35,24 @@ interface Manga : SManga {
fun mangaType(): Int {
val sourceManager: SourceManager by injectLazy()
return if (currentGenres()?.split(",")?.any
val currentTags = currentGenres()?.split(",")?.map { it.trim().toLowerCase(Locale.US) }
return if (currentTags?.any
{ tag ->
val trimmedTag = tag.trim().toLowerCase(Locale.US)
trimmedTag == "long strip" || trimmedTag == "manhwa" ||
trimmedTag.contains("webtoon")
tag == "long strip" || tag == "manhwa" ||
tag.contains("webtoon")
} == true ||
sourceManager.getOrStub(source).name.contains("webtoon", true))
TYPE_MANHWA
TYPE_WEBTOON
else if (currentTags?.any
{ tag ->
tag.startsWith("chinese") || tag == "manhua"
} == true)
TYPE_MANHUA
else if (currentTags?.any
{ tag ->
tag.startsWith("english") || tag == "comic"
} == true)
TYPE_COMIC
else TYPE_MANGA
}
@ -97,7 +107,9 @@ interface Manga : SManga {
const val DISPLAY_MASK = 0x00100000
const val TYPE_MANGA = 0
const val TYPE_MANHWA = 1
const val TYPE_WEBTOON = 1
const val TYPE_MANHUA = 2
const val TYPE_COMIC = 3
fun create(source: Long): Manga = MangaImpl().apply {
this.source = source

View File

@ -29,6 +29,7 @@ class ChapterProgressPutResolver : PutResolver<Chapter>() {
put(ChapterTable.COL_READ, chapter.read)
put(ChapterTable.COL_BOOKMARK, chapter.bookmark)
put(ChapterTable.COL_LAST_PAGE_READ, chapter.last_page_read)
put(ChapterTable.COL_PAGES_LEFT, chapter.pages_left)
}
}

View File

@ -24,6 +24,8 @@ object ChapterTable {
const val COL_LAST_PAGE_READ = "last_page_read"
const val COL_PAGES_LEFT = "pages_left"
const val COL_CHAPTER_NUMBER = "chapter_number"
const val COL_SOURCE_ORDER = "source_order"
@ -38,6 +40,7 @@ object ChapterTable {
$COL_READ BOOLEAN NOT NULL,
$COL_BOOKMARK BOOLEAN NOT NULL,
$COL_LAST_PAGE_READ INT NOT NULL,
$COL_PAGES_LEFT INT NOT NULL,
$COL_CHAPTER_NUMBER FLOAT NOT NULL,
$COL_SOURCE_ORDER INTEGER NOT NULL,
$COL_DATE_FETCH LONG NOT NULL,
@ -62,4 +65,7 @@ object ChapterTable {
val addScanlator: String
get() = "ALTER TABLE $TABLE ADD COLUMN $COL_SCANLATOR TEXT DEFAULT NULL"
val pagesLeftQuery: String
get() = "ALTER TABLE $TABLE ADD COLUMN $COL_PAGES_LEFT INTEGER DEFAULT 0"
}

View File

@ -28,6 +28,7 @@ import eu.kanade.tachiyomi.ui.catalogue.global_search.CatalogueSearchController
import eu.kanade.tachiyomi.ui.catalogue.latest.LatestUpdatesController
import eu.kanade.tachiyomi.ui.setting.SettingsSourcesController
import eu.kanade.tachiyomi.util.view.RecyclerWindowInsetsListener
import eu.kanade.tachiyomi.util.view.applyWindowInsetsForController
import eu.kanade.tachiyomi.widget.preference.SourceLoginDialog
import kotlinx.android.parcel.Parcelize
import kotlinx.android.synthetic.main.catalogue_main_controller.*
@ -101,6 +102,7 @@ class CatalogueController : NucleusController<CataloguePresenter>(),
*/
override fun onViewCreated(view: View) {
super.onViewCreated(view)
view.applyWindowInsetsForController()
adapter = CatalogueAdapter(this)

View File

@ -32,11 +32,13 @@ import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction
import eu.kanade.tachiyomi.ui.catalogue.CatalogueController
import eu.kanade.tachiyomi.ui.library.ChangeMangaCategoriesDialog
import eu.kanade.tachiyomi.ui.main.MainActivity
import eu.kanade.tachiyomi.ui.manga.MangaChaptersController
import eu.kanade.tachiyomi.ui.manga.MangaController
import eu.kanade.tachiyomi.ui.webview.WebViewActivity
import eu.kanade.tachiyomi.util.system.connectivityManager
import eu.kanade.tachiyomi.util.view.HeightTopWindowInsetsListener
import eu.kanade.tachiyomi.util.view.RecyclerWindowInsetsListener
import eu.kanade.tachiyomi.util.view.applyWindowInsetsForController
import eu.kanade.tachiyomi.util.view.gone
import eu.kanade.tachiyomi.util.view.inflate
import eu.kanade.tachiyomi.util.view.marginBottom
@ -47,7 +49,6 @@ import eu.kanade.tachiyomi.util.view.updatePaddingRelative
import eu.kanade.tachiyomi.util.view.visible
import eu.kanade.tachiyomi.widget.AutofitRecyclerView
import kotlinx.android.synthetic.main.catalogue_controller.*
import kotlinx.android.synthetic.main.main_activity.*
import rx.Observable
import rx.Subscription
import rx.android.schedulers.AndroidSchedulers
@ -140,6 +141,7 @@ open class BrowseCatalogueController(bundle: Bundle) :
override fun onViewCreated(view: View) {
super.onViewCreated(view)
view.applyWindowInsetsForController()
// Initialize adapter, scroll listener and recycler views
adapter = FlexibleAdapter(null, this)
@ -317,7 +319,7 @@ open class BrowseCatalogueController(bundle: Bundle) :
when (item.itemId) {
R.id.action_search -> expandActionViewFromInteraction = true
R.id.action_display_mode -> swapDisplayMode()
R.id.action_set_filter -> navView?.let { activity?.drawer?.openDrawer(GravityCompat.END) }
// R.id.action_set_filter -> navView?.let { activity?.drawer?.openDrawer(GravityCompat.END) }
R.id.action_open_in_web_view -> openInWebView()
else -> return super.onOptionsItemSelected(item)
}
@ -499,7 +501,7 @@ open class BrowseCatalogueController(bundle: Bundle) :
*/
override fun onItemClick(view: View?, position: Int): Boolean {
val item = adapter?.getItem(position) as? CatalogueItem ?: return false
router.pushController(MangaController(item.manga, true).withFadeTransaction())
router.pushController(MangaChaptersController(item.manga, true).withFadeTransaction())
return false
}

View File

@ -14,8 +14,9 @@ import eu.kanade.tachiyomi.data.database.models.Manga
import eu.kanade.tachiyomi.source.CatalogueSource
import eu.kanade.tachiyomi.ui.base.controller.NucleusController
import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction
import eu.kanade.tachiyomi.ui.manga.MangaController
import eu.kanade.tachiyomi.ui.manga.MangaChaptersController
import eu.kanade.tachiyomi.util.view.RecyclerWindowInsetsListener
import eu.kanade.tachiyomi.util.view.applyWindowInsetsForController
import kotlinx.android.synthetic.main.catalogue_global_search_controller.*
/**
@ -79,7 +80,7 @@ open class CatalogueSearchController(
*/
override fun onMangaClick(manga: Manga) {
// Open MangaController.
router.pushController(MangaController(manga, true).withFadeTransaction())
router.pushController(MangaChaptersController(manga, true).withFadeTransaction())
}
/**
@ -135,6 +136,7 @@ open class CatalogueSearchController(
*/
override fun onViewCreated(view: View) {
super.onViewCreated(view)
view.applyWindowInsetsForController()
adapter = CatalogueSearchAdapter(this)
@ -193,7 +195,7 @@ open class CatalogueSearchController(
val results = searchResult.first().results
if (results != null && results.size == 1) {
val manga = results.first().manga
router.replaceTopController(MangaController(manga,true,fromExtension = true)
router.replaceTopController(MangaChaptersController(manga, true)
.withFadeTransaction()
)
return

View File

@ -10,13 +10,13 @@ import com.afollestad.materialdialogs.MaterialDialog
import com.google.android.material.snackbar.BaseTransientBottomBar
import com.google.android.material.snackbar.Snackbar
import eu.davidea.flexibleadapter.FlexibleAdapter
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.BaseController
import eu.kanade.tachiyomi.ui.category.CategoryPresenter.Companion.CREATE_CATEGORY_ORDER
import eu.kanade.tachiyomi.ui.main.MainActivity
import eu.kanade.tachiyomi.util.system.toast
import eu.kanade.tachiyomi.util.view.applyWindowInsetsForController
import eu.kanade.tachiyomi.util.view.snack
import kotlinx.android.synthetic.main.categories_controller.*
@ -68,6 +68,7 @@ class CategoryController(bundle: Bundle? = null) : BaseController(bundle),
*/
override fun onViewCreated(view: View) {
super.onViewCreated(view)
view.applyWindowInsetsForController()
adapter = CategoryAdapter(this@CategoryController)
recycler.layoutManager = LinearLayoutManager(view.context)

View File

@ -8,18 +8,16 @@ import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.LinearLayoutManager
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.model.Download
import eu.kanade.tachiyomi.source.model.Page
import eu.kanade.tachiyomi.ui.base.controller.NucleusController
import eu.kanade.tachiyomi.util.view.RecyclerWindowInsetsListener
import eu.kanade.tachiyomi.util.view.applyWindowInsetsForController
import kotlinx.android.synthetic.main.download_controller.*
import rx.Observable
import rx.Subscription
import rx.android.schedulers.AndroidSchedulers
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.injectLazy
import java.util.HashMap
import java.util.concurrent.TimeUnit
@ -63,6 +61,7 @@ class DownloadController : NucleusController<DownloadPresenter>(),
override fun onViewCreated(view: View) {
super.onViewCreated(view)
view.applyWindowInsetsForController()
// Check if download queue is empty and update information accordingly.
setInformationView()

View File

@ -38,7 +38,7 @@ class DownloadHolder(private val view: View, val adapter: DownloadAdapter) :
chapter_title.text = download.chapter.name
// Update the manga title
manga_title.text = download.manga.currentTitle()
manga_full_title.text = download.manga.currentTitle()
// Update the progress bar and the number of downloaded pages
val pages = download.pages

View File

@ -23,6 +23,7 @@ import eu.kanade.tachiyomi.extension.model.Extension
import eu.kanade.tachiyomi.ui.base.controller.NucleusController
import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction
import eu.kanade.tachiyomi.util.view.RecyclerWindowInsetsListener
import eu.kanade.tachiyomi.util.view.applyWindowInsetsForController
import kotlinx.android.synthetic.main.extension_controller.*
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
@ -63,6 +64,7 @@ open class ExtensionController : NucleusController<ExtensionPresenter>(),
override fun onViewCreated(view: View) {
super.onViewCreated(view)
view.applyWindowInsetsForController()
ext_swipe_refresh.isRefreshing = true
ext_swipe_refresh.refreshes().subscribeUntilDestroy {

View File

@ -1,7 +1,6 @@
package eu.kanade.tachiyomi.ui.extension
import android.annotation.SuppressLint
import android.app.Dialog
import android.content.Context
import android.os.Bundle
import android.util.TypedValue
@ -30,9 +29,10 @@ import eu.kanade.tachiyomi.source.Source
import eu.kanade.tachiyomi.source.online.LoginSource
import eu.kanade.tachiyomi.ui.base.controller.NucleusController
import eu.kanade.tachiyomi.ui.setting.preferenceCategory
import eu.kanade.tachiyomi.util.view.RecyclerWindowInsetsListener
import eu.kanade.tachiyomi.widget.preference.ListMatPreference
import eu.kanade.tachiyomi.util.system.LocaleHelper
import eu.kanade.tachiyomi.util.view.RecyclerWindowInsetsListener
import eu.kanade.tachiyomi.util.view.applyWindowInsetsForController
import eu.kanade.tachiyomi.widget.preference.ListMatPreference
import eu.kanade.tachiyomi.widget.preference.LoginPreference
import eu.kanade.tachiyomi.widget.preference.SourceLoginDialog
import kotlinx.android.synthetic.main.extension_detail_controller.*
@ -69,6 +69,7 @@ class ExtensionDetailsController(bundle: Bundle? = null) :
@SuppressLint("PrivateResource")
override fun onViewCreated(view: View) {
super.onViewCreated(view)
view.applyWindowInsetsForController()
val extension = presenter.extension ?: return
val context = view.context

View File

@ -51,6 +51,7 @@ import eu.kanade.tachiyomi.ui.migration.manga.process.MigrationProcedureConfig
import eu.kanade.tachiyomi.ui.reader.ReaderActivity
import eu.kanade.tachiyomi.util.system.getResourceColor
import eu.kanade.tachiyomi.util.system.launchUI
import eu.kanade.tachiyomi.util.view.applyWindowInsetsForController
import eu.kanade.tachiyomi.util.view.setOnQueryTextChangeListener
import eu.kanade.tachiyomi.util.view.snack
import kotlinx.android.synthetic.main.filter_bottom_sheet.*
@ -170,8 +171,10 @@ open class LibraryController(
return inflater.inflate(R.layout.library_controller, container, false)
}
override fun onViewCreated(view: View) {
super.onViewCreated(view)
view.applyWindowInsetsForController()
mangaPerRow = getColumnsPreferenceForCurrentOrientation().getOrDefault()
if (!::presenter.isInitialized)
presenter = LibraryPresenter(this)
@ -244,8 +247,8 @@ open class LibraryController(
override fun onChangeStarted(handler: ControllerChangeHandler, type: ControllerChangeType) {
super.onChangeStarted(handler, type)
if (type.isEnter) {
if (library_pager != null)
activity?.tabs?.setupWithViewPager(library_pager)
//if (library_pager != null)
//activity?.tabs?.setupWithViewPager(library_pager)
presenter.getLibrary()
DownloadService.addListener(this)
DownloadService.callListeners()
@ -308,7 +311,7 @@ open class LibraryController(
}
override fun configureTabs(tabs: TabLayout) {
with(tabs) {
/* with(tabs) {
tabGravity = TabLayout.GRAVITY_CENTER
tabMode = TabLayout.MODE_SCROLLABLE
}
@ -320,7 +323,7 @@ open class LibraryController(
} else if (!visible) {
tabAnimator.collapse()
}
}
}*/
}
override fun cleanupTabs(tabs: TabLayout) {
@ -360,14 +363,14 @@ open class LibraryController(
// Restore active category.
library_pager.setCurrentItem(activeCat, false)
tabsVisibilityRelay.call(categories.size > 1)
//tabsVisibilityRelay.call(categories.size > 1)
libraryMangaRelay.call(LibraryMangaEvent(mangaMap))
view.post {
if (isAttached) {
activity?.tabs?.setScrollPosition(library_pager.currentItem, 0f, true)
}
//if (isAttached) {
// activity?.tabs?.setScrollPosition(library_pager.currentItem, 0f, true)
//}
}
if (!freshStart && justStarted) {

View File

@ -113,6 +113,19 @@ class LibraryListController(bundle: Bundle? = null) : LibraryController(bundle),
override fun onViewCreated(view: View) {
super.onViewCreated(view)
/*launchUI {
view.updateLayoutParams<FrameLayout.LayoutParams> {
val attrsArray = intArrayOf(android.R.attr.actionBarSize)
val array = view.context.obtainStyledAttributes(attrsArray)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
topMargin =
view.rootWindowInsets.systemWindowInsetTop + array.getDimensionPixelSize(
0, 0
)
}
array.recycle()
}
}*/
// pad the recycler if the filter bottom sheet is visible
if (!phoneLandscape) {
val height = view.context.resources.getDimensionPixelSize(R.dimen.rounder_radius) + 4.dpToPx
@ -253,7 +266,7 @@ class LibraryListController(bundle: Bundle? = null) : LibraryController(bundle),
updateScroll = true
}
adapter.isLongPressDragEnabled = canDrag()
tabsVisibilityRelay.call(false)
//tabsVisibilityRelay.call(false)
titlePopupMenu.menu.clear()
presenter.categories.forEach { category ->

View File

@ -169,8 +169,13 @@ class LibraryPresenter(
return@f false
if (filterUnread == STATE_REALLY_EXCLUDE && item.manga.unread > 0) return@f false
if ((filterMangaType == Manga.TYPE_MANHWA) &&
item.manga.mangaType() == Manga.TYPE_MANGA) return@f false
if (filterMangaType > 0) {
val mangaType = item.manga.mangaType()
if ((filterMangaType == Manga.TYPE_MANHUA) && mangaType != Manga.TYPE_MANHUA)
return@f false
if ((filterMangaType == Manga.TYPE_COMIC) && mangaType != Manga.TYPE_COMIC) return@f false
if ((filterMangaType == Manga.TYPE_WEBTOON) && mangaType != Manga.TYPE_WEBTOON) return@f false
}
if (filterCompleted == STATE_INCLUDE && item.manga.status != SManga.COMPLETED)

View File

@ -214,11 +214,18 @@ class SortFilterBottomSheet @JvmOverloads constructor(context: Context, attrs: A
.isNotEmpty()
}
val librryManga = db.getLibraryMangas().executeAsBlocking()
if (librryManga.any { it.mangaType() == Manga.TYPE_MANHWA }) {
val types = mutableListOf<Int>()
if (librryManga.any { it.mangaType() == Manga.TYPE_WEBTOON }) types.add(R.string.webtoon_viewer)
if (librryManga.any { it.mangaType() == Manga.TYPE_MANHUA }) types.add(R.string.manhua)
if (librryManga.any { it.mangaType() == Manga.TYPE_COMIC }) types.add(R.string.comic)
if (types.isNotEmpty()) {
launchUI {
val mangaType = inflate(R.layout.filter_buttons) as FilterTagGroup
mangaType.setup(
this@SortFilterBottomSheet, R.string.manhwa
this@SortFilterBottomSheet,
types.first(),
types.getOrNull(1),
types.getOrNull(2)
)
this@SortFilterBottomSheet.mangaType = mangaType
filter_layout.addView(mangaType)

View File

@ -12,14 +12,12 @@ import android.view.GestureDetector
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
import androidx.appcompat.graphics.drawable.DrawerArrowDrawable
import androidx.core.graphics.ColorUtils
import androidx.core.view.GestureDetectorCompat
import androidx.core.view.GravityCompat
import com.afollestad.materialdialogs.MaterialDialog
import com.bluelinelabs.conductor.Conductor
import com.bluelinelabs.conductor.Controller
import com.bluelinelabs.conductor.ControllerChangeHandler
@ -28,6 +26,7 @@ import com.bluelinelabs.conductor.RouterTransaction
import com.bluelinelabs.conductor.changehandler.FadeChangeHandler
import com.bluelinelabs.conductor.changehandler.SimpleSwapChangeHandler
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
@ -41,8 +40,6 @@ import eu.kanade.tachiyomi.ui.base.activity.BaseActivity
import eu.kanade.tachiyomi.ui.base.controller.BaseController
import eu.kanade.tachiyomi.ui.base.controller.DialogController
import eu.kanade.tachiyomi.ui.base.controller.NoToolbarElevationController
import eu.kanade.tachiyomi.ui.base.controller.SecondaryDrawerController
import eu.kanade.tachiyomi.ui.base.controller.TabbedController
import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction
import eu.kanade.tachiyomi.ui.catalogue.CatalogueController
import eu.kanade.tachiyomi.ui.catalogue.global_search.CatalogueSearchController
@ -50,17 +47,15 @@ import eu.kanade.tachiyomi.ui.download.DownloadController
import eu.kanade.tachiyomi.ui.extension.ExtensionController
import eu.kanade.tachiyomi.ui.library.LibraryController
import eu.kanade.tachiyomi.ui.library.LibraryListController
import eu.kanade.tachiyomi.ui.manga.MangaController
import eu.kanade.tachiyomi.ui.manga.MangaChaptersController
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.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.visible
import kotlinx.android.synthetic.main.main_activity.*
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
@ -131,7 +126,7 @@ open class MainActivity : BaseActivity(), DownloadServiceListener {
drawerArrow?.color = getResourceColor(R.attr.actionBarTintColor)
toolbar.navigationIcon = drawerArrow
tabAnimator = TabsAnimator(tabs)
// tabAnimator = TabsAnimator(tabs)
var continueSwitchingTabs = false
navigationView.setOnNavigationItemSelectedListener { item ->
@ -190,13 +185,20 @@ open class MainActivity : BaseActivity(), DownloadServiceListener {
val container: ViewGroup = findViewById(R.id.controller_container)
val content: ViewGroup = findViewById(R.id.main_content)
//val dwawerContainer: ViewGroup = findViewById(R.id.drawer_container)
DownloadService.addListener(this)
content.systemUiVisibility = View.SYSTEM_UI_FLAG_LAYOUT_STABLE or
View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or
View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
container.systemUiVisibility = View.SYSTEM_UI_FLAG_LAYOUT_STABLE or
View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or
View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
/*dwawerContainer.systemUiVisibility = View.SYSTEM_UI_FLAG_LAYOUT_STABLE or
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
/*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
@ -207,11 +209,12 @@ open class MainActivity : BaseActivity(), DownloadServiceListener {
launchUI {
navigationView.visible()
}
}
}*/
}
supportActionBar?.setDisplayShowCustomEnabled(true)
window.statusBarColor = getResourceColor(android.R.attr.colorPrimary)
content.setOnApplyWindowInsetsListener { v, insets ->
// if device doesn't support light nav bar
window.navigationBarColor = if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
@ -243,8 +246,37 @@ open class MainActivity : BaseActivity(), DownloadServiceListener {
ColorUtils.setAlphaComponent(
getResourceColor(android.R.attr.colorPrimary), 179)
}
v.setPadding(insets.systemWindowInsetLeft, insets.systemWindowInsetTop,
insets.systemWindowInsetRight, 0)
val contextView = window?.decorView?.findViewById<View>(R.id.action_mode_bar)
contextView?.updateLayoutParams<ViewGroup.MarginLayoutParams> {
leftMargin = insets.systemWindowInsetLeft
rightMargin = insets.systemWindowInsetRight
}
// Consume any horizontal insets and pad all content in. There's not much we can do
// with horizontal insets
v.updatePadding(
left = insets.systemWindowInsetLeft,
right = insets.systemWindowInsetRight
)
appbar.updatePadding(
top = insets.systemWindowInsetTop
)
navigationView.updatePadding(bottom = insets.systemWindowInsetBottom)
/*controller_container.updateLayoutParams<ConstraintLayout.LayoutParams> {
val attrsArray = intArrayOf(android.R.attr.actionBarSize)
val array = v.context.obtainStyledAttributes(attrsArray)
topMargin = insets.systemWindowInsetTop + array.getDimensionPixelSize(0, 0)
array.recycle()
}*/
/*nav_bar_scrim.updateLayoutParams<ViewGroup.MarginLayoutParams> {
height = 0//insets.systemWindowInsetBottom
}*/
insets.replaceSystemWindowInsets(
0, insets.systemWindowInsetTop,
0, insets.systemWindowInsetBottom
)
insets
}
val currentNightMode = resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK
@ -258,27 +290,7 @@ open class MainActivity : BaseActivity(), DownloadServiceListener {
content.systemUiVisibility = content.systemUiVisibility.or(View
.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR)
val drawerContainer: FrameLayout = findViewById(R.id.drawer_container)
drawerContainer.setOnApplyWindowInsetsListener { v, insets ->
val contextView = window?.decorView?.findViewById<View>(R.id.action_mode_bar)
contextView?.updateLayoutParams<ViewGroup.MarginLayoutParams> {
leftMargin = insets.systemWindowInsetLeft
rightMargin = insets.systemWindowInsetRight
}
// Consume any horizontal insets and pad all content in. There's not much we can do
// with horizontal insets
v.updatePadding(
left = insets.systemWindowInsetLeft,
right = insets.systemWindowInsetRight
)
nav_bar_scrim.updateLayoutParams<ViewGroup.MarginLayoutParams> {
height = insets.systemWindowInsetBottom
}
insets.replaceSystemWindowInsets(
0, insets.systemWindowInsetTop,
0, insets.systemWindowInsetBottom
)
}
//val drawerContainer: FrameLayout = findViewById(R.id.drawer_container)
router = Conductor.attachRouter(this, container, savedInstanceState)
if (!router.hasRootController()) {
@ -289,23 +301,20 @@ open class MainActivity : BaseActivity(), DownloadServiceListener {
}
toolbar.setNavigationOnClickListener {
if (router.backstackSize == 1) {
drawer.openDrawer(GravityCompat.START)
} else {
onBackPressed()
}
}
navigationView.visibility = if (router.backstackSize > 1) View.GONE else View.VISIBLE
router.addChangeListener(object : ControllerChangeHandler.ControllerChangeListener {
override fun onChangeStarted(to: Controller?, from: Controller?, isPush: Boolean,
container: ViewGroup, handler: ControllerChangeHandler) {
syncActivityViewWithController(to, from)
navigationView.visibility = if (router.backstackSize > 1) View.GONE else View.VISIBLE
}
override fun onChangeCompleted(to: Controller?, from: Controller?, isPush: Boolean,
container: ViewGroup, handler: ControllerChangeHandler) {
}
})
@ -315,7 +324,21 @@ open class MainActivity : BaseActivity(), DownloadServiceListener {
if (savedInstanceState == null) {
// Show changelog if needed
if (Migrations.upgrade(preferences)) {
ChangelogDialogController().showDialog(router)
if (BuildConfig.DEBUG) {
MaterialDialog(this)
.title(text = "Welcome to the J2K MD2 Beta")
.message(text = "This beta is for testing the upcoming " +
"release. Requests for new additions this beta will ignored (however" +
" suggestions on how to better implement a feature in this beta are " +
"welcome).\n\nFor any bugs you come across, there is a bug report " +
"button in settings.\n\nAs a reminder this is a *BETA* build and bugs" +
" may happen and features may be missing/not implemented yet." +
"\n\nEnjoy and thanks for testing!")
.positiveButton(android.R.string.ok)
.cancelOnTouchOutside(false)
.show()
}
else ChangelogDialogController().showDialog(router)
}
}
preferences.extensionUpdatesCount().asObservable().subscribe {
@ -420,7 +443,10 @@ open class MainActivity : BaseActivity(), DownloadServiceListener {
}
SHORTCUT_MANGA -> {
val extras = intent.extras ?: return false
router.setRoot(RouterTransaction.with(MangaController(extras)))
if (router.backstack.isEmpty()) {
navigationView.selectedItemId = R.id.nav_library
}
router.pushController(MangaChaptersController(extras).withFadeTransaction())
}
SHORTCUT_DOWNLOADS -> {
if (router.backstack.none { it.controller() is DownloadController }) {
@ -474,16 +500,16 @@ open class MainActivity : BaseActivity(), DownloadServiceListener {
super.onBackPressed()
return
}
if (drawer.isDrawerOpen(GravityCompat.START) || drawer.isDrawerOpen(GravityCompat.END)) {
/*if (drawer.isDrawerOpen(GravityCompat.START) || drawer.isDrawerOpen(GravityCompat.END)) {
drawer.closeDrawers()
} else {
} else {*/
val baseController = router.backstack.last().controller() as? BaseController
if (if (router.backstackSize == 1) !(baseController?.handleRootBack() ?: false)
else !router.handleBack()) {
SecureActivityDelegate.locked = true
super.onBackPressed()
}
}
//}
}
private fun setRoot(controller: Controller, id: Int) {
@ -522,8 +548,6 @@ open class MainActivity : BaseActivity(), DownloadServiceListener {
return
}
val onRoot = router.backstackSize == 1
//drawer.setDrawerLockMode(androidx.drawerlayout.widget.DrawerLayout
// .LOCK_MODE_LOCKED_CLOSED)
if (onRoot) {
toolbar.navigationIcon = null
} else {
@ -531,7 +555,7 @@ open class MainActivity : BaseActivity(), DownloadServiceListener {
}
drawerArrow?.progress = 1f
if (from is TabbedController) {
/* if (from is TabbedController) {
from.cleanupTabs(tabs)
}
if (to is TabbedController) {
@ -540,11 +564,11 @@ open class MainActivity : BaseActivity(), DownloadServiceListener {
} else {
tabAnimator.collapse()
tabs.setupWithViewPager(null)
}
}*/
currentGestureDelegate = to as? SwipeGestureInterface
if (from is SecondaryDrawerController) {
/*if (from is SecondaryDrawerController) {
if (secondaryDrawer != null) {
from.cleanupSecondaryDrawer(drawer)
drawer.removeView(secondaryDrawer)
@ -557,7 +581,7 @@ open class MainActivity : BaseActivity(), DownloadServiceListener {
drawer.removeView(secondaryDrawer)
null
} else newDrawer
}
}*/
if (to is NoToolbarElevationController) {
appbar.disableElevation()

View File

@ -19,7 +19,6 @@ import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.notification.NotificationReceiver
import eu.kanade.tachiyomi.ui.base.controller.DialogController
import eu.kanade.tachiyomi.ui.base.controller.NoToolbarElevationController
import eu.kanade.tachiyomi.ui.base.controller.TabbedController
import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction
import eu.kanade.tachiyomi.ui.catalogue.global_search.CatalogueSearchController
import eu.kanade.tachiyomi.ui.security.SecureActivityDelegate
@ -43,7 +42,7 @@ class SearchActivity: MainActivity() {
drawerArrow?.color = getResourceColor(R.attr.actionBarTintColor)
sToolbar.navigationIcon = drawerArrow
tabAnimator = TabsAnimator(sTabs)
//tabAnimator = TabsAnimator(sTabs)
val container: ViewGroup = findViewById(R.id.controller_container)
@ -170,7 +169,7 @@ class SearchActivity: MainActivity() {
}
drawerArrow?.progress = 1f
if (from is TabbedController) {
/*if (from is TabbedController) {
from.cleanupTabs(sTabs)
}
if (to is TabbedController) {
@ -179,7 +178,7 @@ class SearchActivity: MainActivity() {
} else {
tabAnimator.collapse()
sTabs.setupWithViewPager(null)
}
}*/
if (to is NoToolbarElevationController) {
appbar.disableElevation()

View File

@ -34,6 +34,7 @@ import eu.kanade.tachiyomi.data.database.DatabaseHelper
import eu.kanade.tachiyomi.data.database.models.Chapter
import eu.kanade.tachiyomi.data.database.models.Manga
import eu.kanade.tachiyomi.data.database.models.MangaImpl
import eu.kanade.tachiyomi.data.download.model.Download
import eu.kanade.tachiyomi.data.glide.GlideApp
import eu.kanade.tachiyomi.data.notification.NotificationReceiver
import eu.kanade.tachiyomi.source.Source
@ -42,13 +43,18 @@ import eu.kanade.tachiyomi.ui.base.controller.BaseController
import eu.kanade.tachiyomi.ui.catalogue.CatalogueController
import eu.kanade.tachiyomi.ui.main.MainActivity
import eu.kanade.tachiyomi.ui.main.SearchActivity
import eu.kanade.tachiyomi.ui.manga.MangaController.Companion.FROM_CATALOGUE_EXTRA
import eu.kanade.tachiyomi.ui.manga.chapter.ChapterItem
import eu.kanade.tachiyomi.ui.manga.chapter.ChaptersAdapter
import eu.kanade.tachiyomi.ui.reader.ReaderActivity
import eu.kanade.tachiyomi.ui.security.SecureActivityDelegate
import eu.kanade.tachiyomi.util.system.dpToPx
import eu.kanade.tachiyomi.util.system.getResourceColor
import eu.kanade.tachiyomi.util.view.doOnApplyWindowInsets
import eu.kanade.tachiyomi.util.view.getText
import eu.kanade.tachiyomi.util.view.snack
import eu.kanade.tachiyomi.util.view.updateLayoutParams
import eu.kanade.tachiyomi.util.view.updatePaddingRelative
import kotlinx.android.synthetic.main.big_manga_controller.*
import kotlinx.android.synthetic.main.main_activity.*
import uy.kohesive.injekt.Injekt
@ -64,7 +70,7 @@ class MangaChaptersController : BaseController,
smartSearchConfig: CatalogueController.SmartSearchConfig? = null,
update: Boolean = false) : super(Bundle().apply {
putLong(MangaController.MANGA_EXTRA, manga?.id ?: 0)
putBoolean(MangaController.FROM_CATALOGUE_EXTRA, fromCatalogue)
putBoolean(FROM_CATALOGUE_EXTRA, fromCatalogue)
putParcelable(MangaController.SMART_SEARCH_CONFIG_EXTRA, smartSearchConfig)
putBoolean(MangaController.UPDATE_EXTRA, update)
}) {
@ -92,12 +98,14 @@ class MangaChaptersController : BaseController,
var coverColor:Int? = null
var toolbarIsColored = false
private var snack: Snackbar? = null
private val fromCatalogue = args.getBoolean(FROM_CATALOGUE_EXTRA, false)
/**
* Adapter containing a list of chapters.
*/
private var adapter: ChaptersAdapter? = null
var headerHeight = 0
init {
setHasOptionsMenu(true)
}
@ -124,12 +132,32 @@ class MangaChaptersController : BaseController,
)
)
recycler.setHasFixedSize(true)
adapter?.fastScroller = fast_scroller
/*activity?.controller_container?.updateLayoutParams<ConstraintLayout.LayoutParams> {
topMargin = 0
}*/
val attrsArray = intArrayOf(android.R.attr.actionBarSize)
val array = view.context.obtainStyledAttributes(attrsArray)
val appbarHeight = array.getDimensionPixelSize(0, 0)
array.recycle()
val offset = 20.dpToPx
recycler.doOnApplyWindowInsets { v, insets, _ ->
headerHeight = appbarHeight + insets.systemWindowInsetTop + offset
(recycler.findViewHolderForAdapterPosition(0) as? MangaHeaderHolder)
?.setTopHeight(headerHeight)
fast_scroller?.updateLayoutParams<ViewGroup.MarginLayoutParams> {
topMargin = appbarHeight + insets.systemWindowInsetTop
bottomMargin = insets.systemWindowInsetBottom
}
// offset the recycler by the fab's inset + some inset on top
v.updatePaddingRelative(bottom = insets.systemWindowInsetBottom)
}
presenter.onCreate()
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
recycler.setOnScrollChangeListener { v, scrollX, scrollY, oldScrollX, oldScrollY ->
val atTop =
((recycler.layoutManager as LinearLayoutManager).findFirstCompletelyVisibleItemPosition() == 0)
val atTop = !recycler.canScrollVertically(-1)
if ((!atTop && !toolbarIsColored) || (atTop && toolbarIsColored)) {
toolbarIsColored = !atTop
colorAnimator?.cancel()
@ -148,7 +176,7 @@ class MangaChaptersController : BaseController,
//colorAnimation.startDelay = 150
colorAnimator?.addUpdateListener { animator ->
(activity as MainActivity).toolbar.setBackgroundColor(animator.animatedValue as Int)
//activity?.window?.statusBarColor = (animator.animatedValue as Int)
activity?.window?.statusBarColor = (animator.animatedValue as Int)
}
colorAnimator?.start()
val isCurrentController = router?.backstack?.lastOrNull()?.controller() == this
@ -156,6 +184,8 @@ class MangaChaptersController : BaseController,
}
}
}
// recycler.setOnApplyWindowInsetsListener(RecyclerWindowInsetsListener)
// recycler.requestApplyInsetsWhenAttached()
GlideApp.with(view.context).load(manga)
.diskCacheStrategy(DiskCacheStrategy.AUTOMATIC)
.signature(ObjectKey(MangaImpl.getLastCoverFetch(manga!!.id!!).toString()))
@ -177,23 +207,35 @@ class MangaChaptersController : BaseController,
)
else it?.getDarkMutedColor(colorBack)) ?: colorBack
onCoverLoaded(backDropColor)
(recycler.findViewHolderForItemId(-1) as? MangaHeaderHolder)
(recycler.findViewHolderForAdapterPosition(0) as? MangaHeaderHolder)
?.setBackDrop(backDropColor)
if (toolbarIsColored)
if (toolbarIsColored) {
(activity as MainActivity).toolbar.setBackgroundColor(backDropColor)
activity?.window?.statusBarColor = backDropColor
}
}
}
override fun onLoadCleared(placeholder: Drawable?) { }
})
swipe_refresh.setOnRefreshListener {
presenter.refreshAll()
}
//adapter?.fastScroller = fast_scroller
}
fun showError(message: String) {
swipe_refresh.isRefreshing = false
view?.snack(message)
}
override fun onChangeStarted(handler: ControllerChangeHandler, type: ControllerChangeType) {
super.onChangeStarted(handler, type)
if (type == ControllerChangeType.PUSH_ENTER || type == ControllerChangeType.POP_ENTER) {
(activity as MainActivity).appbar.setBackgroundColor(Color.TRANSPARENT)
(activity as MainActivity).toolbar.setBackgroundColor(Color.TRANSPARENT)
activity?.window?.statusBarColor = Color.TRANSPARENT
/* val colorFrom = ((activity as MainActivity).toolbar.background as ColorDrawable).color
val colorTo = Color.TRANSPARENT
colorAnimator = ValueAnimator.ofObject(
@ -233,11 +275,14 @@ class MangaChaptersController : BaseController,
android.R.attr.colorPrimary
) ?: Color.BLACK)
// activity!!.window.clearFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS)
activity?.window?.statusBarColor = activity?.getResourceColor(
android.R.attr.colorPrimary
) ?: Color.BLACK
// activity!!.window.clearFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS)
/* activity?.window?.statusBarColor = activity?.getResourceColor(
android.R.attr.colorPrimary
) ?: Color.BLACK*/
/*(activity as MainActivity).appbar.updateLayoutParams<ConstraintLayout.LayoutParams> {
topMargin = 0
}
@ -252,18 +297,32 @@ class MangaChaptersController : BaseController,
}
}
fun setRefresh(enabled: Boolean) {
swipe_refresh.isRefreshing = enabled
}
fun updateHeader() {
if (presenter.chapters.isEmpty()) {
adapter?.updateDataSet(listOf(ChapterItem(Chapter.createH(), presenter.manga)))
}
else
adapter?.updateDataSet(listOf(ChapterItem(Chapter.createH(), presenter.manga))
+ presenter.chapters)
}
fun updateChapters(chapters: List<ChapterItem>) {
if (presenter.chapters.isEmpty()) {
//initialFetchChapters()
swipe_refresh.isRefreshing = false
if (presenter.chapters.isEmpty() && fromCatalogue && !presenter.hasRequested) {
presenter.fetchChaptersFromSource()
}
adapter?.updateDataSet(listOf(ChapterItem(Chapter.create(), manga!!)) + chapters)
adapter?.updateDataSet(listOf(ChapterItem(Chapter.createH(), presenter.manga)) + chapters)
}
override fun onItemClick(view: View?, position: Int): Boolean {
val adapter = adapter ?: return false
val chapter = adapter.getItem(position)?.chapter ?: return false
if (!chapter.isRecognizedNumber) return false
if (chapter.isHeader) return false
/*if (actionMode != null && adapter.mode == SelectableAdapter.Mode.MULTI) {
lastClickPosition = position
toggleSelection(position)
@ -321,14 +380,16 @@ class MangaChaptersController : BaseController,
fun onCoverLoaded(color: Int) {
if (view == null) return
coverColor = color
activity?.window?.statusBarColor = color
//activity?.window?.statusBarColor = color
}
override fun coverColor(): Int? = coverColor
override fun topCoverHeight(): Int = headerHeight
override fun nextChapter(): Chapter? {
return presenter.getNextUnreadChapter()
}
override fun nextChapter(): Chapter? = presenter.getNextUnreadChapter()
override fun newestChapterDate(): Long? = presenter.getNewestChapterTime()
override fun lastChapter(): Float? = presenter.getLatestChapter()
override fun mangaSource(): Source = presenter.source
override fun readNextChapter() {
if (activity is SearchActivity && presenter.isLockedFromSearch) {
@ -354,8 +415,8 @@ class MangaChaptersController : BaseController,
override fun downloadChapter(position: Int) {
val adapter = adapter ?: return
val chapter = adapter.getItem(position) ?: return
if (!chapter.isRecognizedNumber) return
if (chapter.isDownloaded) {
if (chapter.isHeader) return
if (chapter.status != Download.NOT_DOWNLOADED) {
presenter.deleteChapters(listOf(chapter))
}
else presenter.downloadChapters(listOf(chapter))

View File

@ -34,6 +34,7 @@ import eu.kanade.tachiyomi.ui.manga.track.TrackController
import eu.kanade.tachiyomi.ui.migration.manga.process.MigrationListController
import eu.kanade.tachiyomi.ui.security.SecureActivityDelegate
import eu.kanade.tachiyomi.util.system.toast
import eu.kanade.tachiyomi.util.view.applyWindowInsetsForController
import kotlinx.android.synthetic.main.main_activity.*
import kotlinx.android.synthetic.main.manga_controller.*
import kotlinx.android.synthetic.main.search_activity.*
@ -128,6 +129,7 @@ class MangaController : RxController, TabbedController, BottomNavBarInterface {
override fun onViewCreated(view: View) {
super.onViewCreated(view)
view.applyWindowInsetsForController()
if (manga == null || source == null) return

View File

@ -2,7 +2,9 @@ package eu.kanade.tachiyomi.ui.manga
import android.content.res.ColorStateList
import android.graphics.Color
import android.text.format.DateUtils
import android.view.View
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.content.ContextCompat
import androidx.core.graphics.ColorUtils
import com.bumptech.glide.load.engine.DiskCacheStrategy
@ -11,11 +13,15 @@ import eu.kanade.tachiyomi.R
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.manga.chapter.ChaptersAdapter
import eu.kanade.tachiyomi.util.system.getResourceColor
import eu.kanade.tachiyomi.util.view.updateLayoutParams
import eu.kanade.tachiyomi.util.view.visibleIf
import kotlinx.android.synthetic.main.manga_header_item.*
import java.util.Date
import java.util.Locale
class MangaHeaderHolder(
private val view: View,
@ -24,10 +30,13 @@ class MangaHeaderHolder(
init {
start_reading_button.setOnClickListener { adapter.coverListener?.readNextChapter() }
top_view.updateLayoutParams<ConstraintLayout.LayoutParams> {
topMargin = adapter.coverListener?.topCoverHeight() ?: 0
}
}
override fun bind(item: ChapterItem, manga: Manga) {
manga_title.text = manga.currentTitle()
manga_full_title.text = manga.currentTitle()
if (manga.currentAuthor() == manga.currentArtist() ||
manga.currentArtist().isNullOrBlank())
manga_author.text = manga.currentAuthor()
@ -35,8 +44,15 @@ class MangaHeaderHolder(
manga_author.text = "${manga.currentAuthor()?.trim()}, ${manga.currentArtist()}"
}
manga_summary.text = manga.currentDesc()
manga_summary_label.text = "About this ${if (manga.mangaType() == Manga.TYPE_MANGA) "Manga"
else "Manhwa"}"
manga_summary_label.text = itemView.context.getString(R.string.about_this,
itemView.context.getString(
when {
manga.mangaType() == Manga.TYPE_WEBTOON -> R.string.webtoon_viewer
manga.mangaType() == Manga.TYPE_MANHUA -> R.string.manhua
manga.mangaType() == Manga.TYPE_COMIC -> R.string.comic
else -> R.string.manga
}
).toLowerCase(Locale.getDefault()))
with(favorite_button) {
icon = ContextCompat.getDrawable(
itemView.context, when {
@ -70,12 +86,44 @@ class MangaHeaderHolder(
visibleIf(nextChapter != null && !item.isLocked)
if (nextChapter != null) {
val number = adapter.decimalFormat.format(nextChapter.chapter_number.toDouble())
text = resources.getString(if (nextChapter.last_page_read > 0)
R.string.continue_reader_chapter
else R.string.start_reader_chapter, number)
text = resources.getString(
when {
nextChapter.last_page_read > 0 && nextChapter.chapter_number <= 0 ->
R.string.continue_reading
nextChapter.chapter_number <= 0 -> R.string.start_reading
nextChapter.last_page_read > 0 -> R.string.continue_reading_chapter
else -> R.string.start_reader_chapter
}, number
)
}
}
top_view.updateLayoutParams<ConstraintLayout.LayoutParams> {
topMargin = adapter.coverListener?.topCoverHeight() ?: 0
}
val lastUpdated = adapter.coverListener?.newestChapterDate()
if (lastUpdated != null) {
manga_last_update.text = itemView.context.getString(
R.string.last_updated, DateUtils.getRelativeTimeSpanString(
lastUpdated, Date().time, DateUtils.HOUR_IN_MILLIS
).toString()
)
}
else {
manga_last_update.text = itemView.context.getString(R.string.last_update_unknown)
}
val sourceAndStatus = mutableListOf<String>()
sourceAndStatus.add(itemView.context.getString( when (manga.status) {
SManga.ONGOING -> R.string.ongoing
SManga.COMPLETED -> R.string.completed
SManga.LICENSED -> R.string.licensed
else -> R.string.unknown_status
}))
val sourceName = adapter.coverListener?.mangaSource()?.toString()
if (sourceName != null) sourceAndStatus.add(sourceName)
manga_status_source.text = sourceAndStatus.joinToString("")
GlideApp.with(view.context).load(manga)
.diskCacheStrategy(DiskCacheStrategy.AUTOMATIC)
.signature(ObjectKey(MangaImpl.getLastCoverFetch(manga.id!!).toString()))
@ -87,6 +135,12 @@ class MangaHeaderHolder(
.into(backdrop)
}
fun setTopHeight(newHeight: Int) {
top_view.updateLayoutParams<ConstraintLayout.LayoutParams> {
topMargin = newHeight
}
}
fun setBackDrop(color: Int) {
true_backdrop.setBackgroundColor(color)
}

View File

@ -3,6 +3,7 @@ package eu.kanade.tachiyomi.ui.manga
import eu.kanade.tachiyomi.data.database.DatabaseHelper
import eu.kanade.tachiyomi.data.database.models.Chapter
import eu.kanade.tachiyomi.data.database.models.Manga
import eu.kanade.tachiyomi.data.database.models.MangaImpl
import eu.kanade.tachiyomi.data.download.DownloadManager
import eu.kanade.tachiyomi.data.download.model.Download
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
@ -10,8 +11,14 @@ import eu.kanade.tachiyomi.source.LocalSource
import eu.kanade.tachiyomi.source.Source
import eu.kanade.tachiyomi.ui.manga.chapter.ChapterItem
import eu.kanade.tachiyomi.ui.security.SecureActivityDelegate
import eu.kanade.tachiyomi.util.chapter.syncChaptersWithSource
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
import java.util.Date
class MangaPresenter(private val controller: MangaChaptersController,
val manga: Manga,
@ -22,14 +29,46 @@ class MangaPresenter(private val controller: MangaChaptersController,
var isLockedFromSearch = false
var hasRequested = false
var chapters:List<ChapterItem> = emptyList()
private set
fun onCreate() {
isLockedFromSearch = SecureActivityDelegate.shouldBeLocked()
if (!manga.initialized)
fetchMangaFromSource()
updateChapters()
controller.updateChapters(this.chapters)
}
val chapters = db.getChapters(manga).executeAsBlocking().map { it.toModel() }
fun fetchMangaFromSource() {
GlobalScope.launch(Dispatchers.IO) {
withContext(Dispatchers.Main) {
controller.setRefresh(true)
}
val thumbnailUrl = manga.thumbnail_url
val networkManga = try {
source.fetchMangaDetails(manga).toBlocking().single()
} catch (e: java.lang.Exception) {
controller.showError(trimException(e))
return@launch
}
if (networkManga != null) {
manga.copyFrom(networkManga)
manga.initialized = true
db.insertManga(manga).executeAsBlocking()
if (thumbnailUrl != networkManga.thumbnail_url)
MangaImpl.setLastCoverFetch(manga.id!!, Date().time)
withContext(Dispatchers.Main) {
controller.updateHeader()
}
}
}
}
private fun updateChapters(fetchedChapters: List<Chapter>? = null) {
val chapters = (fetchedChapters ?:
db.getChapters(manga).executeAsBlocking()).map { it.toModel() }
// Store the last emission
this.chapters = applyChapterFilters(chapters)
@ -37,43 +76,7 @@ class MangaPresenter(private val controller: MangaChaptersController,
// Find downloaded chapters
setDownloadedChapters(chapters)
controller.updateChapters(this.chapters)
// Listen for download status changes
//observeDownloads()
// Emit the number of chapters to the info tab.
//chapterCountRelay.call(chapters.maxBy { it.chapter_number }?.chapter_number ?: 0f)
// Emit the upload date of the most recent chapter
/*lastUpdateRelay.call(
Date(chapters.maxBy { it.date_upload }?.date_upload ?: 0)
)*/
/* // Prepare the relay.
chaptersRelay.flatMap { applyChapterFilters(it) }
.observeOn(AndroidSchedulers.mainThread())
.subscribeLatestCache(
ChaptersController::onNextChapters
) { _, error -> Timber.e(error) }
// Add the subscription that retrieves the chapters from the database, keeps subscribed to
// changes, and sends the list of chapters to the relay.
add(db.getChapters(manga).asRxObservable()
.map { chapters ->
// Convert every chapter to a model.
chapters.map { it.toModel() }
}
.doOnNext { chapters ->
// Find downloaded chapters
setDownloadedChapters(chapters)
// Store the last emission
this.chapters = chapters
// Listen for download status changes
observeDownloads()
/*
// Emit the number of chapters to the info tab.
chapterCountRelay.call(chapters.maxBy { it.chapter_number }?.chapter_number
?: 0f)
@ -82,22 +85,9 @@ class MangaPresenter(private val controller: MangaChaptersController,
lastUpdateRelay.call(
Date(chapters.maxBy { it.date_upload }?.date_upload
?: 0)
)
}
.subscribe { chaptersRelay.call(it) })*/
)*/
}
/*private fun observeDownloads() {
observeDownloadsSubscription?.let { remove(it) }
observeDownloadsSubscription = downloadManager.queue.getStatusObservable()
.observeOn(AndroidSchedulers.mainThread())
.filter { download -> download.manga.id == manga.id }
.doOnNext { onDownloadStatusChange(it) }
.subscribeLatestCache(ChaptersController::onChapterStatusChange) {
_, error -> Timber.e(error)
}
}*/
/**
* Finds and assigns the list of downloaded chapters.
*
@ -223,6 +213,17 @@ class MangaPresenter(private val controller: MangaChaptersController,
return chapters.sortedByDescending { it.source_order }.find { !it.read }
}
/**
* Returns the next unread chapter or null if everything is read.
*/
fun getNewestChapterTime(): Long? {
return chapters.maxBy { it.date_upload }?.date_upload
}
fun getLatestChapter(): Float? {
return chapters.maxBy { it.chapter_number }?.chapter_number
}
/**
* Downloads the given list of chapters with the manager.
* @param chapters the list of chapters to download.
@ -255,4 +256,39 @@ class MangaPresenter(private val controller: MangaChaptersController,
it.download = null
}
}
fun refreshAll() {
fetchMangaFromSource()
fetchChaptersFromSource()
}
/**
* Requests an updated list of chapters from the source.
*/
fun fetchChaptersFromSource() {
hasRequested = true
GlobalScope.launch(Dispatchers.IO) {
val chapters = try {
source.fetchChapterList(manga).toBlocking().single()
}
catch(e: Exception) {
controller.showError(trimException(e))
return@launch
} ?: listOf()
try {
syncChaptersWithSource(db, chapters, manga, source)
updateChapters()
withContext(Dispatchers.Main) { controller.updateChapters(this@MangaPresenter.chapters) }
}
catch(e: java.lang.Exception) {
controller.showError(trimException(e))
}
}
}
private fun trimException(e: java.lang.Exception): String {
return e.message?.split(": ")?.drop(1)?.joinToString(": ") ?: "Error"
}
}

View File

@ -36,16 +36,16 @@ class ChapterItem(val chapter: Chapter, val manga: Manga) :
get() = status == Download.DOWNLOADED
override fun getLayoutRes(): Int {
return if (!chapter.isRecognizedNumber) R.layout.manga_header_item
return if (chapter.isHeader) R.layout.manga_header_item
else R.layout.chapters_mat_item
}
override fun isSelectable(): Boolean {
return chapter.isRecognizedNumber
return chapter.isHeader
}
override fun createViewHolder(view: View, adapter: FlexibleAdapter<IFlexible<RecyclerView.ViewHolder>>): MangaChapterHolder {
return if (!chapter.isRecognizedNumber) MangaHeaderHolder(view, adapter as ChaptersAdapter)
return if (chapter.isHeader) MangaHeaderHolder(view, adapter as ChaptersAdapter)
else ChapterMatHolder(view, adapter as ChaptersAdapter)
}
@ -59,13 +59,13 @@ class ChapterItem(val chapter: Chapter, val manga: Manga) :
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (other is ChapterItem) {
return chapter.id ?: -1 == other.chapter.id ?: -1
return chapter.id!! == other.chapter.id!!
}
return false
}
override fun hashCode(): Int {
return chapter.id?.hashCode() ?: -1
return chapter.id!!.hashCode()
}
}

View File

@ -1,5 +1,6 @@
package eu.kanade.tachiyomi.ui.manga.chapter
import android.text.format.DateUtils
import android.view.View
import androidx.appcompat.widget.PopupMenu
import eu.kanade.tachiyomi.R
@ -11,6 +12,7 @@ import eu.kanade.tachiyomi.util.view.invisible
import eu.kanade.tachiyomi.util.view.visible
import kotlinx.android.synthetic.main.chapters_mat_item.*
import kotlinx.android.synthetic.main.download_button.*
import java.util.Date
class ChapterMatHolder(
private val view: View,
@ -74,34 +76,34 @@ class ChapterMatHolder(
if (isLocked) download_button.invisible()
// Set correct text color
chapter_title.setTextColor(if (chapter.read && !isLocked)
adapter.readColor else adapter.unreadColor)
if (chapter.bookmark && !isLocked) chapter_title.setTextColor(adapter.bookmarkedColor)
/*if (chapter.date_upload > 0) {
chapter_date.text = adapter.dateFormat.format(Date(chapter.date_upload))
chapter_date.setTextColor(if (chapter.read) adapter.readColor else adapter.unreadColor)
} else {
chapter_date.text = ""
}*/
val statuses = mutableListOf<String>()
//add scanlator if exists
chapter_scanlator.text = chapter.scanlator ?: " "
//allow longer titles if there is no scanlator (most sources)
/*if (chapter_scanlator.text.isNullOrBlank()) {
chapter_title.maxLines = 2
//chapter_scanlator.gone()
} else {
chapter_title.maxLines = 1
}*/
if (chapter.date_upload > 0) {
statuses.add(DateUtils.getRelativeTimeSpanString(chapter.date_upload,
Date().time, DateUtils.HOUR_IN_MILLIS).toString())
}
/* chapter_pages.text = if (!chapter.read && chapter.last_page_read > 0 && !isLocked) {
itemView.context.getString(R.string.chapter_progress, chapter.last_page_read + 1)
} else {
""
}*/
if (!chapter.read && chapter.last_page_read > 0 && chapter.pages_left > 0 && !isLocked) {
statuses.add(itemView.resources.getQuantityString(R.plurals.pages_left, chapter
.pages_left, chapter.pages_left))
}
else if (!chapter.read && chapter.last_page_read > 0 && !isLocked) {
statuses.add(itemView.context.getString(R.string.chapter_progress, chapter
.last_page_read + 1))
}
if (!chapter.scanlator.isNullOrBlank()) {
statuses.add(chapter.scanlator!!)
}
chapter_scanlator.setTextColor(if (chapter.read) adapter.readColor else adapter.unreadColor)
chapter_scanlator.text = statuses.joinToString("")
notifyStatus(item.status, item.isLocked, item.progress)
}

View File

@ -8,6 +8,7 @@ import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.database.models.Chapter
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.data.preference.getOrDefault
import eu.kanade.tachiyomi.source.Source
import eu.kanade.tachiyomi.ui.base.controller.BaseController
import eu.kanade.tachiyomi.ui.security.SecureActivityDelegate
import eu.kanade.tachiyomi.util.system.getResourceColor
@ -62,5 +63,9 @@ class ChaptersAdapter(
fun nextChapter(): Chapter?
fun readNextChapter()
fun downloadChapter(position: Int)
fun topCoverHeight(): Int
fun newestChapterDate(): Long?
fun lastChapter(): Float?
fun mangaSource(): Source
}
}

View File

@ -252,6 +252,7 @@ class ChaptersPresenter(
chapter.read = read
if (!read) {
chapter.last_page_read = 0
chapter.pages_left = 0
}
}
.toList()

View File

@ -77,8 +77,8 @@ class EditMangaDialog : DialogController {
if (isLocal) {
if (manga.title != manga.url)
view.manga_title.append(manga.title)
view.manga_title.hint = "${resources?.getString(R.string.title)}: ${manga.url}"
view.manga_full_title.append(manga.title)
view.manga_full_title.hint = "${resources?.getString(R.string.title)}: ${manga.url}"
view.manga_author.append(manga.author ?: "")
view.manga_artist.append(manga.artist ?: "")
view.manga_description.append(manga.description ?: "")
@ -86,8 +86,8 @@ class EditMangaDialog : DialogController {
}
else {
if (manga.currentTitle() != manga.originalTitle())
view.manga_title.append(manga.currentTitle())
view.manga_title.hint = "${resources?.getString(R.string.title)}: ${manga
view.manga_full_title.append(manga.currentTitle())
view.manga_full_title.hint = "${resources?.getString(R.string.title)}: ${manga
.originalTitle()}"
if (manga.currentAuthor() != manga.originalAuthor())
@ -164,7 +164,7 @@ class EditMangaDialog : DialogController {
}
private fun onPositiveButtonClick() {
infoController.presenter.updateManga(dialogView?.manga_title?.text.toString(),
infoController.presenter.updateManga(dialogView?.manga_full_title?.text.toString(),
dialogView?.manga_author?.text.toString(), dialogView?.manga_artist?.text.toString(),
customCoverUri, dialogView?.manga_description?.text.toString(),
dialogView?.manga_genres_tags?.tags)

View File

@ -18,6 +18,7 @@ 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.util.view.RecyclerWindowInsetsListener
import eu.kanade.tachiyomi.util.view.applyWindowInsetsForController
import kotlinx.android.synthetic.main.migration_controller.*
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
@ -56,6 +57,7 @@ class MigrationController : NucleusController<MigrationPresenter>(),
override fun onViewCreated(view: View) {
super.onViewCreated(view)
view.applyWindowInsetsForController()
adapter = FlexibleAdapter(null, this)
migration_recycler.layoutManager =

View File

@ -18,6 +18,7 @@ import eu.kanade.tachiyomi.ui.base.controller.BaseController
import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction
import eu.kanade.tachiyomi.ui.migration.manga.process.MigrationListController
import eu.kanade.tachiyomi.ui.migration.manga.process.MigrationProcedureConfig
import eu.kanade.tachiyomi.util.view.applyWindowInsetsForController
import eu.kanade.tachiyomi.util.view.doOnApplyWindowInsets
import eu.kanade.tachiyomi.util.view.marginBottom
import eu.kanade.tachiyomi.util.view.updateLayoutParams
@ -46,6 +47,7 @@ class PreMigrationController(bundle: Bundle? = null) : BaseController(bundle), F
override fun onViewCreated(view: View) {
super.onViewCreated(view)
view.applyWindowInsetsForController()
val ourAdapter = adapter ?: MigrationSourceAdapter(
getEnabledSources().map { MigrationSourceItem(it, isEnabled(it.id.toString())) },

View File

@ -35,6 +35,7 @@ import eu.kanade.tachiyomi.util.system.getResourceColor
import eu.kanade.tachiyomi.util.system.launchUI
import eu.kanade.tachiyomi.util.system.toast
import eu.kanade.tachiyomi.util.view.RecyclerWindowInsetsListener
import eu.kanade.tachiyomi.util.view.applyWindowInsetsForController
import kotlinx.android.synthetic.main.chapters_controller.*
import kotlinx.coroutines.CancellationException
import kotlinx.coroutines.CoroutineScope
@ -90,6 +91,7 @@ class MigrationListController(bundle: Bundle? = null) : BaseController(bundle),
override fun onViewCreated(view: View) {
super.onViewCreated(view)
view.applyWindowInsetsForController()
setTitle()
val config = this.config ?: return

View File

@ -13,7 +13,7 @@ import eu.kanade.tachiyomi.source.Source
import eu.kanade.tachiyomi.source.SourceManager
import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction
import eu.kanade.tachiyomi.ui.base.holder.BaseFlexibleViewHolder
import eu.kanade.tachiyomi.ui.manga.MangaController
import eu.kanade.tachiyomi.ui.manga.MangaChaptersController
import eu.kanade.tachiyomi.util.system.getResourceColor
import eu.kanade.tachiyomi.util.system.launchUI
import eu.kanade.tachiyomi.util.view.gone
@ -69,7 +69,7 @@ class MigrationProcessHolder(
migration_manga_card_from.attachManga(manga, source, false)
migration_manga_card_from.setOnClickListener {
adapter.controller.router.pushController(
MangaController(
MangaChaptersController(
manga, true
).withFadeTransaction()
)
@ -101,7 +101,7 @@ class MigrationProcessHolder(
migration_manga_card_to.attachManga(searchResult, resultSource, true)
migration_manga_card_to.setOnClickListener {
adapter.controller.router.pushController(
MangaController(
MangaChaptersController(
searchResult, true
).withFadeTransaction()
)

View File

@ -319,6 +319,8 @@ class ReaderPresenter(
// Save last page read and mark as read if needed
selectedChapter.chapter.last_page_read = page.index
selectedChapter.chapter.pages_left =
(selectedChapter.pages?.size ?: page.index) - page.index
if (selectedChapter.pages?.lastIndex == page.index) {
selectedChapter.chapter.read = true
updateTrackChapterRead(selectedChapter)
@ -395,9 +397,11 @@ class ReaderPresenter(
fun getMangaViewer(): Int {
val manga = manga ?: return preferences.defaultViewer()
if (manga.viewer == -1) {
val type =
if (manga.mangaType() == Manga.TYPE_MANHWA) ReaderActivity.WEBTOON
else 0
val type = when(manga.mangaType()) {
Manga.TYPE_WEBTOON -> ReaderActivity.WEBTOON
Manga.TYPE_COMIC, Manga.TYPE_MANHUA -> ReaderActivity.LEFT_TO_RIGHT
else -> 0
}
manga.viewer = type
db.updateMangaViewer(manga).asRxObservable().subscribe()
}

View File

@ -61,7 +61,7 @@ class RecentChapterHolder(private val view: View, private val adapter: RecentCha
chapter_title.text = item.chapter.name
// Set manga title
manga_title.text = item.manga.currentTitle()
manga_full_title.text = item.manga.currentTitle()
// Set the correct drawable for dropdown and update the tint to match theme.
chapter_menu_icon.setVectorCompat(R.drawable.ic_more_horiz_black_24dp, view.context.getResourceColor(R.attr.icon_color))
@ -79,10 +79,10 @@ class RecentChapterHolder(private val view: View, private val adapter: RecentCha
// Check if chapter is read and set correct color
if (item.chapter.read) {
chapter_title.setTextColor(readColor)
manga_title.setTextColor(readColor)
manga_full_title.setTextColor(readColor)
} else {
chapter_title.setTextColor(unreadColor)
manga_title.setTextColor(unreadColor)
manga_full_title.setTextColor(unreadColor)
}
// Set chapter status

View File

@ -24,11 +24,12 @@ import eu.kanade.tachiyomi.ui.base.controller.NoToolbarElevationController
import eu.kanade.tachiyomi.ui.base.controller.NucleusController
import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction
import eu.kanade.tachiyomi.ui.main.MainActivity
import eu.kanade.tachiyomi.ui.manga.MangaChaptersController
import eu.kanade.tachiyomi.ui.manga.MangaController
import eu.kanade.tachiyomi.ui.reader.ReaderActivity
import eu.kanade.tachiyomi.ui.recently_read.RecentlyReadController
import eu.kanade.tachiyomi.util.system.notificationManager
import eu.kanade.tachiyomi.util.view.RecyclerWindowInsetsListener
import eu.kanade.tachiyomi.util.view.applyWindowInsetsForController
import eu.kanade.tachiyomi.util.view.snack
import kotlinx.android.synthetic.main.recent_chapters_controller.*
import timber.log.Timber
@ -81,6 +82,7 @@ class RecentChaptersController : NucleusController<RecentChaptersPresenter>(),
*/
override fun onViewCreated(view: View) {
super.onViewCreated(view)
view.applyWindowInsetsForController()
view.context.notificationManager.cancel(Notifications.ID_NEW_CHAPTERS)
// Init RecyclerView and adapter
val layoutManager = LinearLayoutManager(view.context)
@ -105,7 +107,7 @@ class RecentChaptersController : NucleusController<RecentChaptersPresenter>(),
// It can be a very long operation, so we disable swipe refresh and show a snackbar.
swipe_refresh.isRefreshing = false
}
recycler.setOnApplyWindowInsetsListener(RecyclerWindowInsetsListener)
//recycler.setOnApplyWindowInsetsListener(RecyclerWindowInsetsListener)
}
override fun onDestroyView(view: View) {
@ -268,7 +270,7 @@ class RecentChaptersController : NucleusController<RecentChaptersPresenter>(),
}
fun openManga(chapter: RecentChapterItem) {
router.pushController(MangaController(chapter.manga).withFadeTransaction())
router.pushController(MangaChaptersController(chapter.manga).withFadeTransaction())
}
/**

View File

@ -152,6 +152,7 @@ class RecentChaptersPresenter(
it.read = read
if (!read) {
it.last_page_read = 0
it.pages_left = 0
}
}

View File

@ -20,12 +20,13 @@ import eu.kanade.tachiyomi.ui.base.controller.BaseController
import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction
import eu.kanade.tachiyomi.ui.catalogue.browse.ProgressItem
import eu.kanade.tachiyomi.ui.main.MainActivity
import eu.kanade.tachiyomi.ui.manga.MangaController
import eu.kanade.tachiyomi.ui.manga.MangaChaptersController
import eu.kanade.tachiyomi.ui.reader.ReaderActivity
import eu.kanade.tachiyomi.ui.recent_updates.RecentChaptersController
import eu.kanade.tachiyomi.util.system.launchUI
import eu.kanade.tachiyomi.util.system.toast
import eu.kanade.tachiyomi.util.view.RecyclerWindowInsetsListener
import eu.kanade.tachiyomi.util.view.applyWindowInsetsForController
import eu.kanade.tachiyomi.util.view.setOnQueryTextChangeListener
import kotlinx.android.synthetic.main.recently_read_controller.*
import uy.kohesive.injekt.Injekt
@ -79,7 +80,16 @@ class RecentlyReadController(bundle: Bundle? = null) : BaseController(bundle),
*/
override fun onViewCreated(view: View) {
super.onViewCreated(view)
view.applyWindowInsetsForController()
/*view.updateLayoutParams<FrameLayout.LayoutParams> {
val attrsArray = intArrayOf(android.R.attr.actionBarSize)
val array = view.context.obtainStyledAttributes(attrsArray)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
topMargin = activity!!.window.decorView.rootWindowInsets.systemWindowInsetTop + array
.getDimensionPixelSize(0, 0)
}
array.recycle()
}*/
// Initialize adapter
adapter = RecentlyReadAdapter(this)
recycler.adapter = adapter
@ -177,7 +187,7 @@ class RecentlyReadController(bundle: Bundle? = null) : BaseController(bundle),
override fun onCoverClick(position: Int, lastTouchY: Float) {
val manga = (adapter?.getItem(position) as? RecentlyReadItem)?.mch?.manga ?: return
router.pushController(MangaController(manga, lastTouchY).withFadeTransaction())
router.pushController(MangaChaptersController(manga).withFadeTransaction())
}
override fun removeHistory(manga: Manga, history: History, all: Boolean) {

View File

@ -62,7 +62,7 @@ class RecentlyReadHolder(
val (manga, chapter, history) = item
// Set manga title
manga_title.text = manga.currentTitle()
manga_full_title.text = manga.currentTitle()
// Set source + chapter title
val formattedNumber = adapter.decimalFormat.format(chapter.chapter_number.toDouble())

View File

@ -7,7 +7,6 @@ import android.view.ContextThemeWrapper
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.FrameLayout
import androidx.appcompat.app.AppCompatActivity
import androidx.preference.PreferenceController
import androidx.preference.PreferenceScreen
@ -17,7 +16,7 @@ import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.ui.base.controller.BaseController
import eu.kanade.tachiyomi.util.view.RecyclerWindowInsetsListener
import eu.kanade.tachiyomi.util.view.updateLayoutParams
import eu.kanade.tachiyomi.util.view.applyWindowInsetsForController
import rx.Observable
import rx.Subscription
import rx.subscriptions.CompositeSubscription
@ -36,12 +35,23 @@ abstract class SettingsController : PreferenceController() {
untilDestroySubscriptions = CompositeSubscription()
}
val view = super.onCreateView(inflater, container, savedInstanceState)
view.updateLayoutParams<FrameLayout.LayoutParams> {
/*view.updateLayoutParams<FrameLayout.LayoutParams> {
val attrsArray = intArrayOf(android.R.attr.actionBarSize)
val array = view.context.obtainStyledAttributes(attrsArray)
topMargin = array.getDimensionPixelSize(0, 0)
array.recycle()
}*/
view.applyWindowInsetsForController()
/*view.updateLayoutParams<FrameLayout.LayoutParams> {
val attrsArray = intArrayOf(android.R.attr.actionBarSize)
val array = view.context.obtainStyledAttributes(attrsArray)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
topMargin = activity!!.window.decorView.rootWindowInsets.systemWindowInsetTop + array
.getDimensionPixelSize(0, 0)
}
array.recycle()
}*/
listView.setOnApplyWindowInsetsListener(RecyclerWindowInsetsListener)
return view
}

View File

@ -14,6 +14,7 @@ import android.view.View
import android.view.ViewGroup
import android.view.WindowInsets
import android.widget.Button
import android.widget.FrameLayout
import android.widget.TextView
import androidx.annotation.Px
import androidx.appcompat.widget.SearchView
@ -27,7 +28,6 @@ import com.google.android.material.bottomsheet.BottomSheetDialog
import com.google.android.material.snackbar.Snackbar
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.ui.main.MainActivity
import eu.kanade.tachiyomi.util.system.getResourceColor
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
@ -161,13 +161,24 @@ inline val View.marginLeft: Int
object RecyclerWindowInsetsListener : View.OnApplyWindowInsetsListener {
override fun onApplyWindowInsets(v: View, insets: WindowInsets): WindowInsets {
if (MainActivity.usingBottomNav) return insets
v.setPadding(0,0,0,insets.systemWindowInsetBottom)
//v.updatePaddingRelative(bottom = v.paddingBottom + insets.systemWindowInsetBottom)
return insets
}
}
object ControllerViewWindowInsetsListener : View.OnApplyWindowInsetsListener {
override fun onApplyWindowInsets(v: View, insets: WindowInsets): WindowInsets {
v.updateLayoutParams<FrameLayout.LayoutParams> {
val attrsArray = intArrayOf(android.R.attr.actionBarSize)
val array = v.context.obtainStyledAttributes(attrsArray)
topMargin = insets.systemWindowInsetTop + array.getDimensionPixelSize(0, 0)
array.recycle()
}
return insets
}
}
object HeightTopWindowInsetsListener : View.OnApplyWindowInsetsListener {
override fun onApplyWindowInsets(v: View, insets: WindowInsets): WindowInsets {
val topInset = insets.systemWindowInsetTop
@ -182,7 +193,6 @@ object HeightTopWindowInsetsListener : View.OnApplyWindowInsetsListener {
fun View.doOnApplyWindowInsets(f: (View, WindowInsets, ViewPaddingState) -> Unit) {
// Create a snapshot of the view's padding state
if (MainActivity.usingBottomNav) return
val paddingState = createStateForView(this)
setOnApplyWindowInsetsListener { v, insets ->
f(v, insets, paddingState)
@ -191,6 +201,13 @@ fun View.doOnApplyWindowInsets(f: (View, WindowInsets, ViewPaddingState) -> Unit
requestApplyInsetsWhenAttached()
}
fun View.applyWindowInsetsForController() {
// Create a snapshot of the view's padding state
setOnApplyWindowInsetsListener(ControllerViewWindowInsetsListener)
requestApplyInsetsWhenAttached()
}
fun View.requestApplyInsetsWhenAttached() {
if (isAttachedToWindow) {
requestApplyInsets()

View File

@ -150,7 +150,7 @@
app:layout_constraintEnd_toEndOf="parent" />
<TextView
android:id="@+id/manga_last_update_label"
android:id="@+id/manga_last_update"
style="@style/TextAppearance.Medium.Body2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
@ -168,8 +168,8 @@
android:ellipsize="end"
android:maxLines="1"
android:textIsSelectable="false"
app:layout_constraintBaseline_toBaselineOf="@+id/manga_last_update_label"
app:layout_constraintStart_toEndOf="@+id/manga_last_update_label"
app:layout_constraintBaseline_toBaselineOf="@+id/manga_last_update"
app:layout_constraintStart_toEndOf="@+id/manga_last_update"
app:layout_constraintEnd_toEndOf="parent" />
<TextView
@ -179,7 +179,7 @@
android:layout_height="wrap_content"
android:text="@string/manga_info_status_label"
android:textIsSelectable="false"
app:layout_constraintTop_toBottomOf="@+id/manga_last_update_label"
app:layout_constraintTop_toBottomOf="@+id/manga_last_update"
app:layout_constraintStart_toStartOf="parent"/>
<TextView

View File

@ -1,18 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/manga_info_layout"
android:id="@id/frame_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
android:background="?android:colorBackground">
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:id="@id/swipe_refresh"
android:layout_width="match_parent"
android:background="?android:colorBackground"
android:fitsSystemWindows="true"
android:layout_height="match_parent"
tools:context="eu.kanade.tachiyomi.ui.catalogue.browse.BrowseCatalogueController">
android:background="?android:colorBackground">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler"
@ -25,8 +24,7 @@
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/chapters_title"
tools:listitem="@layout/chapters_mat_item">
</androidx.recyclerview.widget.RecyclerView>
tools:listitem="@layout/chapters_mat_item"/>
<View
android:id="@+id/full_backdrop"
@ -39,6 +37,8 @@
android:visibility="invisible"
tools:background="@color/md_black_1000" />
<ImageView
android:id="@+id/manga_cover_full"
android:layout_width="match_parent"
@ -50,4 +50,11 @@
android:contentDescription="@string/description_cover"
android:visibility="invisible" />
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
<eu.davidea.fastscroller.FastScroller
android:id="@+id/fast_scroller"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="end"
app:fastScrollerBubbleEnabled="false"
tools:visibility="visible" />
</FrameLayout>

View File

@ -4,7 +4,7 @@
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:id="@+id/catalouge_layout"
android:layout_marginTop="?attr/actionBarSize"
android:fitsSystemWindows="true"
android:layout_height="match_parent">
<LinearLayout

View File

@ -2,7 +2,7 @@
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_marginTop="?attr/actionBarSize"
android:fitsSystemWindows="true"
android:layout_height="wrap_content">
<androidx.recyclerview.widget.RecyclerView

View File

@ -3,7 +3,7 @@
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_marginTop="?attr/actionBarSize"
android:fitsSystemWindows="true"
android:layout_height="wrap_content">
<androidx.recyclerview.widget.RecyclerView

View File

@ -4,7 +4,7 @@
android:id="@+id/cat_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="?attr/actionBarSize"
android:fitsSystemWindows="true"
android:clipToPadding="false"
android:orientation="vertical">

View File

@ -5,7 +5,7 @@
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="?attr/actionBarSize"
android:fitsSystemWindows="true"
android:clipToPadding="false"
android:orientation="vertical">

View File

@ -35,9 +35,11 @@
app:layout_constraintTop_toBottomOf="@+id/chapter_title"
tools:text="3 days ago • On page 45 • Scanlator" />
<include layout="@layout/download_button"
android:layout_height="0dp"
<include
layout="@layout/download_button"
android:layout_width="50dp"
android:layout_height="0dp"
android:layout_marginEnd="8dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />

View File

@ -3,7 +3,7 @@
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_marginTop="?attr/actionBarSize"
android:fitsSystemWindows="true"
android:layout_height="match_parent">
<androidx.recyclerview.widget.RecyclerView

View File

@ -22,7 +22,7 @@
app:srcCompat="@drawable/ic_reorder_grey_24dp" />
<TextView
android:id="@+id/manga_title"
android:id="@+id/manga_full_title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
@ -45,8 +45,8 @@
android:maxLines="1"
android:textAppearance="@style/TextAppearance.Regular.Caption"
app:layout_constraintEnd_toStartOf="@+id/migration_menu"
app:layout_constraintStart_toStartOf="@+id/manga_title"
app:layout_constraintTop_toBottomOf="@+id/manga_title"
app:layout_constraintStart_toStartOf="@+id/manga_full_title"
app:layout_constraintTop_toBottomOf="@+id/manga_full_title"
tools:text="Chapter Title" />
<ProgressBar
@ -64,12 +64,12 @@
android:id="@+id/download_progress_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toEndOf="@id/manga_title"
android:layout_toEndOf="@id/manga_full_title"
android:maxLines="1"
android:textAppearance="@style/TextAppearance.Regular.Caption.Hint"
app:layout_constraintBottom_toBottomOf="@+id/manga_title"
app:layout_constraintBottom_toBottomOf="@+id/manga_full_title"
app:layout_constraintEnd_toStartOf="@+id/migration_menu"
app:layout_constraintTop_toTopOf="@+id/manga_title"
app:layout_constraintTop_toTopOf="@+id/manga_full_title"
tools:text="(0/10)" />
<ImageView

View File

@ -25,7 +25,7 @@
</FrameLayout>
<EditText
android:id="@+id/manga_title"
android:id="@+id/manga_full_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/title"

View File

@ -4,7 +4,7 @@
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="?attr/actionBarSize"
android:fitsSystemWindows="true"
android:id="@+id/ext_swipe_refresh">
<androidx.recyclerview.widget.RecyclerView

View File

@ -3,7 +3,7 @@
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_marginTop="?attr/actionBarSize"
android:fitsSystemWindows="true"
android:layout_height="match_parent">
<ImageView

View File

@ -4,7 +4,6 @@
android:layout_width="match_parent"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/library_layout"
android:layout_marginTop="?attr/actionBarSize"
android:layout_height="match_parent">
<FrameLayout
android:id="@+id/recycler_layout"

View File

@ -1,44 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/drawer_container"
android:layout_width="match_parent"
android:layout_height="match_parent">
<View
android:id="@+id/nav_bar_scrim"
android:layout_width="match_parent"
android:layout_height="30dp"
android:layout_gravity="bottom"
android:background="?attr/colorPrimary" />
<androidx.drawerlayout.widget.DrawerLayout
android:id="@+id/drawer"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<androidx.constraintlayout.widget.ConstraintLayout
android:orientation="vertical"
android:id="@+id/main_content"
android:layout_width="match_parent"
android:fitsSystemWindows="false"
android:layout_height="match_parent">
android:layout_height="match_parent"
android:orientation="vertical">
<eu.kanade.tachiyomi.widget.ElevationAppBarLayout
android:id="@+id/appbar"
android:layout_width="match_parent"
android:translationZ="0.1dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
android:layout_height="wrap_content"
android:stateListAnimator="@null"
android:translationZ="0.1dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
android:layout_height="wrap_content">
app:layout_constraintTop_toTopOf="parent">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
@ -46,17 +25,18 @@
<com.google.android.material.tabs.TabLayout
android:id="@+id/tabs"
android:visibility="gone"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/Theme.ActionBar.Tab"
android:background="?colorPrimary"
app:tabRippleColor="@color/rippleColor"
app:tabIndicatorColor="?attr/actionBarTintColor"
app:tabTextColor="?attr/actionBarTintColor"
app:tabInlineLabel="true"
android:theme="@style/Theme.ActionBar.Tab"
app:tabGravity="center"
app:tabIndicatorColor="?attr/actionBarTintColor"
app:tabInlineLabel="true"
app:tabMinWidth="75dp"
app:tabMode="auto"
app:tabMinWidth="75dp"/>
app:tabRippleColor="@color/rippleColor"
app:tabTextColor="?attr/actionBarTintColor" />
</eu.kanade.tachiyomi.widget.ElevationAppBarLayout>
@ -79,15 +59,12 @@
app:itemIconTint="@drawable/bottom_nav_item_selector"
app:itemRippleColor="@color/rippleColor"
app:itemTextColor="@drawable/bottom_nav_item_selector"
app:labelVisibilityMode="labeled"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:menu="@menu/bottom_navigation"
app:labelVisibilityMode="labeled"
app:tabBackground="@color/rippleColor"
app:tabRippleColor="@color/rippleColor"
app:tabTextColor="?attr/tabBarIconColor" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.drawerlayout.widget.DrawerLayout>
</FrameLayout>

View File

@ -19,26 +19,30 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.35" />
app:layout_constraintGuide_begin="137dp" />
<View
android:id="@+id/true_backdrop"
android:layout_width="0dp"
android:layout_height="200dp"
android:layout_height="0dp"
app:layout_constraintHeight_min="200dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="@id/bottom_line"
app:layout_constraintVertical_bias="0.0"
tools:background="@color/material_red_400" />
<ImageView
android:id="@+id/backdrop"
android:layout_width="0dp"
android:layout_height="200dp"
android:layout_height="0dp"
android:alpha="0.1"
android:scaleType="centerCrop"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintTop_toTopOf="@+id/true_backdrop"
app:layout_constraintBottom_toBottomOf="@+id/true_backdrop"
tools:src="@mipmap/ic_launcher" />
<View
@ -52,42 +56,46 @@
<View
android:id="@+id/top_view"
android:layout_width="match_parent"
android:layout_height="30dp"
android:layout_height="0dp"
android:layout_marginTop="100dp"
app:layout_constraintBottom_toTopOf="@id/top_line"
app:layout_constraintTop_toTopOf="parent" />
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.48000002" />
<androidx.constraintlayout.widget.Barrier
android:id="@+id/top_line"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:barrierDirection="top"
app:constraint_referenced_ids="cover_card,manga_layout" />
app:constraint_referenced_ids="cover_card,manga_layout"
tools:layout_editor_absoluteY="93dp" />
<FrameLayout
android:id="@+id/manga_layout"
android:layout_width="100dp"
android:layout_height="0dp"
android:layout_marginStart="16dp"
android:layout_marginTop="32dp"
android:layout_marginEnd="16dp"
android:layout_marginBottom="16dp"
android:layout_marginStart="16dp"
app:layout_constraintBottom_toBottomOf="@id/guideline"
app:layout_constraintDimensionRatio="h,7:10"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@id/top_line">
app:layout_constraintStart_toStartOf="parent">
</FrameLayout>
<com.google.android.material.card.MaterialCardView
android:id="@+id/cover_card"
android:layout_width="0dp"
android:layout_width="100dp"
android:layout_height="wrap_content"
android:layout_marginTop="32dp"
app:layout_constraintBottom_toBottomOf="@id/manga_layout"
android:layout_marginBottom="16dp"
android:layout_marginStart="16dp"
app:layout_constraintBottom_toBottomOf="@id/guideline"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@id/true_backdrop"
app:layout_constraintEnd_toEndOf="@id/manga_layout"
app:layout_constraintStart_toStartOf="@id/manga_layout"
app:layout_constraintTop_toTopOf="@id/top_line"
app:layout_constraintTop_toBottomOf="@id/top_view"
app:layout_constraintVertical_bias="1.0">
<ImageView
@ -103,7 +111,7 @@
<TextView
android:id="@+id/manga_title"
android:id="@+id/manga_full_title"
style="@style/TextAppearance.MaterialComponents.Headline5"
android:layout_width="0dp"
android:layout_height="wrap_content"
@ -129,31 +137,20 @@
android:text="@string/manga_info_author_label"
android:textIsSelectable="false"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="@id/manga_title"
app:layout_constraintTop_toBottomOf="@+id/manga_title" />
<TextView
android:id="@+id/manga_last_update_label"
style="@style/TextAppearance.Medium.Body2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/manga_info_latest_data_label"
android:textIsSelectable="false"
app:layout_constraintStart_toStartOf="@id/manga_title"
app:layout_constraintTop_toBottomOf="@+id/manga_author" />
app:layout_constraintStart_toStartOf="@id/manga_full_title"
app:layout_constraintTop_toBottomOf="@+id/manga_full_title" />
<TextView
android:id="@+id/manga_last_update"
style="@style/TextAppearance.Regular.Body1.Secondary"
android:layout_width="0dp"
android:layout_marginTop="12dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:ellipsize="end"
android:maxLines="1"
android:text="@string/manga_info_latest_data_label"
tools:text="Last updated 3 days ago"
android:textIsSelectable="false"
app:layout_constraintBaseline_toBaselineOf="@+id/manga_last_update_label"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/manga_last_update_label" />
app:layout_constraintStart_toStartOf="@id/manga_full_title"
app:layout_constraintTop_toBottomOf="@+id/manga_author" />
<com.google.android.material.textview.MaterialTextView
android:id="@+id/manga_status_source"
@ -164,8 +161,8 @@
android:maxLines="1"
android:textIsSelectable="false"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="@id/manga_title"
app:layout_constraintTop_toBottomOf="@id/manga_last_update_label"
app:layout_constraintStart_toStartOf="@id/manga_full_title"
app:layout_constraintTop_toBottomOf="@id/manga_last_update"
tools:text="Completed • Mangadex (EN)" />
<androidx.constraintlayout.widget.Barrier
@ -175,7 +172,7 @@
android:layout_margin="6dp"
android:orientation="horizontal"
app:barrierDirection="bottom"
app:constraint_referenced_ids="manga_status_source,manga_layout" />
app:constraint_referenced_ids="manga_status_source,manga_layout,cover_card" />
<LinearLayout
@ -237,6 +234,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="4dp"
android:layout_marginEnd="16dp"
android:maxLines="3"
android:textIsSelectable="false"
@ -269,7 +267,7 @@
style="@style/Widget.MaterialComponents.Button.TextButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="20sp"
android:layout_marginTop="19.5sp"
android:text="More"
android:textAllCaps="false"
android:textColor="?colorAccent"

View File

@ -87,7 +87,7 @@
android:layout_height="match_parent">
<TextView
android:id="@+id/manga_title"
android:id="@+id/manga_full_title"
style="@style/TextAppearance.Medium.Title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
@ -110,7 +110,7 @@
android:textIsSelectable="false"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toBottomOf="@+id/manga_title" />
app:layout_constraintTop_toBottomOf="@+id/manga_full_title" />
<TextView
android:id="@+id/manga_author"
@ -172,7 +172,7 @@
app:layout_constraintEnd_toEndOf="parent"/>
<TextView
android:id="@+id/manga_last_update_label"
android:id="@+id/manga_last_update"
style="@style/TextAppearance.Medium.Body2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
@ -190,8 +190,8 @@
android:ellipsize="end"
android:maxLines="1"
android:textIsSelectable="false"
app:layout_constraintBaseline_toBaselineOf="@+id/manga_last_update_label"
app:layout_constraintStart_toEndOf="@+id/manga_last_update_label"
app:layout_constraintBaseline_toBaselineOf="@+id/manga_last_update"
app:layout_constraintStart_toEndOf="@+id/manga_last_update"
app:layout_constraintEnd_toEndOf="parent"/>
<TextView
@ -201,7 +201,7 @@
android:layout_height="wrap_content"
android:text="@string/manga_info_status_label"
android:textIsSelectable="false"
app:layout_constraintTop_toBottomOf="@+id/manga_last_update_label"
app:layout_constraintTop_toBottomOf="@+id/manga_last_update"
app:layout_constraintStart_toStartOf="parent"/>
<TextView

View File

@ -4,5 +4,5 @@
android:id="@+id/migration_recycler"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="?attr/actionBarSize"
android:fitsSystemWindows="true"
android:clipToPadding="false"/>

View File

@ -4,7 +4,7 @@
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="?attr/actionBarSize"
android:fitsSystemWindows="true"
android:animateLayoutChanges="true">
<androidx.recyclerview.widget.RecyclerView

View File

@ -4,7 +4,7 @@
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="?attr/actionBarSize"
android:fitsSystemWindows="true"
android:animateLayoutChanges="true">
<androidx.recyclerview.widget.RecyclerView

View File

@ -4,8 +4,6 @@
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipToPadding="false"
android:layout_marginTop="?attr/actionBarSize"
android:orientation="vertical">
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:id="@+id/swipe_refresh"

View File

@ -19,7 +19,7 @@
tools:src="@mipmap/ic_launcher" />
<TextView
android:id="@+id/manga_title"
android:id="@+id/manga_full_title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
@ -43,7 +43,7 @@
android:maxLines="1"
android:textAppearance="@style/TextAppearance.Regular.Caption"
app:layout_constraintStart_toEndOf="@+id/manga_cover"
app:layout_constraintTop_toBottomOf="@+id/manga_title"
app:layout_constraintTop_toBottomOf="@+id/manga_full_title"
app:layout_constraintEnd_toStartOf="@+id/download_text"
app:layout_constraintBottom_toBottomOf="parent"
tools:text="Chapter title" />

View File

@ -4,7 +4,6 @@
android:id="@+id/frame_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="?attr/actionBarSize"
android:orientation="vertical">
<androidx.recyclerview.widget.RecyclerView

View File

@ -28,7 +28,7 @@
android:padding="16dp">
<TextView
android:id="@+id/manga_title"
android:id="@+id/manga_full_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:maxLines="2"
@ -38,7 +38,7 @@
android:id="@+id/manga_source"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/manga_title"
android:layout_below="@id/manga_full_title"
android:textAppearance="@style/TextAppearance.Medium.Body2" />
<TextView

View File

@ -25,7 +25,7 @@
<color name="textColorSecondaryInverse">@color/md_black_1000_54</color>
<color name="textColorHint">@color/md_white_1000_50</color>
<color name="textColorHintInverse">@color/md_black_1000_38</color>
<color name="divider">@android:color/transparent</color>
<color name="divider">@color/md_white_1000_12</color>
<color name="background">#1C1C1D</color>
<color name="dialog">@color/md_grey_800</color>

View File

@ -7,6 +7,8 @@
<string name="categories">Categories</string>
<string name="manga">Manga</string>
<string name="manhwa">Manhwa</string>
<string name="manhua">Manhua</string>
<string name="comic">Comic</string>
<string name="chapters">Chapters</string>
<string name="track">Tracking</string>
<string name="history">History</string>
@ -437,7 +439,6 @@
<item quantity="other">%d unread</item>
</plurals>
<string name="new_chapter">New</string>
<string name="start_reading">Start Reading</string>
<plurals name="download_count">
<item quantity="one">1 downloaded</item>
<item quantity="other">%d downloaded</item>
@ -475,6 +476,9 @@
<string name="description">Description</string>
<string name="ongoing">Ongoing</string>
<string name="unknown">Unknown</string>
<string name="unknown_status">Unknown Status</string>
<string name="last_updated">Last updated %1$s</string>
<string name="last_update_unknown">Last update unknown</string>
<string name="licensed">Licensed</string>
<string name="manga_info_full_title_label">Title</string>
<string name="manga_added_library">Added to library</string>
@ -495,10 +499,13 @@
<string name="icon_creation_fail">Could not create shortcut</string>
<string name="copied_to_clipboard">%1$s copied to clipboard</string>
<string name="source_not_installed">Source not installed: %1$s</string>
<string name="about_this">About this %1$s</string>
<!-- Manga chapters fragment -->
<string name="start_reader_chapter">Start Reading Chapter %1$s</string>
<string name="continue_reader_chapter">Continue Reading Chapter %1$s</string>
<string name="start_reading">Start reading</string>
<string name="start_reader_chapter">Start reading Chapter %1$s</string>
<string name="continue_reading_chapter">Continue reading Chapter %1$s</string>
<string name="continue_reading">Continue reading</string>
<string name="manga_chapters_tab">Chapters</string>
<string name="display_mode_chapter">Chapter %1$s</string>
<string name="chapter_downloaded">Downloaded</string>
@ -580,6 +587,10 @@
<string name="set_as_cover">Set as cover</string>
<string name="cover_updated">Cover updated</string>
<string name="chapter_progress">Page: %1$d</string>
<plurals name="pages_left">
<item quantity="one">%1$d page left</item>
<item quantity="other">%1$d pages left</item>
</plurals>
<string name="no_next_chapter">Next chapter not found</string>
<string name="decode_image_error">The image could not be decoded</string>
<string name="confirm_set_image_as_cover">Use this image as cover art?</string>