Skip to content

Commit 94ab699

Browse files
Axelen123oSumAtrIX
authored andcommitted
feat: add network checks for features that require it
1 parent 1319a03 commit 94ab699

File tree

8 files changed

+97
-8
lines changed

8 files changed

+97
-8
lines changed

app/src/main/java/app/revanced/manager/ui/component/bundle/BundleInformationDialog.kt

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,15 @@ import androidx.compose.ui.window.Dialog
1616
import androidx.compose.ui.window.DialogProperties
1717
import androidx.lifecycle.compose.collectAsStateWithLifecycle
1818
import app.revanced.manager.R
19+
import app.revanced.manager.data.platform.NetworkInfo
1920
import app.revanced.manager.domain.bundles.LocalPatchBundle
2021
import app.revanced.manager.domain.bundles.PatchBundleSource
2122
import app.revanced.manager.domain.bundles.PatchBundleSource.Extensions.asRemoteOrNull
2223
import app.revanced.manager.domain.bundles.PatchBundleSource.Extensions.isDefault
2324
import app.revanced.manager.domain.bundles.PatchBundleSource.Extensions.nameState
2425
import app.revanced.manager.ui.component.ExceptionViewerDialog
2526
import kotlinx.coroutines.launch
27+
import org.koin.compose.koinInject
2628

2729
@OptIn(ExperimentalMaterial3Api::class)
2830
@Composable
@@ -32,6 +34,8 @@ fun BundleInformationDialog(
3234
bundle: PatchBundleSource,
3335
onUpdate: () -> Unit,
3436
) {
37+
val networkInfo = koinInject<NetworkInfo>()
38+
val hasNetwork = remember { networkInfo.isConnected() }
3539
val composableScope = rememberCoroutineScope()
3640
var viewCurrentBundlePatches by remember { mutableStateOf(false) }
3741
val isLocal = bundle is LocalPatchBundle
@@ -81,7 +85,7 @@ fun BundleInformationDialog(
8185
)
8286
}
8387
}
84-
if (!isLocal) {
88+
if (!isLocal && hasNetwork) {
8589
IconButton(onClick = onUpdate) {
8690
Icon(
8791
Icons.Outlined.Update,

app/src/main/java/app/revanced/manager/ui/screen/SelectedAppInfoScreen.kt

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ import androidx.activity.compose.rememberLauncherForActivityResult
44
import androidx.activity.result.contract.ActivityResultContracts
55
import androidx.annotation.StringRes
66
import androidx.compose.foundation.clickable
7+
import androidx.compose.foundation.layout.Arrangement
8+
import androidx.compose.foundation.layout.Column
79
import androidx.compose.foundation.layout.PaddingValues
810
import androidx.compose.foundation.layout.fillMaxSize
911
import androidx.compose.foundation.layout.padding
@@ -12,6 +14,7 @@ import androidx.compose.foundation.lazy.items
1214
import androidx.compose.material.icons.Icons
1315
import androidx.compose.material.icons.automirrored.outlined.ArrowRight
1416
import androidx.compose.material.icons.filled.AutoFixHigh
17+
import androidx.compose.material.icons.outlined.WarningAmber
1518
import androidx.compose.material3.ExperimentalMaterial3Api
1619
import androidx.compose.material3.Icon
1720
import androidx.compose.material3.ListItem
@@ -32,6 +35,7 @@ import androidx.compose.ui.res.stringResource
3235
import androidx.compose.ui.unit.dp
3336
import androidx.lifecycle.compose.collectAsStateWithLifecycle
3437
import app.revanced.manager.R
38+
import app.revanced.manager.data.platform.NetworkInfo
3539
import app.revanced.manager.data.room.apps.installed.InstallType
3640
import app.revanced.manager.data.room.apps.installed.InstalledApp
3741
import app.revanced.manager.network.downloader.LoadedDownloaderPlugin
@@ -40,6 +44,7 @@ import app.revanced.manager.ui.component.AppInfo
4044
import app.revanced.manager.ui.component.AppTopBar
4145
import app.revanced.manager.ui.component.ColumnWithScrollbar
4246
import app.revanced.manager.ui.component.LoadingIndicator
47+
import app.revanced.manager.ui.component.NotificationCard
4348
import app.revanced.manager.ui.component.haptics.HapticExtendedFloatingActionButton
4449
import app.revanced.manager.ui.model.SelectedApp
4550
import app.revanced.manager.ui.viewmodel.SelectedAppInfoViewModel
@@ -50,6 +55,7 @@ import app.revanced.manager.util.enabled
5055
import app.revanced.manager.util.toast
5156
import app.revanced.manager.util.transparentListItemColors
5257
import kotlinx.coroutines.launch
58+
import org.koin.compose.koinInject
5359

5460
@OptIn(ExperimentalMaterial3Api::class)
5561
@Composable
@@ -61,6 +67,9 @@ fun SelectedAppInfoScreen(
6167
vm: SelectedAppInfoViewModel
6268
) {
6369
val context = LocalContext.current
70+
val networkInfo = koinInject<NetworkInfo>()
71+
val networkConnected = remember { networkInfo.isConnected() }
72+
val networkMetered = remember { !networkInfo.isUnmetered() }
6473

6574
val packageName = vm.selectedApp.packageName
6675
val version = vm.selectedApp.version
@@ -208,6 +217,35 @@ fun SelectedAppInfoScreen(
208217
modifier = Modifier.padding(horizontal = 24.dp)
209218
)
210219
}
220+
221+
Column(
222+
modifier = Modifier.padding(horizontal = 24.dp),
223+
verticalArrangement = Arrangement.spacedBy(16.dp)
224+
) {
225+
val needsInternet =
226+
vm.selectedApp.let { it is SelectedApp.Search || it is SelectedApp.Download }
227+
228+
when {
229+
!needsInternet -> {}
230+
!networkConnected -> {
231+
NotificationCard(
232+
isWarning = true,
233+
icon = Icons.Outlined.WarningAmber,
234+
text = stringResource(R.string.network_unavailable_warning),
235+
onDismiss = null
236+
)
237+
}
238+
239+
networkMetered -> {
240+
NotificationCard(
241+
isWarning = true,
242+
icon = Icons.Outlined.WarningAmber,
243+
text = stringResource(R.string.network_metered_warning),
244+
onDismiss = null
245+
)
246+
}
247+
}
248+
}
211249
}
212250
}
213251
}

app/src/main/java/app/revanced/manager/ui/screen/settings/AboutSettingsScreen.kt

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ import app.revanced.manager.ui.model.navigation.Settings
4444
import app.revanced.manager.ui.viewmodel.AboutViewModel
4545
import app.revanced.manager.ui.viewmodel.AboutViewModel.Companion.getSocialIcon
4646
import app.revanced.manager.util.openUrl
47+
import app.revanced.manager.util.toast
4748
import com.google.accompanist.drawablepainter.rememberDrawablePainter
4849
import org.koin.androidx.compose.koinViewModel
4950

@@ -116,7 +117,14 @@ fun AboutSettingsScreen(
116117
Triple(
117118
stringResource(R.string.contributors),
118119
stringResource(R.string.contributors_description),
119-
third = { navigate(Settings.Contributors) }
120+
third = nav@{
121+
if (!viewModel.isConnected) {
122+
context.toast(context.getString(R.string.no_network_toast))
123+
return@nav
124+
}
125+
126+
navigate(Settings.Contributors)
127+
}
120128
),
121129
Triple(
122130
stringResource(R.string.developer_options),

app/src/main/java/app/revanced/manager/ui/screen/settings/ContributorScreen.kt

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,14 @@ fun ContributorScreen(
9797
)
9898
}
9999
}
100-
} ?: item { LoadingIndicator() }
100+
} ?: item {
101+
Row(
102+
modifier = Modifier.fillMaxWidth(),
103+
horizontalArrangement = Arrangement.Center
104+
) {
105+
LoadingIndicator()
106+
}
107+
}
101108
}
102109
}
103110
}

app/src/main/java/app/revanced/manager/ui/screen/settings/update/UpdatesSettingsScreen.kt

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,15 @@ import androidx.compose.runtime.Composable
1111
import androidx.compose.runtime.rememberCoroutineScope
1212
import androidx.compose.ui.Modifier
1313
import androidx.compose.ui.input.nestedscroll.nestedScroll
14+
import androidx.compose.ui.platform.LocalContext
1415
import androidx.compose.ui.res.stringResource
1516
import app.revanced.manager.R
1617
import app.revanced.manager.ui.component.AppTopBar
1718
import app.revanced.manager.ui.component.ColumnWithScrollbar
1819
import app.revanced.manager.ui.component.settings.BooleanItem
1920
import app.revanced.manager.ui.component.settings.SettingsListItem
2021
import app.revanced.manager.ui.viewmodel.UpdatesSettingsViewModel
22+
import app.revanced.manager.util.toast
2123
import kotlinx.coroutines.launch
2224
import org.koin.androidx.compose.koinViewModel
2325

@@ -29,6 +31,7 @@ fun UpdatesSettingsScreen(
2931
onUpdateClick: () -> Unit,
3032
vm: UpdatesSettingsViewModel = koinViewModel(),
3133
) {
34+
val context = LocalContext.current
3235
val coroutineScope = rememberCoroutineScope()
3336
val scrollBehavior = TopAppBarDefaults.pinnedScrollBehavior(rememberTopAppBarState())
3437

@@ -50,6 +53,10 @@ fun UpdatesSettingsScreen(
5053
SettingsListItem(
5154
modifier = Modifier.clickable {
5255
coroutineScope.launch {
56+
if (!vm.isConnected) {
57+
context.toast(context.getString(R.string.no_network_toast))
58+
return@launch
59+
}
5360
if (vm.checkForUpdates()) onUpdateClick()
5461
}
5562
},
@@ -58,7 +65,13 @@ fun UpdatesSettingsScreen(
5865
)
5966

6067
SettingsListItem(
61-
modifier = Modifier.clickable(onClick = onChangelogClick),
68+
modifier = Modifier.clickable {
69+
if (!vm.isConnected) {
70+
context.toast(context.getString(R.string.no_network_toast))
71+
return@clickable
72+
}
73+
onChangelogClick()
74+
},
6275
headlineContent = stringResource(R.string.changelog),
6376
supportingContent = stringResource(
6477
R.string.changelog_description

app/src/main/java/app/revanced/manager/ui/viewmodel/AboutViewModel.kt

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import androidx.compose.runtime.mutableStateOf
77
import androidx.compose.runtime.setValue
88
import androidx.lifecycle.ViewModel
99
import androidx.lifecycle.viewModelScope
10+
import app.revanced.manager.data.platform.NetworkInfo
1011
import app.revanced.manager.network.api.ReVancedAPI
1112
import app.revanced.manager.network.dto.ReVancedDonationLink
1213
import app.revanced.manager.network.dto.ReVancedSocial
@@ -23,16 +24,24 @@ import kotlinx.coroutines.Dispatchers
2324
import kotlinx.coroutines.launch
2425
import kotlinx.coroutines.withContext
2526

26-
class AboutViewModel(private val reVancedAPI: ReVancedAPI) : ViewModel() {
27+
class AboutViewModel(
28+
private val reVancedAPI: ReVancedAPI,
29+
private val network: NetworkInfo,
30+
) : ViewModel() {
2731
var socials by mutableStateOf(emptyList<ReVancedSocial>())
28-
private set
32+
private set
2933
var contact by mutableStateOf<String?>(null)
30-
private set
34+
private set
3135
var donate by mutableStateOf<String?>(null)
32-
private set
36+
private set
37+
val isConnected: Boolean
38+
get() = network.isConnected()
3339

3440
init {
3541
viewModelScope.launch {
42+
if (!isConnected) {
43+
return@launch
44+
}
3645
withContext(Dispatchers.IO) {
3746
reVancedAPI.getInfo("https://api.revanced.app").getOrNull()
3847
}?.let {

app/src/main/java/app/revanced/manager/ui/viewmodel/UpdatesSettingsViewModel.kt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package app.revanced.manager.ui.viewmodel
33
import android.app.Application
44
import androidx.lifecycle.ViewModel
55
import app.revanced.manager.R
6+
import app.revanced.manager.data.platform.NetworkInfo
67
import app.revanced.manager.domain.manager.PreferencesManager
78
import app.revanced.manager.network.api.ReVancedAPI
89
import app.revanced.manager.util.toast
@@ -12,10 +13,14 @@ class UpdatesSettingsViewModel(
1213
prefs: PreferencesManager,
1314
private val app: Application,
1415
private val reVancedAPI: ReVancedAPI,
16+
private val network: NetworkInfo,
1517
) : ViewModel() {
1618
val managerAutoUpdates = prefs.managerAutoUpdates
1719
val showManagerUpdateDialogOnLaunch = prefs.showManagerUpdateDialogOnLaunch
1820

21+
val isConnected: Boolean
22+
get() = network.isConnected()
23+
1924
suspend fun checkForUpdates(): Boolean {
2025
uiSafe(app, R.string.failed_to_check_updates, "Failed to check for updates") {
2126
app.toast(app.getString(R.string.update_check))

app/src/main/res/values/strings.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@
3838
<string name="android_11_bug_dialog_title">Android 11 bug</string>
3939
<string name="android_11_bug_dialog_description">The app installation permission must be granted ahead of time to avoid a bug in the Android 11 system that will negatively affect the user experience.</string>
4040

41+
<string name="no_network_toast">No internet connection available</string>
42+
4143
<string name="selected_app_meta_any_version">Any available version</string>
4244
<string name="app_source_dialog_title">Select source</string>
4345
<string name="app_source_dialog_option_auto">Auto</string>
@@ -51,6 +53,9 @@
5153
<string name="patch_selector_item_description">%d patches selected</string>
5254
<string name="no_patches_selected">No patches selected</string>
5355

56+
<string name="network_unavailable_warning">Your device is not connected to the internet. Downloading will fail later.</string>
57+
<string name="network_metered_warning">You are currently on a metered connection. Data charges from your service provider may apply.</string>
58+
5459
<string name="apk_source_selector_item">Change source</string>
5560
<string name="apk_source_auto">Current: All downloaders</string>
5661
<string name="apk_source_downloader">Current: %s</string>

0 commit comments

Comments
 (0)