mirror of
https://github.com/ReVanced/revanced-manager.git
synced 2024-11-10 01:01:56 +01:00
parent
cdc69ea8ff
commit
afc72ffd85
7 changed files with 136 additions and 47 deletions
|
@ -23,6 +23,7 @@ class PreferencesManager(
|
||||||
|
|
||||||
val firstLaunch = booleanPreference("first_launch", true)
|
val firstLaunch = booleanPreference("first_launch", true)
|
||||||
val managerAutoUpdates = booleanPreference("manager_auto_updates", false)
|
val managerAutoUpdates = booleanPreference("manager_auto_updates", false)
|
||||||
|
val showManagerUpdateDialogOnLaunch = booleanPreference("show_manager_update_dialog_on_launch", true)
|
||||||
|
|
||||||
val disablePatchVersionCompatCheck = booleanPreference("disable_patch_version_compatibility_check", false)
|
val disablePatchVersionCompatCheck = booleanPreference("disable_patch_version_compatibility_check", false)
|
||||||
val disableSelectionWarning = booleanPreference("disable_selection_warning", false)
|
val disableSelectionWarning = booleanPreference("disable_selection_warning", false)
|
||||||
|
|
|
@ -0,0 +1,81 @@
|
||||||
|
package app.revanced.manager.ui.component
|
||||||
|
|
||||||
|
import androidx.compose.foundation.clickable
|
||||||
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
|
import androidx.compose.foundation.layout.Column
|
||||||
|
import androidx.compose.foundation.layout.PaddingValues
|
||||||
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.material.icons.Icons
|
||||||
|
import androidx.compose.material.icons.outlined.Update
|
||||||
|
import androidx.compose.material3.*
|
||||||
|
import androidx.compose.runtime.*
|
||||||
|
import androidx.compose.runtime.saveable.rememberSaveable
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.res.stringResource
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import app.revanced.manager.R
|
||||||
|
|
||||||
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
|
@Composable
|
||||||
|
fun AvailableUpdateDialog(
|
||||||
|
onDismiss: () -> Unit,
|
||||||
|
onConfirm: () -> Unit,
|
||||||
|
setShowManagerUpdateDialogOnLaunch: (Boolean) -> Unit,
|
||||||
|
newVersion: String
|
||||||
|
) {
|
||||||
|
var dontShowAgain by rememberSaveable { mutableStateOf(false) }
|
||||||
|
val dismissDialog = {
|
||||||
|
setShowManagerUpdateDialogOnLaunch(!dontShowAgain)
|
||||||
|
onDismiss()
|
||||||
|
}
|
||||||
|
|
||||||
|
AlertDialogExtended(
|
||||||
|
onDismissRequest = dismissDialog,
|
||||||
|
confirmButton = {
|
||||||
|
TextButton(
|
||||||
|
onClick = {
|
||||||
|
dismissDialog()
|
||||||
|
onConfirm()
|
||||||
|
}
|
||||||
|
) {
|
||||||
|
Text(stringResource(R.string.show))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
dismissButton = {
|
||||||
|
TextButton(
|
||||||
|
onClick = dismissDialog
|
||||||
|
) {
|
||||||
|
Text(stringResource(R.string.dismiss))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
icon = {
|
||||||
|
Icon(imageVector = Icons.Outlined.Update, contentDescription = null)
|
||||||
|
},
|
||||||
|
title = {
|
||||||
|
Text(stringResource(R.string.update_available))
|
||||||
|
},
|
||||||
|
text = {
|
||||||
|
Column(
|
||||||
|
modifier = Modifier.padding(horizontal = 8.dp),
|
||||||
|
verticalArrangement = Arrangement.spacedBy(4.dp),
|
||||||
|
) {
|
||||||
|
Text(
|
||||||
|
modifier = Modifier.padding(horizontal = 16.dp),
|
||||||
|
text = stringResource(R.string.update_available_dialog_description, newVersion)
|
||||||
|
)
|
||||||
|
ListItem(
|
||||||
|
modifier = Modifier.clickable { dontShowAgain = !dontShowAgain },
|
||||||
|
headlineContent = {
|
||||||
|
Text(stringResource(R.string.never_show_again))
|
||||||
|
},
|
||||||
|
leadingContent = {
|
||||||
|
CompositionLocalProvider(LocalMinimumInteractiveComponentEnforcement provides false) {
|
||||||
|
Checkbox(checked = dontShowAgain, onCheckedChange = { dontShowAgain = it })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
textHorizontalPadding = PaddingValues(0.dp)
|
||||||
|
)
|
||||||
|
}
|
|
@ -6,43 +6,17 @@ import android.net.Uri
|
||||||
import android.provider.Settings
|
import android.provider.Settings
|
||||||
import androidx.activity.compose.BackHandler
|
import androidx.activity.compose.BackHandler
|
||||||
import androidx.compose.foundation.ExperimentalFoundationApi
|
import androidx.compose.foundation.ExperimentalFoundationApi
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.*
|
||||||
import androidx.compose.foundation.layout.Column
|
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
|
||||||
import androidx.compose.foundation.layout.padding
|
|
||||||
import androidx.compose.foundation.pager.HorizontalPager
|
import androidx.compose.foundation.pager.HorizontalPager
|
||||||
import androidx.compose.foundation.pager.rememberPagerState
|
import androidx.compose.foundation.pager.rememberPagerState
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.filled.Add
|
import androidx.compose.material.icons.filled.Add
|
||||||
import androidx.compose.material.icons.filled.BatteryAlert
|
import androidx.compose.material.icons.filled.BatteryAlert
|
||||||
import androidx.compose.material.icons.filled.Close
|
import androidx.compose.material.icons.filled.Close
|
||||||
import androidx.compose.material.icons.outlined.Apps
|
import androidx.compose.material.icons.outlined.*
|
||||||
import androidx.compose.material.icons.outlined.DeleteOutline
|
import androidx.compose.material3.*
|
||||||
import androidx.compose.material.icons.outlined.Refresh
|
import androidx.compose.runtime.*
|
||||||
import androidx.compose.material.icons.outlined.Settings
|
|
||||||
import androidx.compose.material.icons.outlined.Source
|
|
||||||
import androidx.compose.material.icons.outlined.Update
|
|
||||||
import androidx.compose.material.icons.outlined.WarningAmber
|
|
||||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
|
||||||
import androidx.compose.material3.FloatingActionButton
|
|
||||||
import androidx.compose.material3.Icon
|
|
||||||
import androidx.compose.material3.IconButton
|
|
||||||
import androidx.compose.material3.MaterialTheme
|
|
||||||
import androidx.compose.material3.Scaffold
|
|
||||||
import androidx.compose.material3.Tab
|
|
||||||
import androidx.compose.material3.TabRow
|
|
||||||
import androidx.compose.material3.Text
|
|
||||||
import androidx.compose.material3.TextButton
|
|
||||||
import androidx.compose.material3.surfaceColorAtElevation
|
|
||||||
import androidx.compose.runtime.Composable
|
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
|
||||||
import androidx.compose.runtime.derivedStateOf
|
|
||||||
import androidx.compose.runtime.getValue
|
|
||||||
import androidx.compose.runtime.mutableStateOf
|
|
||||||
import androidx.compose.runtime.remember
|
|
||||||
import androidx.compose.runtime.rememberCoroutineScope
|
|
||||||
import androidx.compose.runtime.saveable.rememberSaveable
|
import androidx.compose.runtime.saveable.rememberSaveable
|
||||||
import androidx.compose.runtime.setValue
|
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.graphics.vector.ImageVector
|
import androidx.compose.ui.graphics.vector.ImageVector
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
|
@ -55,6 +29,7 @@ import app.revanced.manager.domain.bundles.PatchBundleSource.Extensions.isDefaul
|
||||||
import app.revanced.manager.patcher.aapt.Aapt
|
import app.revanced.manager.patcher.aapt.Aapt
|
||||||
import app.revanced.manager.ui.component.AppTopBar
|
import app.revanced.manager.ui.component.AppTopBar
|
||||||
import app.revanced.manager.ui.component.AutoUpdatesDialog
|
import app.revanced.manager.ui.component.AutoUpdatesDialog
|
||||||
|
import app.revanced.manager.ui.component.AvailableUpdateDialog
|
||||||
import app.revanced.manager.ui.component.NotificationCard
|
import app.revanced.manager.ui.component.NotificationCard
|
||||||
import app.revanced.manager.ui.component.bundle.BundleItem
|
import app.revanced.manager.ui.component.bundle.BundleItem
|
||||||
import app.revanced.manager.ui.component.bundle.BundleTopBar
|
import app.revanced.manager.ui.component.bundle.BundleTopBar
|
||||||
|
@ -113,6 +88,20 @@ fun DashboardScreen(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var showDialog by rememberSaveable { mutableStateOf(vm.prefs.showManagerUpdateDialogOnLaunch.getBlocking()) }
|
||||||
|
val availableUpdate by remember {
|
||||||
|
derivedStateOf { vm.updatedManagerVersion.takeIf { showDialog } }
|
||||||
|
}
|
||||||
|
|
||||||
|
availableUpdate?.let { version ->
|
||||||
|
AvailableUpdateDialog(
|
||||||
|
onDismiss = { showDialog = false },
|
||||||
|
setShowManagerUpdateDialogOnLaunch = vm::setShowManagerUpdateDialogOnLaunch,
|
||||||
|
onConfirm = onUpdateClick,
|
||||||
|
newVersion = version
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
Scaffold(
|
Scaffold(
|
||||||
topBar = {
|
topBar = {
|
||||||
if (bundlesSelectable) {
|
if (bundlesSelectable) {
|
||||||
|
@ -154,6 +143,23 @@ fun DashboardScreen(
|
||||||
AppTopBar(
|
AppTopBar(
|
||||||
title = stringResource(R.string.app_name),
|
title = stringResource(R.string.app_name),
|
||||||
actions = {
|
actions = {
|
||||||
|
if (!vm.updatedManagerVersion.isNullOrEmpty()) {
|
||||||
|
IconButton(
|
||||||
|
onClick = onUpdateClick,
|
||||||
|
) {
|
||||||
|
BadgedBox(
|
||||||
|
badge = {
|
||||||
|
Badge(
|
||||||
|
// A size value above 6.dp forces the Badge icon to be closer to the center, fixing a clipping issue
|
||||||
|
modifier = Modifier.size(7.dp),
|
||||||
|
containerColor = MaterialTheme.colorScheme.primary,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
) {
|
||||||
|
Icon(Icons.Outlined.Update, stringResource(R.string.update))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
IconButton(onClick = onSettingsClick) {
|
IconButton(onClick = onSettingsClick) {
|
||||||
Icon(Icons.Outlined.Settings, stringResource(R.string.settings))
|
Icon(Icons.Outlined.Settings, stringResource(R.string.settings))
|
||||||
}
|
}
|
||||||
|
@ -230,23 +236,7 @@ fun DashboardScreen(
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
} else null,
|
} else null
|
||||||
vm.updatedManagerVersion?.let {
|
|
||||||
{
|
|
||||||
NotificationCard(
|
|
||||||
text = stringResource(R.string.update_available_dialog_description, it),
|
|
||||||
icon = Icons.Outlined.Update,
|
|
||||||
actions = {
|
|
||||||
TextButton(onClick = vm::dismissUpdateDialog) {
|
|
||||||
Text(stringResource(R.string.dismiss))
|
|
||||||
}
|
|
||||||
TextButton(onClick = onUpdateClick) {
|
|
||||||
Text(stringResource(R.string.show))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
|
|
||||||
HorizontalPager(
|
HorizontalPager(
|
||||||
|
|
|
@ -64,6 +64,12 @@ fun UpdatesSettingsScreen(
|
||||||
headline = R.string.update_checking_manager,
|
headline = R.string.update_checking_manager,
|
||||||
description = R.string.update_checking_manager_description
|
description = R.string.update_checking_manager_description
|
||||||
)
|
)
|
||||||
|
|
||||||
|
BooleanItem(
|
||||||
|
preference = vm.showManagerUpdateDialogOnLaunch,
|
||||||
|
headline = R.string.show_manager_update_dialog_on_launch,
|
||||||
|
description = R.string.update_checking_manager_description
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -64,6 +64,12 @@ class DashboardViewModel(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun setShowManagerUpdateDialogOnLaunch(value: Boolean) {
|
||||||
|
viewModelScope.launch {
|
||||||
|
prefs.showManagerUpdateDialogOnLaunch.update(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun applyAutoUpdatePrefs(manager: Boolean, patches: Boolean) = viewModelScope.launch {
|
fun applyAutoUpdatePrefs(manager: Boolean, patches: Boolean) = viewModelScope.launch {
|
||||||
prefs.firstLaunch.update(false)
|
prefs.firstLaunch.update(false)
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,7 @@ class UpdatesSettingsViewModel(
|
||||||
private val reVancedAPI: ReVancedAPI,
|
private val reVancedAPI: ReVancedAPI,
|
||||||
) : ViewModel() {
|
) : ViewModel() {
|
||||||
val managerAutoUpdates = prefs.managerAutoUpdates
|
val managerAutoUpdates = prefs.managerAutoUpdates
|
||||||
|
val showManagerUpdateDialogOnLaunch = prefs.showManagerUpdateDialogOnLaunch
|
||||||
|
|
||||||
suspend fun checkForUpdates(): Boolean {
|
suspend fun checkForUpdates(): Boolean {
|
||||||
uiSafe(app, R.string.failed_to_check_updates, "Failed to check for updates") {
|
uiSafe(app, R.string.failed_to_check_updates, "Failed to check for updates") {
|
||||||
|
|
|
@ -367,4 +367,8 @@
|
||||||
<string name="add_patch_bundle">Add patch bundle</string>
|
<string name="add_patch_bundle">Add patch bundle</string>
|
||||||
<string name="bundle_url">Bundle URL</string>
|
<string name="bundle_url">Bundle URL</string>
|
||||||
<string name="auto_update">Auto update</string>
|
<string name="auto_update">Auto update</string>
|
||||||
|
<string name="never_show_again">Never show again</string>
|
||||||
|
<string name="show_manager_update_dialog_on_launch">Show update message on launch</string>
|
||||||
|
<string name="show_manager_update_dialog_on_launch_description">Shows a popup notification whenever there is a new update available on launch.</string>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
|
|
Loading…
Reference in a new issue