diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadNotifier.kt b/app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadNotifier.kt index c98b0dbf88..dbc7ef0fe8 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadNotifier.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadNotifier.kt @@ -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) } diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/library/LibraryUpdateService.kt b/app/src/main/java/eu/kanade/tachiyomi/data/library/LibraryUpdateService.kt index 458a03522e..ea521fc937 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/library/LibraryUpdateService.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/library/LibraryUpdateService.kt @@ -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() + val newUpdates = ArrayList>() // list containing failed updates val failedUpdates = ArrayList() // 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) { @@ -442,52 +442,49 @@ class LibraryUpdateService( * * @param updates a list of manga with new updates. */ - private fun showResultNotification(updates: List) { - 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>) { + val notifications = ArrayList>() + 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) + }) + } + } } /** diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/notification/NotificationReceiver.kt b/app/src/main/java/eu/kanade/tachiyomi/data/notification/NotificationReceiver.kt index 4a9e76efe3..d0652895b3 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/notification/NotificationReceiver.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/notification/NotificationReceiver.kt @@ -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) } /** diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/notification/Notifications.kt b/app/src/main/java/eu/kanade/tachiyomi/data/notification/Notifications.kt index df85f45ccc..f4564ac8c8 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/notification/Notifications.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/notification/Notifications.kt @@ -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. diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/catalogue/browse/BrowseCatalogueController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/catalogue/browse/BrowseCatalogueController.kt index 1c7f81b800..f8e56adb90 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/catalogue/browse/BrowseCatalogueController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/catalogue/browse/BrowseCatalogueController.kt @@ -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) } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryCategoryView.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryCategoryView.kt index 2e5815efbb..e1edb981f6 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryCategoryView.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryCategoryView.kt @@ -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 diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryController.kt index b07cd99fb3..3f3e088737 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryController.kt @@ -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) } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/info/MangaWebViewController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/info/MangaWebViewController.kt index 5cef0d4677..b119c3a56b 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/info/MangaWebViewController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/info/MangaWebViewController.kt @@ -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) { diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderActivity.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderActivity.kt index 47edae77d6..0165ff919f 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderActivity.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderActivity.kt @@ -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(), 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(), 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) { diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderPresenter.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderPresenter.kt index b2aafa0a23..4b391f3c2d 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderPresenter.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderPresenter.kt @@ -185,6 +185,15 @@ class ReaderPresenter( }, ReaderActivity::setInitialChapterError) } + fun init(mangaId: Long, chapterUrl: String) { + if (!needsInit()) return + val context = Injekt.get() + 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. diff --git a/app/src/main/res/layout/catalogue_controller.xml b/app/src/main/res/layout/catalogue_controller.xml index a165ebcc3e..caf67918e2 100644 --- a/app/src/main/res/layout/catalogue_controller.xml +++ b/app/src/main/res/layout/catalogue_controller.xml @@ -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">