mirror of
https://github.com/ReVanced/revanced-manager.git
synced 2024-11-10 01:01:56 +01:00
feat: settings migration (compose) (#1309)
This commit is contained in:
parent
5762859906
commit
56a4a7043d
4 changed files with 138 additions and 10 deletions
|
@ -1,24 +1,36 @@
|
|||
package app.revanced.manager
|
||||
|
||||
import android.content.ActivityNotFoundException
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.util.Log
|
||||
import androidx.activity.ComponentActivity
|
||||
import androidx.activity.compose.rememberLauncherForActivityResult
|
||||
import androidx.activity.compose.setContent
|
||||
import androidx.activity.result.ActivityResult
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.compose.animation.ExperimentalAnimationApi
|
||||
import androidx.compose.foundation.isSystemInDarkTheme
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.saveable.rememberSaveable
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
|
||||
import app.revanced.manager.ui.component.AutoUpdatesDialog
|
||||
import app.revanced.manager.ui.destination.Destination
|
||||
import app.revanced.manager.ui.screen.AppInfoScreen
|
||||
import app.revanced.manager.ui.screen.VersionSelectorScreen
|
||||
import app.revanced.manager.ui.screen.AppSelectorScreen
|
||||
import app.revanced.manager.ui.screen.DashboardScreen
|
||||
import app.revanced.manager.ui.screen.InstallerScreen
|
||||
import app.revanced.manager.ui.screen.PatchesSelectorScreen
|
||||
import app.revanced.manager.ui.screen.SettingsScreen
|
||||
import app.revanced.manager.ui.screen.VersionSelectorScreen
|
||||
import app.revanced.manager.ui.theme.ReVancedManagerTheme
|
||||
import app.revanced.manager.ui.theme.Theme
|
||||
import app.revanced.manager.ui.viewmodel.MainViewModel
|
||||
import app.revanced.manager.util.tag
|
||||
import app.revanced.manager.util.toast
|
||||
import dev.olshevski.navigation.reimagined.AnimatedNavHost
|
||||
import dev.olshevski.navigation.reimagined.NavBackHandler
|
||||
import dev.olshevski.navigation.reimagined.navigate
|
||||
|
@ -51,9 +63,48 @@ class MainActivity : ComponentActivity() {
|
|||
|
||||
NavBackHandler(navController)
|
||||
|
||||
val showAutoUpdatesDialog by vm.prefs.showAutoUpdatesDialog.getAsState()
|
||||
if (showAutoUpdatesDialog) {
|
||||
AutoUpdatesDialog(vm::applyAutoUpdatePrefs)
|
||||
val firstLaunch by vm.prefs.firstLaunch.getAsState()
|
||||
|
||||
if (firstLaunch) {
|
||||
var legacyActivityState by rememberSaveable { mutableStateOf(LegacyActivity.NOT_LAUNCHED) }
|
||||
if (legacyActivityState == LegacyActivity.NOT_LAUNCHED) {
|
||||
val launcher = rememberLauncherForActivityResult(
|
||||
contract = ActivityResultContracts.StartActivityForResult()
|
||||
) { result: ActivityResult ->
|
||||
if (result.resultCode == RESULT_OK) {
|
||||
if (result.data != null) {
|
||||
val jsonData = result.data!!.getStringExtra("data")!!
|
||||
vm.applyLegacySettings(jsonData)
|
||||
}
|
||||
} else {
|
||||
legacyActivityState = LegacyActivity.FAILED
|
||||
toast(getString(R.string.legacy_import_failed))
|
||||
}
|
||||
}
|
||||
|
||||
val intent = Intent().apply {
|
||||
setClassName(
|
||||
"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
|
||||
}
|
||||
}
|
||||
|
||||
legacyActivityState = LegacyActivity.LAUNCHED
|
||||
} else if (legacyActivityState == LegacyActivity.FAILED){
|
||||
AutoUpdatesDialog(vm::applyAutoUpdatePrefs)
|
||||
}
|
||||
}
|
||||
|
||||
AnimatedNavHost(
|
||||
|
@ -120,4 +171,10 @@ class MainActivity : ComponentActivity() {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private enum class LegacyActivity {
|
||||
NOT_LAUNCHED,
|
||||
LAUNCHED,
|
||||
FAILED
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,7 +19,7 @@ class PreferencesManager(
|
|||
|
||||
val preferSplits = booleanPreference("prefer_splits", false)
|
||||
|
||||
val showAutoUpdatesDialog = booleanPreference("show_auto_updates_dialog", true)
|
||||
val firstLaunch = booleanPreference("first_launch", true)
|
||||
val managerAutoUpdates = booleanPreference("manager_auto_updates", false)
|
||||
|
||||
val disableSelectionWarning = booleanPreference("disable_selection_warning", false)
|
||||
|
|
|
@ -1,21 +1,28 @@
|
|||
package app.revanced.manager.ui.viewmodel
|
||||
|
||||
import android.util.Base64
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import app.revanced.manager.domain.bundles.PatchBundleSource.Companion.asRemoteOrNull
|
||||
import app.revanced.manager.domain.manager.KeystoreManager
|
||||
import app.revanced.manager.domain.manager.PreferencesManager
|
||||
import app.revanced.manager.domain.repository.PatchBundleRepository
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import app.revanced.manager.domain.repository.PatchSelectionRepository
|
||||
import app.revanced.manager.domain.repository.SerializedSelection
|
||||
import app.revanced.manager.ui.theme.Theme
|
||||
import kotlinx.coroutines.flow.first
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.json.Json
|
||||
|
||||
class MainViewModel(
|
||||
private val patchBundleRepository: PatchBundleRepository,
|
||||
private val patchSelectionRepository: PatchSelectionRepository,
|
||||
private val keystoreManager: KeystoreManager,
|
||||
val prefs: PreferencesManager
|
||||
) : ViewModel() {
|
||||
|
||||
fun applyAutoUpdatePrefs(manager: Boolean, patches: Boolean) = viewModelScope.launch {
|
||||
prefs.showAutoUpdatesDialog.update(false)
|
||||
prefs.firstLaunch.update(false)
|
||||
|
||||
prefs.managerAutoUpdates.update(manager)
|
||||
if (patches) {
|
||||
|
@ -30,4 +37,66 @@ class MainViewModel(
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun applyLegacySettings(data: String) = viewModelScope.launch {
|
||||
val json = Json { ignoreUnknownKeys = true }
|
||||
val settings = json.decodeFromString<LegacySettings>(data)
|
||||
|
||||
settings.themeMode?.let { theme ->
|
||||
val themeMap = mapOf(
|
||||
0 to Theme.SYSTEM,
|
||||
1 to Theme.LIGHT,
|
||||
2 to Theme.DARK
|
||||
)
|
||||
prefs.theme.update(themeMap[theme]!!)
|
||||
}
|
||||
settings.useDynamicTheme?.let { dynamicColor ->
|
||||
prefs.dynamicColor.update(dynamicColor)
|
||||
}
|
||||
settings.apiUrl?.let { api ->
|
||||
prefs.api.update(api.removeSuffix("/"))
|
||||
}
|
||||
settings.experimentalPatchesEnabled?.let { allowExperimental ->
|
||||
prefs.allowExperimental.update(allowExperimental)
|
||||
}
|
||||
settings.patchesAutoUpdate?.let { autoUpdate ->
|
||||
with(patchBundleRepository) {
|
||||
sources
|
||||
.first()
|
||||
.find { it.uid == 0 }
|
||||
?.asRemoteOrNull
|
||||
?.setAutoUpdate(autoUpdate)
|
||||
|
||||
updateCheck()
|
||||
}
|
||||
}
|
||||
settings.patchesChangeEnabled?.let { disableSelectionWarning ->
|
||||
prefs.disableSelectionWarning.update(disableSelectionWarning)
|
||||
}
|
||||
settings.keystore?.let { keystore ->
|
||||
val keystoreBytes = Base64.decode(keystore, Base64.DEFAULT)
|
||||
keystoreManager.import(
|
||||
"ReVanced",
|
||||
settings.keystorePassword,
|
||||
keystoreBytes.inputStream()
|
||||
)
|
||||
}
|
||||
settings.patches?.let { selection ->
|
||||
patchSelectionRepository.import(0, selection)
|
||||
}
|
||||
prefs.firstLaunch.update(false)
|
||||
}
|
||||
|
||||
@Serializable
|
||||
private data class LegacySettings(
|
||||
val keystorePassword: String,
|
||||
val themeMode: Int? = null,
|
||||
val useDynamicTheme: Boolean? = null,
|
||||
val apiUrl: String? = null,
|
||||
val experimentalPatchesEnabled: Boolean? = null,
|
||||
val patchesAutoUpdate: Boolean? = null,
|
||||
val patchesChangeEnabled: Boolean? = null,
|
||||
val keystore: String? = null,
|
||||
val patches: SerializedSelection? = null,
|
||||
)
|
||||
}
|
||||
|
|
|
@ -24,6 +24,8 @@
|
|||
<string name="bundle_missing">Missing</string>
|
||||
<string name="bundle_error">Error</string>
|
||||
|
||||
<string name="legacy_import_failed">Could not import legacy settings</string>
|
||||
|
||||
<string name="auto_updates_dialog_title">Select updates to receive</string>
|
||||
<string name="auto_updates_dialog_description">Periodically connect to update providers to check for updates.</string>
|
||||
<string name="auto_updates_dialog_manager">ReVanced Manager</string>
|
||||
|
|
Loading…
Reference in a new issue