Changed clone dialog design and improved text field behavior with long text

This commit is contained in:
Abdelilah El Aissaoui 2022-09-03 18:30:26 +02:00
parent 7148e59eeb
commit d2608f8f60
6 changed files with 89 additions and 43 deletions

View file

@ -15,6 +15,9 @@ import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.FocusProperties
import androidx.compose.ui.focus.FocusRequester
import androidx.compose.ui.graphics.Shape
import androidx.compose.ui.graphics.SolidColor
import androidx.compose.ui.graphics.takeOrElse
import androidx.compose.ui.text.TextStyle
@ -28,11 +31,13 @@ fun AdjustableOutlinedTextField(
modifier: Modifier = Modifier,
enabled: Boolean = true,
isError: Boolean = false,
singleLine: Boolean = false,
colors: TextFieldColors = outlinedTextFieldColors(),
maxLines: Int = Int.MAX_VALUE,
keyboardOptions: KeyboardOptions = KeyboardOptions.Default,
textStyle: TextStyle = LocalTextStyle.current.copy(fontSize = MaterialTheme.typography.body1.fontSize),
interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
shape: Shape = RoundedCornerShape(4.dp),
) {
val textColor = textStyle.color.takeOrElse {
colors.textColor(enabled).value
@ -51,13 +56,14 @@ fun AdjustableOutlinedTextField(
interactionSource = interactionSource,
keyboardOptions = keyboardOptions,
cursorBrush = SolidColor(cursorColor),
singleLine = singleLine,
decorationBox = { innerTextField ->
Box(
modifier = Modifier
.border(
width = 1.dp,
color = indicatorColor,
shape = RoundedCornerShape(4.dp)
shape = shape
)
.padding(12.dp),
contentAlignment = Alignment.CenterStart,

View file

@ -155,7 +155,7 @@ private fun TextInput(
enabled = enabled,
onValueChange = onValueChange,
colors = outlinedTextFieldColors(),
maxLines = 1,
singleLine = true,
)
}
}

View file

@ -12,14 +12,17 @@ import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.focus.FocusProperties
import androidx.compose.ui.focus.FocusRequester
import androidx.compose.ui.focus.focusProperties
import androidx.compose.ui.focus.focusRequester
import androidx.compose.ui.graphics.Shape
import androidx.compose.ui.unit.dp
import app.git.CloneStatus
import app.theme.outlinedTextFieldColors
import app.theme.primaryTextColor
import app.theme.textButtonColors
import app.ui.components.AdjustableOutlinedTextField
import app.ui.components.PrimaryButton
import app.ui.openDirectoryDialog
import app.viewmodels.CloneViewModel
@ -37,7 +40,8 @@ fun CloneDialog(
MaterialDialog(onCloseRequested = onClose) {
Box(
modifier = Modifier
.width(400.dp)
.width(720.dp)
.heightIn(min = 200.dp)
.animateContentSize()
) {
when (cloneStatusValue) {
@ -46,7 +50,7 @@ fun CloneDialog(
}
is CloneStatus.Cancelling -> {
onClose()
// onClose()
}
is CloneStatus.Completed -> {
@ -90,29 +94,24 @@ private fun CloneInput(
Column(
modifier = Modifier.fillMaxWidth()
.padding(horizontal = 8.dp)
) {
Text(
"Clone a new repository",
color = MaterialTheme.colors.primaryTextColor,
style = MaterialTheme.typography.h3,
modifier = Modifier
.fillMaxWidth()
.padding(vertical = 4.dp, horizontal = 8.dp)
.padding(vertical = 4.dp)
)
OutlinedTextField(
modifier = Modifier
.fillMaxWidth()
.padding(vertical = 4.dp, horizontal = 8.dp)
.focusRequester(urlFocusRequester)
.focusProperties {
previous = cancelButtonFocusRequester
next = directoryFocusRequester
},
label = { Text("URL") },
textStyle = MaterialTheme.typography.body1,
maxLines = 1,
TextInput(
title = "URL",
value = url,
colors = outlinedTextFieldColors(),
focusRequester = urlFocusRequester,
focusProperties = {
previous = cancelButtonFocusRequester
next = directoryFocusRequester
},
onValueChange = {
cloneViewModel.resetStateIfError()
url = it
@ -122,37 +121,35 @@ private fun CloneInput(
Row(
modifier = Modifier
.fillMaxWidth()
.padding(vertical = 4.dp, horizontal = 8.dp),
.fillMaxWidth(),
verticalAlignment = Alignment.CenterVertically,
) {
OutlinedTextField(
modifier = Modifier
.weight(1f)
.padding(end = 4.dp)
.focusRequester(directoryFocusRequester)
.focusProperties {
previous = urlFocusRequester
next = directoryButtonFocusRequester
},
textStyle = MaterialTheme.typography.body1,
maxLines = 1,
label = { Text("Directory") },
TextInput(
modifier = Modifier.weight(1f),
title = "Directory",
value = directory,
colors = outlinedTextFieldColors(),
focusRequester = directoryButtonFocusRequester,
focusProperties = {
previous = urlFocusRequester
next = directoryButtonFocusRequester
},
onValueChange = {
cloneViewModel.resetStateIfError()
directory = it
cloneViewModel.directory = directory
}
},
textFieldShape = RoundedCornerShape(topStart = 4.dp, bottomStart = 4.dp)
)
IconButton(
onClick = {
cloneViewModel.resetStateIfError()
val newDirectory = openDirectoryDialog()
if (newDirectory != null)
if (newDirectory != null) {
directory = newDirectory
cloneViewModel.directory = directory
}
},
modifier = Modifier
.focusRequester(directoryButtonFocusRequester)
@ -160,6 +157,9 @@ private fun CloneInput(
previous = directoryFocusRequester
next = cloneButtonFocusRequester
}
.clip(RoundedCornerShape(topEnd = 4.dp, bottomEnd = 4.dp))
.background(MaterialTheme.colors.primary)
.height(44.5.dp) // Height of the AdjustableOutlinedTextField with a single line by default
) {
Icon(
Icons.Default.Search,
@ -288,4 +288,43 @@ private fun Cancelling() {
modifier = Modifier.padding(vertical = 16.dp),
)
}
}
@Composable
private fun TextInput(
modifier: Modifier = Modifier,
title: String,
value: String,
enabled: Boolean = true,
focusRequester: FocusRequester,
focusProperties: FocusProperties.() -> Unit,
onValueChange: (String) -> Unit,
textFieldShape: Shape = RoundedCornerShape(4.dp),
) {
Row(
modifier = modifier
.padding(vertical = 8.dp),
verticalAlignment = Alignment.CenterVertically
) {
Text(
text = title,
style = MaterialTheme.typography.body1,
modifier = Modifier
.width(100.dp)
.padding(end = 16.dp),
)
AdjustableOutlinedTextField(
value = value,
modifier = Modifier
.weight(1f)
.focusRequester(focusRequester)
.focusProperties(focusProperties),
enabled = enabled,
onValueChange = onValueChange,
colors = outlinedTextFieldColors(),
singleLine = true,
shape = textFieldShape,
)
}
}

View file

@ -228,7 +228,7 @@ fun EditRemotesDialog(
selectedRemote = newSelectedRemoteConfig
)
},
maxLines = 1,
singleLine = true,
modifier = Modifier
.fillMaxWidth()
.padding(vertical = 8.dp)
@ -248,7 +248,7 @@ fun EditRemotesDialog(
remotesEditorData = remotesEditorData.copy(selectedRemote = newSelectedRemoteConfig)
remoteChanged = newSelectedRemoteConfig.haveUrisChanged
},
maxLines = 1,
singleLine = true,
colors = outlinedTextFieldColors(),
modifier = Modifier
.fillMaxWidth()
@ -268,7 +268,7 @@ fun EditRemotesDialog(
remotesEditorData = remotesEditorData.copy(selectedRemote = newSelectedRemoteConfig)
remoteChanged = newSelectedRemoteConfig.haveUrisChanged
},
maxLines = 1,
singleLine = true,
modifier = Modifier
.fillMaxWidth()
.padding(vertical = 8.dp)

View file

@ -432,7 +432,7 @@ fun SettingIntInput(
}
},
colors = outlinedTextFieldColors(),
maxLines = 1,
singleLine = true,
textStyle = LocalTextStyle.current.copy(textAlign = TextAlign.End),
)
}

View file

@ -5,9 +5,9 @@ import app.git.TabState
import app.git.remote_operations.CloneRepositoryUseCase
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.cancelAndJoin
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.flowOn
import java.io.File
import javax.inject.Inject
@ -83,9 +83,10 @@ class CloneViewModel @Inject constructor(
directory = ""
}
fun cancelClone() {
cloneJob?.cancel()
fun cancelClone() = tabState.safeProcessingWihoutGit {
_cloneStatus.value = CloneStatus.Cancelling
cloneJob?.cancelAndJoin()
_cloneStatus.value = CloneStatus.None
}
fun resetStateIfError() {