mirror of
https://git.mihon.tech/mihonapp/mihon
synced 2024-11-27 09:44:55 +03:00
Use coroutines for updater
This commit is contained in:
parent
340829bb71
commit
6a95ff56df
9 changed files with 67 additions and 81 deletions
|
@ -110,16 +110,16 @@ dependencies {
|
|||
// Android support library
|
||||
implementation 'androidx.appcompat:appcompat:1.1.0'
|
||||
implementation 'androidx.cardview:cardview:1.0.0'
|
||||
implementation 'com.google.android.material:material:1.1.0'
|
||||
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
|
||||
implementation 'androidx.recyclerview:recyclerview:1.1.0'
|
||||
implementation 'androidx.preference:preference:1.1.0'
|
||||
implementation 'androidx.annotation:annotation:1.1.0'
|
||||
implementation 'androidx.browser:browser:1.2.0'
|
||||
|
||||
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
|
||||
|
||||
implementation 'androidx.multidex:multidex:2.0.1'
|
||||
|
||||
// UI library
|
||||
implementation 'com.google.android.material:material:1.1.0'
|
||||
|
||||
standardImplementation 'com.google.firebase:firebase-core:17.2.2'
|
||||
|
||||
// ReactiveX
|
||||
|
@ -221,7 +221,7 @@ dependencies {
|
|||
implementation "com.jakewharton.rxbinding:rxbinding-recyclerview-v7-kotlin:$rxbindings_version"
|
||||
|
||||
// Tests
|
||||
testImplementation 'junit:junit:4.12'
|
||||
testImplementation 'junit:junit:4.13'
|
||||
testImplementation 'org.assertj:assertj-core:1.7.1'
|
||||
testImplementation 'org.mockito:mockito-core:1.10.19'
|
||||
|
||||
|
|
|
@ -53,12 +53,11 @@ class TrackSearch : Track {
|
|||
result = 31 * result + media_id
|
||||
return result
|
||||
}
|
||||
companion object {
|
||||
|
||||
companion object {
|
||||
fun create(serviceId: Int): TrackSearch = TrackSearch().apply {
|
||||
sync_id = serviceId
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,6 @@ package eu.kanade.tachiyomi.data.updater
|
|||
import eu.kanade.tachiyomi.BuildConfig
|
||||
import eu.kanade.tachiyomi.data.updater.devrepo.DevRepoUpdateChecker
|
||||
import eu.kanade.tachiyomi.data.updater.github.GithubUpdateChecker
|
||||
import rx.Observable
|
||||
|
||||
abstract class UpdateChecker {
|
||||
|
||||
|
@ -20,6 +19,6 @@ abstract class UpdateChecker {
|
|||
/**
|
||||
* Returns observable containing release information
|
||||
*/
|
||||
abstract fun checkForUpdate(): Observable<UpdateResult>
|
||||
abstract suspend fun checkForUpdate(): UpdateResult
|
||||
|
||||
}
|
||||
|
|
|
@ -9,36 +9,37 @@ import com.evernote.android.job.JobRequest
|
|||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.data.notification.Notifications
|
||||
import eu.kanade.tachiyomi.util.system.notificationManager
|
||||
import kotlinx.coroutines.runBlocking
|
||||
|
||||
class UpdaterJob : Job() {
|
||||
|
||||
override fun onRunJob(params: Params): Result {
|
||||
return UpdateChecker.getUpdateChecker()
|
||||
.checkForUpdate()
|
||||
.map { result ->
|
||||
if (result is UpdateResult.NewUpdate<*>) {
|
||||
val url = result.release.downloadLink
|
||||
return runBlocking {
|
||||
try {
|
||||
val result = UpdateChecker.getUpdateChecker().checkForUpdate()
|
||||
|
||||
val intent = Intent(context, UpdaterService::class.java).apply {
|
||||
putExtra(UpdaterService.EXTRA_DOWNLOAD_URL, url)
|
||||
}
|
||||
if (result is UpdateResult.NewUpdate<*>) {
|
||||
val url = result.release.downloadLink
|
||||
|
||||
NotificationCompat.Builder(context, Notifications.CHANNEL_COMMON).update {
|
||||
setContentTitle(context.getString(R.string.app_name))
|
||||
setContentText(context.getString(R.string.update_check_notification_update_available))
|
||||
setSmallIcon(android.R.drawable.stat_sys_download_done)
|
||||
// Download action
|
||||
addAction(android.R.drawable.stat_sys_download_done,
|
||||
context.getString(R.string.action_download),
|
||||
PendingIntent.getService(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT))
|
||||
}
|
||||
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_check_notification_update_available))
|
||||
setSmallIcon(android.R.drawable.stat_sys_download_done)
|
||||
// Download action
|
||||
addAction(android.R.drawable.stat_sys_download_done,
|
||||
context.getString(R.string.action_download),
|
||||
PendingIntent.getService(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT))
|
||||
}
|
||||
Result.SUCCESS
|
||||
}
|
||||
.onErrorReturn { Result.FAILURE }
|
||||
// Sadly, the task needs to be synchronous.
|
||||
.toBlocking()
|
||||
.single()
|
||||
Result.SUCCESS
|
||||
} catch (e: Exception) {
|
||||
Result.FAILURE
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun NotificationCompat.Builder.update(block: NotificationCompat.Builder.() -> Unit) {
|
||||
|
|
|
@ -5,9 +5,8 @@ import eu.kanade.tachiyomi.data.updater.UpdateChecker
|
|||
import eu.kanade.tachiyomi.data.updater.UpdateResult
|
||||
import eu.kanade.tachiyomi.network.GET
|
||||
import eu.kanade.tachiyomi.network.NetworkHelper
|
||||
import eu.kanade.tachiyomi.network.asObservable
|
||||
import eu.kanade.tachiyomi.network.await
|
||||
import okhttp3.OkHttpClient
|
||||
import rx.Observable
|
||||
import uy.kohesive.injekt.Injekt
|
||||
import uy.kohesive.injekt.api.get
|
||||
|
||||
|
@ -23,18 +22,17 @@ class DevRepoUpdateChecker : UpdateChecker() {
|
|||
Regex("tachiyomi-r(\\d+).apk")
|
||||
}
|
||||
|
||||
override fun checkForUpdate(): Observable<UpdateResult> {
|
||||
return client.newCall(GET(DevRepoRelease.LATEST_URL)).asObservable()
|
||||
.map { response ->
|
||||
// Get latest repo version number from header in format "Location: tachiyomi-r1512.apk"
|
||||
val latestVersionNumber: String = versionRegex.find(response.header("Location")!!)!!.groupValues[1]
|
||||
override suspend fun checkForUpdate(): UpdateResult {
|
||||
val response = client.newCall(GET(DevRepoRelease.LATEST_URL)).await(assertSuccess = false)
|
||||
|
||||
if (latestVersionNumber.toInt() > BuildConfig.COMMIT_COUNT.toInt()) {
|
||||
DevRepoUpdateResult.NewUpdate(DevRepoRelease("v$latestVersionNumber"))
|
||||
} else {
|
||||
DevRepoUpdateResult.NoNewUpdate()
|
||||
}
|
||||
}
|
||||
// Get latest repo version number from header in format "Location: tachiyomi-r1512.apk"
|
||||
val latestVersionNumber: String = versionRegex.find(response.header("Location")!!)!!.groupValues[1]
|
||||
|
||||
return if (latestVersionNumber.toInt() > BuildConfig.COMMIT_COUNT.toInt()) {
|
||||
DevRepoUpdateResult.NewUpdate(DevRepoRelease("v$latestVersionNumber"))
|
||||
} else {
|
||||
DevRepoUpdateResult.NoNewUpdate()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -5,7 +5,6 @@ import retrofit2.Retrofit
|
|||
import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory
|
||||
import retrofit2.converter.gson.GsonConverterFactory
|
||||
import retrofit2.http.GET
|
||||
import rx.Observable
|
||||
import uy.kohesive.injekt.Injekt
|
||||
import uy.kohesive.injekt.api.get
|
||||
|
||||
|
@ -28,6 +27,6 @@ interface GithubService {
|
|||
}
|
||||
|
||||
@GET("/repos/inorichi/tachiyomi/releases/latest")
|
||||
fun getLatestVersion(): Observable<GithubRelease>
|
||||
suspend fun getLatestVersion(): GithubRelease
|
||||
|
||||
}
|
||||
|
|
|
@ -3,22 +3,21 @@ package eu.kanade.tachiyomi.data.updater.github
|
|||
import eu.kanade.tachiyomi.BuildConfig
|
||||
import eu.kanade.tachiyomi.data.updater.UpdateChecker
|
||||
import eu.kanade.tachiyomi.data.updater.UpdateResult
|
||||
import rx.Observable
|
||||
|
||||
class GithubUpdateChecker : UpdateChecker() {
|
||||
|
||||
private val service: GithubService = GithubService.create()
|
||||
|
||||
override fun checkForUpdate(): Observable<UpdateResult> {
|
||||
return service.getLatestVersion().map { release ->
|
||||
val newVersion = release.version.replace("[^\\d.]".toRegex(), "")
|
||||
override suspend fun checkForUpdate(): UpdateResult {
|
||||
val release = service.getLatestVersion()
|
||||
|
||||
// Check if latest version is different from current version
|
||||
if (newVersion != BuildConfig.VERSION_NAME) {
|
||||
GithubUpdateResult.NewUpdate(release)
|
||||
} else {
|
||||
GithubUpdateResult.NoNewUpdate()
|
||||
}
|
||||
val newVersion = release.version.replace("[^\\d.]".toRegex(), "")
|
||||
|
||||
// Check if latest version is different from current version
|
||||
return if (newVersion != BuildConfig.VERSION_NAME) {
|
||||
GithubUpdateResult.NewUpdate(release)
|
||||
} else {
|
||||
GithubUpdateResult.NoNewUpdate()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -48,11 +48,11 @@ fun Call.asObservable(): Observable<Response> {
|
|||
}
|
||||
|
||||
// Based on https://github.com/gildor/kotlin-coroutines-okhttp
|
||||
suspend fun Call.await(): Response {
|
||||
suspend fun Call.await(assertSuccess: Boolean = false): Response {
|
||||
return suspendCancellableCoroutine { continuation ->
|
||||
enqueue(object : Callback {
|
||||
override fun onResponse(call: Call, response: Response) {
|
||||
if (!response.isSuccessful) {
|
||||
if (assertSuccess && !response.isSuccessful) {
|
||||
continuation.resumeWithException(Exception("HTTP error ${response.code}"))
|
||||
return
|
||||
}
|
||||
|
|
|
@ -4,7 +4,6 @@ import android.app.Dialog
|
|||
import android.content.Intent
|
||||
import android.net.Uri
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import androidx.preference.PreferenceScreen
|
||||
import com.afollestad.materialdialogs.MaterialDialog
|
||||
import eu.kanade.tachiyomi.BuildConfig
|
||||
|
@ -17,12 +16,11 @@ import eu.kanade.tachiyomi.data.updater.UpdaterJob
|
|||
import eu.kanade.tachiyomi.data.updater.UpdaterService
|
||||
import eu.kanade.tachiyomi.ui.base.controller.DialogController
|
||||
import eu.kanade.tachiyomi.ui.main.ChangelogDialogController
|
||||
import eu.kanade.tachiyomi.util.lang.launchIO
|
||||
import eu.kanade.tachiyomi.util.lang.launchUI
|
||||
import eu.kanade.tachiyomi.util.lang.toTimestampString
|
||||
import eu.kanade.tachiyomi.util.preference.*
|
||||
import eu.kanade.tachiyomi.util.system.toast
|
||||
import rx.Subscription
|
||||
import rx.android.schedulers.AndroidSchedulers
|
||||
import rx.schedulers.Schedulers
|
||||
import timber.log.Timber
|
||||
import uy.kohesive.injekt.injectLazy
|
||||
import java.text.DateFormat
|
||||
|
@ -43,11 +41,6 @@ class SettingsAboutController : SettingsController() {
|
|||
|
||||
private val dateFormat: DateFormat = userPreferences.dateFormat().getOrDefault()
|
||||
|
||||
/**
|
||||
* The subscribtion service of the obtained release object
|
||||
*/
|
||||
private var releaseSubscription: Subscription? = null
|
||||
|
||||
private val isUpdaterEnabled = BuildConfig.INCLUDE_UPDATER
|
||||
|
||||
override fun setupPreferenceScreen(screen: PreferenceScreen) = with(screen) {
|
||||
|
@ -118,12 +111,6 @@ class SettingsAboutController : SettingsController() {
|
|||
}
|
||||
}
|
||||
|
||||
override fun onDestroyView(view: View) {
|
||||
super.onDestroyView(view)
|
||||
releaseSubscription?.unsubscribe()
|
||||
releaseSubscription = null
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks version and shows a user prompt if an update is available.
|
||||
*/
|
||||
|
@ -131,11 +118,11 @@ class SettingsAboutController : SettingsController() {
|
|||
if (activity == null) return
|
||||
|
||||
activity?.toast(R.string.update_check_look_for_updates)
|
||||
releaseSubscription?.unsubscribe()
|
||||
releaseSubscription = updateChecker.checkForUpdate()
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe({ result ->
|
||||
|
||||
launchIO {
|
||||
try {
|
||||
val result = updateChecker.checkForUpdate()
|
||||
launchUI {
|
||||
when (result) {
|
||||
is UpdateResult.NewUpdate<*> -> {
|
||||
val body = result.release.info
|
||||
|
@ -148,10 +135,14 @@ class SettingsAboutController : SettingsController() {
|
|||
activity?.toast(R.string.update_check_no_new_updates)
|
||||
}
|
||||
}
|
||||
}, { error ->
|
||||
}
|
||||
} catch (error: Exception) {
|
||||
launchUI {
|
||||
activity?.toast(error.message)
|
||||
Timber.e(error)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class NewUpdateDialogController(bundle: Bundle? = null) : DialogController(bundle) {
|
||||
|
|
Loading…
Reference in a new issue