Library updates are now in groups, tapping on them take you directly to the chapter to read
Fixes to lollipop snackbar and webview
This commit is contained in:
parent
1b545c9e4d
commit
1291adf821
@ -11,7 +11,6 @@ import eu.kanade.tachiyomi.data.notification.NotificationHandler
|
||||
import eu.kanade.tachiyomi.data.notification.NotificationReceiver
|
||||
import eu.kanade.tachiyomi.data.notification.Notifications
|
||||
import eu.kanade.tachiyomi.util.chop
|
||||
import eu.kanade.tachiyomi.util.getResourceColor
|
||||
import eu.kanade.tachiyomi.util.notificationManager
|
||||
import java.util.regex.Pattern
|
||||
|
||||
@ -170,8 +169,8 @@ internal class DownloadNotifier(private val context: Context) {
|
||||
setSmallIcon(android.R.drawable.stat_sys_download_done)
|
||||
setAutoCancel(true)
|
||||
clearActions()
|
||||
setContentIntent(NotificationReceiver.openChapterPendingBroadcast(context, download
|
||||
.manga, download.chapter, Notifications.ID_DOWNLOAD_CHAPTER))
|
||||
setContentIntent(NotificationReceiver.openChapterPendingActivity(context, download
|
||||
.manga, download.chapter))
|
||||
setProgress(0, 0, false)
|
||||
}
|
||||
|
||||
|
@ -10,6 +10,7 @@ import android.os.Build
|
||||
import android.os.IBinder
|
||||
import android.os.PowerManager
|
||||
import androidx.core.app.NotificationCompat
|
||||
import androidx.core.app.NotificationManagerCompat
|
||||
import androidx.core.content.ContextCompat
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.data.database.DatabaseHelper
|
||||
@ -30,8 +31,6 @@ import eu.kanade.tachiyomi.source.SourceManager
|
||||
import eu.kanade.tachiyomi.source.model.SManga
|
||||
import eu.kanade.tachiyomi.source.online.HttpSource
|
||||
import eu.kanade.tachiyomi.ui.main.MainActivity
|
||||
import eu.kanade.tachiyomi.ui.reader.ReaderActivity
|
||||
import eu.kanade.tachiyomi.ui.recent_updates.RecentChapterItem
|
||||
import eu.kanade.tachiyomi.util.*
|
||||
import rx.Observable
|
||||
import rx.Subscription
|
||||
@ -274,7 +273,7 @@ class LibraryUpdateService(
|
||||
// Initialize the variables holding the progress of the updates.
|
||||
val count = AtomicInteger(0)
|
||||
// List containing new updates
|
||||
val newUpdates = ArrayList<Manga>()
|
||||
val newUpdates = ArrayList<Pair<Manga, Chapter>>()
|
||||
// list containing failed updates
|
||||
val failedUpdates = ArrayList<Manga>()
|
||||
// List containing categories that get included in downloads.
|
||||
@ -307,7 +306,7 @@ class LibraryUpdateService(
|
||||
}
|
||||
}
|
||||
// Convert to the manga that contains new chapters.
|
||||
.map { manga }
|
||||
.map { Pair(manga, (it.first.minBy { ch -> ch.chapter_number }!!)) }
|
||||
}
|
||||
// Add manga with new chapters to the list.
|
||||
.doOnNext { manga ->
|
||||
@ -329,6 +328,7 @@ class LibraryUpdateService(
|
||||
|
||||
cancelProgressNotification()
|
||||
}
|
||||
.map { manga -> manga.first }
|
||||
}
|
||||
|
||||
fun downloadChapters(manga: Manga, chapters: List<Chapter>) {
|
||||
@ -442,52 +442,49 @@ class LibraryUpdateService(
|
||||
*
|
||||
* @param updates a list of manga with new updates.
|
||||
*/
|
||||
private fun showResultNotification(updates: List<Manga>) {
|
||||
val newUpdates = updates.map { it.title.chop(45) }.toMutableSet()
|
||||
|
||||
// Append new chapters from a previous, existing notification
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
val previousNotification = notificationManager.activeNotifications
|
||||
.find { it.id == Notifications.ID_NEW_CHAPTERS }
|
||||
|
||||
if (previousNotification != null) {
|
||||
val oldUpdates = previousNotification.notification.extras
|
||||
.getString(Notification.EXTRA_BIG_TEXT)
|
||||
|
||||
if (!oldUpdates.isNullOrEmpty()) {
|
||||
newUpdates += oldUpdates.split("\n")
|
||||
}
|
||||
}
|
||||
private fun showResultNotification(updates: List<Pair<Manga, Chapter>>) {
|
||||
val notifications = ArrayList<Pair<Notification, Int>>()
|
||||
updates.forEach {
|
||||
val manga = it.first
|
||||
val chapter = it.second
|
||||
notifications.add(Pair(notification(Notifications.CHANNEL_NEW_CHAPTERS) {
|
||||
setSmallIcon(R.drawable.ic_book_white_24dp)
|
||||
setLargeIcon(notificationBitmap)
|
||||
setContentTitle(manga.title.chop(45))
|
||||
color = ContextCompat.getColor(applicationContext, R.color.colorAccentLight)
|
||||
setContentText(chapter.name)
|
||||
priority = NotificationCompat.PRIORITY_HIGH
|
||||
setGroup(Notifications.GROUP_NEW_CHAPTERS)
|
||||
setContentIntent(
|
||||
NotificationReceiver.openChapterPendingActivity(
|
||||
this@LibraryUpdateService, manga, chapter
|
||||
)
|
||||
)
|
||||
setAutoCancel(true)
|
||||
}, manga.id.hashCode()))
|
||||
}
|
||||
|
||||
notificationManager.notify(Notifications.ID_NEW_CHAPTERS, notification(Notifications.CHANNEL_NEW_CHAPTERS) {
|
||||
setSmallIcon(R.drawable.ic_book_white_24dp)
|
||||
setLargeIcon(notificationBitmap)
|
||||
setContentTitle(getString(R.string.notification_new_chapters))
|
||||
color = ContextCompat.getColor(applicationContext, R.color.colorAccentLight)
|
||||
if (newUpdates.size > 1) {
|
||||
setContentText(getString(R.string.notification_new_chapters_text, newUpdates.size))
|
||||
setStyle(NotificationCompat.BigTextStyle().bigText(newUpdates.joinToString("\n")))
|
||||
setNumber(newUpdates.size)
|
||||
} else {
|
||||
val onlyManga = updates.first()
|
||||
val id = onlyManga.id ?: 0
|
||||
setContentText(newUpdates.first())
|
||||
|
||||
val context = applicationContext
|
||||
val db = DatabaseHelper(context)
|
||||
val chapters = db.getChapters(onlyManga).executeAsBlocking()
|
||||
val chapter = chapters.sortedByDescending { it.source_order }.find { !it.read }
|
||||
if (chapter != null) {
|
||||
addAction(R.drawable.ic_in_library_24dp, getString(R.string.action_start_reading),
|
||||
NotificationReceiver.openChapterPendingBroadcast(context, onlyManga,
|
||||
chapter, Notifications.ID_NEW_CHAPTERS))
|
||||
}
|
||||
NotificationManagerCompat.from(this).apply {
|
||||
notifications.forEach {
|
||||
notify(it.second, it.first)
|
||||
}
|
||||
priority = NotificationCompat.PRIORITY_HIGH
|
||||
setContentIntent(getNotificationIntent())
|
||||
setAutoCancel(true)
|
||||
})
|
||||
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N || notificationManager
|
||||
.activeNotifications.find { it.groupKey == Notifications.GROUP_NEW_CHAPTERS } == null) {
|
||||
notify(Notifications.ID_NEW_CHAPTERS, notification(Notifications.CHANNEL_NEW_CHAPTERS) {
|
||||
setSmallIcon(R.drawable.ic_book_white_24dp)
|
||||
setLargeIcon(notificationBitmap)
|
||||
setContentTitle(getString(R.string.notification_new_chapters))
|
||||
color = ContextCompat.getColor(applicationContext, R.color.colorAccentLight)
|
||||
setContentText(getString(R.string.notification_new_chapters_text, updates.size))
|
||||
priority = NotificationCompat.PRIORITY_HIGH
|
||||
setGroup(Notifications.GROUP_NEW_CHAPTERS)
|
||||
setGroupSummary(true)
|
||||
setContentIntent(getNotificationIntent())
|
||||
setAutoCancel(true)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -300,10 +300,11 @@ class NotificationReceiver : BroadcastReceiver() {
|
||||
* @param manga manga of chapter
|
||||
* @param chapter chapter that needs to be opened
|
||||
*/
|
||||
internal fun openChapterPendingBroadcast(context: Context, manga: Manga, chapter:
|
||||
Chapter, notificationId: Int): PendingIntent {
|
||||
val newIntent = ReaderActivity.newIntent(context, manga, chapter, notificationId)
|
||||
return PendingIntent.getActivity(context, 0, newIntent, PendingIntent.FLAG_UPDATE_CURRENT)
|
||||
internal fun openChapterPendingActivity(context: Context, manga: Manga, chapter:
|
||||
Chapter): PendingIntent {
|
||||
val newIntent = ReaderActivity.newIntent(context, manga, chapter)
|
||||
return PendingIntent.getActivity(context, manga.id.hashCode(), newIntent, PendingIntent
|
||||
.FLAG_UPDATE_CURRENT)
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -36,7 +36,8 @@ object Notifications {
|
||||
* Notification channel and ids used by the library updater.
|
||||
*/
|
||||
const val CHANNEL_NEW_CHAPTERS = "new_chapters_channel"
|
||||
const val ID_NEW_CHAPTERS = 301
|
||||
const val ID_NEW_CHAPTERS = -301
|
||||
const val GROUP_NEW_CHAPTERS = "eu.kanade.tachiyomi.NEW_CHAPTERS"
|
||||
|
||||
/**
|
||||
* Creates the notification channels introduced in Android Oreo.
|
||||
|
@ -508,15 +508,14 @@ open class BrowseCatalogueController(bundle: Bundle) :
|
||||
presenter.changeMangaFavorite(manga)
|
||||
adapter?.notifyItemChanged(position)
|
||||
snack =
|
||||
catalogue_view?.snack(activity.getString(R.string.manga_removed_library), 5000) {
|
||||
catalouge_layout?.snack(R.string.manga_removed_library, 5000) {
|
||||
setAction(R.string.action_undo) {
|
||||
if (!manga.favorite) addManga(manga, position)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
addManga(manga, position)
|
||||
snack =
|
||||
catalogue_view?.snack(activity.getString(R.string.manga_added_library))
|
||||
snack = catalouge_layout?.snack(R.string.manga_added_library)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -7,6 +7,7 @@ import android.util.AttributeSet
|
||||
import android.view.MotionEvent
|
||||
import android.view.View
|
||||
import android.widget.FrameLayout
|
||||
import com.google.android.material.snackbar.Snackbar
|
||||
import eu.davidea.flexibleadapter.FlexibleAdapter
|
||||
import eu.davidea.flexibleadapter.SelectableAdapter
|
||||
import eu.kanade.tachiyomi.R
|
||||
@ -98,7 +99,8 @@ class LibraryCategoryView @JvmOverloads constructor(context: Context, attrs: Att
|
||||
swipe_refresh.setOnRefreshListener {
|
||||
if (!LibraryUpdateService.isRunning(context)) {
|
||||
LibraryUpdateService.start(context, category)
|
||||
swipe_refresh.snack(R.string.updating_category)
|
||||
controller.snack?.dismiss()
|
||||
controller.snack = swipe_refresh.snack(R.string.updating_category)
|
||||
}
|
||||
// It can be a very long operation, so we disable swipe refresh and show a toast.
|
||||
swipe_refresh.isRefreshing = false
|
||||
|
@ -18,6 +18,7 @@ import androidx.core.view.GravityCompat
|
||||
import com.bluelinelabs.conductor.ControllerChangeHandler
|
||||
import com.bluelinelabs.conductor.ControllerChangeType
|
||||
import com.f2prateek.rx.preferences.Preference
|
||||
import com.google.android.material.snackbar.Snackbar
|
||||
import com.jakewharton.rxbinding.support.v4.view.pageSelections
|
||||
import com.jakewharton.rxbinding.support.v7.widget.queryTextChanges
|
||||
import com.jakewharton.rxrelay.BehaviorRelay
|
||||
@ -121,6 +122,8 @@ class LibraryController(
|
||||
|
||||
private var searchViewSubscription: Subscription? = null
|
||||
|
||||
var snack: Snackbar? = null
|
||||
|
||||
init {
|
||||
setHasOptionsMenu(true)
|
||||
retainViewMode = RetainViewMode.RETAIN_DETACH
|
||||
@ -176,6 +179,12 @@ class LibraryController(
|
||||
super.onDestroyView(view)
|
||||
}
|
||||
|
||||
override fun onDetach(view: View) {
|
||||
snack?.dismiss()
|
||||
snack = null
|
||||
super.onDetach(view)
|
||||
}
|
||||
|
||||
override fun createSecondaryDrawer(drawer: androidx.drawerlayout.widget.DrawerLayout): ViewGroup {
|
||||
val view = drawer.inflate(R.layout.library_drawer) as LibraryNavigationView
|
||||
navView = view
|
||||
@ -476,7 +485,8 @@ class LibraryController(
|
||||
val mangas = selectedMangas.toList()
|
||||
presenter.removeMangaFromLibrary(mangas, true)
|
||||
destroyActionModeIfNeeded()
|
||||
view?.snack(activity?.getString(R.string.manga_removed_library) ?: "", 5000) {
|
||||
snack?.dismiss()
|
||||
snack = view?.snack(activity?.getString(R.string.manga_removed_library) ?: "", 5000) {
|
||||
setAction(R.string.action_undo) {
|
||||
presenter.addMangas(mangas)
|
||||
}
|
||||
|
@ -27,7 +27,8 @@ class MangaWebViewController(bundle: Bundle? = null) : BaseController(bundle) {
|
||||
})
|
||||
|
||||
override fun inflateView(inflater: LayoutInflater, container: ViewGroup): View {
|
||||
return inflater.inflate(R.layout.manga_info_web_controller, container, false)
|
||||
return WebView(applicationContext)// inflater.inflate(R.layout.manga_info_web_controller, container,
|
||||
// false)
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View) {
|
||||
|
@ -19,6 +19,7 @@ import android.widget.LinearLayout
|
||||
import android.widget.SeekBar
|
||||
import com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView
|
||||
import eu.kanade.tachiyomi.R
|
||||
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.notification.Notifications
|
||||
@ -120,13 +121,13 @@ class ReaderActivity : BaseRxActivity<ReaderPresenter>(),
|
||||
const val VERTICAL = 3
|
||||
const val WEBTOON = 4
|
||||
|
||||
fun newIntent(context: Context, manga: Manga, chapter: Chapter, notificationId:Int? =
|
||||
null):
|
||||
fun newIntent(context: Context, manga: Manga, chapter: Chapter):
|
||||
Intent {
|
||||
val intent = Intent(context, ReaderActivity::class.java)
|
||||
intent.putExtra("manga", manga.id)
|
||||
intent.putExtra("chapter", chapter.id)
|
||||
intent.putExtra("notificationId", notificationId)
|
||||
intent.putExtra("chapterUrl", chapter.url)
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
|
||||
return intent
|
||||
}
|
||||
}
|
||||
@ -146,17 +147,14 @@ class ReaderActivity : BaseRxActivity<ReaderPresenter>(),
|
||||
if (presenter.needsInit()) {
|
||||
val manga = intent.extras!!.getLong("manga", -1)
|
||||
val chapter = intent.extras!!.getLong("chapter", -1)
|
||||
val notificationId = intent.extras!!.getInt("notificationId", -1)
|
||||
if (notificationId > 0) {
|
||||
applicationContext.notificationManager.cancel(notificationId)
|
||||
}
|
||||
|
||||
if (manga == -1L || chapter == -1L) {
|
||||
val chapterUrl = intent.extras!!.getString("chapterUrl", "")
|
||||
if (manga == -1L || chapterUrl == "" && chapter == -1L) {
|
||||
finish()
|
||||
return
|
||||
}
|
||||
|
||||
presenter.init(manga, chapter)
|
||||
if (chapterUrl.isEmpty()) presenter.init(manga, chapter)
|
||||
else presenter.init(manga, chapterUrl)
|
||||
}
|
||||
|
||||
if (savedState != null) {
|
||||
|
@ -185,6 +185,15 @@ class ReaderPresenter(
|
||||
}, ReaderActivity::setInitialChapterError)
|
||||
}
|
||||
|
||||
fun init(mangaId: Long, chapterUrl: String) {
|
||||
if (!needsInit()) return
|
||||
val context = Injekt.get<Application>()
|
||||
val db = DatabaseHelper(context)
|
||||
val chapterId = db.getChapter(chapterUrl).executeAsBlocking()?.id
|
||||
if (chapterId != null)
|
||||
init(mangaId, chapterId)
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes this presenter with the given [manga] and [initialChapterId]. This method will
|
||||
* set the chapter loader, view subscriptions and trigger an initial load.
|
||||
|
@ -3,6 +3,7 @@
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:id="@+id/catalouge_layout"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<LinearLayout
|
||||
|
Loading…
Reference in New Issue
Block a user