Changed clone dialog design and improved text field behavior with long text
This commit is contained in:
parent
7148e59eeb
commit
d2608f8f60
6 changed files with 89 additions and 43 deletions
|
@ -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,
|
||||
|
|
|
@ -155,7 +155,7 @@ private fun TextInput(
|
|||
enabled = enabled,
|
||||
onValueChange = onValueChange,
|
||||
colors = outlinedTextFieldColors(),
|
||||
maxLines = 1,
|
||||
singleLine = true,
|
||||
)
|
||||
}
|
||||
}
|
|
@ -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 {
|
||||
TextInput(
|
||||
title = "URL",
|
||||
value = url,
|
||||
focusRequester = urlFocusRequester,
|
||||
focusProperties = {
|
||||
previous = cancelButtonFocusRequester
|
||||
next = directoryFocusRequester
|
||||
},
|
||||
label = { Text("URL") },
|
||||
textStyle = MaterialTheme.typography.body1,
|
||||
maxLines = 1,
|
||||
value = url,
|
||||
colors = outlinedTextFieldColors(),
|
||||
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 {
|
||||
|
||||
TextInput(
|
||||
modifier = Modifier.weight(1f),
|
||||
title = "Directory",
|
||||
value = directory,
|
||||
focusRequester = directoryButtonFocusRequester,
|
||||
focusProperties = {
|
||||
previous = urlFocusRequester
|
||||
next = directoryButtonFocusRequester
|
||||
},
|
||||
textStyle = MaterialTheme.typography.body1,
|
||||
maxLines = 1,
|
||||
label = { Text("Directory") },
|
||||
value = directory,
|
||||
colors = outlinedTextFieldColors(),
|
||||
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,
|
||||
|
@ -289,3 +289,42 @@ private fun Cancelling() {
|
|||
)
|
||||
}
|
||||
}
|
||||
|
||||
@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,
|
||||
)
|
||||
}
|
||||
}
|
|
@ -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)
|
||||
|
|
|
@ -432,7 +432,7 @@ fun SettingIntInput(
|
|||
}
|
||||
},
|
||||
colors = outlinedTextFieldColors(),
|
||||
maxLines = 1,
|
||||
singleLine = true,
|
||||
textStyle = LocalTextStyle.current.copy(textAlign = TextAlign.End),
|
||||
)
|
||||
}
|
||||
|
|
|
@ -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() {
|
||||
|
|
Loading…
Reference in a new issue