parent
ab50502ca2
commit
96cbdba8d9
@ -26,6 +26,19 @@ fun Modifier.handMouseClickable(onClick: () -> Unit): Modifier {
|
|||||||
.handOnHover()
|
.handOnHover()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun Modifier.handMouseClickable(
|
||||||
|
interactionSource: MutableInteractionSource,
|
||||||
|
indication: Indication?,
|
||||||
|
onClick: () -> Unit
|
||||||
|
): Modifier {
|
||||||
|
return this
|
||||||
|
.clickable(
|
||||||
|
interactionSource = interactionSource,
|
||||||
|
indication = indication,
|
||||||
|
) { onClick() }
|
||||||
|
.handOnHover()
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Ignore keyboard events of that components.
|
* Ignore keyboard events of that components.
|
||||||
* Specially useful for clickable components that may get focused and become clickable when pressing ENTER.
|
* Specially useful for clickable components that may get focused and become clickable when pressing ENTER.
|
||||||
|
@ -59,6 +59,7 @@ fun UncommitedChanges(
|
|||||||
var commitMessage by remember(statusViewModel) { mutableStateOf(statusViewModel.savedCommitMessage.message) }
|
var commitMessage by remember(statusViewModel) { mutableStateOf(statusViewModel.savedCommitMessage.message) }
|
||||||
val stagedListState by statusViewModel.stagedLazyListState.collectAsState()
|
val stagedListState by statusViewModel.stagedLazyListState.collectAsState()
|
||||||
val unstagedListState by statusViewModel.unstagedLazyListState.collectAsState()
|
val unstagedListState by statusViewModel.unstagedLazyListState.collectAsState()
|
||||||
|
val isAmend by statusViewModel.isAmend.collectAsState()
|
||||||
|
|
||||||
val stageStatus = stageStatusState.value
|
val stageStatus = stageStatusState.value
|
||||||
val staged: List<StatusEntry>
|
val staged: List<StatusEntry>
|
||||||
@ -75,16 +76,16 @@ fun UncommitedChanges(
|
|||||||
isLoading = true
|
isLoading = true
|
||||||
}
|
}
|
||||||
|
|
||||||
val doCommit = { amend: Boolean ->
|
val doCommit = {
|
||||||
statusViewModel.commit(commitMessage, amend)
|
statusViewModel.commit(commitMessage)
|
||||||
onStagedDiffEntrySelected(null)
|
onStagedDiffEntrySelected(null)
|
||||||
commitMessage = ""
|
commitMessage = ""
|
||||||
}
|
}
|
||||||
|
|
||||||
val canCommit = commitMessage.isNotEmpty() && staged.isNotEmpty()
|
val canCommit = commitMessage.isNotEmpty() && staged.isNotEmpty()
|
||||||
val canAmend = (commitMessage.isNotEmpty() || staged.isNotEmpty()) && statusViewModel.hasPreviousCommits
|
val canAmend = commitMessage.isNotEmpty() && statusViewModel.hasPreviousCommits
|
||||||
|
|
||||||
LaunchedEffect(Unit) {
|
LaunchedEffect(statusViewModel) {
|
||||||
statusViewModel.commitMessageChangesFlow.collect { newCommitMessage ->
|
statusViewModel.commitMessageChangesFlow.collect { newCommitMessage ->
|
||||||
commitMessage = newCommitMessage
|
commitMessage = newCommitMessage
|
||||||
}
|
}
|
||||||
@ -179,7 +180,7 @@ fun UncommitedChanges(
|
|||||||
.weight(weight = 1f, fill = true)
|
.weight(weight = 1f, fill = true)
|
||||||
.onPreviewKeyEvent { keyEvent ->
|
.onPreviewKeyEvent { keyEvent ->
|
||||||
if (keyEvent.matchesBinding(KeybindingOption.TEXT_ACCEPT) && canCommit) {
|
if (keyEvent.matchesBinding(KeybindingOption.TEXT_ACCEPT) && canCommit) {
|
||||||
doCommit(false)
|
doCommit()
|
||||||
true
|
true
|
||||||
} else
|
} else
|
||||||
false
|
false
|
||||||
@ -215,7 +216,7 @@ fun UncommitedChanges(
|
|||||||
statusViewModel.resetRepoState()
|
statusViewModel.resetRepoState()
|
||||||
statusViewModel.updateCommitMessage("")
|
statusViewModel.updateCommitMessage("")
|
||||||
},
|
},
|
||||||
onMerge = { doCommit(false) }
|
onMerge = { doCommit() }
|
||||||
)
|
)
|
||||||
|
|
||||||
repositoryState.isRebasing -> RebasingButtons(
|
repositoryState.isRebasing -> RebasingButtons(
|
||||||
@ -236,7 +237,7 @@ fun UncommitedChanges(
|
|||||||
statusViewModel.updateCommitMessage("")
|
statusViewModel.updateCommitMessage("")
|
||||||
},
|
},
|
||||||
onCommit = {
|
onCommit = {
|
||||||
doCommit(false)
|
doCommit()
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -248,14 +249,18 @@ fun UncommitedChanges(
|
|||||||
statusViewModel.updateCommitMessage("")
|
statusViewModel.updateCommitMessage("")
|
||||||
},
|
},
|
||||||
onCommit = {
|
onCommit = {
|
||||||
doCommit(false)
|
doCommit()
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
else -> UncommitedChangesButtons(
|
else -> UncommitedChangesButtons(
|
||||||
canCommit = canCommit,
|
canCommit = canCommit,
|
||||||
canAmend = canAmend,
|
canAmend = canAmend,
|
||||||
onCommit = { amend -> doCommit(amend) },
|
isAmend = isAmend,
|
||||||
|
onAmendChecked = { isAmend ->
|
||||||
|
statusViewModel.amend(isAmend)
|
||||||
|
},
|
||||||
|
onCommit = { doCommit() },
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -267,32 +272,67 @@ fun UncommitedChanges(
|
|||||||
fun UncommitedChangesButtons(
|
fun UncommitedChangesButtons(
|
||||||
canCommit: Boolean,
|
canCommit: Boolean,
|
||||||
canAmend: Boolean,
|
canAmend: Boolean,
|
||||||
onCommit: (Boolean) -> Unit
|
isAmend: Boolean,
|
||||||
|
onAmendChecked: (Boolean) -> Unit,
|
||||||
|
onCommit: () -> Unit
|
||||||
) {
|
) {
|
||||||
var showDropDownMenu by remember { mutableStateOf(false) }
|
var showDropDownMenu by remember { mutableStateOf(false) }
|
||||||
|
|
||||||
|
val buttonText = if (isAmend)
|
||||||
|
"Amend"
|
||||||
|
else
|
||||||
|
"Commit"
|
||||||
|
|
||||||
|
Column {
|
||||||
|
Row(
|
||||||
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
|
modifier = Modifier.handMouseClickable(
|
||||||
|
interactionSource = remember { MutableInteractionSource() },
|
||||||
|
indication = null,
|
||||||
|
) {
|
||||||
|
onAmendChecked(!isAmend)
|
||||||
|
}
|
||||||
|
) {
|
||||||
|
Checkbox(
|
||||||
|
checked = isAmend,
|
||||||
|
onCheckedChange = {
|
||||||
|
onAmendChecked(!isAmend)
|
||||||
|
},
|
||||||
|
modifier = Modifier
|
||||||
|
.padding(all = 8.dp)
|
||||||
|
.size(12.dp)
|
||||||
|
)
|
||||||
|
|
||||||
|
Text(
|
||||||
|
"Amend previous commit",
|
||||||
|
style = MaterialTheme.typography.caption,
|
||||||
|
color = MaterialTheme.colors.onBackground,
|
||||||
|
)
|
||||||
|
}
|
||||||
Row(
|
Row(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.padding(top = 2.dp)
|
.padding(top = 2.dp)
|
||||||
) {
|
) {
|
||||||
ConfirmationButton(
|
ConfirmationButton(
|
||||||
text = "Commit",
|
text = buttonText,
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.weight(1f)
|
.weight(1f)
|
||||||
.height(40.dp),
|
.height(36.dp),
|
||||||
onClick = { onCommit(false) },
|
onClick = {
|
||||||
enabled = canCommit,
|
onCommit()
|
||||||
|
},
|
||||||
|
enabled = canCommit || (canAmend && isAmend),
|
||||||
shape = MaterialTheme.shapes.small.copy(topEnd = CornerSize(0.dp), bottomEnd = CornerSize(0.dp))
|
shape = MaterialTheme.shapes.small.copy(topEnd = CornerSize(0.dp), bottomEnd = CornerSize(0.dp))
|
||||||
)
|
)
|
||||||
Spacer(
|
Spacer(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.width(1.dp)
|
.width(1.dp)
|
||||||
.height(40.dp),
|
.height(36.dp),
|
||||||
)
|
)
|
||||||
|
|
||||||
Box(
|
Box(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.height(40.dp)
|
.height(36.dp)
|
||||||
.clip(MaterialTheme.shapes.small.copy(topStart = CornerSize(0.dp), bottomStart = CornerSize(0.dp)))
|
.clip(MaterialTheme.shapes.small.copy(topStart = CornerSize(0.dp), bottomStart = CornerSize(0.dp)))
|
||||||
.background(MaterialTheme.colors.primary)
|
.background(MaterialTheme.colors.primary)
|
||||||
.handMouseClickable { showDropDownMenu = true }
|
.handMouseClickable { showDropDownMenu = true }
|
||||||
@ -310,20 +350,21 @@ fun UncommitedChangesButtons(
|
|||||||
showDropDownMenu = false
|
showDropDownMenu = false
|
||||||
},
|
},
|
||||||
content = {
|
content = {
|
||||||
DropDownContent(
|
/*DropDownContent(
|
||||||
enabled = canAmend,
|
enabled = canAmend,
|
||||||
dropDownContentData = DropDownContentData(
|
dropDownContentData = DropDownContentData(
|
||||||
label = "Amend previous commit",
|
label = "Amend previous commit",
|
||||||
icon = null,
|
icon = null,
|
||||||
onClick = { onCommit(true) }
|
onClick = onCommit
|
||||||
),
|
),
|
||||||
onDismiss = { showDropDownMenu = false }
|
onDismiss = { showDropDownMenu = false }
|
||||||
)
|
)*/
|
||||||
},
|
},
|
||||||
expanded = showDropDownMenu,
|
expanded = showDropDownMenu,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
|
@ -66,6 +66,9 @@ class StatusViewModel @Inject constructor(
|
|||||||
private val _commitMessageChangesFlow = MutableSharedFlow<String>()
|
private val _commitMessageChangesFlow = MutableSharedFlow<String>()
|
||||||
val commitMessageChangesFlow: SharedFlow<String> = _commitMessageChangesFlow
|
val commitMessageChangesFlow: SharedFlow<String> = _commitMessageChangesFlow
|
||||||
|
|
||||||
|
private val _isAmend = MutableStateFlow(false)
|
||||||
|
val isAmend: StateFlow<Boolean> = _isAmend
|
||||||
|
|
||||||
init {
|
init {
|
||||||
tabScope.launch {
|
tabScope.launch {
|
||||||
tabState.refreshFlowFiltered(
|
tabState.refreshFlowFiltered(
|
||||||
@ -191,10 +194,19 @@ class StatusViewModel @Inject constructor(
|
|||||||
private suspend fun loadHasUncommitedChanges(git: Git) = withContext(Dispatchers.IO) {
|
private suspend fun loadHasUncommitedChanges(git: Git) = withContext(Dispatchers.IO) {
|
||||||
lastUncommitedChangesState = checkHasUncommitedChangedUseCase(git)
|
lastUncommitedChangesState = checkHasUncommitedChangedUseCase(git)
|
||||||
}
|
}
|
||||||
|
fun amend(isAmend: Boolean) {
|
||||||
|
_isAmend.value = isAmend
|
||||||
|
|
||||||
fun commit(message: String, amend: Boolean) = tabState.safeProcessing(
|
if (isAmend && savedCommitMessage.message.isEmpty()) {
|
||||||
|
takeMessageFromPreviousCommit()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun commit(message: String) = tabState.safeProcessing(
|
||||||
refreshType = RefreshType.ALL_DATA,
|
refreshType = RefreshType.ALL_DATA,
|
||||||
) { git ->
|
) { git ->
|
||||||
|
val amend = isAmend.value
|
||||||
|
|
||||||
val commitMessage = if (amend && message.isBlank()) {
|
val commitMessage = if (amend && message.isBlank()) {
|
||||||
getLastCommitMessageUseCase(git)
|
getLastCommitMessageUseCase(git)
|
||||||
} else
|
} else
|
||||||
@ -202,6 +214,7 @@ class StatusViewModel @Inject constructor(
|
|||||||
|
|
||||||
doCommitUseCase(git, commitMessage, amend)
|
doCommitUseCase(git, commitMessage, amend)
|
||||||
updateCommitMessage("")
|
updateCommitMessage("")
|
||||||
|
_isAmend.value = false
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun refresh(git: Git) = withContext(Dispatchers.IO) {
|
suspend fun refresh(git: Git) = withContext(Dispatchers.IO) {
|
||||||
@ -263,6 +276,14 @@ class StatusViewModel @Inject constructor(
|
|||||||
savedCommitMessage = savedCommitMessage.copy(message = message)
|
savedCommitMessage = savedCommitMessage.copy(message = message)
|
||||||
persistMessage()
|
persistMessage()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun takeMessageFromPreviousCommit() = tabState.runOperation(
|
||||||
|
refreshType = RefreshType.NONE,
|
||||||
|
) { git ->
|
||||||
|
savedCommitMessage = savedCommitMessage.copy(message = getLastCommitMessageUseCase(git))
|
||||||
|
persistMessage()
|
||||||
|
_commitMessageChangesFlow.emit(savedCommitMessage.message)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sealed class StageStatus {
|
sealed class StageStatus {
|
||||||
|
Loading…
Reference in New Issue
Block a user