Skip to content

Commit

Permalink
Add input dialog base dialog
Browse files Browse the repository at this point in the history
  • Loading branch information
Pururun committed Aug 22, 2024
1 parent b98b40d commit 3497938
Show file tree
Hide file tree
Showing 6 changed files with 219 additions and 256 deletions.
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
package net.mullvad.mullvadvpn.compose.dialog

import androidx.compose.material3.AlertDialog
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.derivedStateOf
Expand All @@ -22,7 +19,6 @@ import com.ramcosta.composedestinations.navigation.DestinationsNavigator
import com.ramcosta.composedestinations.result.ResultBackNavigator
import com.ramcosta.composedestinations.spec.DestinationStyle
import net.mullvad.mullvadvpn.R
import net.mullvad.mullvadvpn.compose.button.PrimaryButton
import net.mullvad.mullvadvpn.compose.communication.CustomListActionResultData
import net.mullvad.mullvadvpn.compose.state.CreateCustomListUiState
import net.mullvad.mullvadvpn.compose.test.CREATE_CUSTOM_LIST_DIALOG_INPUT_TEST_TAG
Expand Down Expand Up @@ -101,17 +97,14 @@ fun CreateCustomListDialog(
onInputChanged: () -> Unit = {},
onDismiss: () -> Unit = {}
) {

val name = remember { mutableStateOf("") }
val isValidName by remember { derivedStateOf { name.value.isNotBlank() } }

AlertDialog(
title = {
Text(
text = stringResource(id = R.string.create_new_list),
)
},
text = {
InputDialog(
title = stringResource(id = R.string.create_new_list),
confirmButtonText = stringResource(id = R.string.create),
confirmButtonEnabled = isValidName,
input = {
CustomListNameTextField(
name = name.value,
isValidName = isValidName,
Expand All @@ -124,19 +117,8 @@ fun CreateCustomListDialog(
modifier = Modifier.testTag(CREATE_CUSTOM_LIST_DIALOG_INPUT_TEST_TAG)
)
},
containerColor = MaterialTheme.colorScheme.surface,
titleContentColor = MaterialTheme.colorScheme.onSurface,
onDismissRequest = onDismiss,
confirmButton = {
PrimaryButton(
text = stringResource(id = R.string.create),
onClick = { createCustomList(name.value) },
isEnabled = isValidName
)
},
dismissButton = {
PrimaryButton(text = stringResource(id = R.string.cancel), onClick = onDismiss)
}
onBack = onDismiss,
onConfirm = { createCustomList(name.value) }
)
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,7 @@
package net.mullvad.mullvadvpn.compose.dialog

import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.AlertDialog
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
Expand All @@ -19,13 +14,10 @@ import com.ramcosta.composedestinations.annotation.RootGraph
import com.ramcosta.composedestinations.result.ResultBackNavigator
import com.ramcosta.composedestinations.spec.DestinationStyle
import net.mullvad.mullvadvpn.R
import net.mullvad.mullvadvpn.compose.button.NegativeButton
import net.mullvad.mullvadvpn.compose.button.PrimaryButton
import net.mullvad.mullvadvpn.compose.communication.DnsDialogResult
import net.mullvad.mullvadvpn.compose.textfield.DnsTextField
import net.mullvad.mullvadvpn.compose.util.LaunchedEffectCollect
import net.mullvad.mullvadvpn.lib.theme.AppTheme
import net.mullvad.mullvadvpn.lib.theme.Dimens
import net.mullvad.mullvadvpn.viewmodel.DnsDialogSideEffect
import net.mullvad.mullvadvpn.viewmodel.DnsDialogViewModel
import net.mullvad.mullvadvpn.viewmodel.DnsDialogViewState
Expand Down Expand Up @@ -90,79 +82,41 @@ fun DnsDialog(
onRemoveDnsClick: (Int) -> Unit,
onDismiss: () -> Unit
) {
AlertDialog(
title = {
Text(
text =
if (state.isNewEntry) {
stringResource(R.string.add_dns_server_dialog_title)
} else {
stringResource(R.string.update_dns_server_dialog_title)
},
color = MaterialTheme.colorScheme.onSurface,
InputDialog(
title =
if (state.isNewEntry) {
stringResource(R.string.add_dns_server_dialog_title)
} else {
stringResource(R.string.update_dns_server_dialog_title)
},
input = {
DnsTextField(
value = state.input,
isValidValue = state.isValid(),
onValueChanged = { newDnsValue -> onDnsInputChange(newDnsValue) },
onSubmit = onSaveDnsClick,
isEnabled = true,
placeholderText = stringResource(R.string.custom_dns_hint),
modifier = Modifier.fillMaxWidth()
)
},
text = {
Column {
DnsTextField(
value = state.input,
isValidValue = state.isValid(),
onValueChanged = { newDnsValue -> onDnsInputChange(newDnsValue) },
onSubmit = onSaveDnsClick,
isEnabled = true,
placeholderText = stringResource(R.string.custom_dns_hint),
modifier = Modifier.fillMaxWidth()
)

val errorMessage =
when {
state.validationError is ValidationError.DuplicateAddress -> {
stringResource(R.string.duplicate_address_warning)
}
state.isLocal && !state.isAllowLanEnabled -> {
stringResource(id = R.string.confirm_local_dns)
}
else -> {
null
}
}

if (errorMessage != null) {
Text(
text = errorMessage,
style = MaterialTheme.typography.bodySmall,
color = MaterialTheme.colorScheme.error,
modifier = Modifier.padding(top = Dimens.smallPadding)
)
message =
when {
state.validationError is ValidationError.DuplicateAddress -> {
stringResource(R.string.duplicate_address_warning)
}
}
},
confirmButton = {
Column(verticalArrangement = Arrangement.spacedBy(Dimens.buttonSpacing)) {
PrimaryButton(
modifier = Modifier.fillMaxWidth(),
onClick = onSaveDnsClick,
isEnabled = state.isValid(),
text = stringResource(id = R.string.submit_button),
)

if (state.index != null) {
NegativeButton(
modifier = Modifier.fillMaxWidth(),
onClick = { onRemoveDnsClick(state.index) },
text = stringResource(id = R.string.remove_button)
)
state.isLocal && !state.isAllowLanEnabled -> {
stringResource(id = R.string.confirm_local_dns)
}

PrimaryButton(
modifier = Modifier.fillMaxWidth(),
onClick = onDismiss,
text = stringResource(id = R.string.cancel)
)
}
},
onDismissRequest = onDismiss,
containerColor = MaterialTheme.colorScheme.surface,
titleContentColor = MaterialTheme.colorScheme.onSurface,
else -> {
null
}
},
onResetButtonText = stringResource(id = R.string.remove_button),
confirmButtonEnabled = state.isValid(),
messageTextColor = MaterialTheme.colorScheme.error,
onReset = state.index?.let { { onRemoveDnsClick(state.index) } },
onBack = onDismiss,
onConfirm = onSaveDnsClick
)
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
package net.mullvad.mullvadvpn.compose.dialog

import androidx.compose.material3.AlertDialog
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
Expand All @@ -16,7 +13,6 @@ import com.ramcosta.composedestinations.annotation.RootGraph
import com.ramcosta.composedestinations.result.ResultBackNavigator
import com.ramcosta.composedestinations.spec.DestinationStyle
import net.mullvad.mullvadvpn.R
import net.mullvad.mullvadvpn.compose.button.PrimaryButton
import net.mullvad.mullvadvpn.compose.communication.CustomListActionResultData
import net.mullvad.mullvadvpn.compose.state.EditCustomListNameUiState
import net.mullvad.mullvadvpn.compose.test.EDIT_CUSTOM_LIST_DIALOG_INPUT_TEST_TAG
Expand Down Expand Up @@ -77,13 +73,11 @@ fun EditCustomListNameDialog(
onInputChanged: (String) -> Unit = {},
onDismiss: () -> Unit = {}
) {
AlertDialog(
title = {
Text(
text = stringResource(id = R.string.update_list_name),
)
},
text = {
InputDialog(
title = stringResource(id = R.string.update_list_name),
confirmButtonText = stringResource(id = R.string.save),
confirmButtonEnabled = state.isValidName,
input = {
CustomListNameTextField(
name = state.name,
isValidName = state.isValidName,
Expand All @@ -93,19 +87,8 @@ fun EditCustomListNameDialog(
modifier = Modifier.testTag(EDIT_CUSTOM_LIST_DIALOG_INPUT_TEST_TAG)
)
},
containerColor = MaterialTheme.colorScheme.surface,
titleContentColor = MaterialTheme.colorScheme.onSurface,
onDismissRequest = onDismiss,
confirmButton = {
PrimaryButton(
text = stringResource(id = R.string.save),
onClick = { updateName(state.name) },
isEnabled = state.isValidName
)
},
dismissButton = {
PrimaryButton(text = stringResource(id = R.string.cancel), onClick = onDismiss)
}
onBack = onDismiss,
onConfirm = { updateName(state.name) }
)
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
package net.mullvad.mullvadvpn.compose.dialog

import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.ColumnScope
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.AlertDialog
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.tooling.preview.Preview
import net.mullvad.mullvadvpn.R
import net.mullvad.mullvadvpn.compose.button.NegativeButton
import net.mullvad.mullvadvpn.compose.button.PrimaryButton
import net.mullvad.mullvadvpn.compose.textfield.CustomTextField
import net.mullvad.mullvadvpn.lib.theme.AppTheme
import net.mullvad.mullvadvpn.lib.theme.Dimens

@Preview
@Composable
private fun PreviewInputDialog() {
AppTheme {
InputDialog(
title = "Input here",
message = "Lorem ipsum",
input = {
CustomTextField(
value = "input",
keyboardType = KeyboardType.Text,
onValueChanged = {},
onSubmit = {},
placeholderText = "Placeholder",
isValidValue = true,
isDigitsOnlyAllowed = false,
)
},
onReset = {},
onBack = {},
onConfirm = {},
)
}
}

@Composable
fun InputDialog(
title: String,
message: String? = null,
input: @Composable ColumnScope.() -> Unit,
confirmButtonEnabled: Boolean = true,
confirmButtonText: String = stringResource(R.string.submit_button),
onResetButtonText: String = stringResource(R.string.reset_to_default_button),
messageTextColor: Color = MaterialTheme.colorScheme.onSurfaceVariant,
onBack: () -> Unit,
onConfirm: () -> Unit,
onReset: (() -> Unit)? = null
) {
AlertDialog(
onDismissRequest = onBack,
title = {
Text(
text = title,
color = MaterialTheme.colorScheme.onSurface,
)
},
text = {
Column {
input()

message?.let {
Text(
text = message,
style = MaterialTheme.typography.bodySmall,
color = messageTextColor,
modifier = Modifier.padding(top = Dimens.smallPadding)
)
}
}
},
confirmButton = {
Column(verticalArrangement = Arrangement.spacedBy(Dimens.buttonSpacing)) {
PrimaryButton(
modifier = Modifier.fillMaxWidth(),
isEnabled = confirmButtonEnabled,
text = confirmButtonText,
onClick = onConfirm
)

if (onReset != null) {
NegativeButton(
modifier = Modifier.fillMaxWidth(),
text = onResetButtonText,
onClick = onReset
)
}

PrimaryButton(
modifier = Modifier.fillMaxWidth(),
text = stringResource(R.string.cancel),
onClick = onBack
)
}
},
containerColor = MaterialTheme.colorScheme.surface,
titleContentColor = MaterialTheme.colorScheme.onSurface,
)
}
Loading

0 comments on commit 3497938

Please sign in to comment.