mirror of
https://github.com/revanced/revanced-manager
synced 2024-05-14 13:56:57 +02:00
feat: check for updates on startup (#1462)
This commit is contained in:
parent
1a83315424
commit
1dc41badd9
@ -1,27 +1,25 @@
|
|||||||
package app.revanced.manager
|
package app.revanced.manager
|
||||||
|
|
||||||
import android.content.ActivityNotFoundException
|
|
||||||
import android.content.Intent
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.util.Log
|
|
||||||
import androidx.activity.ComponentActivity
|
import androidx.activity.ComponentActivity
|
||||||
import androidx.activity.compose.rememberLauncherForActivityResult
|
|
||||||
import androidx.activity.compose.setContent
|
import androidx.activity.compose.setContent
|
||||||
import androidx.activity.result.ActivityResult
|
|
||||||
import androidx.activity.result.contract.ActivityResultContracts
|
|
||||||
import androidx.compose.animation.ExperimentalAnimationApi
|
import androidx.compose.animation.ExperimentalAnimationApi
|
||||||
import androidx.compose.foundation.isSystemInDarkTheme
|
import androidx.compose.foundation.isSystemInDarkTheme
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
import androidx.compose.material.icons.Icons
|
||||||
|
import androidx.compose.material.icons.outlined.Update
|
||||||
|
import androidx.compose.material3.AlertDialog
|
||||||
|
import androidx.compose.material3.Icon
|
||||||
|
import androidx.compose.material3.Text
|
||||||
|
import androidx.compose.material3.TextButton
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.runtime.saveable.rememberSaveable
|
|
||||||
import androidx.compose.runtime.setValue
|
|
||||||
import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
|
import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
|
||||||
import app.revanced.manager.ui.component.AutoUpdatesDialog
|
import app.revanced.manager.ui.component.AutoUpdatesDialog
|
||||||
import app.revanced.manager.ui.destination.Destination
|
import app.revanced.manager.ui.destination.Destination
|
||||||
import app.revanced.manager.ui.screen.InstalledAppInfoScreen
|
import app.revanced.manager.ui.destination.SettingsDestination
|
||||||
import app.revanced.manager.ui.screen.AppSelectorScreen
|
import app.revanced.manager.ui.screen.AppSelectorScreen
|
||||||
import app.revanced.manager.ui.screen.DashboardScreen
|
import app.revanced.manager.ui.screen.DashboardScreen
|
||||||
|
import app.revanced.manager.ui.screen.InstalledAppInfoScreen
|
||||||
import app.revanced.manager.ui.screen.InstallerScreen
|
import app.revanced.manager.ui.screen.InstallerScreen
|
||||||
import app.revanced.manager.ui.screen.SelectedAppInfoScreen
|
import app.revanced.manager.ui.screen.SelectedAppInfoScreen
|
||||||
import app.revanced.manager.ui.screen.SettingsScreen
|
import app.revanced.manager.ui.screen.SettingsScreen
|
||||||
@ -30,17 +28,15 @@ import app.revanced.manager.ui.theme.ReVancedManagerTheme
|
|||||||
import app.revanced.manager.ui.theme.Theme
|
import app.revanced.manager.ui.theme.Theme
|
||||||
import app.revanced.manager.ui.viewmodel.MainViewModel
|
import app.revanced.manager.ui.viewmodel.MainViewModel
|
||||||
import app.revanced.manager.ui.viewmodel.SelectedAppInfoViewModel
|
import app.revanced.manager.ui.viewmodel.SelectedAppInfoViewModel
|
||||||
import app.revanced.manager.util.tag
|
|
||||||
import app.revanced.manager.util.toast
|
|
||||||
import dev.olshevski.navigation.reimagined.AnimatedNavHost
|
import dev.olshevski.navigation.reimagined.AnimatedNavHost
|
||||||
import dev.olshevski.navigation.reimagined.NavBackHandler
|
import dev.olshevski.navigation.reimagined.NavBackHandler
|
||||||
import dev.olshevski.navigation.reimagined.navigate
|
import dev.olshevski.navigation.reimagined.navigate
|
||||||
import dev.olshevski.navigation.reimagined.pop
|
import dev.olshevski.navigation.reimagined.pop
|
||||||
import dev.olshevski.navigation.reimagined.popUpTo
|
import dev.olshevski.navigation.reimagined.popUpTo
|
||||||
import dev.olshevski.navigation.reimagined.rememberNavController
|
import dev.olshevski.navigation.reimagined.rememberNavController
|
||||||
|
import org.koin.core.parameter.parametersOf
|
||||||
import org.koin.androidx.compose.getViewModel as getComposeViewModel
|
import org.koin.androidx.compose.getViewModel as getComposeViewModel
|
||||||
import org.koin.androidx.viewmodel.ext.android.getViewModel as getAndroidViewModel
|
import org.koin.androidx.viewmodel.ext.android.getViewModel as getAndroidViewModel
|
||||||
import org.koin.core.parameter.parametersOf
|
|
||||||
|
|
||||||
class MainActivity : ComponentActivity() {
|
class MainActivity : ComponentActivity() {
|
||||||
@ExperimentalAnimationApi
|
@ExperimentalAnimationApi
|
||||||
@ -51,6 +47,8 @@ class MainActivity : ComponentActivity() {
|
|||||||
|
|
||||||
val vm: MainViewModel = getAndroidViewModel()
|
val vm: MainViewModel = getAndroidViewModel()
|
||||||
|
|
||||||
|
vm.importLegacySettings(this)
|
||||||
|
|
||||||
setContent {
|
setContent {
|
||||||
val theme by vm.prefs.theme.getAsState()
|
val theme by vm.prefs.theme.getAsState()
|
||||||
val dynamicColor by vm.prefs.dynamicColor.getAsState()
|
val dynamicColor by vm.prefs.dynamicColor.getAsState()
|
||||||
@ -66,46 +64,30 @@ class MainActivity : ComponentActivity() {
|
|||||||
|
|
||||||
val firstLaunch by vm.prefs.firstLaunch.getAsState()
|
val firstLaunch by vm.prefs.firstLaunch.getAsState()
|
||||||
|
|
||||||
if (firstLaunch) {
|
if (firstLaunch) AutoUpdatesDialog(vm::applyAutoUpdatePrefs)
|
||||||
var legacyActivityState by rememberSaveable { mutableStateOf(LegacyActivity.NOT_LAUNCHED) }
|
|
||||||
if (legacyActivityState == LegacyActivity.NOT_LAUNCHED) {
|
vm.updatedManagerVersion?.let {
|
||||||
val launcher = rememberLauncherForActivityResult(
|
AlertDialog(
|
||||||
contract = ActivityResultContracts.StartActivityForResult()
|
onDismissRequest = vm::dismissUpdateDialog,
|
||||||
) { result: ActivityResult ->
|
confirmButton = {
|
||||||
if (result.resultCode == RESULT_OK) {
|
TextButton(
|
||||||
if (result.data != null) {
|
onClick = {
|
||||||
val jsonData = result.data!!.getStringExtra("data")!!
|
vm.dismissUpdateDialog()
|
||||||
vm.applyLegacySettings(jsonData)
|
navController.navigate(Destination.Settings(SettingsDestination.UpdateProgress))
|
||||||
}
|
}
|
||||||
} else {
|
) {
|
||||||
legacyActivityState = LegacyActivity.FAILED
|
Text(stringResource(R.string.update))
|
||||||
toast(getString(R.string.legacy_import_failed))
|
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
dismissButton = {
|
||||||
val intent = Intent().apply {
|
TextButton(onClick = vm::dismissUpdateDialog) {
|
||||||
setClassName(
|
Text(stringResource(R.string.dismiss_temporary))
|
||||||
"app.revanced.manager.flutter",
|
|
||||||
"app.revanced.manager.flutter.ExportSettingsActivity"
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
LaunchedEffect(Unit) {
|
|
||||||
try {
|
|
||||||
launcher.launch(intent)
|
|
||||||
} catch (e: Exception) {
|
|
||||||
if (e !is ActivityNotFoundException) {
|
|
||||||
toast(getString(R.string.legacy_import_failed))
|
|
||||||
Log.e(tag, "Failed to launch legacy import activity: $e")
|
|
||||||
}
|
|
||||||
legacyActivityState = LegacyActivity.FAILED
|
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
icon = { Icon(Icons.Outlined.Update, null) },
|
||||||
legacyActivityState = LegacyActivity.LAUNCHED
|
title = { Text(stringResource(R.string.update_available)) },
|
||||||
} else if (legacyActivityState == LegacyActivity.FAILED) {
|
text = { Text(stringResource(R.string.update_available_description, it)) }
|
||||||
AutoUpdatesDialog(vm::applyAutoUpdatePrefs)
|
)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
AnimatedNavHost(
|
AnimatedNavHost(
|
||||||
@ -113,7 +95,7 @@ class MainActivity : ComponentActivity() {
|
|||||||
) { destination ->
|
) { destination ->
|
||||||
when (destination) {
|
when (destination) {
|
||||||
is Destination.Dashboard -> DashboardScreen(
|
is Destination.Dashboard -> DashboardScreen(
|
||||||
onSettingsClick = { navController.navigate(Destination.Settings) },
|
onSettingsClick = { navController.navigate(Destination.Settings()) },
|
||||||
onAppSelectorClick = { navController.navigate(Destination.AppSelector) },
|
onAppSelectorClick = { navController.navigate(Destination.AppSelector) },
|
||||||
onAppClick = { installedApp ->
|
onAppClick = { installedApp ->
|
||||||
navController.navigate(
|
navController.navigate(
|
||||||
@ -138,7 +120,8 @@ class MainActivity : ComponentActivity() {
|
|||||||
)
|
)
|
||||||
|
|
||||||
is Destination.Settings -> SettingsScreen(
|
is Destination.Settings -> SettingsScreen(
|
||||||
onBackClick = { navController.pop() }
|
onBackClick = { navController.pop() },
|
||||||
|
startDestination = destination.startDestination
|
||||||
)
|
)
|
||||||
|
|
||||||
is Destination.AppSelector -> AppSelectorScreen(
|
is Destination.AppSelector -> AppSelectorScreen(
|
||||||
@ -199,10 +182,4 @@ class MainActivity : ComponentActivity() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private enum class LegacyActivity {
|
|
||||||
NOT_LAUNCHED,
|
|
||||||
LAUNCHED,
|
|
||||||
FAILED
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -11,16 +11,16 @@ import kotlinx.parcelize.RawValue
|
|||||||
sealed interface Destination : Parcelable {
|
sealed interface Destination : Parcelable {
|
||||||
|
|
||||||
@Parcelize
|
@Parcelize
|
||||||
object Dashboard : Destination
|
data object Dashboard : Destination
|
||||||
|
|
||||||
@Parcelize
|
@Parcelize
|
||||||
data class InstalledApplicationInfo(val installedApp: InstalledApp) : Destination
|
data class InstalledApplicationInfo(val installedApp: InstalledApp) : Destination
|
||||||
|
|
||||||
@Parcelize
|
@Parcelize
|
||||||
object AppSelector : Destination
|
data object AppSelector : Destination
|
||||||
|
|
||||||
@Parcelize
|
@Parcelize
|
||||||
object Settings : Destination
|
data class Settings(val startDestination: SettingsDestination = SettingsDestination.Settings) : Destination
|
||||||
|
|
||||||
@Parcelize
|
@Parcelize
|
||||||
data class VersionSelector(val packageName: String, val patchesSelection: PatchesSelection? = null) : Destination
|
data class VersionSelector(val packageName: String, val patchesSelection: PatchesSelection? = null) : Destination
|
||||||
|
@ -43,10 +43,16 @@ import app.revanced.manager.ui.component.settings.SettingsListItem
|
|||||||
@Composable
|
@Composable
|
||||||
fun SettingsScreen(
|
fun SettingsScreen(
|
||||||
onBackClick: () -> Unit,
|
onBackClick: () -> Unit,
|
||||||
|
startDestination: SettingsDestination,
|
||||||
viewModel: SettingsViewModel = getViewModel()
|
viewModel: SettingsViewModel = getViewModel()
|
||||||
) {
|
) {
|
||||||
val navController =
|
val navController = rememberNavController(startDestination)
|
||||||
rememberNavController<SettingsDestination>(startDestination = SettingsDestination.Settings)
|
|
||||||
|
val backClick: () -> Unit = {
|
||||||
|
if (navController.backstack.entries.size == 1)
|
||||||
|
onBackClick()
|
||||||
|
else navController.pop()
|
||||||
|
}
|
||||||
|
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
val pm = context.getSystemService(Context.POWER_SERVICE) as PowerManager
|
val pm = context.getSystemService(Context.POWER_SERVICE) as PowerManager
|
||||||
@ -92,48 +98,48 @@ fun SettingsScreen(
|
|||||||
when (destination) {
|
when (destination) {
|
||||||
|
|
||||||
is SettingsDestination.General -> GeneralSettingsScreen(
|
is SettingsDestination.General -> GeneralSettingsScreen(
|
||||||
onBackClick = { navController.pop() },
|
onBackClick = backClick,
|
||||||
viewModel = viewModel
|
viewModel = viewModel
|
||||||
)
|
)
|
||||||
|
|
||||||
is SettingsDestination.Advanced -> AdvancedSettingsScreen(
|
is SettingsDestination.Advanced -> AdvancedSettingsScreen(
|
||||||
onBackClick = { navController.pop() }
|
onBackClick = backClick
|
||||||
)
|
)
|
||||||
|
|
||||||
is SettingsDestination.Updates -> UpdatesSettingsScreen(
|
is SettingsDestination.Updates -> UpdatesSettingsScreen(
|
||||||
onBackClick = { navController.pop() },
|
onBackClick = backClick,
|
||||||
onChangelogClick = { navController.navigate(SettingsDestination.Changelogs) },
|
onChangelogClick = { navController.navigate(SettingsDestination.Changelogs) },
|
||||||
onUpdateClick = { navController.navigate(SettingsDestination.UpdateProgress) }
|
onUpdateClick = { navController.navigate(SettingsDestination.UpdateProgress) }
|
||||||
)
|
)
|
||||||
|
|
||||||
is SettingsDestination.Downloads -> DownloadsSettingsScreen(
|
is SettingsDestination.Downloads -> DownloadsSettingsScreen(
|
||||||
onBackClick = { navController.pop() }
|
onBackClick = backClick
|
||||||
)
|
)
|
||||||
|
|
||||||
is SettingsDestination.ImportExport -> ImportExportSettingsScreen(
|
is SettingsDestination.ImportExport -> ImportExportSettingsScreen(
|
||||||
onBackClick = { navController.pop() }
|
onBackClick = backClick
|
||||||
)
|
)
|
||||||
|
|
||||||
is SettingsDestination.About -> AboutSettingsScreen(
|
is SettingsDestination.About -> AboutSettingsScreen(
|
||||||
onBackClick = { navController.pop() },
|
onBackClick = backClick,
|
||||||
onContributorsClick = { navController.navigate(SettingsDestination.Contributors) },
|
onContributorsClick = { navController.navigate(SettingsDestination.Contributors) },
|
||||||
onLicensesClick = { navController.navigate(SettingsDestination.Licenses) }
|
onLicensesClick = { navController.navigate(SettingsDestination.Licenses) }
|
||||||
)
|
)
|
||||||
|
|
||||||
is SettingsDestination.UpdateProgress -> UpdateProgressScreen(
|
is SettingsDestination.UpdateProgress -> UpdateProgressScreen(
|
||||||
onBackClick = { navController.pop() },
|
onBackClick = backClick,
|
||||||
)
|
)
|
||||||
|
|
||||||
is SettingsDestination.Changelogs -> ChangelogsScreen(
|
is SettingsDestination.Changelogs -> ChangelogsScreen(
|
||||||
onBackClick = { navController.pop() },
|
onBackClick = backClick,
|
||||||
)
|
)
|
||||||
|
|
||||||
is SettingsDestination.Contributors -> ContributorScreen(
|
is SettingsDestination.Contributors -> ContributorScreen(
|
||||||
onBackClick = { navController.pop() },
|
onBackClick = backClick,
|
||||||
)
|
)
|
||||||
|
|
||||||
is SettingsDestination.Licenses -> LicensesScreen(
|
is SettingsDestination.Licenses -> LicensesScreen(
|
||||||
onBackClick = { navController.pop() },
|
onBackClick = backClick,
|
||||||
)
|
)
|
||||||
|
|
||||||
is SettingsDestination.Settings -> {
|
is SettingsDestination.Settings -> {
|
||||||
@ -141,7 +147,7 @@ fun SettingsScreen(
|
|||||||
topBar = {
|
topBar = {
|
||||||
AppTopBar(
|
AppTopBar(
|
||||||
title = stringResource(R.string.settings),
|
title = stringResource(R.string.settings),
|
||||||
onBackClick = onBackClick,
|
onBackClick = backClick,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
) { paddingValues ->
|
) { paddingValues ->
|
||||||
|
@ -1,15 +1,32 @@
|
|||||||
package app.revanced.manager.ui.viewmodel
|
package app.revanced.manager.ui.viewmodel
|
||||||
|
|
||||||
|
import android.app.Application
|
||||||
|
import android.content.ActivityNotFoundException
|
||||||
|
import android.content.Intent
|
||||||
|
import android.os.Build
|
||||||
import android.util.Base64
|
import android.util.Base64
|
||||||
|
import android.util.Log
|
||||||
|
import androidx.activity.ComponentActivity
|
||||||
|
import androidx.activity.result.ActivityResult
|
||||||
|
import androidx.activity.result.contract.ActivityResultContracts
|
||||||
|
import androidx.compose.runtime.getValue
|
||||||
|
import androidx.compose.runtime.mutableStateOf
|
||||||
|
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.data.platform.NetworkInfo
|
||||||
import app.revanced.manager.domain.bundles.PatchBundleSource.Companion.asRemoteOrNull
|
import app.revanced.manager.domain.bundles.PatchBundleSource.Companion.asRemoteOrNull
|
||||||
import app.revanced.manager.domain.manager.KeystoreManager
|
import app.revanced.manager.domain.manager.KeystoreManager
|
||||||
import app.revanced.manager.domain.manager.PreferencesManager
|
import app.revanced.manager.domain.manager.PreferencesManager
|
||||||
import app.revanced.manager.domain.repository.PatchBundleRepository
|
import app.revanced.manager.domain.repository.PatchBundleRepository
|
||||||
import app.revanced.manager.domain.repository.PatchSelectionRepository
|
import app.revanced.manager.domain.repository.PatchSelectionRepository
|
||||||
import app.revanced.manager.domain.repository.SerializedSelection
|
import app.revanced.manager.domain.repository.SerializedSelection
|
||||||
|
import app.revanced.manager.network.api.ReVancedAPI
|
||||||
|
import app.revanced.manager.network.utils.getOrThrow
|
||||||
import app.revanced.manager.ui.theme.Theme
|
import app.revanced.manager.ui.theme.Theme
|
||||||
|
import app.revanced.manager.util.tag
|
||||||
|
import app.revanced.manager.util.toast
|
||||||
import kotlinx.coroutines.flow.first
|
import kotlinx.coroutines.flow.first
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
@ -19,12 +36,42 @@ class MainViewModel(
|
|||||||
private val patchBundleRepository: PatchBundleRepository,
|
private val patchBundleRepository: PatchBundleRepository,
|
||||||
private val patchSelectionRepository: PatchSelectionRepository,
|
private val patchSelectionRepository: PatchSelectionRepository,
|
||||||
private val keystoreManager: KeystoreManager,
|
private val keystoreManager: KeystoreManager,
|
||||||
|
private val reVancedAPI: ReVancedAPI,
|
||||||
|
private val app: Application,
|
||||||
|
private val networkInfo: NetworkInfo,
|
||||||
val prefs: PreferencesManager
|
val prefs: PreferencesManager
|
||||||
) : ViewModel() {
|
) : ViewModel() {
|
||||||
|
var updatedManagerVersion: String? by mutableStateOf(null)
|
||||||
|
private set
|
||||||
|
|
||||||
|
init {
|
||||||
|
viewModelScope.launch { checkForManagerUpdates() }
|
||||||
|
}
|
||||||
|
|
||||||
|
fun dismissUpdateDialog() {
|
||||||
|
updatedManagerVersion = null
|
||||||
|
}
|
||||||
|
|
||||||
|
private suspend fun checkForManagerUpdates() {
|
||||||
|
if (!prefs.managerAutoUpdates.get() || !networkInfo.isConnected()) return
|
||||||
|
|
||||||
|
try {
|
||||||
|
reVancedAPI.getLatestRelease("revanced-manager").getOrThrow().let { release ->
|
||||||
|
updatedManagerVersion = release.metadata.tag.takeIf { it != Build.VERSION.RELEASE }
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
app.toast(app.getString(R.string.failed_to_check_updates))
|
||||||
|
Log.e(tag, "Failed to check for updates", e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun applyAutoUpdatePrefs(manager: Boolean, patches: Boolean) = viewModelScope.launch {
|
fun applyAutoUpdatePrefs(manager: Boolean, patches: Boolean) = viewModelScope.launch {
|
||||||
prefs.firstLaunch.update(false)
|
prefs.firstLaunch.update(false)
|
||||||
|
|
||||||
prefs.managerAutoUpdates.update(manager)
|
prefs.managerAutoUpdates.update(manager)
|
||||||
|
|
||||||
|
if (manager) checkForManagerUpdates()
|
||||||
|
|
||||||
if (patches) {
|
if (patches) {
|
||||||
with(patchBundleRepository) {
|
with(patchBundleRepository) {
|
||||||
sources
|
sources
|
||||||
@ -38,7 +85,39 @@ class MainViewModel(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun applyLegacySettings(data: String) = viewModelScope.launch {
|
fun importLegacySettings(componentActivity: ComponentActivity) {
|
||||||
|
if (!prefs.firstLaunch.getBlocking()) return
|
||||||
|
|
||||||
|
try {
|
||||||
|
val launcher = componentActivity.registerForActivityResult(
|
||||||
|
ActivityResultContracts.StartActivityForResult()
|
||||||
|
) { result: ActivityResult ->
|
||||||
|
if (result.resultCode == ComponentActivity.RESULT_OK) {
|
||||||
|
result.data?.getStringExtra("data")?.let {
|
||||||
|
applyLegacySettings(it)
|
||||||
|
} ?: app.toast(app.getString(R.string.legacy_import_failed))
|
||||||
|
} else {
|
||||||
|
app.toast(app.getString(R.string.legacy_import_failed))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val intent = Intent().apply {
|
||||||
|
setClassName(
|
||||||
|
"app.revanced.manager.flutter",
|
||||||
|
"app.revanced.manager.flutter.ExportSettingsActivity"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
launcher.launch(intent)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
if (e !is ActivityNotFoundException) {
|
||||||
|
app.toast(app.getString(R.string.legacy_import_failed))
|
||||||
|
Log.e(tag, "Failed to launch legacy import activity: $e")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun applyLegacySettings(data: String) = viewModelScope.launch {
|
||||||
val json = Json { ignoreUnknownKeys = true }
|
val json = Json { ignoreUnknownKeys = true }
|
||||||
val settings = json.decodeFromString<LegacySettings>(data)
|
val settings = json.decodeFromString<LegacySettings>(data)
|
||||||
|
|
||||||
@ -48,7 +127,7 @@ class MainViewModel(
|
|||||||
1 to Theme.LIGHT,
|
1 to Theme.LIGHT,
|
||||||
2 to Theme.DARK
|
2 to Theme.DARK
|
||||||
)
|
)
|
||||||
prefs.theme.update(themeMap[theme]!!)
|
prefs.theme.update(themeMap[theme] ?: Theme.SYSTEM)
|
||||||
}
|
}
|
||||||
settings.useDynamicTheme?.let { dynamicColor ->
|
settings.useDynamicTheme?.let { dynamicColor ->
|
||||||
prefs.dynamicColor.update(dynamicColor)
|
prefs.dynamicColor.update(dynamicColor)
|
||||||
@ -84,7 +163,6 @@ class MainViewModel(
|
|||||||
settings.patches?.let { selection ->
|
settings.patches?.let { selection ->
|
||||||
patchSelectionRepository.import(0, selection)
|
patchSelectionRepository.import(0, selection)
|
||||||
}
|
}
|
||||||
prefs.firstLaunch.update(false)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
|
@ -297,4 +297,9 @@
|
|||||||
<string name="days_ago">%sd ago</string>
|
<string name="days_ago">%sd ago</string>
|
||||||
<string name="invalid_date">Invalid date</string>
|
<string name="invalid_date">Invalid date</string>
|
||||||
<string name="disable_battery_optimization">Disable battery optimization</string>
|
<string name="disable_battery_optimization">Disable battery optimization</string>
|
||||||
|
|
||||||
|
<string name="failed_to_check_updates">Failed to check for updates</string>
|
||||||
|
<string name="dismiss_temporary">Not now</string>
|
||||||
|
<string name="update_available">New update available</string>
|
||||||
|
<string name="update_available_description">A new version (%s) is available for download.</string>
|
||||||
</resources>
|
</resources>
|
Loading…
x
Reference in New Issue
Block a user