Skip to content

Commit

Permalink
Fix stuff
Browse files Browse the repository at this point in the history
  • Loading branch information
w2sv committed Apr 12, 2023
1 parent 8edf1fd commit ec834fa
Show file tree
Hide file tree
Showing 12 changed files with 78 additions and 85 deletions.
52 changes: 35 additions & 17 deletions app/src/main/kotlin/com/w2sv/wifiwidget/ui/NonAppliedState.kt
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,19 @@ import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.merge
import kotlinx.coroutines.flow.transform
import kotlinx.coroutines.launch

abstract class NonAppliedState<T> {
val stateChanged = MutableStateFlow(false)

protected fun resetStateChanged() {
protected fun resetStateChanged(){
stateChanged.value = false
}

abstract val value: T
abstract suspend fun apply()
abstract suspend fun sync()
abstract fun reset()
}

Expand All @@ -31,15 +33,16 @@ class NonAppliedSnapshotStateMap<K : DataStoreProperty<V>, V>(
private val map: SnapshotStateMap<K, V> = appliedFlowMap
.getDeflowedMap()
.getMutableStateMap(),
private val onApplyState: (Map<K, V>) -> Unit = {}
private val onStateSynced: (Map<K, V>) -> Unit = {}
) : NonAppliedState<Map<K, V>>(),
MutableMap<K, V> by map {

override val value: Map<K, V> get() = this

override suspend fun apply() {
override suspend fun sync() {
dataStoreRepository.saveMap(value)
onApplyState(value)
onStateSynced(value)
dissimilarKeys.clear()
resetStateChanged()
}

Expand All @@ -49,6 +52,7 @@ class NonAppliedSnapshotStateMap<K : DataStoreProperty<V>, V>(
map[k] = v.first()
}
}
dissimilarKeys.clear()
resetStateChanged()
}

Expand All @@ -70,7 +74,7 @@ class NonAppliedSnapshotStateMap<K : DataStoreProperty<V>, V>(
class NonAppliedStateFlow<T>(
private val coroutineScope: CoroutineScope,
private val appliedFlow: Flow<T>,
private val updateAppliedState: (T) -> Unit
private val syncState: (T) -> Unit
) : NonAppliedState<T>(),
MutableStateFlow<T> by MutableStateFlow(
appliedFlow.getValueSynchronously()
Expand All @@ -84,8 +88,8 @@ class NonAppliedStateFlow<T>(
}
}

override suspend fun apply() {
updateAppliedState(value)
override suspend fun sync() {
syncState(value)
resetStateChanged()
}

Expand All @@ -102,27 +106,41 @@ class CoherentNonAppliedStates(
coroutineScope: CoroutineScope
) : List<NonAppliedState<*>> by nonAppliedState.asList() {

val requiringUpdate = MutableStateFlow(false)
val stateChanged = MutableStateFlow(false)

private val changedStateIndices = mutableSetOf<Int>()

init {
forEach {
coroutineScope.launch {
it.stateChanged.collect {
requiringUpdate.value = any { it.stateChanged.value }
coroutineScope.launch {
mapIndexed { i, it -> it.stateChanged.transform { emit(it to i) } }
.merge()
.collect { (stateChanged, i) ->
if (stateChanged) {
changedStateIndices.add(i)
} else {
changedStateIndices.remove(i)
}

this@CoherentNonAppliedStates.stateChanged.value = changedStateIndices.isNotEmpty()
}
}
}
}

suspend fun apply() {
suspend fun sync() {
forEach {
it.apply()
if (it.stateChanged.value) {
it.sync()
}
}
changedStateIndices.clear()
}

fun reset() {
forEach {
it.reset()
if (it.stateChanged.value) {
it.reset()
}
}
changedStateIndices.clear()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ internal fun HomeScreen(
}
}
viewModel.lapDialogTrigger.collectAsState().value?.let {
LocationAccessPermissionDialog(it)
LocationAccessPermissionRationalDialog(it)
}
viewModel.lapRequestTrigger.collectAsState().value?.let {
LocationAccessPermissionRequest(it)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ class HomeScreenViewModel @Inject constructor(
dataStoreRepository.inAppTheme
) {
viewModelScope.launch {
dataStoreRepository.saveEnum(it, PreferencesKey.IN_APP_THEME)
dataStoreRepository.saveEnum(PreferencesKey.IN_APP_THEME, it)
}
}

Expand Down Expand Up @@ -79,8 +79,8 @@ class HomeScreenViewModel @Inject constructor(
fun onLAPDialogAnswered() {
viewModelScope.launch {
dataStoreRepository.save(
true,
PreferencesKey.LOCATION_ACCESS_PERMISSION_DIALOG_ANSWERED
PreferencesKey.LOCATION_ACCESS_PERMISSION_DIALOG_ANSWERED,
true
)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import com.w2sv.wifiwidget.ui.shared.WifiWidgetTheme
@Composable
private fun Prev() {
WifiWidgetTheme {
LocationAccessPermissionDialog(Modifier, "Proceed without SSID", {}, {})
LocationAccessPermissionRationalDialog(Modifier, "Proceed without SSID", {}, {})
}
}

Expand All @@ -36,7 +36,7 @@ enum class LocationAccessPermissionDialogTrigger {
}

@Composable
fun LocationAccessPermissionDialog(
fun LocationAccessPermissionRationalDialog(
trigger: LocationAccessPermissionDialogTrigger,
homeScreenViewModel: HomeScreenViewModel = viewModel(),
widgetConfigurationViewModel: WidgetConfigurationViewModel = viewModel()
Expand All @@ -45,7 +45,7 @@ fun LocationAccessPermissionDialog(

when (trigger) {
LocationAccessPermissionDialogTrigger.PinWidgetButtonPress -> {
LocationAccessPermissionDialog(
LocationAccessPermissionRationalDialog(
dismissButtonText = stringResource(R.string.proceed_without_ssid),
onConfirmButtonPressed = {
homeScreenViewModel.lapRequestTrigger.value = trigger
Expand All @@ -56,7 +56,7 @@ fun LocationAccessPermissionDialog(
)
}

LocationAccessPermissionDialogTrigger.SSIDCheck -> LocationAccessPermissionDialog(
LocationAccessPermissionDialogTrigger.SSIDCheck -> LocationAccessPermissionRationalDialog(
dismissButtonText = stringResource(R.string.never_mind),
onConfirmButtonPressed = {
homeScreenViewModel.lapRequestTrigger.value = trigger
Expand All @@ -69,7 +69,7 @@ fun LocationAccessPermissionDialog(
}

@Composable
private fun LocationAccessPermissionDialog(
private fun LocationAccessPermissionRationalDialog(
modifier: Modifier = Modifier,
dismissButtonText: String,
onConfirmButtonPressed: () -> Unit,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.lifecycle.viewmodel.compose.viewModel
import com.google.accompanist.permissions.ExperimentalPermissionsApi
import com.google.accompanist.permissions.rememberMultiplePermissionsState
Expand All @@ -31,7 +30,7 @@ fun LocationAccessPermissionRequest(
LocationAccessPermissionDialogTrigger.PinWidgetButtonPress -> LocationAccessPermissionRequest(
onGranted = {
widgetConfigurationViewModel.widgetPropertyStateMap[WifiProperty.SSID] = true
widgetConfigurationViewModel.widgetPropertyStateMap.apply()
widgetConfigurationViewModel.widgetPropertyStateMap.sync()
WidgetProvider.pinWidget(context)
},
onDenied = {
Expand Down Expand Up @@ -70,32 +69,31 @@ private fun LocationAccessPermissionRequest(
false -> onDenied()
}
homeScreenViewModel.lapRequestTrigger.reset()
homeScreenViewModel.dataStoreRepository.save(
true,
PreferencesKey.LOCATION_ACCESS_PERMISSION_REQUESTED_AT_LEAST_ONCE
)
}
}
)

when (permissionState.allPermissionsGranted) {
true -> LaunchedEffect(
key1 = permissionState.permissions,
block = { onGranted() }
)

false -> {
if (permissionState.launchingSuppressed(homeScreenViewModel.lapRequestLaunchedAtLeastOnce)) {
context.showToast(
stringResource(R.string.go_to_app_settings_and_grant_location_access_permission),
Toast.LENGTH_LONG
)
LaunchedEffect(key1 = permissionState.permissions) {
when (permissionState.allPermissionsGranted) {
true -> {
onGranted()
homeScreenViewModel.lapRequestTrigger.reset()
} else {
LaunchedEffect(
key1 = permissionState.permissions,
block = { permissionState.launchMultiplePermissionRequest() }
)
}

false -> {
if (permissionState.launchingSuppressed(homeScreenViewModel.lapRequestLaunchedAtLeastOnce)) {
context.showToast(
context.getString(R.string.go_to_app_settings_and_grant_location_access_permission),
Toast.LENGTH_LONG
)
homeScreenViewModel.lapRequestTrigger.reset()
} else {
permissionState.launchMultiplePermissionRequest()
homeScreenViewModel.dataStoreRepository.save(
PreferencesKey.LOCATION_ACCESS_PERMISSION_REQUESTED_AT_LEAST_ONCE,
true
)
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ fun StatefulNavigationDrawer(
onApplyButtonPress = {
setShowThemeDialog(false)
scope.launch {
homeScreenViewModel.inAppThemeState.apply()
homeScreenViewModel.inAppThemeState.sync()
context.showToast("Updated Theme")
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,15 @@ internal fun ButtonRow(
) {
val context = LocalContext.current
val scope = rememberCoroutineScope()
val applyButtonEnabled by widgetConfigurationViewModel.widgetConfigurationStates.requiringUpdate.collectAsState()
val applyButtonEnabled by widgetConfigurationViewModel.widgetConfigurationStates.stateChanged.collectAsState()

ButtonRow(
onCancel = {
widgetConfigurationViewModel.onDismissWidgetConfigurationDialog()
},
onApply = {
scope.launch {
widgetConfigurationViewModel.widgetConfigurationStates.apply()
widgetConfigurationViewModel.widgetConfigurationStates.sync()
WidgetProvider.triggerDataRefresh(context)
context.showToast(R.string.updated_widget_configuration)
widgetConfigurationViewModel.showWidgetConfigurationDialog.value = false
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ class WidgetConfigurationViewModel @Inject constructor(
dataStoreRepository.widgetTheme
) {
viewModelScope.launch {
dataStoreRepository.saveEnum(it, PreferencesKey.WIDGET_THEME)
dataStoreRepository.saveEnum(PreferencesKey.WIDGET_THEME, it)
}
}

Expand All @@ -83,7 +83,7 @@ class WidgetConfigurationViewModel @Inject constructor(
dataStoreRepository.opacity
) {
viewModelScope.launch {
dataStoreRepository.save(it, PreferencesKey.OPACITY)
dataStoreRepository.save(PreferencesKey.OPACITY, it)
}
}

Expand Down Expand Up @@ -116,18 +116,4 @@ class WidgetConfigurationViewModel @Inject constructor(
widgetConfigurationStates.reset()
showWidgetConfigurationDialog.value = false
}

/**
* @return Boolean indicating whether change has been confirmed
*/
fun confirmAndSyncPropertyChange(
property: WifiProperty,
value: Boolean,
onChangeRejected: () -> Unit
) {
when (value || widgetPropertyStateMap.values.count { true } != 1) {
true -> widgetPropertyStateMap[property] = value
false -> onChangeRejected()
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ private fun SectionCustomizationRow(
viewModel: WidgetConfigurationViewModel = androidx.lifecycle.viewmodel.compose.viewModel()
) {
val label = stringResource(id = widgetColorSection.labelRes)

Row(
modifier = modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.Start,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,13 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.lifecycle.viewmodel.compose.viewModel
import com.w2sv.androidutils.extensions.showToast
import com.w2sv.common.Theme
import com.w2sv.common.WidgetColorSection
import com.w2sv.common.WifiProperty
Expand Down Expand Up @@ -70,8 +68,6 @@ fun ConfigColumn(
val theme by widgetConfigurationViewModel.widgetThemeState.collectAsState()
val opacity by widgetConfigurationViewModel.widgetOpacityState.collectAsState()

val context = LocalContext.current

Column(
horizontalAlignment = Alignment.CenterHorizontally,
modifier = modifier
Expand Down Expand Up @@ -171,21 +167,16 @@ fun ConfigColumn(
widgetConfigurationViewModel.widgetPropertyStateMap.getValue(property)
},
onCheckedChange = { property, value ->
if (property == WifiProperty.SSID && value) {
when (homeScreenViewModel.lapDialogAnswered) {
when (property == WifiProperty.SSID && value) {
true -> when (homeScreenViewModel.lapDialogAnswered) {
false -> homeScreenViewModel.lapDialogTrigger.value =
LocationAccessPermissionDialogTrigger.SSIDCheck

true -> homeScreenViewModel.lapRequestTrigger.value =
LocationAccessPermissionDialogTrigger.SSIDCheck
}
} else {
widgetConfigurationViewModel.confirmAndSyncPropertyChange(
property,
value
) {
context.showToast(R.string.uncheck_all_properties_toast)
}

false -> widgetConfigurationViewModel.widgetPropertyStateMap[property] = value
}
},
onInfoButtonClick = { widgetConfigurationViewModel.infoDialogProperty.value = it })
Expand Down
1 change: 0 additions & 1 deletion app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
<resources>
<string name="app_name">WiFi Widget</string>
<string name="pin_widget">Pin Widget</string>
<string name="uncheck_all_properties_toast">You need to leave at least one property checked!</string>
<string name="updated_widget_configuration">Updated Widget Configuration</string>
<string name="pinned_widget">Pinned Widget</string>
<string name="lap_dialog_text">If you want your device\'s SSID to be displayed amongst the WiFi properties, you\'ll have to grant location access permission.</string>
Expand Down
Loading

0 comments on commit ec834fa

Please sign in to comment.