diff --git a/app/src/main/java/org/unifiedpush/distributor/sunup/AppStore.kt b/app/src/main/java/org/unifiedpush/distributor/sunup/AppStore.kt index 026cdd7..ababc19 100644 --- a/app/src/main/java/org/unifiedpush/distributor/sunup/AppStore.kt +++ b/app/src/main/java/org/unifiedpush/distributor/sunup/AppStore.kt @@ -20,6 +20,17 @@ class AppStore(context: Context) : Store(context, PREF_NAME) { .putOrRemove(PREF_API_URL, value) .apply() + /** + * Show toasts when a new app is registered or an error occurred + */ + var showToasts: Boolean + get() = sharedPreferences + .getBoolean(PREF_SHOW_TOASTS, false) + set(value) = sharedPreferences + .edit() + .putBoolean(PREF_SHOW_TOASTS, value) + .apply() + override fun wipe() { uaid = null } @@ -28,5 +39,6 @@ class AppStore(context: Context) : Store(context, PREF_NAME) { internal const val PREF_NAME = "Sunup" private const val PREF_UAID = "uaid" private const val PREF_API_URL = "api_url" + private const val PREF_SHOW_TOASTS = "show_toasts" } } diff --git a/app/src/main/java/org/unifiedpush/distributor/sunup/activities/AppAction.kt b/app/src/main/java/org/unifiedpush/distributor/sunup/activities/AppAction.kt index 427702a..411b714 100644 --- a/app/src/main/java/org/unifiedpush/distributor/sunup/activities/AppAction.kt +++ b/app/src/main/java/org/unifiedpush/distributor/sunup/activities/AppAction.kt @@ -5,6 +5,7 @@ import android.util.Log import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import kotlinx.coroutines.launch +import org.unifiedpush.distributor.sunup.AppStore import org.unifiedpush.distributor.sunup.Distributor import org.unifiedpush.distributor.sunup.EventBus import org.unifiedpush.distributor.sunup.api.ApiUrlCandidate @@ -17,6 +18,7 @@ class AppAction(private val action: Action) { sealed class Action { data object RestartService : Action() class NewPushServer(val url: String) : Action() + class ShowToasts(val enable: Boolean) : Action() class DeleteRegistration(val registrations: List) : Action() } @@ -24,6 +26,7 @@ class AppAction(private val action: Action) { when (action) { is Action.RestartService -> restartService(context) is Action.NewPushServer -> newPushServer(context, action) + is Action.ShowToasts -> showToasts(context, action) is Action.DeleteRegistration -> deleteRegistration(context, action) } } @@ -42,6 +45,10 @@ class AppAction(private val action: Action) { RestartWorker.run(context, delay = 0) } + private fun showToasts(context: Context, action: Action.ShowToasts) { + AppStore(context).showToasts = action.enable + } + private fun deleteRegistration(context: Context, action: Action.DeleteRegistration) { action.registrations.forEach { Distributor.deleteApp(context, it) {} diff --git a/app/src/main/java/org/unifiedpush/distributor/sunup/activities/AppBarViewModel.kt b/app/src/main/java/org/unifiedpush/distributor/sunup/activities/AppBarViewModel.kt index 118cd7b..908fc58 100644 --- a/app/src/main/java/org/unifiedpush/distributor/sunup/activities/AppBarViewModel.kt +++ b/app/src/main/java/org/unifiedpush/distributor/sunup/activities/AppBarViewModel.kt @@ -1,5 +1,6 @@ package org.unifiedpush.distributor.sunup.activities +import android.content.Context import android.util.Log import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf @@ -14,6 +15,10 @@ import org.unifiedpush.distributor.sunup.utils.TAG class AppBarViewModel(appBarUiState: AppBarUiState) : ViewModel() { + constructor(context: Context) : this( + AppBarUiState.from(context) + ) + var state by mutableStateOf(appBarUiState) fun toggleMenu() { @@ -49,4 +54,11 @@ class AppBarViewModel(appBarUiState: AppBarUiState) : ViewModel() { } } } + + fun toggleShowToasts() { + viewModelScope.launch { + state = state.copy(showToasts = !state.showToasts) + publishAction(AppAction(AppAction.Action.ShowToasts(state.showToasts))) + } + } } diff --git a/app/src/main/java/org/unifiedpush/distributor/sunup/activities/MainViewModel.kt b/app/src/main/java/org/unifiedpush/distributor/sunup/activities/MainViewModel.kt index fdf328a..775637f 100644 --- a/app/src/main/java/org/unifiedpush/distributor/sunup/activities/MainViewModel.kt +++ b/app/src/main/java/org/unifiedpush/distributor/sunup/activities/MainViewModel.kt @@ -13,7 +13,6 @@ import org.unifiedpush.android.distributor.ui.compose.BatteryOptimisationViewMod import org.unifiedpush.android.distributor.ui.compose.RegistrationsViewModel import org.unifiedpush.android.distributor.ui.compose.state.RegistrationListState import org.unifiedpush.distributor.sunup.AppStore -import org.unifiedpush.distributor.sunup.activities.ui.AppBarUiState import org.unifiedpush.distributor.sunup.activities.ui.MainUiState class MainViewModel( @@ -24,7 +23,7 @@ class MainViewModel( ) : ViewModel() { constructor(context: Context) : this( mainUiState = MainUiState(), - appBarViewModel = AppBarViewModel(AppBarUiState(AppStore(context).apiUrl)), + appBarViewModel = AppBarViewModel(context), batteryOptimisationViewModel = BatteryOptimisationViewModel(context), registrationsViewModel = RegistrationsViewModel( getRegistrationListState(context) @@ -51,7 +50,7 @@ class MainViewModel( fun refreshApiUrl(context: Context) { viewModelScope.launch { - appBarViewModel.state = AppBarUiState(AppStore(context).apiUrl) + appBarViewModel.state = appBarViewModel.state.copy(currentApiUrl = AppStore(context).apiUrl) } } diff --git a/app/src/main/java/org/unifiedpush/distributor/sunup/activities/ui/AppBarUi.kt b/app/src/main/java/org/unifiedpush/distributor/sunup/activities/ui/AppBarUi.kt index 333c1a3..689d156 100644 --- a/app/src/main/java/org/unifiedpush/distributor/sunup/activities/ui/AppBarUi.kt +++ b/app/src/main/java/org/unifiedpush/distributor/sunup/activities/ui/AppBarUi.kt @@ -1,7 +1,10 @@ package org.unifiedpush.distributor.sunup.activities.ui +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.MoreVert +import androidx.compose.material3.Checkbox import androidx.compose.material3.DropdownMenu import androidx.compose.material3.DropdownMenuItem import androidx.compose.material3.ExperimentalMaterial3Api @@ -12,6 +15,8 @@ import androidx.compose.material3.Text import androidx.compose.material3.TopAppBar import androidx.compose.material3.TopAppBarDefaults import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource import org.unifiedpush.android.distributor.ui.R as LibR import org.unifiedpush.distributor.sunup.R @@ -48,6 +53,7 @@ fun AppBarUi(appBarViewModel: AppBarViewModel) { } Dropdown( state.menuExpanded, + state.showToasts, onRestart = { appBarViewModel.publishAction(AppAction(AppAction.Action.RestartService)) appBarViewModel.toggleMenu() @@ -57,6 +63,9 @@ fun AppBarUi(appBarViewModel: AppBarViewModel) { }, onChangeServer = { appBarViewModel.toggleChangeServer() + }, + onToggleShowToasts = { + appBarViewModel.toggleShowToasts() } ) } @@ -72,7 +81,14 @@ fun AppBarUi(appBarViewModel: AppBarViewModel) { } @Composable -fun Dropdown(expanded: Boolean, onRestart: () -> Unit, onDismiss: () -> Unit, onChangeServer: () -> Unit) { +fun Dropdown( + expanded: Boolean, + showToasts: Boolean, + onRestart: () -> Unit, + onDismiss: () -> Unit, + onChangeServer: () -> Unit, + onToggleShowToasts: () -> Unit +) { DropdownMenu( expanded = expanded, onDismissRequest = onDismiss @@ -94,5 +110,18 @@ fun Dropdown(expanded: Boolean, onRestart: () -> Unit, onDismiss: () -> Unit, on ) } ) + DropdownMenuItem( + onClick = onToggleShowToasts, + text = { + Row(verticalAlignment = Alignment.CenterVertically) { + Text(stringResource(LibR.string.app_dropdown_show_toasts)) + Spacer(Modifier.weight(1f)) + Checkbox( + showToasts, + onCheckedChange = { onToggleShowToasts() } + ) + } + } + ) } } diff --git a/app/src/main/java/org/unifiedpush/distributor/sunup/activities/ui/AppBarUiState.kt b/app/src/main/java/org/unifiedpush/distributor/sunup/activities/ui/AppBarUiState.kt index 0e165d6..50b8a52 100644 --- a/app/src/main/java/org/unifiedpush/distributor/sunup/activities/ui/AppBarUiState.kt +++ b/app/src/main/java/org/unifiedpush/distributor/sunup/activities/ui/AppBarUiState.kt @@ -1,7 +1,21 @@ package org.unifiedpush.distributor.sunup.activities.ui +import android.content.Context +import org.unifiedpush.distributor.sunup.AppStore + data class AppBarUiState( val currentApiUrl: String, + val showToasts: Boolean, val menuExpanded: Boolean = false, val showChangeServerDialog: Boolean = false -) +) { + companion object { + fun from(context: Context): AppBarUiState { + val store = AppStore(context) + return AppBarUiState( + store.apiUrl, + store.showToasts + ) + } + } +} diff --git a/app/src/main/java/org/unifiedpush/distributor/sunup/activities/ui/MainUi.kt b/app/src/main/java/org/unifiedpush/distributor/sunup/activities/ui/MainUi.kt index 8eb2bed..8c8ed5c 100644 --- a/app/src/main/java/org/unifiedpush/distributor/sunup/activities/ui/MainUi.kt +++ b/app/src/main/java/org/unifiedpush/distributor/sunup/activities/ui/MainUi.kt @@ -161,7 +161,7 @@ fun MainPreview() { MainUi( MainViewModel( MainUiState(), - AppBarViewModel(AppBarUiState(BuildConfig.DEFAULT_API_URL)), + AppBarViewModel(AppBarUiState(BuildConfig.DEFAULT_API_URL, false)), BatteryOptimisationViewModel(true), RegistrationsViewModel(RegistrationListState(regList)) ) diff --git a/app/src/main/java/org/unifiedpush/distributor/sunup/receivers/RegisterBroadcastReceiver.kt b/app/src/main/java/org/unifiedpush/distributor/sunup/receivers/RegisterBroadcastReceiver.kt index 58539eb..516f727 100644 --- a/app/src/main/java/org/unifiedpush/distributor/sunup/receivers/RegisterBroadcastReceiver.kt +++ b/app/src/main/java/org/unifiedpush/distributor/sunup/receivers/RegisterBroadcastReceiver.kt @@ -4,6 +4,7 @@ package org.unifiedpush.distributor.sunup.receivers import android.content.Context import org.unifiedpush.distributor.receiver.DistributorReceiver +import org.unifiedpush.distributor.sunup.AppStore import org.unifiedpush.distributor.sunup.Distributor import org.unifiedpush.distributor.sunup.callback.NetworkCallbackFactory @@ -22,4 +23,8 @@ class RegisterBroadcastReceiver : DistributorReceiver() { override fun hasInternet(context: Context): Boolean { return NetworkCallbackFactory.hasInternet() } + + override fun showToasts(context: Context): Boolean { + return AppStore(context).showToasts + } }