mirror of
https://github.com/tachiyomiorg/tachiyomi.git
synced 2024-12-23 10:41:48 +01:00
Adding a button in new release notification to open GitHub release page
Shows also while downloading/error/installed Should help those who can't complete their downloads for some reason There's also refactoring from upstream in this, including tapping on the notification for an intent. However the intent here opens the app with the release notes dialog
This commit is contained in:
parent
0b4f83d83e
commit
77c080cc47
@ -23,6 +23,7 @@ import eu.kanade.tachiyomi.source.SourceManager
|
||||
import eu.kanade.tachiyomi.ui.main.MainActivity
|
||||
import eu.kanade.tachiyomi.ui.manga.MangaDetailsController
|
||||
import eu.kanade.tachiyomi.ui.reader.ReaderActivity
|
||||
import eu.kanade.tachiyomi.ui.setting.AboutController
|
||||
import eu.kanade.tachiyomi.util.storage.DiskUtil
|
||||
import eu.kanade.tachiyomi.util.storage.getUriCompat
|
||||
import eu.kanade.tachiyomi.util.system.notificationManager
|
||||
@ -278,6 +279,8 @@ class NotificationReceiver : BroadcastReceiver() {
|
||||
// Called to cancel library update.
|
||||
private const val ACTION_CANCEL_LIBRARY_UPDATE = "$ID.$NAME.CANCEL_LIBRARY_UPDATE"
|
||||
|
||||
private const val ACTION_CANCEL_UPDATE_DOWNLOAD = "$ID.$NAME.CANCEL_UPDATE_DOWNLOAD"
|
||||
|
||||
// Called to mark as read
|
||||
private const val ACTION_MARK_AS_READ = "$ID.$NAME.MARK_AS_READ"
|
||||
|
||||
@ -471,6 +474,27 @@ class NotificationReceiver : BroadcastReceiver() {
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns [PendingIntent] that opens the manga details controller.
|
||||
*
|
||||
* @param context context of application
|
||||
* @param manga manga of chapter
|
||||
*/
|
||||
internal fun openUpdatePendingActivity(context: Context, notes: String, downloadLink: String):
|
||||
PendingIntent {
|
||||
val newIntent =
|
||||
Intent(context, MainActivity::class.java).setAction(MainActivity.SHORTCUT_UPDATE_NOTES)
|
||||
.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_SINGLE_TOP)
|
||||
.putExtra(AboutController.NewUpdateDialogController.BODY_KEY, notes)
|
||||
.putExtra(AboutController.NewUpdateDialogController.URL_KEY, downloadLink)
|
||||
return PendingIntent.getActivity(
|
||||
context,
|
||||
downloadLink.hashCode(),
|
||||
newIntent,
|
||||
PendingIntent.FLAG_UPDATE_CURRENT
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns [PendingIntent] that opens the manga details controller.
|
||||
*
|
||||
|
@ -9,4 +9,6 @@ interface Release {
|
||||
* @return download link of latest release.
|
||||
*/
|
||||
val downloadLink: String
|
||||
|
||||
val releaseLink: String
|
||||
}
|
||||
|
@ -1,8 +1,6 @@
|
||||
package eu.kanade.tachiyomi.data.updater
|
||||
|
||||
import android.app.PendingIntent
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import androidx.core.app.NotificationCompat
|
||||
import androidx.work.Constraints
|
||||
import androidx.work.CoroutineWorker
|
||||
@ -11,9 +9,7 @@ import androidx.work.NetworkType
|
||||
import androidx.work.PeriodicWorkRequestBuilder
|
||||
import androidx.work.WorkManager
|
||||
import androidx.work.WorkerParameters
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.data.notification.Notifications
|
||||
import eu.kanade.tachiyomi.util.system.getResourceColor
|
||||
import eu.kanade.tachiyomi.util.system.notificationManager
|
||||
import kotlinx.coroutines.coroutineScope
|
||||
import java.util.concurrent.TimeUnit
|
||||
@ -22,37 +18,19 @@ class UpdaterJob(private val context: Context, workerParams: WorkerParameters) :
|
||||
CoroutineWorker(context, workerParams) {
|
||||
|
||||
override suspend fun doWork(): Result = coroutineScope {
|
||||
val result = try {
|
||||
UpdateChecker.getUpdateChecker().checkForUpdate()
|
||||
try {
|
||||
val result = UpdateChecker.getUpdateChecker().checkForUpdate()
|
||||
if (result is UpdateResult.NewUpdate<*>) {
|
||||
UpdaterNotifier(context).promptUpdate(
|
||||
result.release.info,
|
||||
result.release.downloadLink,
|
||||
result.release.releaseLink
|
||||
)
|
||||
}
|
||||
Result.success()
|
||||
} catch (e: Exception) {
|
||||
Result.failure()
|
||||
}
|
||||
if (result is UpdateResult.NewUpdate<*>) {
|
||||
val url = result.release.downloadLink
|
||||
|
||||
val intent = Intent(context, UpdaterService::class.java).apply {
|
||||
putExtra(UpdaterService.EXTRA_DOWNLOAD_URL, url)
|
||||
}
|
||||
|
||||
NotificationCompat.Builder(context, Notifications.CHANNEL_COMMON).update {
|
||||
setContentTitle(context.getString(R.string.app_name))
|
||||
setContentText(context.getString(R.string.update_available))
|
||||
setSmallIcon(android.R.drawable.stat_sys_download_done)
|
||||
color = context.getResourceColor(R.attr.colorAccent)
|
||||
// Download action
|
||||
addAction(
|
||||
android.R.drawable.stat_sys_download_done,
|
||||
context.getString(R.string.download),
|
||||
PendingIntent.getService(
|
||||
context,
|
||||
0,
|
||||
intent,
|
||||
PendingIntent.FLAG_UPDATE_CURRENT
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
Result.success()
|
||||
}
|
||||
|
||||
fun NotificationCompat.Builder.update(block: NotificationCompat.Builder.() -> Unit) {
|
||||
|
@ -1,13 +1,17 @@
|
||||
package eu.kanade.tachiyomi.data.updater
|
||||
|
||||
import android.app.PendingIntent
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.net.Uri
|
||||
import androidx.core.app.NotificationCompat
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.core.net.toUri
|
||||
import eu.kanade.tachiyomi.R
|
||||
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.system.getResourceColor
|
||||
import eu.kanade.tachiyomi.util.system.notificationManager
|
||||
|
||||
/**
|
||||
@ -20,10 +24,14 @@ internal class UpdaterNotifier(private val context: Context) {
|
||||
/**
|
||||
* Builder to manage notifications.
|
||||
*/
|
||||
private val notification by lazy {
|
||||
private val notificationBuilder by lazy {
|
||||
NotificationCompat.Builder(context, Notifications.CHANNEL_COMMON)
|
||||
}
|
||||
|
||||
companion object {
|
||||
var releasePageUrl: String? = null
|
||||
}
|
||||
|
||||
/**
|
||||
* Call to show notification.
|
||||
*
|
||||
@ -33,20 +41,68 @@ internal class UpdaterNotifier(private val context: Context) {
|
||||
context.notificationManager.notify(id, build())
|
||||
}
|
||||
|
||||
fun promptUpdate(body: String, url: String, releaseUrl: String) {
|
||||
val intent = Intent(context, UpdaterService::class.java).apply {
|
||||
putExtra(UpdaterService.EXTRA_DOWNLOAD_URL, url)
|
||||
}
|
||||
|
||||
val pendingIntent = NotificationReceiver.openUpdatePendingActivity(context, body, url)
|
||||
releasePageUrl = releaseUrl
|
||||
with(notificationBuilder) {
|
||||
setContentTitle(context.getString(R.string.app_name))
|
||||
setContentText(context.getString(R.string.new_version_available))
|
||||
setContentIntent(pendingIntent)
|
||||
setAutoCancel(true)
|
||||
setSmallIcon(android.R.drawable.stat_sys_download_done)
|
||||
color = context.getResourceColor(R.attr.colorAccent)
|
||||
clearActions()
|
||||
// Download action
|
||||
addAction(
|
||||
android.R.drawable.stat_sys_download_done,
|
||||
context.getString(R.string.download),
|
||||
PendingIntent.getService(
|
||||
context,
|
||||
0,
|
||||
intent,
|
||||
PendingIntent.FLAG_UPDATE_CURRENT
|
||||
)
|
||||
)
|
||||
addReleasePageAction()
|
||||
}
|
||||
notificationBuilder.show()
|
||||
}
|
||||
|
||||
private fun NotificationCompat.Builder.addReleasePageAction() {
|
||||
releasePageUrl?.let { releaseUrl ->
|
||||
val releaseIntent = Intent(Intent.ACTION_VIEW, releaseUrl.toUri()).apply {
|
||||
flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP
|
||||
}
|
||||
addAction(
|
||||
R.drawable.ic_new_releases_24dp,
|
||||
context.getString(R.string.release_page),
|
||||
PendingIntent.getActivity(context, releaseUrl.hashCode(), releaseIntent, PendingIntent.FLAG_UPDATE_CURRENT)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Call when apk download starts.
|
||||
*
|
||||
* @param title tile of notification.
|
||||
*/
|
||||
fun onDownloadStarted(title: String): NotificationCompat.Builder {
|
||||
with(notification) {
|
||||
with(notificationBuilder) {
|
||||
setContentTitle(title)
|
||||
setContentText(context.getString(R.string.downloading))
|
||||
setSmallIcon(android.R.drawable.stat_sys_download)
|
||||
setAutoCancel(false)
|
||||
setOngoing(true)
|
||||
clearActions()
|
||||
|
||||
addReleasePageAction()
|
||||
}
|
||||
notification.show()
|
||||
return notification
|
||||
notificationBuilder.show()
|
||||
return notificationBuilder
|
||||
}
|
||||
|
||||
/**
|
||||
@ -55,11 +111,11 @@ internal class UpdaterNotifier(private val context: Context) {
|
||||
* @param progress progress of download (xx%/100).
|
||||
*/
|
||||
fun onProgressChange(progress: Int) {
|
||||
with(notification) {
|
||||
with(notificationBuilder) {
|
||||
setProgress(100, progress, false)
|
||||
setOnlyAlertOnce(true)
|
||||
}
|
||||
notification.show()
|
||||
notificationBuilder.show()
|
||||
}
|
||||
|
||||
/**
|
||||
@ -68,13 +124,15 @@ internal class UpdaterNotifier(private val context: Context) {
|
||||
* @param uri path location of apk.
|
||||
*/
|
||||
fun onDownloadFinished(uri: Uri) {
|
||||
with(notification) {
|
||||
with(notificationBuilder) {
|
||||
setContentText(context.getString(R.string.download_complete))
|
||||
setSmallIcon(android.R.drawable.stat_sys_download_done)
|
||||
setAutoCancel(false)
|
||||
setOnlyAlertOnce(false)
|
||||
setProgress(0, 0, false)
|
||||
// Install action
|
||||
setContentIntent(NotificationHandler.installApkPendingActivity(context, uri))
|
||||
clearActions()
|
||||
addAction(
|
||||
R.drawable.ic_system_update_24dp,
|
||||
context.getString(R.string.install),
|
||||
@ -86,8 +144,9 @@ internal class UpdaterNotifier(private val context: Context) {
|
||||
context.getString(R.string.cancel),
|
||||
NotificationReceiver.dismissNotificationPendingBroadcast(context, Notifications.ID_UPDATER)
|
||||
)
|
||||
addReleasePageAction()
|
||||
}
|
||||
notification.show()
|
||||
notificationBuilder.show()
|
||||
}
|
||||
|
||||
/**
|
||||
@ -96,12 +155,14 @@ internal class UpdaterNotifier(private val context: Context) {
|
||||
* @param url web location of apk to download.
|
||||
*/
|
||||
fun onDownloadError(url: String) {
|
||||
with(notification) {
|
||||
with(notificationBuilder) {
|
||||
setContentText(context.getString(R.string.download_error))
|
||||
setSmallIcon(android.R.drawable.stat_sys_warning)
|
||||
setOnlyAlertOnce(false)
|
||||
setAutoCancel(false)
|
||||
setProgress(0, 0, false)
|
||||
color = ContextCompat.getColor(context, R.color.colorAccent)
|
||||
clearActions()
|
||||
// Retry action
|
||||
addAction(
|
||||
R.drawable.ic_refresh_24dp,
|
||||
@ -114,7 +175,9 @@ internal class UpdaterNotifier(private val context: Context) {
|
||||
context.getString(R.string.cancel),
|
||||
NotificationReceiver.dismissNotificationPendingBroadcast(context, Notifications.ID_UPDATER)
|
||||
)
|
||||
addReleasePageAction()
|
||||
}
|
||||
notification.show(Notifications.ID_UPDATER)
|
||||
notificationBuilder.show(Notifications.ID_UPDATER)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -14,6 +14,7 @@ import eu.kanade.tachiyomi.data.updater.Release
|
||||
class GithubRelease(
|
||||
@SerializedName("tag_name") val version: String,
|
||||
@SerializedName("body") override val info: String,
|
||||
@SerializedName("html_url") override val releaseLink: String,
|
||||
@SerializedName("assets") private val assets: List<Assets>
|
||||
) : Release {
|
||||
|
||||
|
@ -49,6 +49,7 @@ import eu.kanade.tachiyomi.data.preference.asImmediateFlowIn
|
||||
import eu.kanade.tachiyomi.data.preference.getOrDefault
|
||||
import eu.kanade.tachiyomi.data.updater.UpdateChecker
|
||||
import eu.kanade.tachiyomi.data.updater.UpdateResult
|
||||
import eu.kanade.tachiyomi.data.updater.UpdaterNotifier
|
||||
import eu.kanade.tachiyomi.databinding.MainActivityBinding
|
||||
import eu.kanade.tachiyomi.extension.api.ExtensionGithubApi
|
||||
import eu.kanade.tachiyomi.ui.base.MaterialMenuSheet
|
||||
@ -497,6 +498,7 @@ open class MainActivity : BaseActivity<MainActivityBinding>(), DownloadServiceLi
|
||||
|
||||
// Create confirmation window
|
||||
withContext(Dispatchers.Main) {
|
||||
UpdaterNotifier.releasePageUrl = result.release.releaseLink
|
||||
AboutController.NewUpdateDialogController(body, url).showDialog(router)
|
||||
}
|
||||
}
|
||||
@ -570,6 +572,13 @@ open class MainActivity : BaseActivity<MainActivityBinding>(), DownloadServiceLi
|
||||
if (router.backstack.isEmpty()) binding.bottomNav.selectedItemId = R.id.nav_library
|
||||
router.pushController(MangaDetailsController(extras).withFadeTransaction())
|
||||
}
|
||||
SHORTCUT_UPDATE_NOTES -> {
|
||||
val extras = intent.extras ?: return false
|
||||
if (router.backstack.isEmpty()) binding.bottomNav.selectedItemId = R.id.nav_library
|
||||
if (router.backstack.lastOrNull()?.controller() !is AboutController.NewUpdateDialogController) {
|
||||
AboutController.NewUpdateDialogController(extras).showDialog(router)
|
||||
}
|
||||
}
|
||||
SHORTCUT_SOURCE -> {
|
||||
val extras = intent.extras ?: return false
|
||||
if (router.backstack.isEmpty()) binding.bottomNav.selectedItemId = R.id.nav_library
|
||||
@ -882,6 +891,7 @@ open class MainActivity : BaseActivity<MainActivityBinding>(), DownloadServiceLi
|
||||
const val SHORTCUT_BROWSE = "eu.kanade.tachiyomi.SHOW_BROWSE"
|
||||
const val SHORTCUT_DOWNLOADS = "eu.kanade.tachiyomi.SHOW_DOWNLOADS"
|
||||
const val SHORTCUT_MANGA = "eu.kanade.tachiyomi.SHOW_MANGA"
|
||||
const val SHORTCUT_UPDATE_NOTES = "eu.kanade.tachiyomi.SHOW_UPDATE_NOTES"
|
||||
const val SHORTCUT_SOURCE = "eu.kanade.tachiyomi.SHOW_SOURCE"
|
||||
const val SHORTCUT_READER_SETTINGS = "eu.kanade.tachiyomi.READER_SETTINGS"
|
||||
const val SHORTCUT_EXTENSIONS = "eu.kanade.tachiyomi.EXTENSIONS"
|
||||
|
@ -12,6 +12,7 @@ import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
||||
import eu.kanade.tachiyomi.data.updater.UpdateChecker
|
||||
import eu.kanade.tachiyomi.data.updater.UpdateResult
|
||||
import eu.kanade.tachiyomi.data.updater.UpdaterNotifier
|
||||
import eu.kanade.tachiyomi.data.updater.UpdaterService
|
||||
import eu.kanade.tachiyomi.ui.base.controller.DialogController
|
||||
import eu.kanade.tachiyomi.util.lang.toTimestampString
|
||||
@ -166,6 +167,7 @@ class AboutController : SettingsController() {
|
||||
|
||||
// Create confirmation window
|
||||
withContext(Dispatchers.Main) {
|
||||
UpdaterNotifier.releasePageUrl = result.release.releaseLink
|
||||
NewUpdateDialogController(body, url).showDialog(router)
|
||||
}
|
||||
}
|
||||
@ -202,7 +204,7 @@ class AboutController : SettingsController() {
|
||||
.negativeButton(R.string.ignore)
|
||||
}
|
||||
|
||||
private companion object {
|
||||
companion object {
|
||||
const val BODY_KEY = "NewUpdateDialogController.body"
|
||||
const val URL_KEY = "NewUpdateDialogController.key"
|
||||
}
|
||||
|
@ -108,6 +108,7 @@
|
||||
<string name="new_version_available">New version available!</string>
|
||||
<string name="no_new_updates_available">No new updates available</string>
|
||||
<string name="searching_for_updates">Searching for updates…</string>
|
||||
<string name="release_page">Release page</string>
|
||||
|
||||
<!-- Main Screens -->
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user