Started addition of "Quick actions" dialog
This commit is contained in:
parent
7fd3c1fdc2
commit
8ebcc10dde
@ -26,15 +26,26 @@ enum class KeybindingOption {
|
|||||||
/**
|
/**
|
||||||
* Used to accept multi-line text field like the commit message
|
* Used to accept multi-line text field like the commit message
|
||||||
*/
|
*/
|
||||||
ACCEPT,
|
TEXT_ACCEPT,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used to close dialogs or components
|
* Used to close dialogs or components
|
||||||
*/
|
*/
|
||||||
EXIT,
|
EXIT,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used to go up in lists
|
||||||
|
*/
|
||||||
|
UP,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used to go down in lists
|
||||||
|
*/
|
||||||
|
DOWN,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@OptIn(ExperimentalComposeUiApi::class)
|
||||||
private fun baseKeybindings() = mapOf(
|
private fun baseKeybindings() = mapOf(
|
||||||
KeybindingOption.REFRESH to listOf(
|
KeybindingOption.REFRESH to listOf(
|
||||||
Keybinding(key = Key.F5),
|
Keybinding(key = Key.F5),
|
||||||
@ -43,12 +54,18 @@ private fun baseKeybindings() = mapOf(
|
|||||||
KeybindingOption.SIMPLE_ACCEPT to listOf(
|
KeybindingOption.SIMPLE_ACCEPT to listOf(
|
||||||
Keybinding(key = Key.Enter),
|
Keybinding(key = Key.Enter),
|
||||||
),
|
),
|
||||||
KeybindingOption.ACCEPT to listOf(
|
KeybindingOption.TEXT_ACCEPT to listOf(
|
||||||
Keybinding(control = true, key = Key.Enter),
|
Keybinding(control = true, key = Key.Enter),
|
||||||
),
|
),
|
||||||
KeybindingOption.EXIT to listOf(
|
KeybindingOption.EXIT to listOf(
|
||||||
Keybinding(key = Key.Escape),
|
Keybinding(key = Key.Escape),
|
||||||
),
|
),
|
||||||
|
KeybindingOption.UP to listOf(
|
||||||
|
Keybinding(key = Key.DirectionUp),
|
||||||
|
),
|
||||||
|
KeybindingOption.DOWN to listOf(
|
||||||
|
Keybinding(key = Key.DirectionDown),
|
||||||
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
private fun linuxKeybindings(): Map<KeybindingOption, List<Keybinding>> = baseKeybindings()
|
private fun linuxKeybindings(): Map<KeybindingOption, List<Keybinding>> = baseKeybindings()
|
||||||
|
@ -35,9 +35,8 @@ fun Menu(
|
|||||||
onCreateBranch: () -> Unit,
|
onCreateBranch: () -> Unit,
|
||||||
onGoToWorkspace: () -> Unit,
|
onGoToWorkspace: () -> Unit,
|
||||||
onStashWithMessage: () -> Unit,
|
onStashWithMessage: () -> Unit,
|
||||||
|
onQuickActions: () -> Unit,
|
||||||
) {
|
) {
|
||||||
var showAdditionalOptionsDropDownMenu by remember { mutableStateOf(false) }
|
|
||||||
|
|
||||||
Row(
|
Row(
|
||||||
modifier = modifier,
|
modifier = modifier,
|
||||||
horizontalArrangement = Arrangement.Center,
|
horizontalArrangement = Arrangement.Center,
|
||||||
@ -113,34 +112,13 @@ fun Menu(
|
|||||||
|
|
||||||
Spacer(modifier = Modifier.weight(1f))
|
Spacer(modifier = Modifier.weight(1f))
|
||||||
|
|
||||||
Box {
|
MenuButton(
|
||||||
IconMenuButton(
|
title = "Quick actions",
|
||||||
modifier = Modifier
|
modifier = Modifier.padding(end = 16.dp),
|
||||||
.padding(end = 8.dp)
|
icon = painterResource("bolt.svg"),
|
||||||
.size(36.dp),
|
fixedWidth = false,
|
||||||
icon = painterResource("more_vert.svg"),
|
onClick = onQuickActions,
|
||||||
onClick = {
|
)
|
||||||
showAdditionalOptionsDropDownMenu = true
|
|
||||||
},
|
|
||||||
)
|
|
||||||
DropdownMenu(
|
|
||||||
expanded = showAdditionalOptionsDropDownMenu,
|
|
||||||
content = {
|
|
||||||
val menuOptions = remember {
|
|
||||||
repositoryAdditionalOptionsMenu(
|
|
||||||
onOpenRepositoryOnFileExplorer = { menuViewModel.openFolderInFileExplorer() },
|
|
||||||
)
|
|
||||||
}
|
|
||||||
for (item in menuOptions) {
|
|
||||||
DropDownContent(
|
|
||||||
dropDownContentData = item,
|
|
||||||
onDismiss = { showAdditionalOptionsDropDownMenu = false }
|
|
||||||
)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
onDismissRequest = { showAdditionalOptionsDropDownMenu = false }
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,6 +39,7 @@ import com.jetpackduba.gitnuro.theme.secondarySurface
|
|||||||
import com.jetpackduba.gitnuro.ui.components.ScrollableColumn
|
import com.jetpackduba.gitnuro.ui.components.ScrollableColumn
|
||||||
import com.jetpackduba.gitnuro.ui.dialogs.AuthorDialog
|
import com.jetpackduba.gitnuro.ui.dialogs.AuthorDialog
|
||||||
import com.jetpackduba.gitnuro.ui.dialogs.NewBranchDialog
|
import com.jetpackduba.gitnuro.ui.dialogs.NewBranchDialog
|
||||||
|
import com.jetpackduba.gitnuro.ui.dialogs.QuickActionsDialog
|
||||||
import com.jetpackduba.gitnuro.ui.dialogs.StashWithMessageDialog
|
import com.jetpackduba.gitnuro.ui.dialogs.StashWithMessageDialog
|
||||||
import com.jetpackduba.gitnuro.ui.dialogs.settings.SettingsDialog
|
import com.jetpackduba.gitnuro.ui.dialogs.settings.SettingsDialog
|
||||||
import com.jetpackduba.gitnuro.ui.diff.Diff
|
import com.jetpackduba.gitnuro.ui.diff.Diff
|
||||||
@ -64,6 +65,7 @@ fun RepositoryOpenPage(tabViewModel: TabViewModel) {
|
|||||||
|
|
||||||
var showNewBranchDialog by remember { mutableStateOf(false) }
|
var showNewBranchDialog by remember { mutableStateOf(false) }
|
||||||
var showStashWithMessageDialog by remember { mutableStateOf(false) }
|
var showStashWithMessageDialog by remember { mutableStateOf(false) }
|
||||||
|
var showQuickActionsDialog by remember { mutableStateOf(false) }
|
||||||
|
|
||||||
if (showNewBranchDialog) {
|
if (showNewBranchDialog) {
|
||||||
NewBranchDialog(
|
NewBranchDialog(
|
||||||
@ -95,6 +97,13 @@ fun RepositoryOpenPage(tabViewModel: TabViewModel) {
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
} else if (showQuickActionsDialog) {
|
||||||
|
QuickActionsDialog(
|
||||||
|
onClose = { showQuickActionsDialog = false },
|
||||||
|
onAction = {
|
||||||
|
showQuickActionsDialog = false
|
||||||
|
},
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
val focusRequester = remember { FocusRequester() }
|
val focusRequester = remember { FocusRequester() }
|
||||||
@ -135,7 +144,8 @@ fun RepositoryOpenPage(tabViewModel: TabViewModel) {
|
|||||||
menuViewModel = tabViewModel.menuViewModel,
|
menuViewModel = tabViewModel.menuViewModel,
|
||||||
onCreateBranch = { showNewBranchDialog = true },
|
onCreateBranch = { showNewBranchDialog = true },
|
||||||
onStashWithMessage = { showStashWithMessageDialog = true },
|
onStashWithMessage = { showStashWithMessageDialog = true },
|
||||||
onGoToWorkspace = { tabViewModel.selectUncommitedChanges() }
|
onGoToWorkspace = { tabViewModel.selectUncommitedChanges() },
|
||||||
|
onQuickActions = { showQuickActionsDialog = true }
|
||||||
)
|
)
|
||||||
|
|
||||||
RepoContent(tabViewModel, diffSelected, selectedItem, repositoryState, blameState, showHistory)
|
RepoContent(tabViewModel, diffSelected, selectedItem, repositoryState, blameState, showHistory)
|
||||||
|
@ -172,7 +172,7 @@ fun UncommitedChanges(
|
|||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
.weight(weight = 1f, fill = true)
|
.weight(weight = 1f, fill = true)
|
||||||
.onPreviewKeyEvent { keyEvent ->
|
.onPreviewKeyEvent { keyEvent ->
|
||||||
if (keyEvent.matchesBinding(KeybindingOption.ACCEPT) && canCommit) {
|
if (keyEvent.matchesBinding(KeybindingOption.TEXT_ACCEPT) && canCommit) {
|
||||||
doCommit(false)
|
doCommit(false)
|
||||||
true
|
true
|
||||||
} else
|
} else
|
||||||
|
@ -0,0 +1,126 @@
|
|||||||
|
package com.jetpackduba.gitnuro.ui.dialogs
|
||||||
|
|
||||||
|
import androidx.compose.foundation.layout.*
|
||||||
|
import androidx.compose.foundation.lazy.LazyColumn
|
||||||
|
import androidx.compose.foundation.lazy.itemsIndexed
|
||||||
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||||
|
import androidx.compose.material.Icon
|
||||||
|
import androidx.compose.material.MaterialTheme
|
||||||
|
import androidx.compose.material.Text
|
||||||
|
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.FocusRequester
|
||||||
|
import androidx.compose.ui.focus.focusRequester
|
||||||
|
import androidx.compose.ui.input.key.onKeyEvent
|
||||||
|
import androidx.compose.ui.res.painterResource
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import com.jetpackduba.gitnuro.extensions.backgroundIf
|
||||||
|
import com.jetpackduba.gitnuro.extensions.handMouseClickable
|
||||||
|
import com.jetpackduba.gitnuro.keybindings.KeybindingOption
|
||||||
|
import com.jetpackduba.gitnuro.keybindings.matchesBinding
|
||||||
|
import com.jetpackduba.gitnuro.theme.backgroundSelected
|
||||||
|
import com.jetpackduba.gitnuro.ui.components.AdjustableOutlinedTextField
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun QuickActionsDialog(
|
||||||
|
onClose: () -> Unit,
|
||||||
|
onAction: (QuickActionType) -> Unit,
|
||||||
|
) {
|
||||||
|
|
||||||
|
val textFieldFocusRequester = remember { FocusRequester() }
|
||||||
|
val items = remember {
|
||||||
|
listOf(
|
||||||
|
QuickAction("open.svg", "Open project in file manager", QuickActionType.OPEN_DIR_IN_FILE_MANAGER),
|
||||||
|
QuickAction("download.svg", "Clone new repository", QuickActionType.CLONE),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
var searchFilter by remember { mutableStateOf("") }
|
||||||
|
|
||||||
|
val filteredItems by remember(searchFilter) {
|
||||||
|
derivedStateOf { items.filter { it.title.contains(searchFilter, ignoreCase = true) } }
|
||||||
|
}
|
||||||
|
|
||||||
|
var selectedIndex by remember(filteredItems) {
|
||||||
|
mutableStateOf(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
LaunchedEffect(Unit) {
|
||||||
|
textFieldFocusRequester.requestFocus()
|
||||||
|
}
|
||||||
|
|
||||||
|
MaterialDialog(
|
||||||
|
onCloseRequested = onClose,
|
||||||
|
background = MaterialTheme.colors.surface,
|
||||||
|
) {
|
||||||
|
Column(
|
||||||
|
modifier = Modifier.width(680.dp)
|
||||||
|
.height(400.dp)
|
||||||
|
.onKeyEvent { keyEvent ->
|
||||||
|
if (keyEvent.matchesBinding(KeybindingOption.DOWN)) {
|
||||||
|
if (selectedIndex < filteredItems.count() - 1)
|
||||||
|
selectedIndex++
|
||||||
|
true
|
||||||
|
} else if (keyEvent.matchesBinding(KeybindingOption.UP)) {
|
||||||
|
if (selectedIndex > 0)
|
||||||
|
selectedIndex--
|
||||||
|
true
|
||||||
|
} else if (keyEvent.matchesBinding(KeybindingOption.SIMPLE_ACCEPT)) {
|
||||||
|
val item = filteredItems.getOrNull(selectedIndex)
|
||||||
|
if (item != null)
|
||||||
|
onAction(item.type)
|
||||||
|
true
|
||||||
|
} else
|
||||||
|
false
|
||||||
|
}
|
||||||
|
) {
|
||||||
|
AdjustableOutlinedTextField(
|
||||||
|
value = searchFilter,
|
||||||
|
onValueChange = { searchFilter = it },
|
||||||
|
maxLines = 1,
|
||||||
|
modifier = Modifier.fillMaxWidth()
|
||||||
|
.padding(bottom = 16.dp)
|
||||||
|
.focusRequester(textFieldFocusRequester)
|
||||||
|
)
|
||||||
|
|
||||||
|
LazyColumn(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.weight(1f)
|
||||||
|
) {
|
||||||
|
itemsIndexed(filteredItems) { index, item ->
|
||||||
|
Row(
|
||||||
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.clip(RoundedCornerShape(4.dp))
|
||||||
|
.backgroundIf(selectedIndex == index, MaterialTheme.colors.backgroundSelected)
|
||||||
|
.handMouseClickable { onAction(item.type) }
|
||||||
|
) {
|
||||||
|
Icon(
|
||||||
|
painterResource(item.icon),
|
||||||
|
contentDescription = null,
|
||||||
|
modifier = Modifier.padding(vertical = 16.dp, horizontal = 16.dp),
|
||||||
|
tint = MaterialTheme.colors.onBackground,
|
||||||
|
)
|
||||||
|
|
||||||
|
Text(
|
||||||
|
item.title,
|
||||||
|
color = MaterialTheme.colors.onBackground,
|
||||||
|
style = MaterialTheme.typography.body1,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
data class QuickAction(val icon: String, val title: String, val type: QuickActionType)
|
||||||
|
|
||||||
|
enum class QuickActionType {
|
||||||
|
OPEN_DIR_IN_FILE_MANAGER,
|
||||||
|
CLONE;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user