mirror of
https://github.com/revanced/revanced-manager
synced 2024-05-14 13:56:57 +02:00
feat: switch to the new api (#75)
This commit is contained in:
parent
7e3c31c4b2
commit
3f059d7748
@ -4,14 +4,13 @@ import app.revanced.manager.data.platform.FileSystem
|
|||||||
import app.revanced.manager.data.platform.NetworkInfo
|
import app.revanced.manager.data.platform.NetworkInfo
|
||||||
import app.revanced.manager.domain.repository.*
|
import app.revanced.manager.domain.repository.*
|
||||||
import app.revanced.manager.domain.worker.WorkerRepository
|
import app.revanced.manager.domain.worker.WorkerRepository
|
||||||
import app.revanced.manager.network.api.ManagerAPI
|
import app.revanced.manager.network.api.ReVancedAPI
|
||||||
import org.koin.core.module.dsl.singleOf
|
import org.koin.core.module.dsl.singleOf
|
||||||
import org.koin.dsl.module
|
import org.koin.dsl.module
|
||||||
|
|
||||||
val repositoryModule = module {
|
val repositoryModule = module {
|
||||||
singleOf(::ReVancedRepository)
|
singleOf(::ReVancedAPI)
|
||||||
singleOf(::GithubRepository)
|
singleOf(::GithubRepository)
|
||||||
singleOf(::ManagerAPI)
|
|
||||||
singleOf(::FileSystem)
|
singleOf(::FileSystem)
|
||||||
singleOf(::NetworkInfo)
|
singleOf(::NetworkInfo)
|
||||||
singleOf(::PatchBundlePersistenceRepository)
|
singleOf(::PatchBundlePersistenceRepository)
|
||||||
|
@ -2,20 +2,18 @@ package app.revanced.manager.domain.bundles
|
|||||||
|
|
||||||
import androidx.compose.runtime.Stable
|
import androidx.compose.runtime.Stable
|
||||||
import app.revanced.manager.data.room.bundles.VersionInfo
|
import app.revanced.manager.data.room.bundles.VersionInfo
|
||||||
import app.revanced.manager.domain.bundles.APIPatchBundle.Companion.toBundleAsset
|
|
||||||
import app.revanced.manager.domain.repository.Assets
|
|
||||||
import app.revanced.manager.domain.repository.PatchBundlePersistenceRepository
|
import app.revanced.manager.domain.repository.PatchBundlePersistenceRepository
|
||||||
import app.revanced.manager.domain.repository.ReVancedRepository
|
import app.revanced.manager.network.api.ReVancedAPI
|
||||||
import app.revanced.manager.network.dto.Asset
|
import app.revanced.manager.network.api.ReVancedAPI.Extensions.findAssetByType
|
||||||
import app.revanced.manager.network.dto.BundleAsset
|
import app.revanced.manager.network.dto.BundleAsset
|
||||||
import app.revanced.manager.network.dto.BundleInfo
|
import app.revanced.manager.network.dto.BundleInfo
|
||||||
import app.revanced.manager.network.service.HttpService
|
import app.revanced.manager.network.service.HttpService
|
||||||
import app.revanced.manager.network.utils.getOrThrow
|
import app.revanced.manager.network.utils.getOrThrow
|
||||||
import app.revanced.manager.util.ghIntegrations
|
import app.revanced.manager.util.APK_MIMETYPE
|
||||||
import app.revanced.manager.util.ghPatches
|
import app.revanced.manager.util.JAR_MIMETYPE
|
||||||
import io.ktor.client.request.url
|
import io.ktor.client.request.url
|
||||||
import io.ktor.http.Url
|
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.async
|
||||||
import kotlinx.coroutines.coroutineScope
|
import kotlinx.coroutines.coroutineScope
|
||||||
import kotlinx.coroutines.flow.first
|
import kotlinx.coroutines.flow.first
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
@ -57,7 +55,11 @@ sealed class RemotePatchBundle(name: String, id: Int, directory: File, val endpo
|
|||||||
|
|
||||||
suspend fun update(): Boolean = withContext(Dispatchers.IO) {
|
suspend fun update(): Boolean = withContext(Dispatchers.IO) {
|
||||||
val info = getLatestInfo()
|
val info = getLatestInfo()
|
||||||
if (hasInstalled() && VersionInfo(info.patches.version, info.integrations.version) == currentVersion()) {
|
if (hasInstalled() && VersionInfo(
|
||||||
|
info.patches.version,
|
||||||
|
info.integrations.version
|
||||||
|
) == currentVersion()
|
||||||
|
) {
|
||||||
return@withContext false
|
return@withContext false
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -94,18 +96,24 @@ class JsonPatchBundle(name: String, id: Int, directory: File, endpoint: String)
|
|||||||
|
|
||||||
class APIPatchBundle(name: String, id: Int, directory: File, endpoint: String) :
|
class APIPatchBundle(name: String, id: Int, directory: File, endpoint: String) :
|
||||||
RemotePatchBundle(name, id, directory, endpoint) {
|
RemotePatchBundle(name, id, directory, endpoint) {
|
||||||
private val api: ReVancedRepository by inject()
|
private val api: ReVancedAPI by inject()
|
||||||
|
|
||||||
override suspend fun getLatestInfo() = api.getAssets().toBundleInfo()
|
override suspend fun getLatestInfo() = coroutineScope {
|
||||||
|
fun getAssetAsync(repo: String, mime: String) = async(Dispatchers.IO) {
|
||||||
private companion object {
|
api
|
||||||
fun Assets.toBundleInfo(): BundleInfo {
|
.getRelease(repo)
|
||||||
val patches = find(ghPatches, ".jar")
|
.getOrThrow()
|
||||||
val integrations = find(ghIntegrations, ".apk")
|
.let {
|
||||||
|
BundleAsset(it.metadata.tag, it.findAssetByType(mime).downloadUrl)
|
||||||
return BundleInfo(patches.toBundleAsset(), integrations.toBundleAsset())
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun Asset.toBundleAsset() = BundleAsset(version, downloadUrl)
|
val patches = getAssetAsync("revanced-patches", JAR_MIMETYPE)
|
||||||
|
val integrations = getAssetAsync("revanced-integrations", APK_MIMETYPE)
|
||||||
|
|
||||||
|
BundleInfo(
|
||||||
|
patches.await(),
|
||||||
|
integrations.await()
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -10,7 +10,7 @@ class PreferencesManager(
|
|||||||
val dynamicColor = booleanPreference("dynamic_color", true)
|
val dynamicColor = booleanPreference("dynamic_color", true)
|
||||||
val theme = enumPreference("theme", Theme.SYSTEM)
|
val theme = enumPreference("theme", Theme.SYSTEM)
|
||||||
|
|
||||||
val api = stringPreference("api_url", "https://releases.revanced.app")
|
val api = stringPreference("api_url", "https://api.revanced.app")
|
||||||
|
|
||||||
val allowExperimental = booleanPreference("allow_experimental", false)
|
val allowExperimental = booleanPreference("allow_experimental", false)
|
||||||
|
|
||||||
|
@ -2,6 +2,7 @@ package app.revanced.manager.domain.repository
|
|||||||
|
|
||||||
import app.revanced.manager.network.service.GithubService
|
import app.revanced.manager.network.service.GithubService
|
||||||
|
|
||||||
|
// TODO: delete this when the revanced api adds download count.
|
||||||
class GithubRepository(private val service: GithubService) {
|
class GithubRepository(private val service: GithubService) {
|
||||||
suspend fun getChangelog(repo: String) = service.getChangelog(repo)
|
suspend fun getChangelog(repo: String) = service.getChangelog(repo)
|
||||||
}
|
}
|
@ -1,25 +0,0 @@
|
|||||||
package app.revanced.manager.domain.repository
|
|
||||||
|
|
||||||
import app.revanced.manager.domain.manager.PreferencesManager
|
|
||||||
import app.revanced.manager.network.api.MissingAssetException
|
|
||||||
import app.revanced.manager.network.dto.Asset
|
|
||||||
import app.revanced.manager.network.dto.ReVancedReleases
|
|
||||||
import app.revanced.manager.network.service.ReVancedService
|
|
||||||
import app.revanced.manager.network.utils.getOrThrow
|
|
||||||
|
|
||||||
class ReVancedRepository(
|
|
||||||
private val service: ReVancedService,
|
|
||||||
private val prefs: PreferencesManager
|
|
||||||
) {
|
|
||||||
private suspend fun apiUrl() = prefs.api.get()
|
|
||||||
|
|
||||||
suspend fun getContributors() = service.getContributors(apiUrl())
|
|
||||||
|
|
||||||
suspend fun getAssets() = Assets(service.getAssets(apiUrl()).getOrThrow())
|
|
||||||
}
|
|
||||||
|
|
||||||
class Assets(private val releases: ReVancedReleases): List<Asset> by releases.tools {
|
|
||||||
fun find(repo: String, file: String) = find { asset ->
|
|
||||||
asset.name.contains(file) && asset.repository.contains(repo)
|
|
||||||
} ?: throw MissingAssetException()
|
|
||||||
}
|
|
@ -1,43 +0,0 @@
|
|||||||
package app.revanced.manager.network.api
|
|
||||||
|
|
||||||
import androidx.compose.runtime.getValue
|
|
||||||
import androidx.compose.runtime.mutableStateOf
|
|
||||||
import androidx.compose.runtime.setValue
|
|
||||||
import app.revanced.manager.domain.repository.Assets
|
|
||||||
import app.revanced.manager.domain.repository.ReVancedRepository
|
|
||||||
import app.revanced.manager.network.dto.Asset
|
|
||||||
import app.revanced.manager.network.service.HttpService
|
|
||||||
import app.revanced.manager.util.*
|
|
||||||
import io.ktor.client.plugins.onDownload
|
|
||||||
import io.ktor.client.request.url
|
|
||||||
import java.io.File
|
|
||||||
|
|
||||||
// TODO: merge ReVancedRepository into this class
|
|
||||||
class ManagerAPI(
|
|
||||||
private val http: HttpService,
|
|
||||||
private val revancedRepository: ReVancedRepository
|
|
||||||
) {
|
|
||||||
var downloadProgress: Float? by mutableStateOf(null)
|
|
||||||
var downloadedSize: Long? by mutableStateOf(null)
|
|
||||||
var totalSize: Long? by mutableStateOf(null)
|
|
||||||
|
|
||||||
private suspend fun downloadAsset(asset: Asset, saveLocation: File) {
|
|
||||||
http.download(saveLocation) {
|
|
||||||
url(asset.downloadUrl)
|
|
||||||
onDownload { bytesSentTotal, contentLength ->
|
|
||||||
downloadProgress = (bytesSentTotal.toFloat() / contentLength.toFloat())
|
|
||||||
downloadedSize = bytesSentTotal
|
|
||||||
totalSize = contentLength
|
|
||||||
}
|
|
||||||
}
|
|
||||||
downloadProgress = null
|
|
||||||
}
|
|
||||||
|
|
||||||
suspend fun downloadManager(location: File) {
|
|
||||||
val managerAsset = revancedRepository.getAssets().find(ghManager, ".apk")
|
|
||||||
downloadAsset(managerAsset, location)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
class MissingAssetException : Exception()
|
|
@ -0,0 +1,26 @@
|
|||||||
|
package app.revanced.manager.network.api
|
||||||
|
|
||||||
|
import app.revanced.manager.domain.manager.PreferencesManager
|
||||||
|
import app.revanced.manager.network.dto.Asset
|
||||||
|
import app.revanced.manager.network.dto.ReVancedLatestRelease
|
||||||
|
import app.revanced.manager.network.dto.ReVancedRelease
|
||||||
|
import app.revanced.manager.network.service.ReVancedService
|
||||||
|
import app.revanced.manager.network.utils.getOrThrow
|
||||||
|
import app.revanced.manager.network.utils.transform
|
||||||
|
|
||||||
|
class ReVancedAPI(
|
||||||
|
private val service: ReVancedService,
|
||||||
|
private val prefs: PreferencesManager
|
||||||
|
) {
|
||||||
|
private suspend fun apiUrl() = prefs.api.get()
|
||||||
|
|
||||||
|
suspend fun getContributors() = service.getContributors(apiUrl()).transform { it.repositories }
|
||||||
|
|
||||||
|
suspend fun getRelease(name: String) = service.getRelease(apiUrl(), name).transform { it.release }
|
||||||
|
|
||||||
|
companion object Extensions {
|
||||||
|
fun ReVancedRelease.findAssetByType(mime: String) = assets.singleOrNull { it.contentType == mime } ?: throw MissingAssetException(mime)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class MissingAssetException(type: String) : Exception("No asset with type $type")
|
@ -4,18 +4,18 @@ import kotlinx.serialization.SerialName
|
|||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
class ReVancedRepositories(
|
data class ReVancedGitRepositories(
|
||||||
@SerialName("repositories") val repositories: List<ReVancedRepository>,
|
val repositories: List<ReVancedGitRepository>,
|
||||||
)
|
)
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
class ReVancedRepository(
|
data class ReVancedGitRepository(
|
||||||
@SerialName("name") val name: String,
|
val name: String,
|
||||||
@SerialName("contributors") val contributors: List<ReVancedContributor>,
|
val contributors: List<ReVancedContributor>,
|
||||||
)
|
)
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
class ReVancedContributor(
|
data class ReVancedContributor(
|
||||||
@SerialName("login") val username: String,
|
val username: String,
|
||||||
@SerialName("avatar_url") val avatarUrl: String,
|
@SerialName("avatar_url") val avatarUrl: String,
|
||||||
)
|
)
|
||||||
|
@ -0,0 +1,32 @@
|
|||||||
|
package app.revanced.manager.network.dto
|
||||||
|
|
||||||
|
import kotlinx.serialization.SerialName
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class ReVancedLatestRelease(
|
||||||
|
val release: ReVancedRelease,
|
||||||
|
)
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class ReVancedRelease(
|
||||||
|
val metadata: ReVancedReleaseMeta,
|
||||||
|
val assets: List<Asset>
|
||||||
|
)
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class ReVancedReleaseMeta(
|
||||||
|
@SerialName("tag_name") val tag: String,
|
||||||
|
val name: String,
|
||||||
|
val draft: Boolean,
|
||||||
|
val prerelease: Boolean,
|
||||||
|
@SerialName("created_at") val createdAt: String,
|
||||||
|
@SerialName("published_at") val publishedAt: String
|
||||||
|
)
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class Asset(
|
||||||
|
val name: String,
|
||||||
|
@SerialName("browser_download_url") val downloadUrl: String,
|
||||||
|
@SerialName("content_type") val contentType: String
|
||||||
|
)
|
@ -1,20 +0,0 @@
|
|||||||
package app.revanced.manager.network.dto
|
|
||||||
|
|
||||||
import kotlinx.serialization.SerialName
|
|
||||||
import kotlinx.serialization.Serializable
|
|
||||||
|
|
||||||
@Serializable
|
|
||||||
class ReVancedReleases(
|
|
||||||
@SerialName("tools") val tools: List<Asset>,
|
|
||||||
)
|
|
||||||
|
|
||||||
@Serializable
|
|
||||||
class Asset(
|
|
||||||
@SerialName("repository") val repository: String,
|
|
||||||
@SerialName("version") val version: String,
|
|
||||||
@SerialName("timestamp") val timestamp: String,
|
|
||||||
@SerialName("name") val name: String,
|
|
||||||
@SerialName("size") val size: String?,
|
|
||||||
@SerialName("browser_download_url") val downloadUrl: String,
|
|
||||||
@SerialName("content_type") val content_type: String
|
|
||||||
)
|
|
@ -1,11 +1,8 @@
|
|||||||
package app.revanced.manager.network.service
|
package app.revanced.manager.network.service
|
||||||
|
|
||||||
import app.revanced.manager.network.api.MissingAssetException
|
import app.revanced.manager.network.dto.ReVancedLatestRelease
|
||||||
import app.revanced.manager.network.dto.Asset
|
import app.revanced.manager.network.dto.ReVancedGitRepositories
|
||||||
import app.revanced.manager.network.dto.ReVancedReleases
|
|
||||||
import app.revanced.manager.network.dto.ReVancedRepositories
|
|
||||||
import app.revanced.manager.network.utils.APIResponse
|
import app.revanced.manager.network.utils.APIResponse
|
||||||
import app.revanced.manager.network.utils.getOrThrow
|
|
||||||
import io.ktor.client.request.*
|
import io.ktor.client.request.*
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
@ -13,20 +10,17 @@ import kotlinx.coroutines.withContext
|
|||||||
class ReVancedService(
|
class ReVancedService(
|
||||||
private val client: HttpService,
|
private val client: HttpService,
|
||||||
) {
|
) {
|
||||||
suspend fun getAssets(api: String): APIResponse<ReVancedReleases> {
|
suspend fun getRelease(api: String, repo: String): APIResponse<ReVancedLatestRelease> =
|
||||||
return withContext(Dispatchers.IO) {
|
withContext(Dispatchers.IO) {
|
||||||
client.request {
|
client.request {
|
||||||
url("$api/tools")
|
url("$api/v2/$repo/releases/latest")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
suspend fun getContributors(api: String): APIResponse<ReVancedRepositories> {
|
suspend fun getContributors(api: String): APIResponse<ReVancedGitRepositories> =
|
||||||
return withContext(Dispatchers.IO) {
|
withContext(Dispatchers.IO) {
|
||||||
client.request {
|
client.request {
|
||||||
url("$api/contributors")
|
url("$api/contributors")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
@ -56,7 +56,7 @@ fun UpdateProgressScreen(
|
|||||||
), style = MaterialTheme.typography.headlineMedium
|
), style = MaterialTheme.typography.headlineMedium
|
||||||
)
|
)
|
||||||
LinearProgressIndicator(
|
LinearProgressIndicator(
|
||||||
progress = vm.downloadProgress / 100f,
|
progress = vm.downloadProgress,
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.padding(vertical = 16.dp)
|
.padding(vertical = 16.dp)
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
@ -66,7 +66,7 @@ fun UpdateProgressScreen(
|
|||||||
vm.totalSize.div(
|
vm.totalSize.div(
|
||||||
1000000
|
1000000
|
||||||
)
|
)
|
||||||
} MB (${vm.downloadProgress.toInt()}%)" else stringResource(R.string.installing_message),
|
} MB (${vm.downloadProgress.times(100).toInt()}%)" else stringResource(R.string.installing_message),
|
||||||
style = MaterialTheme.typography.bodyMedium,
|
style = MaterialTheme.typography.bodyMedium,
|
||||||
color = MaterialTheme.colorScheme.outline,
|
color = MaterialTheme.colorScheme.outline,
|
||||||
modifier = Modifier.align(Alignment.CenterHorizontally),
|
modifier = Modifier.align(Alignment.CenterHorizontally),
|
||||||
|
@ -3,22 +3,21 @@ package app.revanced.manager.ui.viewmodel
|
|||||||
import androidx.compose.runtime.mutableStateListOf
|
import androidx.compose.runtime.mutableStateListOf
|
||||||
import androidx.lifecycle.ViewModel
|
import androidx.lifecycle.ViewModel
|
||||||
import androidx.lifecycle.viewModelScope
|
import androidx.lifecycle.viewModelScope
|
||||||
import app.revanced.manager.domain.repository.ReVancedRepository
|
import app.revanced.manager.network.api.ReVancedAPI
|
||||||
|
import app.revanced.manager.network.dto.ReVancedGitRepository
|
||||||
import app.revanced.manager.network.utils.getOrNull
|
import app.revanced.manager.network.utils.getOrNull
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
|
|
||||||
class ContributorViewModel(private val repository: ReVancedRepository): ViewModel() {
|
class ContributorViewModel(private val reVancedAPI: ReVancedAPI) : ViewModel() {
|
||||||
val repositories = mutableStateListOf<app.revanced.manager.network.dto.ReVancedRepository>()
|
val repositories = mutableStateListOf<ReVancedGitRepository>()
|
||||||
|
|
||||||
init {
|
init {
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
withContext(Dispatchers.IO) {
|
withContext(Dispatchers.IO) { reVancedAPI.getContributors().getOrNull() }?.let(
|
||||||
val repos = repository.getContributors().getOrNull()?.repositories
|
repositories::addAll
|
||||||
withContext(Dispatchers.Main) {
|
)
|
||||||
if (repos != null) { repositories.addAll(repos) }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -8,24 +8,36 @@ import androidx.compose.runtime.setValue
|
|||||||
import androidx.lifecycle.ViewModel
|
import androidx.lifecycle.ViewModel
|
||||||
import androidx.lifecycle.viewModelScope
|
import androidx.lifecycle.viewModelScope
|
||||||
import app.revanced.manager.R
|
import app.revanced.manager.R
|
||||||
import app.revanced.manager.network.api.ManagerAPI
|
import app.revanced.manager.network.api.ReVancedAPI
|
||||||
|
import app.revanced.manager.network.api.ReVancedAPI.Extensions.findAssetByType
|
||||||
|
import app.revanced.manager.network.service.HttpService
|
||||||
|
import app.revanced.manager.network.utils.getOrThrow
|
||||||
|
import app.revanced.manager.util.APK_MIMETYPE
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import app.revanced.manager.util.PM
|
import app.revanced.manager.util.PM
|
||||||
import app.revanced.manager.util.uiSafe
|
import app.revanced.manager.util.uiSafe
|
||||||
|
import io.ktor.client.plugins.onDownload
|
||||||
|
import io.ktor.client.request.url
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
class UpdateProgressViewModel(
|
class UpdateProgressViewModel(
|
||||||
app: Application,
|
app: Application,
|
||||||
private val managerAPI: ManagerAPI,
|
private val reVancedAPI: ReVancedAPI,
|
||||||
|
private val http: HttpService,
|
||||||
private val pm: PM
|
private val pm: PM
|
||||||
) : ViewModel() {
|
) : ViewModel() {
|
||||||
|
var downloadedSize by mutableStateOf(0L)
|
||||||
|
private set
|
||||||
|
var totalSize by mutableStateOf(0L)
|
||||||
|
private set
|
||||||
|
val downloadProgress by derivedStateOf {
|
||||||
|
if (downloadedSize == 0L || totalSize == 0L) return@derivedStateOf 0f
|
||||||
|
|
||||||
val downloadProgress by derivedStateOf { managerAPI.downloadProgress?.times(100) ?: 0f }
|
downloadedSize.toFloat() / totalSize.toFloat()
|
||||||
val downloadedSize by derivedStateOf { managerAPI.downloadedSize ?: 0L }
|
}
|
||||||
val totalSize by derivedStateOf { managerAPI.totalSize ?: 0L }
|
val isInstalling by derivedStateOf { downloadProgress >= 1 }
|
||||||
val isInstalling by derivedStateOf { downloadProgress >= 100 }
|
|
||||||
var finished by mutableStateOf(false)
|
var finished by mutableStateOf(false)
|
||||||
private set
|
private set
|
||||||
|
|
||||||
@ -33,7 +45,18 @@ class UpdateProgressViewModel(
|
|||||||
private val job = viewModelScope.launch {
|
private val job = viewModelScope.launch {
|
||||||
uiSafe(app, R.string.download_manager_failed, "Failed to download manager") {
|
uiSafe(app, R.string.download_manager_failed, "Failed to download manager") {
|
||||||
withContext(Dispatchers.IO) {
|
withContext(Dispatchers.IO) {
|
||||||
managerAPI.downloadManager(location)
|
val asset = reVancedAPI
|
||||||
|
.getRelease("revanced-manager")
|
||||||
|
.getOrThrow()
|
||||||
|
.findAssetByType(APK_MIMETYPE)
|
||||||
|
|
||||||
|
http.download(location) {
|
||||||
|
url(asset.downloadUrl)
|
||||||
|
onDownload { bytesSentTotal, contentLength ->
|
||||||
|
downloadedSize = bytesSentTotal
|
||||||
|
totalSize = contentLength
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
finished = true
|
finished = true
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user