Added option to stash with a custom message
This commit is contained in:
parent
1380eced08
commit
7156a976dc
@ -7,10 +7,14 @@ import org.eclipse.jgit.revwalk.RevCommit
|
|||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class StashManager @Inject constructor() {
|
class StashManager @Inject constructor() {
|
||||||
suspend fun stash(git: Git) = withContext(Dispatchers.IO) {
|
suspend fun stash(git: Git, message: String?) = withContext(Dispatchers.IO) {
|
||||||
git
|
git
|
||||||
.stashCreate()
|
.stashCreate()
|
||||||
.setIncludeUntracked(true)
|
.setIncludeUntracked(true)
|
||||||
|
.apply {
|
||||||
|
if (message != null)
|
||||||
|
setWorkingDirectoryMessage(message)
|
||||||
|
}
|
||||||
.call()
|
.call()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,6 +32,7 @@ fun Menu(
|
|||||||
menuViewModel: MenuViewModel,
|
menuViewModel: MenuViewModel,
|
||||||
onRepositoryOpen: () -> Unit,
|
onRepositoryOpen: () -> Unit,
|
||||||
onCreateBranch: () -> Unit,
|
onCreateBranch: () -> Unit,
|
||||||
|
onStashWithMessage: () -> Unit,
|
||||||
) {
|
) {
|
||||||
var showAdditionalOptionsDropDownMenu by remember { mutableStateOf(false) }
|
var showAdditionalOptionsDropDownMenu by remember { mutableStateOf(false) }
|
||||||
|
|
||||||
@ -93,11 +94,14 @@ fun Menu(
|
|||||||
|
|
||||||
Spacer(modifier = Modifier.width(24.dp))
|
Spacer(modifier = Modifier.width(24.dp))
|
||||||
|
|
||||||
MenuButton(
|
ExtendedMenuButton(
|
||||||
modifier = Modifier.padding(end = 8.dp),
|
modifier = Modifier.padding(end = 8.dp),
|
||||||
title = "Stash",
|
title = "Stash",
|
||||||
icon = painterResource("stash.svg"),
|
icon = painterResource("stash.svg"),
|
||||||
onClick = { menuViewModel.stash() },
|
onClick = { menuViewModel.stash() },
|
||||||
|
extendedListItems = stashContextMenuItems(
|
||||||
|
onStashWithMessage = onStashWithMessage
|
||||||
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
MenuButton(
|
MenuButton(
|
||||||
|
@ -20,6 +20,7 @@ import app.theme.borderColor
|
|||||||
import app.theme.primaryTextColor
|
import app.theme.primaryTextColor
|
||||||
import app.ui.dialogs.NewBranchDialog
|
import app.ui.dialogs.NewBranchDialog
|
||||||
import app.ui.dialogs.RebaseInteractive
|
import app.ui.dialogs.RebaseInteractive
|
||||||
|
import app.ui.dialogs.StashWithMessageDialog
|
||||||
import app.ui.log.Log
|
import app.ui.log.Log
|
||||||
import app.viewmodels.BlameState
|
import app.viewmodels.BlameState
|
||||||
import app.viewmodels.TabViewModel
|
import app.viewmodels.TabViewModel
|
||||||
@ -43,6 +44,7 @@ fun RepositoryOpenPage(tabViewModel: TabViewModel) {
|
|||||||
val showHistory by tabViewModel.showHistory.collectAsState()
|
val showHistory by tabViewModel.showHistory.collectAsState()
|
||||||
|
|
||||||
var showNewBranchDialog by remember { mutableStateOf(false) }
|
var showNewBranchDialog by remember { mutableStateOf(false) }
|
||||||
|
var showStashWithMessageDialog by remember { mutableStateOf(false) }
|
||||||
|
|
||||||
if (showNewBranchDialog) {
|
if (showNewBranchDialog) {
|
||||||
NewBranchDialog(
|
NewBranchDialog(
|
||||||
@ -54,6 +56,16 @@ fun RepositoryOpenPage(tabViewModel: TabViewModel) {
|
|||||||
showNewBranchDialog = false
|
showNewBranchDialog = false
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
} else if (showStashWithMessageDialog) {
|
||||||
|
StashWithMessageDialog(
|
||||||
|
onReject = {
|
||||||
|
showStashWithMessageDialog = false
|
||||||
|
},
|
||||||
|
onAccept = { stashMessage ->
|
||||||
|
tabViewModel.menuViewModel.stashWithMessage(stashMessage)
|
||||||
|
showStashWithMessageDialog = false
|
||||||
|
}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
Column {
|
Column {
|
||||||
@ -72,7 +84,8 @@ fun RepositoryOpenPage(tabViewModel: TabViewModel) {
|
|||||||
onRepositoryOpen = {
|
onRepositoryOpen = {
|
||||||
openRepositoryDialog(tabViewModel = tabViewModel)
|
openRepositoryDialog(tabViewModel = tabViewModel)
|
||||||
},
|
},
|
||||||
onCreateBranch = { showNewBranchDialog = true }
|
onCreateBranch = { showNewBranchDialog = true },
|
||||||
|
onStashWithMessage = { showStashWithMessageDialog = true },
|
||||||
)
|
)
|
||||||
|
|
||||||
RepoContent(tabViewModel, diffSelected, selectedItem, repositoryState, blameState, showHistory)
|
RepoContent(tabViewModel, diffSelected, selectedItem, repositoryState, blameState, showHistory)
|
||||||
@ -90,10 +103,10 @@ fun RepoContent(
|
|||||||
blameState: BlameState,
|
blameState: BlameState,
|
||||||
showHistory: Boolean,
|
showHistory: Boolean,
|
||||||
) {
|
) {
|
||||||
if(showHistory) {
|
if (showHistory) {
|
||||||
val historyViewModel = tabViewModel.historyViewModel
|
val historyViewModel = tabViewModel.historyViewModel
|
||||||
|
|
||||||
if(historyViewModel != null) {
|
if (historyViewModel != null) {
|
||||||
FileHistory(
|
FileHistory(
|
||||||
historyViewModel = historyViewModel,
|
historyViewModel = historyViewModel,
|
||||||
onClose = {
|
onClose = {
|
||||||
|
15
src/main/kotlin/app/ui/context_menu/StashContextMenu.kt
Normal file
15
src/main/kotlin/app/ui/context_menu/StashContextMenu.kt
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
package app.ui.context_menu
|
||||||
|
|
||||||
|
import androidx.compose.foundation.ExperimentalFoundationApi
|
||||||
|
|
||||||
|
@OptIn(ExperimentalFoundationApi::class)
|
||||||
|
fun stashContextMenuItems(
|
||||||
|
onStashWithMessage: () -> Unit,
|
||||||
|
): List<DropDownContentData> {
|
||||||
|
return mutableListOf(
|
||||||
|
DropDownContentData(
|
||||||
|
label = "Stash with message",
|
||||||
|
onClick = onStashWithMessage,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
94
src/main/kotlin/app/ui/dialogs/StashWithMessageDialog.kt
Normal file
94
src/main/kotlin/app/ui/dialogs/StashWithMessageDialog.kt
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
package app.ui.dialogs
|
||||||
|
|
||||||
|
import androidx.compose.foundation.background
|
||||||
|
import androidx.compose.foundation.layout.*
|
||||||
|
import androidx.compose.material.*
|
||||||
|
import androidx.compose.runtime.*
|
||||||
|
import androidx.compose.ui.Alignment
|
||||||
|
import androidx.compose.ui.ExperimentalComposeUiApi
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.focus.FocusRequester
|
||||||
|
import androidx.compose.ui.focus.focusOrder
|
||||||
|
import androidx.compose.ui.input.key.Key
|
||||||
|
import androidx.compose.ui.input.key.key
|
||||||
|
import androidx.compose.ui.input.key.onPreviewKeyEvent
|
||||||
|
import androidx.compose.ui.text.TextStyle
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import androidx.compose.ui.unit.sp
|
||||||
|
import app.theme.outlinedTextFieldColors
|
||||||
|
import app.theme.primaryTextColor
|
||||||
|
import app.theme.textButtonColors
|
||||||
|
import app.ui.components.PrimaryButton
|
||||||
|
|
||||||
|
@OptIn(ExperimentalComposeUiApi::class)
|
||||||
|
@Composable
|
||||||
|
fun StashWithMessageDialog(
|
||||||
|
onReject: () -> Unit,
|
||||||
|
onAccept: (stashMessage: String) -> Unit
|
||||||
|
) {
|
||||||
|
var textField by remember { mutableStateOf("") }
|
||||||
|
val textFieldFocusRequester = remember { FocusRequester() }
|
||||||
|
val buttonFieldFocusRequester = remember { FocusRequester() }
|
||||||
|
|
||||||
|
MaterialDialog(onCloseRequested = onReject) {
|
||||||
|
Column(
|
||||||
|
modifier = Modifier
|
||||||
|
.background(MaterialTheme.colors.background),
|
||||||
|
horizontalAlignment = Alignment.CenterHorizontally,
|
||||||
|
verticalArrangement = Arrangement.Center,
|
||||||
|
) {
|
||||||
|
OutlinedTextField(
|
||||||
|
modifier = Modifier
|
||||||
|
.focusOrder(textFieldFocusRequester) {
|
||||||
|
this.next = buttonFieldFocusRequester
|
||||||
|
}
|
||||||
|
.width(300.dp)
|
||||||
|
.onPreviewKeyEvent {
|
||||||
|
if (it.key == Key.Enter) {
|
||||||
|
onAccept(textField)
|
||||||
|
true
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
value = textField,
|
||||||
|
label = { Text("New stash message", fontSize = 14.sp) },
|
||||||
|
textStyle = TextStyle(fontSize = 14.sp, color = MaterialTheme.colors.primaryTextColor),
|
||||||
|
colors = outlinedTextFieldColors(),
|
||||||
|
onValueChange = {
|
||||||
|
textField = it
|
||||||
|
},
|
||||||
|
)
|
||||||
|
Row(
|
||||||
|
modifier = Modifier
|
||||||
|
.padding(top = 16.dp)
|
||||||
|
.align(Alignment.End)
|
||||||
|
) {
|
||||||
|
TextButton(
|
||||||
|
modifier = Modifier.padding(end = 8.dp),
|
||||||
|
colors = textButtonColors(),
|
||||||
|
onClick = {
|
||||||
|
onReject()
|
||||||
|
}
|
||||||
|
) {
|
||||||
|
Text("Cancel")
|
||||||
|
}
|
||||||
|
PrimaryButton(
|
||||||
|
modifier = Modifier.focusOrder(buttonFieldFocusRequester) {
|
||||||
|
this.previous = textFieldFocusRequester
|
||||||
|
this.next = textFieldFocusRequester
|
||||||
|
},
|
||||||
|
enabled = textField.isNotEmpty(),
|
||||||
|
onClick = {
|
||||||
|
onAccept(textField)
|
||||||
|
},
|
||||||
|
text = "Stash"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LaunchedEffect(Unit) {
|
||||||
|
textFieldFocusRequester.requestFocus()
|
||||||
|
}
|
||||||
|
}
|
@ -35,7 +35,14 @@ class MenuViewModel @Inject constructor(
|
|||||||
refreshType = RefreshType.UNCOMMITED_CHANGES_AND_LOG,
|
refreshType = RefreshType.UNCOMMITED_CHANGES_AND_LOG,
|
||||||
) { git ->
|
) { git ->
|
||||||
statusManager.stageUntrackedFiles(git)
|
statusManager.stageUntrackedFiles(git)
|
||||||
stashManager.stash(git)
|
stashManager.stash(git, null)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun stashWithMessage(message: String) = tabState.safeProcessing(
|
||||||
|
refreshType = RefreshType.UNCOMMITED_CHANGES_AND_LOG,
|
||||||
|
) { git ->
|
||||||
|
statusManager.stageUntrackedFiles(git)
|
||||||
|
stashManager.stash(git, message)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun popStash() = tabState.safeProcessing(
|
fun popStash() = tabState.safeProcessing(
|
||||||
|
Loading…
Reference in New Issue
Block a user