mirror of
				https://github.com/mihonapp/mihon.git
				synced 2025-10-31 14:27:57 +01:00 
			
		
		
		
	Add update notifications for EH/EXH galleries
This commit is contained in:
		| @@ -0,0 +1,75 @@ | ||||
| package eu.kanade.tachiyomi.data.library | ||||
|  | ||||
| import android.app.Notification | ||||
| import android.app.PendingIntent | ||||
| import android.content.Context | ||||
| import android.content.Intent | ||||
| import android.graphics.BitmapFactory | ||||
| import android.os.Build | ||||
| import android.support.v4.app.NotificationCompat | ||||
| import eu.kanade.tachiyomi.R | ||||
| import eu.kanade.tachiyomi.data.database.models.Manga | ||||
| import eu.kanade.tachiyomi.data.notification.Notifications | ||||
| import eu.kanade.tachiyomi.ui.main.MainActivity | ||||
| import eu.kanade.tachiyomi.util.chop | ||||
| import eu.kanade.tachiyomi.util.notification | ||||
| import eu.kanade.tachiyomi.util.notificationManager | ||||
|  | ||||
| class LibraryUpdateNotifier(private val context: Context) { | ||||
|     /** | ||||
|      * Bitmap of the app for notifications. | ||||
|      */ | ||||
|     val notificationBitmap by lazy { | ||||
|         BitmapFactory.decodeResource(context.resources, R.mipmap.ic_launcher) | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Shows the notification containing the result of the update done by the service. | ||||
|      * | ||||
|      * @param updates a list of manga with new updates. | ||||
|      */ | ||||
|     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 = context.notificationManager.activeNotifications | ||||
|                     .find { it.id == Notifications.ID_LIBRARY_RESULT } | ||||
|  | ||||
|             if (previousNotification != null) { | ||||
|                 val oldUpdates = previousNotification.notification.extras | ||||
|                         .getString(Notification.EXTRA_BIG_TEXT) | ||||
|  | ||||
|                 if (!oldUpdates.isNullOrEmpty()) { | ||||
|                     newUpdates += oldUpdates.split("\n") | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         context.notificationManager.notify(Notifications.ID_LIBRARY_RESULT, context.notification(Notifications.CHANNEL_LIBRARY) { | ||||
|             setSmallIcon(R.drawable.ic_book_white_24dp) | ||||
|             setLargeIcon(notificationBitmap) | ||||
|             setContentTitle(context.getString(R.string.notification_new_chapters)) | ||||
|             if (newUpdates.size > 1) { | ||||
|                 setContentText(context.getString(R.string.notification_new_chapters_text, newUpdates.size)) | ||||
|                 setStyle(NotificationCompat.BigTextStyle().bigText(newUpdates.joinToString("\n"))) | ||||
|                 setNumber(newUpdates.size) | ||||
|             } else { | ||||
|                 setContentText(newUpdates.first()) | ||||
|             } | ||||
|             priority = NotificationCompat.PRIORITY_HIGH | ||||
|             setContentIntent(getNotificationIntent(context)) | ||||
|             setAutoCancel(true) | ||||
|         }) | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Returns an intent to open the main activity. | ||||
|      */ | ||||
|     private fun getNotificationIntent(context: Context): PendingIntent { | ||||
|         val intent = Intent(context, MainActivity::class.java) | ||||
|         intent.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_SINGLE_TOP | ||||
|         intent.action = MainActivity.SHORTCUT_RECENTLY_UPDATED | ||||
|         return PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT) | ||||
|     } | ||||
| } | ||||
| @@ -1,11 +1,8 @@ | ||||
| package eu.kanade.tachiyomi.data.library | ||||
|  | ||||
| import android.app.Notification | ||||
| import android.app.PendingIntent | ||||
| import android.app.Service | ||||
| import android.content.Context | ||||
| import android.content.Intent | ||||
| import android.graphics.BitmapFactory | ||||
| import android.os.Build | ||||
| import android.os.IBinder | ||||
| import android.os.PowerManager | ||||
| @@ -28,7 +25,6 @@ import eu.kanade.tachiyomi.data.track.TrackManager | ||||
| 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.util.* | ||||
| import exh.LIBRARY_UPDATE_EXCLUDED_SOURCES | ||||
| import rx.Observable | ||||
| @@ -73,12 +69,7 @@ class LibraryUpdateService( | ||||
|         NotificationReceiver.cancelLibraryUpdatePendingBroadcast(this) | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Bitmap of the app for notifications. | ||||
|      */ | ||||
|     private val notificationBitmap by lazy { | ||||
|         BitmapFactory.decodeResource(resources, R.mipmap.ic_launcher) | ||||
|     } | ||||
|     private val updateNotifier by lazy { LibraryUpdateNotifier(this) } | ||||
|  | ||||
|     /** | ||||
|      * Cached progress notification to avoid creating a lot. | ||||
| @@ -86,7 +77,7 @@ class LibraryUpdateService( | ||||
|     private val progressNotification by lazy { NotificationCompat.Builder(this, Notifications.CHANNEL_LIBRARY) | ||||
|             .setContentTitle(getString(R.string.app_name)) | ||||
|             .setSmallIcon(R.drawable.ic_refresh_white_24dp_img) | ||||
|             .setLargeIcon(notificationBitmap) | ||||
|             .setLargeIcon(updateNotifier.notificationBitmap) | ||||
|             .setOngoing(true) | ||||
|             .setOnlyAlertOnce(true) | ||||
|             .addAction(R.drawable.ic_clear_grey_24dp_img, getString(android.R.string.cancel), cancelIntent) | ||||
| @@ -319,7 +310,7 @@ class LibraryUpdateService( | ||||
|                 // Notify result of the overall update. | ||||
|                 .doOnCompleted { | ||||
|                     if (newUpdates.isNotEmpty()) { | ||||
|                         showResultNotification(newUpdates) | ||||
|                         updateNotifier.showResultNotification(newUpdates) | ||||
|                         if (downloadNew && hasDownloads) { | ||||
|                             DownloadService.start(this) | ||||
|                         } | ||||
| @@ -439,61 +430,10 @@ class LibraryUpdateService( | ||||
|                 .build()) | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Shows the notification containing the result of the update done by the service. | ||||
|      * | ||||
|      * @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_LIBRARY_RESULT } | ||||
|  | ||||
|             if (previousNotification != null) { | ||||
|                 val oldUpdates = previousNotification.notification.extras | ||||
|                         .getString(Notification.EXTRA_BIG_TEXT) | ||||
|  | ||||
|                 if (!oldUpdates.isNullOrEmpty()) { | ||||
|                     newUpdates += oldUpdates.split("\n") | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         notificationManager.notify(Notifications.ID_LIBRARY_RESULT, notification(Notifications.CHANNEL_LIBRARY) { | ||||
|             setSmallIcon(R.drawable.ic_book_white_24dp) | ||||
|             setLargeIcon(notificationBitmap) | ||||
|             setContentTitle(getString(R.string.notification_new_chapters)) | ||||
|             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 { | ||||
|                 setContentText(newUpdates.first()) | ||||
|             } | ||||
|             priority = NotificationCompat.PRIORITY_HIGH | ||||
|             setContentIntent(getNotificationIntent()) | ||||
|             setAutoCancel(true) | ||||
|         }) | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Cancels the progress notification. | ||||
|      */ | ||||
|     private fun cancelProgressNotification() { | ||||
|         notificationManager.cancel(Notifications.ID_LIBRARY_PROGRESS) | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Returns an intent to open the main activity. | ||||
|      */ | ||||
|     private fun getNotificationIntent(): PendingIntent { | ||||
|         val intent = Intent(this, MainActivity::class.java) | ||||
|         intent.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_SINGLE_TOP | ||||
|         intent.action = MainActivity.SHORTCUT_RECENTLY_UPDATED | ||||
|         return PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT) | ||||
|     } | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -26,9 +26,9 @@ class EHentaiUpdateHelper(context: Context) { | ||||
|     /** | ||||
|      * @param chapters Cannot be an empty list! | ||||
|      * | ||||
|      * @return Pair<Accepted, Discarded> | ||||
|      * @return Triple<Accepted, Discarded, HasNew> | ||||
|      */ | ||||
|     fun findAcceptedRootAndDiscardOthers(sourceId: Long, chapters: List<Chapter>): Single<Pair<ChapterChain, List<ChapterChain>>> { | ||||
|     fun findAcceptedRootAndDiscardOthers(sourceId: Long, chapters: List<Chapter>): Single<Triple<ChapterChain, List<ChapterChain>, Boolean>> { | ||||
|         // Find other chains | ||||
|         val chainsObservable = Observable.merge(chapters.map { chapter -> | ||||
|             db.getChapters(chapter.url).asRxSingle().toObservable() | ||||
| @@ -62,6 +62,8 @@ class EHentaiUpdateHelper(context: Context) { | ||||
|             val chainsAsChapters = chains.flatMap { it.chapters } | ||||
|  | ||||
|             if(toDiscard.isNotEmpty()) { | ||||
|                 var new = false | ||||
|  | ||||
|                 // Copy chain chapters to curChapters | ||||
|                 val newChapters = toDiscard | ||||
|                         .flatMap { chain -> | ||||
| @@ -98,6 +100,7 @@ class EHentaiUpdateHelper(context: Context) { | ||||
|                                 existing.bookmark = existing.bookmark || chapter.bookmark | ||||
|                                 curChapters | ||||
|                             } else if (chapter.date_upload > 0) { // Ignore chapters using the old system | ||||
|                                 new = true | ||||
|                                 curChapters + ChapterImpl().apply { | ||||
|                                     manga_id = accepted.manga.id | ||||
|                                     url = chapter.url | ||||
| @@ -145,8 +148,8 @@ class EHentaiUpdateHelper(context: Context) { | ||||
|                     db.setMangaCategories(newCategories, rootsToMutate.map { it.manga }) | ||||
|                 } | ||||
|  | ||||
|                 newAccepted to toDiscard | ||||
|             } else accepted to emptyList() | ||||
|                 Triple(newAccepted, toDiscard, new) | ||||
|             } else Triple(accepted, emptyList(), false) | ||||
|         }.toSingle() | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -15,6 +15,7 @@ import com.kizitonwose.time.hours | ||||
| 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.library.LibraryUpdateNotifier | ||||
| import eu.kanade.tachiyomi.data.preference.PreferencesHelper | ||||
| import eu.kanade.tachiyomi.data.preference.getOrDefault | ||||
| import eu.kanade.tachiyomi.source.SourceManager | ||||
| @@ -49,6 +50,8 @@ class EHentaiUpdateWorker: JobService(), CoroutineScope { | ||||
|     private val updateHelper: EHentaiUpdateHelper by injectLazy() | ||||
|     private val logger = XLog.tag("EHUpdater") | ||||
|  | ||||
|     private val updateNotifier by lazy { LibraryUpdateNotifier(this) } | ||||
|  | ||||
|     /** | ||||
|      * This method is called if the system has determined that you must stop execution of your job | ||||
|      * even before you've had a chance to call [.jobFinished]. | ||||
| @@ -152,6 +155,7 @@ class EHentaiUpdateWorker: JobService(), CoroutineScope { | ||||
|  | ||||
|         var failuresThisIteration = 0 | ||||
|         var updatedThisIteration = 0 | ||||
|         val updatedManga = mutableListOf<Manga>() | ||||
|         val modifiedThisIteration = mutableSetOf<Long>() | ||||
|  | ||||
|         try { | ||||
| @@ -205,9 +209,13 @@ class EHentaiUpdateWorker: JobService(), CoroutineScope { | ||||
|                 } | ||||
|  | ||||
|                 // Find accepted root and discard others | ||||
|                 val (acceptedRoot, discardedRoots) = | ||||
|                 val (acceptedRoot, discardedRoots, hasNew) = | ||||
|                         updateHelper.findAcceptedRootAndDiscardOthers(manga.source, chapters).await() | ||||
|  | ||||
|                 if(hasNew && updatedManga.none { it.id == acceptedRoot.manga.id }) { | ||||
|                     updatedManga += acceptedRoot.manga | ||||
|                 } | ||||
|  | ||||
|                 modifiedThisIteration += acceptedRoot.manga.id!! | ||||
|                 modifiedThisIteration += discardedRoots.map { it.manga.id!! } | ||||
|                 updatedThisIteration++ | ||||
| @@ -222,6 +230,8 @@ class EHentaiUpdateWorker: JobService(), CoroutineScope { | ||||
|                             ) | ||||
|                     ) | ||||
|             ) | ||||
|  | ||||
|             updateNotifier.showResultNotification(updatedManga) | ||||
|         } | ||||
|     } | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user