Updates to stuff once more
More manga type handling Fixed download progress colors Manga controller now listens to global updates Removed search activity layout, using main activty with navbar hidden Empty library while using filters now has new text
This commit is contained in:
parent
0c81459143
commit
52e6a7fc95
@ -3,7 +3,8 @@ package eu.kanade.tachiyomi.data.database.models
|
|||||||
import eu.kanade.tachiyomi.source.SourceManager
|
import eu.kanade.tachiyomi.source.SourceManager
|
||||||
import eu.kanade.tachiyomi.source.model.SManga
|
import eu.kanade.tachiyomi.source.model.SManga
|
||||||
import eu.kanade.tachiyomi.ui.reader.ReaderActivity
|
import eu.kanade.tachiyomi.ui.reader.ReaderActivity
|
||||||
import uy.kohesive.injekt.injectLazy
|
import uy.kohesive.injekt.Injekt
|
||||||
|
import uy.kohesive.injekt.api.get
|
||||||
import java.util.Locale
|
import java.util.Locale
|
||||||
|
|
||||||
interface Manga : SManga {
|
interface Manga : SManga {
|
||||||
@ -35,47 +36,62 @@ interface Manga : SManga {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun mangaType(): Int {
|
fun mangaType(): Int {
|
||||||
val sourceManager: SourceManager by injectLazy()
|
val sourceName = Injekt.get<SourceManager>().getOrStub(source).name
|
||||||
val currentTags = currentGenres()?.split(",")?.map { it.trim().toLowerCase(Locale.US) }
|
val currentTags = currentGenres()?.split(",")?.map { it.trim().toLowerCase(Locale.US) }
|
||||||
return if (currentTags?.any
|
return if (currentTags?.any
|
||||||
{ tag ->
|
{ tag ->
|
||||||
tag.startsWith("english") || tag == "comic"
|
tag.startsWith("english") || tag == "comic"
|
||||||
} == true)
|
} == true || isComicSource(sourceName))
|
||||||
TYPE_COMIC
|
TYPE_COMIC
|
||||||
else if (currentTags?.any
|
else if (currentTags?.any
|
||||||
{ tag ->
|
{ tag ->
|
||||||
tag.startsWith("chinese") || tag == "manhua"
|
tag.startsWith("chinese") || tag == "manhua"
|
||||||
} == true)
|
} == true ||
|
||||||
|
sourceName.contains("manhua", true))
|
||||||
TYPE_MANHUA
|
TYPE_MANHUA
|
||||||
else if (currentTags?.any
|
else if (currentTags?.any
|
||||||
{ tag ->
|
{ tag ->
|
||||||
tag == "long strip" || tag == "manhwa" ||
|
tag == "long strip" || tag == "manhwa" ||
|
||||||
tag.contains("webtoon")
|
tag.contains("webtoon")
|
||||||
} == true ||
|
} == true || isWebtoonSource(sourceName))
|
||||||
sourceManager.getOrStub(source).name.contains("webtoon", true))
|
|
||||||
TYPE_MANHWA
|
TYPE_MANHWA
|
||||||
else TYPE_MANGA
|
else TYPE_MANGA
|
||||||
}
|
}
|
||||||
|
|
||||||
fun defaultReaderType(): Int {
|
fun defaultReaderType(): Int {
|
||||||
val sourceManager: SourceManager by injectLazy()
|
val sourceName = Injekt.get<SourceManager>().getOrStub(source).name
|
||||||
val currentTags = currentGenres()?.split(",")?.map { it.trim().toLowerCase(Locale.US) }
|
val currentTags = currentGenres()?.split(",")?.map { it.trim().toLowerCase(Locale.US) }
|
||||||
return if (currentTags?.any
|
return if (currentTags?.any
|
||||||
{ tag ->
|
{ tag ->
|
||||||
tag == "long strip" || tag == "manhwa" ||
|
tag == "long strip" || tag == "manhwa" ||
|
||||||
tag.contains("webtoon")
|
tag.contains("webtoon")
|
||||||
} == true ||
|
} == true || isWebtoonSource(sourceName))
|
||||||
sourceManager.getOrStub(source).name.contains("webtoon", true))
|
|
||||||
ReaderActivity.WEBTOON
|
ReaderActivity.WEBTOON
|
||||||
else if (currentTags?.any
|
else if (currentTags?.any
|
||||||
{ tag ->
|
{ tag ->
|
||||||
tag.startsWith("chinese") || tag == "manhua" ||
|
tag.startsWith("chinese") || tag == "manhua" ||
|
||||||
tag.startsWith("english") || tag == "comic"
|
tag.startsWith("english") || tag == "comic"
|
||||||
} == true)
|
} == true || isComicSource(sourceName) ||
|
||||||
|
sourceName.contains("manhua", true) )
|
||||||
ReaderActivity.LEFT_TO_RIGHT
|
ReaderActivity.LEFT_TO_RIGHT
|
||||||
else 0
|
else 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun isWebtoonSource(sourceName: String): Boolean {
|
||||||
|
return sourceName.contains("webtoon", true) ||
|
||||||
|
sourceName.contains("manwha", true) ||
|
||||||
|
sourceName.contains("toonily", true)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun isComicSource(sourceName: String): Boolean {
|
||||||
|
return sourceName.contains("gunnerkrigg", true) ||
|
||||||
|
sourceName.contains("gunnerkrigg", true) ||
|
||||||
|
sourceName.contains("dilbert", true) ||
|
||||||
|
sourceName.contains("cyanide", true) ||
|
||||||
|
sourceName.contains("xkcd", true) ||
|
||||||
|
sourceName.contains("tapastic", true)
|
||||||
|
}
|
||||||
|
|
||||||
// Used to display the chapter's title one way or another
|
// Used to display the chapter's title one way or another
|
||||||
var displayMode: Int
|
var displayMode: Int
|
||||||
get() = chapter_flags and DISPLAY_MASK
|
get() = chapter_flags and DISPLAY_MASK
|
||||||
|
@ -196,8 +196,9 @@ class LibraryUpdateService(
|
|||||||
this.listener = listener
|
this.listener = listener
|
||||||
}
|
}
|
||||||
|
|
||||||
fun removeListener() {
|
fun removeListener(listener: LibraryServiceListener) {
|
||||||
listener = null
|
if (this.listener == listener)
|
||||||
|
this.listener = null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,6 +17,8 @@ class DownloadButton @JvmOverloads constructor(context: Context, attrs: Attribut
|
|||||||
: FrameLayout(context, attrs) {
|
: FrameLayout(context, attrs) {
|
||||||
|
|
||||||
private val activeColor = context.getResourceColor(R.attr.colorAccent)
|
private val activeColor = context.getResourceColor(R.attr.colorAccent)
|
||||||
|
private val progressBGColor = ContextCompat.getColor(context,
|
||||||
|
R.color.divider)
|
||||||
private val disabledColor = ContextCompat.getColor(context,
|
private val disabledColor = ContextCompat.getColor(context,
|
||||||
R.color.material_on_surface_disabled)
|
R.color.material_on_surface_disabled)
|
||||||
private val downloadedColor = ContextCompat.getColor(context,
|
private val downloadedColor = ContextCompat.getColor(context,
|
||||||
@ -60,7 +62,7 @@ class DownloadButton @JvmOverloads constructor(context: Context, attrs: Attribut
|
|||||||
download_border.setImageDrawable(borderCircle)
|
download_border.setImageDrawable(borderCircle)
|
||||||
download_progress.isIndeterminate = false
|
download_progress.isIndeterminate = false
|
||||||
download_progress.progress = progress
|
download_progress.progress = progress
|
||||||
download_border.drawable.setTint(disabledColor)
|
download_border.drawable.setTint(progressBGColor)
|
||||||
download_progress.progressDrawable?.setTint(downloadedColor)
|
download_progress.progressDrawable?.setTint(downloadedColor)
|
||||||
download_icon.drawable.setTint(disabledColor)
|
download_icon.drawable.setTint(disabledColor)
|
||||||
if (!isAnimating) {
|
if (!isAnimating) {
|
||||||
|
@ -299,7 +299,7 @@ open class LibraryController(
|
|||||||
override fun onDestroyView(view: View) {
|
override fun onDestroyView(view: View) {
|
||||||
pagerAdapter?.onDestroy()
|
pagerAdapter?.onDestroy()
|
||||||
DownloadService.removeListener(this)
|
DownloadService.removeListener(this)
|
||||||
LibraryUpdateService.removeListener()
|
LibraryUpdateService.removeListener(this)
|
||||||
pagerAdapter = null
|
pagerAdapter = null
|
||||||
actionMode = null
|
actionMode = null
|
||||||
tabsVisibilitySubscription?.unsubscribe()
|
tabsVisibilitySubscription?.unsubscribe()
|
||||||
|
@ -222,7 +222,11 @@ class LibraryListController(bundle: Bundle? = null) : LibraryController(bundle),
|
|||||||
if (mangaMap.isNotEmpty()) {
|
if (mangaMap.isNotEmpty()) {
|
||||||
empty_view?.hide()
|
empty_view?.hide()
|
||||||
} else {
|
} else {
|
||||||
empty_view?.show(R.drawable.ic_book_black_128dp, R.string.information_empty_library)
|
empty_view?.show(
|
||||||
|
R.drawable.ic_book_black_128dp,
|
||||||
|
if (bottom_sheet.hasActiveFilters()) R.string.information_empty_library_filtered
|
||||||
|
else R.string.information_empty_library
|
||||||
|
)
|
||||||
}
|
}
|
||||||
adapter.setItems(mangaMap)
|
adapter.setItems(mangaMap)
|
||||||
|
|
||||||
|
@ -170,14 +170,9 @@ class LibraryPresenter(
|
|||||||
if (filterUnread == STATE_REALLY_EXCLUDE && item.manga.unread > 0) return@f false
|
if (filterUnread == STATE_REALLY_EXCLUDE && item.manga.unread > 0) return@f false
|
||||||
|
|
||||||
if (filterMangaType > 0) {
|
if (filterMangaType > 0) {
|
||||||
val mangaType = item.manga.mangaType()
|
if (filterMangaType != item.manga.mangaType()) return@f false
|
||||||
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_MANHWA) && mangaType != Manga.TYPE_MANHWA) return@f false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (filterCompleted == STATE_INCLUDE && item.manga.status != SManga.COMPLETED)
|
if (filterCompleted == STATE_INCLUDE && item.manga.status != SManga.COMPLETED)
|
||||||
return@f false
|
return@f false
|
||||||
if (filterCompleted == STATE_EXCLUDE && item.manga.status == SManga.COMPLETED)
|
if (filterCompleted == STATE_EXCLUDE && item.manga.status == SManga.COMPLETED)
|
||||||
|
@ -80,8 +80,6 @@ open class MainActivity : BaseActivity(), DownloadServiceListener {
|
|||||||
private var currentGestureDelegate:SwipeGestureInterface? = null
|
private var currentGestureDelegate:SwipeGestureInterface? = null
|
||||||
private lateinit var gestureDetector:GestureDetectorCompat
|
private lateinit var gestureDetector:GestureDetectorCompat
|
||||||
|
|
||||||
protected open var trulyGoBack = false
|
|
||||||
|
|
||||||
private var secondaryDrawer: ViewGroup? = null
|
private var secondaryDrawer: ViewGroup? = null
|
||||||
|
|
||||||
private var snackBar:Snackbar? = null
|
private var snackBar:Snackbar? = null
|
||||||
@ -112,7 +110,6 @@ open class MainActivity : BaseActivity(), DownloadServiceListener {
|
|||||||
Timber.e(e, "Exception when creating webview at start")
|
Timber.e(e, "Exception when creating webview at start")
|
||||||
}
|
}
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
if (trulyGoBack) return
|
|
||||||
|
|
||||||
// Do not let the launcher create a new activity http://stackoverflow.com/questions/16283079
|
// Do not let the launcher create a new activity http://stackoverflow.com/questions/16283079
|
||||||
if (!isTaskRoot) {
|
if (!isTaskRoot) {
|
||||||
@ -314,8 +311,6 @@ open class MainActivity : BaseActivity(), DownloadServiceListener {
|
|||||||
container: ViewGroup, handler: ControllerChangeHandler) {
|
container: ViewGroup, handler: ControllerChangeHandler) {
|
||||||
|
|
||||||
syncActivityViewWithController(to, from)
|
syncActivityViewWithController(to, from)
|
||||||
if (to !is DialogController)
|
|
||||||
navigationView.visibility = if (router.backstackSize > 1) View.GONE else View.VISIBLE
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onChangeCompleted(to: Controller?, from: Controller?, isPush: Boolean,
|
override fun onChangeCompleted(to: Controller?, from: Controller?, isPush: Boolean,
|
||||||
@ -394,7 +389,6 @@ open class MainActivity : BaseActivity(), DownloadServiceListener {
|
|||||||
override fun onResume() {
|
override fun onResume() {
|
||||||
super.onResume()
|
super.onResume()
|
||||||
// setting in case someone comes from the search activity to main
|
// setting in case someone comes from the search activity to main
|
||||||
usingBottomNav = true
|
|
||||||
getExtensionUpdates()
|
getExtensionUpdates()
|
||||||
DownloadService.callListeners()
|
DownloadService.callListeners()
|
||||||
}
|
}
|
||||||
@ -501,10 +495,10 @@ open class MainActivity : BaseActivity(), DownloadServiceListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun onBackPressed() {
|
override fun onBackPressed() {
|
||||||
if (trulyGoBack) {
|
/*if (trulyGoBack) {
|
||||||
super.onBackPressed()
|
super.onBackPressed()
|
||||||
return
|
return
|
||||||
}
|
}*/
|
||||||
/*if (drawer.isDrawerOpen(GravityCompat.START) || drawer.isDrawerOpen(GravityCompat.END)) {
|
/*if (drawer.isDrawerOpen(GravityCompat.START) || drawer.isDrawerOpen(GravityCompat.END)) {
|
||||||
drawer.closeDrawers()
|
drawer.closeDrawers()
|
||||||
} else {*/
|
} else {*/
|
||||||
@ -560,17 +554,6 @@ open class MainActivity : BaseActivity(), DownloadServiceListener {
|
|||||||
}
|
}
|
||||||
drawerArrow?.progress = 1f
|
drawerArrow?.progress = 1f
|
||||||
|
|
||||||
/* if (from is TabbedController) {
|
|
||||||
from.cleanupTabs(tabs)
|
|
||||||
}
|
|
||||||
if (to is TabbedController) {
|
|
||||||
tabAnimator.expand()
|
|
||||||
to.configureTabs(tabs)
|
|
||||||
} else {
|
|
||||||
tabAnimator.collapse()
|
|
||||||
tabs.setupWithViewPager(null)
|
|
||||||
}*/
|
|
||||||
|
|
||||||
currentGestureDelegate = to as? SwipeGestureInterface
|
currentGestureDelegate = to as? SwipeGestureInterface
|
||||||
|
|
||||||
/*if (from is SecondaryDrawerController) {
|
/*if (from is SecondaryDrawerController) {
|
||||||
@ -593,6 +576,9 @@ open class MainActivity : BaseActivity(), DownloadServiceListener {
|
|||||||
} else {
|
} else {
|
||||||
appbar.enableElevation()
|
appbar.enableElevation()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (to !is DialogController)
|
||||||
|
navigationView.visibility = if (router.backstackSize > 1) View.GONE else View.VISIBLE
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun downloadStatusChanged(downloading: Boolean) {
|
override fun downloadStatusChanged(downloading: Boolean) {
|
||||||
@ -672,8 +658,6 @@ open class MainActivity : BaseActivity(), DownloadServiceListener {
|
|||||||
const val INTENT_SEARCH_QUERY = "query"
|
const val INTENT_SEARCH_QUERY = "query"
|
||||||
const val INTENT_SEARCH_FILTER = "filter"
|
const val INTENT_SEARCH_FILTER = "filter"
|
||||||
|
|
||||||
var usingBottomNav = true
|
|
||||||
internal set
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,148 +2,24 @@ package eu.kanade.tachiyomi.ui.main
|
|||||||
|
|
||||||
import android.app.SearchManager
|
import android.app.SearchManager
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.content.res.Configuration
|
|
||||||
import android.graphics.Color
|
|
||||||
import android.os.Build
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.View
|
|
||||||
import android.view.ViewGroup
|
|
||||||
import android.widget.FrameLayout
|
|
||||||
import android.widget.LinearLayout
|
|
||||||
import androidx.appcompat.graphics.drawable.DrawerArrowDrawable
|
|
||||||
import androidx.core.graphics.ColorUtils
|
|
||||||
import com.bluelinelabs.conductor.Conductor
|
|
||||||
import com.bluelinelabs.conductor.Controller
|
import com.bluelinelabs.conductor.Controller
|
||||||
import com.bluelinelabs.conductor.ControllerChangeHandler
|
|
||||||
import eu.kanade.tachiyomi.R
|
|
||||||
import eu.kanade.tachiyomi.data.notification.NotificationReceiver
|
import eu.kanade.tachiyomi.data.notification.NotificationReceiver
|
||||||
import eu.kanade.tachiyomi.ui.base.controller.DialogController
|
import eu.kanade.tachiyomi.ui.base.controller.DialogController
|
||||||
import eu.kanade.tachiyomi.ui.base.controller.NoToolbarElevationController
|
import eu.kanade.tachiyomi.ui.base.controller.NoToolbarElevationController
|
||||||
import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction
|
import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction
|
||||||
import eu.kanade.tachiyomi.ui.catalogue.global_search.CatalogueSearchController
|
import eu.kanade.tachiyomi.ui.catalogue.global_search.CatalogueSearchController
|
||||||
import eu.kanade.tachiyomi.ui.security.SecureActivityDelegate
|
import eu.kanade.tachiyomi.ui.security.SecureActivityDelegate
|
||||||
import eu.kanade.tachiyomi.util.system.getResourceColor
|
import eu.kanade.tachiyomi.util.view.gone
|
||||||
import eu.kanade.tachiyomi.util.view.updateLayoutParams
|
import kotlinx.android.synthetic.main.main_activity.*
|
||||||
import eu.kanade.tachiyomi.util.view.updatePadding
|
|
||||||
import kotlinx.android.synthetic.main.search_activity.*
|
|
||||||
|
|
||||||
class SearchActivity: MainActivity() {
|
class SearchActivity: MainActivity() {
|
||||||
override var trulyGoBack = true
|
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
|
toolbar.setNavigationOnClickListener {
|
||||||
usingBottomNav = false
|
|
||||||
setContentView(R.layout.search_activity)
|
|
||||||
|
|
||||||
setSupportActionBar(sToolbar)
|
|
||||||
|
|
||||||
drawerArrow = DrawerArrowDrawable(this)
|
|
||||||
drawerArrow?.color = getResourceColor(R.attr.actionBarTintColor)
|
|
||||||
sToolbar.navigationIcon = drawerArrow
|
|
||||||
|
|
||||||
//tabAnimator = TabsAnimator(sTabs)
|
|
||||||
|
|
||||||
val container: ViewGroup = findViewById(R.id.controller_container)
|
|
||||||
|
|
||||||
val content: LinearLayout = findViewById(R.id.main_content)
|
|
||||||
container.systemUiVisibility = View.SYSTEM_UI_FLAG_LAYOUT_STABLE or
|
|
||||||
View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or
|
|
||||||
View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
|
|
||||||
content.systemUiVisibility = View.SYSTEM_UI_FLAG_LAYOUT_STABLE or
|
|
||||||
View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or
|
|
||||||
View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
|
|
||||||
|
|
||||||
content.setOnApplyWindowInsetsListener { v, insets ->
|
|
||||||
window.navigationBarColor =
|
|
||||||
// if the os does not support light nav bar and is portrait, draw a dark translucent
|
|
||||||
// nav bar
|
|
||||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
|
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M &&
|
|
||||||
(v.rootWindowInsets.systemWindowInsetLeft > 0 ||
|
|
||||||
v.rootWindowInsets.systemWindowInsetRight > 0))
|
|
||||||
// For lollipop, draw opaque nav bar
|
|
||||||
Color.BLACK
|
|
||||||
else Color.argb(179, 0, 0, 0)
|
|
||||||
}
|
|
||||||
// if the android q+ device has gesture nav, transparent nav bar
|
|
||||||
else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q
|
|
||||||
&& (v.rootWindowInsets.systemWindowInsetBottom != v.rootWindowInsets
|
|
||||||
.tappableElementInsets.bottom)) {
|
|
||||||
getColor(android.R.color.transparent)
|
|
||||||
}
|
|
||||||
// if in landscape with 2/3 button mode, fully opaque nav bar
|
|
||||||
else if (v.rootWindowInsets.systemWindowInsetLeft > 0
|
|
||||||
|| v.rootWindowInsets.systemWindowInsetRight > 0) {
|
|
||||||
getResourceColor(android.R.attr.colorBackground)
|
|
||||||
}
|
|
||||||
// if in portrait with 2/3 button mode, translucent nav bar
|
|
||||||
else {
|
|
||||||
ColorUtils.setAlphaComponent(
|
|
||||||
getResourceColor(android.R.attr.colorBackground), 179)
|
|
||||||
}
|
|
||||||
v.setPadding(insets.systemWindowInsetLeft, insets.systemWindowInsetTop,
|
|
||||||
insets.systemWindowInsetRight, 0)
|
|
||||||
insets
|
|
||||||
}
|
|
||||||
val currentNightMode = resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK
|
|
||||||
if (Build.VERSION.SDK_INT >= 26 && currentNightMode == Configuration.UI_MODE_NIGHT_NO &&
|
|
||||||
preferences.theme() >= 8) {
|
|
||||||
content.systemUiVisibility = content.systemUiVisibility.or(View
|
|
||||||
.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR)
|
|
||||||
}
|
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && currentNightMode == Configuration
|
|
||||||
.UI_MODE_NIGHT_NO && preferences.theme() >= 8)
|
|
||||||
content.systemUiVisibility = content.systemUiVisibility.or(View
|
|
||||||
.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR)
|
|
||||||
|
|
||||||
val searchContainer: FrameLayout = findViewById(R.id.search_container)
|
|
||||||
searchContainer.setOnApplyWindowInsetsListener { v, insets ->
|
|
||||||
window.statusBarColor = getResourceColor(R.attr.colorPrimary)
|
|
||||||
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
|
|
||||||
)
|
|
||||||
insets.replaceSystemWindowInsets(
|
|
||||||
0, insets.systemWindowInsetTop,
|
|
||||||
0, insets.systemWindowInsetBottom
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
router = Conductor.attachRouter(this, container, savedInstanceState)
|
|
||||||
if (!router.hasRootController()) {
|
|
||||||
// Set start screen
|
|
||||||
handleIntentAction(intent)
|
|
||||||
}
|
|
||||||
|
|
||||||
sToolbar.setNavigationOnClickListener {
|
|
||||||
popToRoot()
|
popToRoot()
|
||||||
}
|
}
|
||||||
|
|
||||||
router.addChangeListener(object : ControllerChangeHandler.ControllerChangeListener {
|
|
||||||
override fun onChangeStarted(to: Controller?, from: Controller?, isPush: Boolean,
|
|
||||||
container: ViewGroup, handler: ControllerChangeHandler
|
|
||||||
) {
|
|
||||||
|
|
||||||
syncActivityViewWithController(to, from)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onChangeCompleted(to: Controller?, from: Controller?, isPush: Boolean,
|
|
||||||
container: ViewGroup, handler: ControllerChangeHandler
|
|
||||||
) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
})
|
|
||||||
|
|
||||||
syncActivityViewWithController(router.backstack.lastOrNull()?.controller())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onBackPressed() {
|
override fun onBackPressed() {
|
||||||
@ -167,29 +43,15 @@ class SearchActivity: MainActivity() {
|
|||||||
if (from is DialogController || to is DialogController) {
|
if (from is DialogController || to is DialogController) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
toolbar.navigationIcon = drawerArrow
|
||||||
drawerArrow?.progress = 1f
|
drawerArrow?.progress = 1f
|
||||||
|
|
||||||
/*if (from is TabbedController) {
|
|
||||||
from.cleanupTabs(sTabs)
|
|
||||||
}
|
|
||||||
if (to is TabbedController) {
|
|
||||||
tabAnimator.expand()
|
|
||||||
to.configureTabs(sTabs)
|
|
||||||
} else {
|
|
||||||
tabAnimator.collapse()
|
|
||||||
sTabs.setupWithViewPager(null)
|
|
||||||
}*/
|
|
||||||
|
|
||||||
if (to is NoToolbarElevationController) {
|
if (to is NoToolbarElevationController) {
|
||||||
appbar.disableElevation()
|
appbar.disableElevation()
|
||||||
} else {
|
} else {
|
||||||
appbar.enableElevation()
|
appbar.enableElevation()
|
||||||
}
|
}
|
||||||
}
|
navigationView.gone()
|
||||||
|
|
||||||
override fun onResume() {
|
|
||||||
super.onResume()
|
|
||||||
usingBottomNav = false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun handleIntentAction(intent: Intent): Boolean {
|
override fun handleIntentAction(intent: Intent): Boolean {
|
||||||
|
@ -44,6 +44,7 @@ import eu.kanade.tachiyomi.data.notification.NotificationReceiver
|
|||||||
import eu.kanade.tachiyomi.source.Source
|
import eu.kanade.tachiyomi.source.Source
|
||||||
import eu.kanade.tachiyomi.source.SourceManager
|
import eu.kanade.tachiyomi.source.SourceManager
|
||||||
import eu.kanade.tachiyomi.ui.base.controller.BaseController
|
import eu.kanade.tachiyomi.ui.base.controller.BaseController
|
||||||
|
import eu.kanade.tachiyomi.ui.base.controller.NoToolbarElevationController
|
||||||
import eu.kanade.tachiyomi.ui.catalogue.CatalogueController
|
import eu.kanade.tachiyomi.ui.catalogue.CatalogueController
|
||||||
import eu.kanade.tachiyomi.ui.library.ChangeMangaCategoriesDialog
|
import eu.kanade.tachiyomi.ui.library.ChangeMangaCategoriesDialog
|
||||||
import eu.kanade.tachiyomi.ui.library.LibraryController
|
import eu.kanade.tachiyomi.ui.library.LibraryController
|
||||||
@ -75,7 +76,8 @@ class MangaChaptersController : BaseController,
|
|||||||
FlexibleAdapter.OnItemClickListener,
|
FlexibleAdapter.OnItemClickListener,
|
||||||
FlexibleAdapter.OnItemLongClickListener,
|
FlexibleAdapter.OnItemLongClickListener,
|
||||||
ChaptersAdapter.MangaHeaderInterface,
|
ChaptersAdapter.MangaHeaderInterface,
|
||||||
ChangeMangaCategoriesDialog.Listener {
|
ChangeMangaCategoriesDialog.Listener,
|
||||||
|
NoToolbarElevationController {
|
||||||
|
|
||||||
constructor(manga: Manga?,
|
constructor(manga: Manga?,
|
||||||
fromCatalogue: Boolean = false,
|
fromCatalogue: Boolean = false,
|
||||||
@ -148,11 +150,11 @@ class MangaChaptersController : BaseController,
|
|||||||
val array = view.context.obtainStyledAttributes(attrsArray)
|
val array = view.context.obtainStyledAttributes(attrsArray)
|
||||||
val appbarHeight = array.getDimensionPixelSize(0, 0)
|
val appbarHeight = array.getDimensionPixelSize(0, 0)
|
||||||
array.recycle()
|
array.recycle()
|
||||||
val offset = 20.dpToPx
|
val offset = 10.dpToPx
|
||||||
|
|
||||||
recycler.doOnApplyWindowInsets { v, insets, _ ->
|
recycler.doOnApplyWindowInsets { v, insets, _ ->
|
||||||
headerHeight = appbarHeight + insets.systemWindowInsetTop + offset
|
headerHeight = appbarHeight + insets.systemWindowInsetTop
|
||||||
swipe_refresh.setProgressViewOffset(false, (-40).dpToPx, headerHeight)
|
swipe_refresh.setProgressViewOffset(false, (-40).dpToPx, headerHeight + offset)
|
||||||
(recycler.findViewHolderForAdapterPosition(0) as? MangaHeaderHolder)
|
(recycler.findViewHolderForAdapterPosition(0) as? MangaHeaderHolder)
|
||||||
?.setTopHeight(headerHeight)
|
?.setTopHeight(headerHeight)
|
||||||
fast_scroller?.updateLayoutParams<ViewGroup.MarginLayoutParams> {
|
fast_scroller?.updateLayoutParams<ViewGroup.MarginLayoutParams> {
|
||||||
@ -169,15 +171,18 @@ class MangaChaptersController : BaseController,
|
|||||||
val atTop = !recycler.canScrollVertically(-1)
|
val atTop = !recycler.canScrollVertically(-1)
|
||||||
if ((!atTop && !toolbarIsColored) || (atTop && toolbarIsColored)) {
|
if ((!atTop && !toolbarIsColored) || (atTop && toolbarIsColored)) {
|
||||||
toolbarIsColored = !atTop
|
toolbarIsColored = !atTop
|
||||||
colorAnimator?.cancel()
|
|
||||||
val color =
|
val color =
|
||||||
coverColor ?: activity!!.getResourceColor(android.R.attr.colorPrimary)
|
coverColor ?: activity!!.getResourceColor(android.R.attr.colorPrimary)
|
||||||
val colorFrom = ColorUtils.setAlphaComponent(
|
val colorFrom =
|
||||||
|
if (colorAnimator?.isRunning == true) activity?.window?.statusBarColor
|
||||||
|
?: color
|
||||||
|
else ColorUtils.setAlphaComponent(
|
||||||
color, if (toolbarIsColored) 0 else 255
|
color, if (toolbarIsColored) 0 else 255
|
||||||
)
|
)
|
||||||
val colorTo = ColorUtils.setAlphaComponent(
|
val colorTo = ColorUtils.setAlphaComponent(
|
||||||
color, if (toolbarIsColored) 255 else 0
|
color, if (toolbarIsColored) 255 else 0
|
||||||
)
|
)
|
||||||
|
colorAnimator?.cancel()
|
||||||
colorAnimator = ValueAnimator.ofObject(
|
colorAnimator = ValueAnimator.ofObject(
|
||||||
ArgbEvaluator(), colorFrom, colorTo
|
ArgbEvaluator(), colorFrom, colorTo
|
||||||
)
|
)
|
||||||
@ -192,6 +197,15 @@ class MangaChaptersController : BaseController,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
setPaletteColor()
|
||||||
|
|
||||||
|
swipe_refresh.setOnRefreshListener {
|
||||||
|
presenter.refreshAll()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun setPaletteColor() {
|
||||||
|
val view = view ?: return
|
||||||
GlideApp.with(view.context).load(manga)
|
GlideApp.with(view.context).load(manga)
|
||||||
.diskCacheStrategy(DiskCacheStrategy.AUTOMATIC)
|
.diskCacheStrategy(DiskCacheStrategy.AUTOMATIC)
|
||||||
.signature(ObjectKey(MangaImpl.getLastCoverFetch(manga!!.id!!).toString()))
|
.signature(ObjectKey(MangaImpl.getLastCoverFetch(manga!!.id!!).toString()))
|
||||||
@ -224,19 +238,17 @@ class MangaChaptersController : BaseController,
|
|||||||
|
|
||||||
override fun onLoadCleared(placeholder: Drawable?) { }
|
override fun onLoadCleared(placeholder: Drawable?) { }
|
||||||
})
|
})
|
||||||
|
|
||||||
swipe_refresh.setOnRefreshListener {
|
|
||||||
presenter.refreshAll()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onActivityResumed(activity: Activity) {
|
override fun onActivityResumed(activity: Activity) {
|
||||||
super.onActivityResumed(activity)
|
super.onActivityResumed(activity)
|
||||||
|
presenter.isLockedFromSearch = SecureActivityDelegate.shouldBeLocked()
|
||||||
|
presenter.headerItem.isLocked = presenter.isLockedFromSearch
|
||||||
presenter.fetchChapters()
|
presenter.fetchChapters()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun showError(message: String) {
|
fun showError(message: String) {
|
||||||
swipe_refresh?.isRefreshing = false
|
swipe_refresh?.isRefreshing = presenter.isLoading
|
||||||
view?.snack(message)
|
view?.snack(message)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -275,24 +287,24 @@ class MangaChaptersController : BaseController,
|
|||||||
|
|
||||||
fun updateHeader() {
|
fun updateHeader() {
|
||||||
if (presenter.chapters.isEmpty()) {
|
if (presenter.chapters.isEmpty()) {
|
||||||
adapter?.updateDataSet(listOf(ChapterItem(Chapter.createH(), presenter.manga)))
|
adapter?.updateDataSet(listOf(presenter.headerItem))
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
swipe_refresh?.isRefreshing = false
|
swipe_refresh?.isRefreshing = presenter.isLoading
|
||||||
adapter?.updateDataSet(
|
adapter?.updateDataSet(
|
||||||
listOf(ChapterItem(Chapter.createH(), presenter.manga)) + presenter.chapters
|
listOf(ChapterItem(presenter.headerItem, presenter.manga)) + presenter.chapters
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fun updateChapters(chapters: List<ChapterItem>) {
|
fun updateChapters(chapters: List<ChapterItem>) {
|
||||||
swipe_refresh?.isRefreshing = false
|
swipe_refresh?.isRefreshing = presenter.isLoading
|
||||||
if (presenter.chapters.isEmpty() && fromCatalogue && !presenter.hasRequested) {
|
if (presenter.chapters.isEmpty() && fromCatalogue && !presenter.hasRequested) {
|
||||||
launchUI { swipe_refresh?.isRefreshing = true }
|
launchUI { swipe_refresh?.isRefreshing = true }
|
||||||
presenter.fetchChaptersFromSource()
|
presenter.fetchChaptersFromSource()
|
||||||
}
|
}
|
||||||
adapter?.updateDataSet(listOf(ChapterItem(Chapter.createH(), presenter.manga)) + chapters)
|
adapter?.updateDataSet(listOf(presenter.headerItem) + chapters)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onItemClick(view: View?, position: Int): Boolean {
|
override fun onItemClick(view: View?, position: Int): Boolean {
|
||||||
@ -442,10 +454,15 @@ class MangaChaptersController : BaseController,
|
|||||||
val adapter = adapter ?: return
|
val adapter = adapter ?: return
|
||||||
val chapter = adapter.getItem(position) ?: return
|
val chapter = adapter.getItem(position) ?: return
|
||||||
if (chapter.isHeader) return
|
if (chapter.isHeader) return
|
||||||
if (chapter.status != Download.NOT_DOWNLOADED) {
|
if (chapter.status != Download.NOT_DOWNLOADED && chapter.status != Download.ERROR) {
|
||||||
presenter.deleteChapters(listOf(chapter))
|
presenter.deleteChapters(listOf(chapter))
|
||||||
}
|
}
|
||||||
else presenter.downloadChapters(listOf(chapter))
|
else {
|
||||||
|
val isError = chapter.status == Download.ERROR
|
||||||
|
presenter.downloadChapters(listOf(chapter))
|
||||||
|
if (isError)
|
||||||
|
presenter.restartDownloads()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun tagClicked(text: String) {
|
override fun tagClicked(text: String) {
|
||||||
@ -463,6 +480,10 @@ class MangaChaptersController : BaseController,
|
|||||||
override fun chapterCount():Int = presenter.chapters.size
|
override fun chapterCount():Int = presenter.chapters.size
|
||||||
|
|
||||||
override fun favoriteManga(longPress: Boolean) {
|
override fun favoriteManga(longPress: Boolean) {
|
||||||
|
if (presenter.isLockedFromSearch) {
|
||||||
|
SecureActivityDelegate.promptLockIfNeeded(activity)
|
||||||
|
return
|
||||||
|
}
|
||||||
val manga = presenter.manga
|
val manga = presenter.manga
|
||||||
if (longPress) {
|
if (longPress) {
|
||||||
if (!manga.favorite) {
|
if (!manga.favorite) {
|
||||||
|
@ -35,9 +35,7 @@ import eu.kanade.tachiyomi.ui.migration.manga.process.MigrationListController
|
|||||||
import eu.kanade.tachiyomi.ui.security.SecureActivityDelegate
|
import eu.kanade.tachiyomi.ui.security.SecureActivityDelegate
|
||||||
import eu.kanade.tachiyomi.util.system.toast
|
import eu.kanade.tachiyomi.util.system.toast
|
||||||
import eu.kanade.tachiyomi.util.view.applyWindowInsetsForController
|
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.manga_controller.*
|
||||||
import kotlinx.android.synthetic.main.search_activity.*
|
|
||||||
import rx.Subscription
|
import rx.Subscription
|
||||||
import uy.kohesive.injekt.Injekt
|
import uy.kohesive.injekt.Injekt
|
||||||
import uy.kohesive.injekt.api.get
|
import uy.kohesive.injekt.api.get
|
||||||
@ -178,8 +176,7 @@ class MangaController : RxController, TabbedController, BottomNavBarInterface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun tabLayout():TabLayout? {
|
fun tabLayout():TabLayout? {
|
||||||
return if (activity is SearchActivity) activity?.sTabs
|
return null
|
||||||
else activity?.tabs
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun updateTitle(manga: Manga) {
|
fun updateTitle(manga: Manga) {
|
||||||
|
@ -162,6 +162,7 @@ class MangaHeaderHolder(
|
|||||||
}))
|
}))
|
||||||
manga_source.text = adapter.coverListener?.mangaSource()?.toString()
|
manga_source.text = adapter.coverListener?.mangaSource()?.toString()
|
||||||
|
|
||||||
|
if (!manga.initialized) return
|
||||||
GlideApp.with(view.context).load(manga)
|
GlideApp.with(view.context).load(manga)
|
||||||
.diskCacheStrategy(DiskCacheStrategy.AUTOMATIC)
|
.diskCacheStrategy(DiskCacheStrategy.AUTOMATIC)
|
||||||
.signature(ObjectKey(MangaImpl.getLastCoverFetch(manga.id!!).toString()))
|
.signature(ObjectKey(MangaImpl.getLastCoverFetch(manga.id!!).toString()))
|
||||||
|
@ -5,12 +5,15 @@ import eu.kanade.tachiyomi.data.cache.CoverCache
|
|||||||
import eu.kanade.tachiyomi.data.database.DatabaseHelper
|
import eu.kanade.tachiyomi.data.database.DatabaseHelper
|
||||||
import eu.kanade.tachiyomi.data.database.models.Category
|
import eu.kanade.tachiyomi.data.database.models.Category
|
||||||
import eu.kanade.tachiyomi.data.database.models.Chapter
|
import eu.kanade.tachiyomi.data.database.models.Chapter
|
||||||
|
import eu.kanade.tachiyomi.data.database.models.LibraryManga
|
||||||
import eu.kanade.tachiyomi.data.database.models.Manga
|
import eu.kanade.tachiyomi.data.database.models.Manga
|
||||||
import eu.kanade.tachiyomi.data.database.models.MangaCategory
|
import eu.kanade.tachiyomi.data.database.models.MangaCategory
|
||||||
import eu.kanade.tachiyomi.data.database.models.MangaImpl
|
import eu.kanade.tachiyomi.data.database.models.MangaImpl
|
||||||
import eu.kanade.tachiyomi.data.download.DownloadManager
|
import eu.kanade.tachiyomi.data.download.DownloadManager
|
||||||
import eu.kanade.tachiyomi.data.download.model.Download
|
import eu.kanade.tachiyomi.data.download.model.Download
|
||||||
import eu.kanade.tachiyomi.data.download.model.DownloadQueue
|
import eu.kanade.tachiyomi.data.download.model.DownloadQueue
|
||||||
|
import eu.kanade.tachiyomi.data.library.LibraryServiceListener
|
||||||
|
import eu.kanade.tachiyomi.data.library.LibraryUpdateService
|
||||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
||||||
import eu.kanade.tachiyomi.source.LocalSource
|
import eu.kanade.tachiyomi.source.LocalSource
|
||||||
import eu.kanade.tachiyomi.source.Source
|
import eu.kanade.tachiyomi.source.Source
|
||||||
@ -21,7 +24,6 @@ import eu.kanade.tachiyomi.util.chapter.syncChaptersWithSource
|
|||||||
import eu.kanade.tachiyomi.util.system.launchUI
|
import eu.kanade.tachiyomi.util.system.launchUI
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.GlobalScope
|
|
||||||
import kotlinx.coroutines.Job
|
import kotlinx.coroutines.Job
|
||||||
import kotlinx.coroutines.async
|
import kotlinx.coroutines.async
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
@ -39,19 +41,25 @@ class MangaPresenter(private val controller: MangaChaptersController,
|
|||||||
private val db: DatabaseHelper = Injekt.get(),
|
private val db: DatabaseHelper = Injekt.get(),
|
||||||
private val downloadManager: DownloadManager = Injekt.get()):
|
private val downloadManager: DownloadManager = Injekt.get()):
|
||||||
CoroutineScope,
|
CoroutineScope,
|
||||||
DownloadQueue.DownloadListener {
|
DownloadQueue.DownloadListener,
|
||||||
|
LibraryServiceListener {
|
||||||
|
|
||||||
override var coroutineContext:CoroutineContext = Job() + Dispatchers.Default
|
override var coroutineContext:CoroutineContext = Job() + Dispatchers.Default
|
||||||
|
|
||||||
var isLockedFromSearch = false
|
var isLockedFromSearch = false
|
||||||
var hasRequested = false
|
var hasRequested = false
|
||||||
|
var isLoading = false
|
||||||
|
|
||||||
var chapters:List<ChapterItem> = emptyList()
|
var chapters:List<ChapterItem> = emptyList()
|
||||||
private set
|
private set
|
||||||
|
|
||||||
|
var headerItem = ChapterItem(Chapter.createH(), manga)
|
||||||
|
|
||||||
fun onCreate() {
|
fun onCreate() {
|
||||||
isLockedFromSearch = SecureActivityDelegate.shouldBeLocked()
|
isLockedFromSearch = SecureActivityDelegate.shouldBeLocked()
|
||||||
|
headerItem.isLocked = isLockedFromSearch
|
||||||
downloadManager.addListener(this)
|
downloadManager.addListener(this)
|
||||||
|
LibraryUpdateService.setListener(this)
|
||||||
if (!manga.initialized) {
|
if (!manga.initialized) {
|
||||||
controller.updateHeader()
|
controller.updateHeader()
|
||||||
launchUI {
|
launchUI {
|
||||||
@ -67,31 +75,7 @@ class MangaPresenter(private val controller: MangaChaptersController,
|
|||||||
|
|
||||||
fun onDestroy() {
|
fun onDestroy() {
|
||||||
downloadManager.removeListener(this)
|
downloadManager.removeListener(this)
|
||||||
}
|
LibraryUpdateService.removeListener(this)
|
||||||
|
|
||||||
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()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun fetchChapters() {
|
fun fetchChapters() {
|
||||||
@ -275,6 +259,11 @@ class MangaPresenter(private val controller: MangaChaptersController,
|
|||||||
downloadManager.downloadChapters(manga, chapters)
|
downloadManager.downloadChapters(manga, chapters)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun restartDownloads() {
|
||||||
|
if (downloadManager.isPaused())
|
||||||
|
downloadManager.startDownloads()
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Deletes the given list of chapter.
|
* Deletes the given list of chapter.
|
||||||
* @param chapters the list of chapters to delete.
|
* @param chapters the list of chapters to delete.
|
||||||
@ -304,6 +293,7 @@ class MangaPresenter(private val controller: MangaChaptersController,
|
|||||||
|
|
||||||
fun refreshAll() {
|
fun refreshAll() {
|
||||||
launch {
|
launch {
|
||||||
|
isLoading = true
|
||||||
var mangaError: java.lang.Exception? = null
|
var mangaError: java.lang.Exception? = null
|
||||||
var chapterError: java.lang.Exception? = null
|
var chapterError: java.lang.Exception? = null
|
||||||
val chapters = async(Dispatchers.IO) {
|
val chapters = async(Dispatchers.IO) {
|
||||||
@ -338,6 +328,7 @@ class MangaPresenter(private val controller: MangaChaptersController,
|
|||||||
syncChaptersWithSource(db, finChapters, manga, source)
|
syncChaptersWithSource(db, finChapters, manga, source)
|
||||||
withContext(Dispatchers.IO) { updateChapters() }
|
withContext(Dispatchers.IO) { updateChapters() }
|
||||||
}
|
}
|
||||||
|
isLoading = false
|
||||||
if (chapterError == null)
|
if (chapterError == null)
|
||||||
withContext(Dispatchers.Main) { controller.updateChapters(this@MangaPresenter.chapters) }
|
withContext(Dispatchers.Main) { controller.updateChapters(this@MangaPresenter.chapters) }
|
||||||
if (mangaError != null)
|
if (mangaError != null)
|
||||||
@ -350,6 +341,7 @@ class MangaPresenter(private val controller: MangaChaptersController,
|
|||||||
*/
|
*/
|
||||||
fun fetchChaptersFromSource() {
|
fun fetchChaptersFromSource() {
|
||||||
hasRequested = true
|
hasRequested = true
|
||||||
|
isLoading = true
|
||||||
|
|
||||||
launch(Dispatchers.IO) {
|
launch(Dispatchers.IO) {
|
||||||
val chapters = try {
|
val chapters = try {
|
||||||
@ -359,6 +351,7 @@ class MangaPresenter(private val controller: MangaChaptersController,
|
|||||||
withContext(Dispatchers.Main) { controller.showError(trimException(e)) }
|
withContext(Dispatchers.Main) { controller.showError(trimException(e)) }
|
||||||
return@launch
|
return@launch
|
||||||
} ?: listOf()
|
} ?: listOf()
|
||||||
|
isLoading = false
|
||||||
try {
|
try {
|
||||||
syncChaptersWithSource(db, chapters, manga, source)
|
syncChaptersWithSource(db, chapters, manga, source)
|
||||||
|
|
||||||
@ -480,4 +473,10 @@ class MangaPresenter(private val controller: MangaChaptersController,
|
|||||||
}
|
}
|
||||||
toggleFavorite()
|
toggleFavorite()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onUpdateManga(manga: LibraryManga) {
|
||||||
|
if (manga.id == this.manga.id) {
|
||||||
|
fetchChapters()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
@ -200,8 +200,6 @@ class MangaInfoController : NucleusController<MangaInfoPresenter>(),
|
|||||||
setFullCoverToThumb()
|
setFullCoverToThumb()
|
||||||
}
|
}
|
||||||
container?.setOnApplyWindowInsetsListener { _, insets ->
|
container?.setOnApplyWindowInsetsListener { _, insets ->
|
||||||
if (MainActivity.usingBottomNav)
|
|
||||||
return@setOnApplyWindowInsetsListener insets
|
|
||||||
if (resources?.configuration?.orientation == Configuration.ORIENTATION_LANDSCAPE) {
|
if (resources?.configuration?.orientation == Configuration.ORIENTATION_LANDSCAPE) {
|
||||||
fab_favorite?.updateLayoutParams<ViewGroup.MarginLayoutParams> {
|
fab_favorite?.updateLayoutParams<ViewGroup.MarginLayoutParams> {
|
||||||
bottomMargin = fabBaseMarginBottom + insets.systemWindowInsetBottom
|
bottomMargin = fabBaseMarginBottom + insets.systemWindowInsetBottom
|
||||||
|
@ -13,12 +13,14 @@ class BiometricActivity : BaseActivity() {
|
|||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
|
val fromSearch = intent.getBooleanExtra("fromSearch", false)
|
||||||
val biometricPrompt = BiometricPrompt(this, executor, object : BiometricPrompt
|
val biometricPrompt = BiometricPrompt(this, executor, object : BiometricPrompt
|
||||||
.AuthenticationCallback() {
|
.AuthenticationCallback() {
|
||||||
|
|
||||||
override fun onAuthenticationError(errorCode: Int, errString: CharSequence) {
|
override fun onAuthenticationError(errorCode: Int, errString: CharSequence) {
|
||||||
super.onAuthenticationError(errorCode, errString)
|
super.onAuthenticationError(errorCode, errString)
|
||||||
finishAffinity()
|
if (fromSearch) finish()
|
||||||
|
else finishAffinity()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onAuthenticationSucceeded(result: BiometricPrompt.AuthenticationResult) {
|
override fun onAuthenticationSucceeded(result: BiometricPrompt.AuthenticationResult) {
|
||||||
|
@ -6,6 +6,7 @@ import android.view.WindowManager
|
|||||||
import androidx.biometric.BiometricManager
|
import androidx.biometric.BiometricManager
|
||||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
||||||
import eu.kanade.tachiyomi.data.preference.getOrDefault
|
import eu.kanade.tachiyomi.data.preference.getOrDefault
|
||||||
|
import eu.kanade.tachiyomi.ui.main.SearchActivity
|
||||||
import uy.kohesive.injekt.injectLazy
|
import uy.kohesive.injekt.injectLazy
|
||||||
import java.util.Date
|
import java.util.Date
|
||||||
|
|
||||||
@ -33,6 +34,7 @@ object SecureActivityDelegate {
|
|||||||
if (lockApp && BiometricManager.from(activity).canAuthenticate() == BiometricManager.BIOMETRIC_SUCCESS) {
|
if (lockApp && BiometricManager.from(activity).canAuthenticate() == BiometricManager.BIOMETRIC_SUCCESS) {
|
||||||
if (isAppLocked()) {
|
if (isAppLocked()) {
|
||||||
val intent = Intent(activity, BiometricActivity::class.java)
|
val intent = Intent(activity, BiometricActivity::class.java)
|
||||||
|
intent.putExtra("fromSearch", (activity is SearchActivity))
|
||||||
activity.startActivity(intent)
|
activity.startActivity(intent)
|
||||||
activity.overridePendingTransition(0, 0)
|
activity.overridePendingTransition(0, 0)
|
||||||
}
|
}
|
||||||
|
@ -12,13 +12,12 @@ import android.content.res.Resources
|
|||||||
import android.net.ConnectivityManager
|
import android.net.ConnectivityManager
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import android.os.PowerManager
|
import android.os.PowerManager
|
||||||
|
import android.widget.Toast
|
||||||
import androidx.annotation.AttrRes
|
import androidx.annotation.AttrRes
|
||||||
import androidx.annotation.StringRes
|
import androidx.annotation.StringRes
|
||||||
import androidx.browser.customtabs.CustomTabsIntent
|
import androidx.browser.customtabs.CustomTabsIntent
|
||||||
import androidx.core.app.NotificationCompat
|
import androidx.core.app.NotificationCompat
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
import androidx.localbroadcastmanager.content.LocalBroadcastManager
|
|
||||||
import android.widget.Toast
|
|
||||||
import com.nononsenseapps.filepicker.FilePickerActivity
|
import com.nononsenseapps.filepicker.FilePickerActivity
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
import eu.kanade.tachiyomi.widget.CustomLayoutPickerActivity
|
import eu.kanade.tachiyomi.widget.CustomLayoutPickerActivity
|
||||||
@ -102,6 +101,9 @@ val Int.pxToDp: Int
|
|||||||
val Int.dpToPx: Int
|
val Int.dpToPx: Int
|
||||||
get() = (this * Resources.getSystem().displayMetrics.density).toInt()
|
get() = (this * Resources.getSystem().displayMetrics.density).toInt()
|
||||||
|
|
||||||
|
val Float.dpToPx: Float
|
||||||
|
get() = (this * Resources.getSystem().displayMetrics.density)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Property to get the notification manager from the context.
|
* Property to get the notification manager from the context.
|
||||||
*/
|
*/
|
||||||
|
@ -1,10 +1,8 @@
|
|||||||
package eu.kanade.tachiyomi.widget
|
package eu.kanade.tachiyomi.widget
|
||||||
|
|
||||||
import android.animation.ObjectAnimator
|
|
||||||
import android.animation.StateListAnimator
|
import android.animation.StateListAnimator
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.util.AttributeSet
|
import android.util.AttributeSet
|
||||||
import com.google.android.material.R
|
|
||||||
import com.google.android.material.appbar.AppBarLayout
|
import com.google.android.material.appbar.AppBarLayout
|
||||||
|
|
||||||
class ElevationAppBarLayout @JvmOverloads constructor(
|
class ElevationAppBarLayout @JvmOverloads constructor(
|
||||||
@ -13,29 +11,24 @@ class ElevationAppBarLayout @JvmOverloads constructor(
|
|||||||
) : AppBarLayout(context, attrs) {
|
) : AppBarLayout(context, attrs) {
|
||||||
|
|
||||||
private var origStateAnimator: StateListAnimator? = null
|
private var origStateAnimator: StateListAnimator? = null
|
||||||
|
private var origElevation: Float
|
||||||
|
|
||||||
init {
|
init {
|
||||||
origStateAnimator = stateListAnimator
|
origStateAnimator = stateListAnimator
|
||||||
|
origElevation = elevation
|
||||||
}
|
}
|
||||||
|
|
||||||
fun enableElevation() {
|
fun enableElevation() {
|
||||||
|
if (stateListAnimator == null) {
|
||||||
stateListAnimator = origStateAnimator
|
stateListAnimator = origStateAnimator
|
||||||
|
elevation = origElevation
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun disableElevation() {
|
fun disableElevation() {
|
||||||
stateListAnimator = StateListAnimator().apply {
|
stateListAnimator = null
|
||||||
val objAnimator = ObjectAnimator.ofFloat(this, "elevation", 0f)
|
elevation = 0f
|
||||||
|
//translationZ = 0.1f.dpToPx
|
||||||
// Enabled and collapsible, but not collapsed means not elevated
|
|
||||||
addState(intArrayOf(android.R.attr.enabled, R.attr.state_collapsible, -R.attr.state_collapsed),
|
|
||||||
objAnimator)
|
|
||||||
|
|
||||||
// Default enabled state
|
|
||||||
addState(intArrayOf(android.R.attr.enabled), objAnimator)
|
|
||||||
|
|
||||||
// Disabled state
|
|
||||||
addState(IntArray(0), objAnimator)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -6,12 +6,21 @@
|
|||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:orientation="vertical">
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<com.bluelinelabs.conductor.ChangeHandlerFrameLayout
|
||||||
|
android:id="@+id/controller_container"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
app:layout_constraintBottom_toTopOf="@+id/navigationView"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent">
|
||||||
|
|
||||||
|
</com.bluelinelabs.conductor.ChangeHandlerFrameLayout>
|
||||||
|
|
||||||
<eu.kanade.tachiyomi.widget.ElevationAppBarLayout
|
<eu.kanade.tachiyomi.widget.ElevationAppBarLayout
|
||||||
android:id="@+id/appbar"
|
android:id="@+id/appbar"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:stateListAnimator="@null"
|
|
||||||
android:translationZ="0.1dp"
|
|
||||||
app:layout_constraintLeft_toLeftOf="parent"
|
app:layout_constraintLeft_toLeftOf="parent"
|
||||||
app:layout_constraintRight_toRightOf="parent"
|
app:layout_constraintRight_toRightOf="parent"
|
||||||
app:layout_constraintTop_toTopOf="parent">
|
app:layout_constraintTop_toTopOf="parent">
|
||||||
@ -40,17 +49,6 @@
|
|||||||
|
|
||||||
</eu.kanade.tachiyomi.widget.ElevationAppBarLayout>
|
</eu.kanade.tachiyomi.widget.ElevationAppBarLayout>
|
||||||
|
|
||||||
<com.bluelinelabs.conductor.ChangeHandlerFrameLayout
|
|
||||||
android:id="@+id/controller_container"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="0dp"
|
|
||||||
app:layout_constraintBottom_toTopOf="@+id/navigationView"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintTop_toTopOf="parent">
|
|
||||||
|
|
||||||
</com.bluelinelabs.conductor.ChangeHandlerFrameLayout>
|
|
||||||
|
|
||||||
<com.google.android.material.bottomnavigation.BottomNavigationView
|
<com.google.android.material.bottomnavigation.BottomNavigationView
|
||||||
android:id="@+id/navigationView"
|
android:id="@+id/navigationView"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
|
@ -1,50 +0,0 @@
|
|||||||
<FrameLayout
|
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
|
||||||
android:id="@+id/search_container"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent">
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:orientation="vertical"
|
|
||||||
android:id="@+id/main_content"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:fitsSystemWindows="true"
|
|
||||||
android:layout_height="match_parent">
|
|
||||||
|
|
||||||
<eu.kanade.tachiyomi.widget.ElevationAppBarLayout
|
|
||||||
android:id="@+id/appbar"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content">
|
|
||||||
|
|
||||||
<androidx.appcompat.widget.Toolbar
|
|
||||||
android:id="@+id/sToolbar"
|
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="?attr/actionBarSize"
|
|
||||||
android:background="?attr/colorPrimary"
|
|
||||||
android:theme="?attr/actionBarTheme"/>
|
|
||||||
|
|
||||||
<com.google.android.material.tabs.TabLayout
|
|
||||||
android:id="@+id/sTabs"
|
|
||||||
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"
|
|
||||||
app:tabGravity="center"
|
|
||||||
app:tabMode="auto"
|
|
||||||
app:tabMinWidth="75dp"/>
|
|
||||||
|
|
||||||
</eu.kanade.tachiyomi.widget.ElevationAppBarLayout>
|
|
||||||
|
|
||||||
<com.bluelinelabs.conductor.ChangeHandlerFrameLayout
|
|
||||||
android:id="@+id/controller_container"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent" />
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
</FrameLayout>
|
|
@ -677,6 +677,8 @@
|
|||||||
<string name="information_no_recent">No recent chapters</string>
|
<string name="information_no_recent">No recent chapters</string>
|
||||||
<string name="information_no_recent_manga">No recently read manga</string>
|
<string name="information_no_recent_manga">No recently read manga</string>
|
||||||
<string name="information_empty_library">Your library is empty, add series to your library from the catalogues.</string>
|
<string name="information_empty_library">Your library is empty, add series to your library from the catalogues.</string>
|
||||||
|
<string name="information_empty_library_filtered">No matches found for your current
|
||||||
|
filters</string>
|
||||||
<string name="information_empty_category">You have no categories. Hit the plus button to create one for organizing your library.</string>
|
<string name="information_empty_category">You have no categories. Hit the plus button to create one for organizing your library.</string>
|
||||||
|
|
||||||
<!-- Download Notification -->
|
<!-- Download Notification -->
|
||||||
|
Loading…
x
Reference in New Issue
Block a user