Added dialog/window closing on pressing ESC

Should partially fix:
https://github.com/JetpackDuba/Gitnuro/issues/9
This commit is contained in:
Abdelilah El Aissaoui 2022-06-06 14:58:53 +02:00
parent 6901bf9f1c
commit 3a100f547b
15 changed files with 127 additions and 28 deletions

View File

@ -4,6 +4,7 @@ package app.ui
import androidx.compose.foundation.Image import androidx.compose.foundation.Image
import androidx.compose.foundation.background import androidx.compose.foundation.background
import androidx.compose.foundation.focusable
import androidx.compose.foundation.layout.* import androidx.compose.foundation.layout.*
import androidx.compose.foundation.text.selection.DisableSelection import androidx.compose.foundation.text.selection.DisableSelection
import androidx.compose.foundation.text.selection.SelectionContainer import androidx.compose.foundation.text.selection.SelectionContainer
@ -11,10 +12,17 @@ import androidx.compose.material.IconButton
import androidx.compose.material.MaterialTheme import androidx.compose.material.MaterialTheme
import androidx.compose.material.Text import androidx.compose.material.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.ExperimentalComposeUiApi import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.FocusRequester
import androidx.compose.ui.focus.focusRequester
import androidx.compose.ui.graphics.ColorFilter import androidx.compose.ui.graphics.ColorFilter
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.input.pointer.PointerIconDefaults import androidx.compose.ui.input.pointer.PointerIconDefaults
import androidx.compose.ui.input.pointer.pointerHoverIcon import androidx.compose.ui.input.pointer.pointerHoverIcon
import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.painterResource
@ -38,7 +46,25 @@ fun Blame(
onSelectCommit: (RevCommit) -> Unit, onSelectCommit: (RevCommit) -> Unit,
onClose: () -> Unit, onClose: () -> Unit,
) { ) {
Column {
val focusRequester = remember { FocusRequester() }
LaunchedEffect(Unit) {
focusRequester.requestFocus()
}
Column(
modifier = Modifier
.focusRequester(focusRequester)
.focusable()
.onPreviewKeyEvent {
if (it.key == Key.Escape) {
onClose()
true
} else
false
},
) {
Header(filePath, onClose = onClose) Header(filePath, onClose = onClose)
SelectionContainer { SelectionContainer {
ScrollableLazyColumn( ScrollableLazyColumn(

View File

@ -4,6 +4,7 @@ package app.ui
import androidx.compose.foundation.Image import androidx.compose.foundation.Image
import androidx.compose.foundation.background import androidx.compose.foundation.background
import androidx.compose.foundation.focusable
import androidx.compose.foundation.layout.* import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyListState import androidx.compose.foundation.lazy.LazyListState
import androidx.compose.foundation.lazy.items import androidx.compose.foundation.lazy.items
@ -13,14 +14,17 @@ import androidx.compose.material.IconButton
import androidx.compose.material.LinearProgressIndicator import androidx.compose.material.LinearProgressIndicator
import androidx.compose.material.MaterialTheme import androidx.compose.material.MaterialTheme
import androidx.compose.material.Text import androidx.compose.material.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.*
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.ExperimentalComposeUiApi import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.FocusRequester
import androidx.compose.ui.focus.focusRequester
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.ColorFilter import androidx.compose.ui.graphics.ColorFilter
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.input.pointer.PointerIconDefaults import androidx.compose.ui.input.pointer.PointerIconDefaults
import androidx.compose.ui.input.pointer.pointerHoverIcon import androidx.compose.ui.input.pointer.pointerHoverIcon
import androidx.compose.ui.res.loadImageBitmap import androidx.compose.ui.res.loadImageBitmap
@ -59,11 +63,25 @@ fun Diff(
) { ) {
val diffResultState = diffViewModel.diffResult.collectAsState() val diffResultState = diffViewModel.diffResult.collectAsState()
val viewDiffResult = diffResultState.value ?: return val viewDiffResult = diffResultState.value ?: return
val focusRequester = remember { FocusRequester() }
LaunchedEffect(Unit) {
focusRequester.requestFocus()
}
Column( Column(
modifier = Modifier modifier = Modifier
.background(MaterialTheme.colors.background) .background(MaterialTheme.colors.background)
.fillMaxSize() .fillMaxSize()
.focusRequester(focusRequester)
.focusable()
.onPreviewKeyEvent {
if (it.key == Key.Escape) {
onCloseDiffView()
true
} else
false
}
) { ) {
when (viewDiffResult) { when (viewDiffResult) {
ViewDiffResult.DiffNotFound -> { onCloseDiffView() } ViewDiffResult.DiffNotFound -> { onCloseDiffView() }
@ -323,7 +341,7 @@ fun DiffHeader(
Spacer(modifier = Modifier.weight(1f)) Spacer(modifier = Modifier.weight(1f))
if(diffEntryType is DiffEntryType.UncommitedDiff) { if (diffEntryType is DiffEntryType.UncommitedDiff) {
val buttonText: String val buttonText: String
val color: Color val color: Color
@ -405,7 +423,10 @@ fun DiffLine(
} }
Text( Text(
text = line.text.replace("\t", " "), // TODO this replace is a workaround until this issue gets fixed https://github.com/JetBrains/compose-jb/issues/615 text = line.text.replace(
"\t",
" "
), // TODO this replace is a workaround until this issue gets fixed https://github.com/JetBrains/compose-jb/issues/615
modifier = Modifier modifier = Modifier
.padding(start = 8.dp) .padding(start = 8.dp)
.fillMaxSize(), .fillMaxSize(),

View File

@ -4,20 +4,24 @@ package app.ui
import androidx.compose.foundation.Image import androidx.compose.foundation.Image
import androidx.compose.foundation.background import androidx.compose.foundation.background
import androidx.compose.foundation.focusable
import androidx.compose.foundation.layout.* import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyListState import androidx.compose.foundation.lazy.LazyListState
import androidx.compose.foundation.lazy.items import androidx.compose.foundation.lazy.items
import androidx.compose.material.IconButton import androidx.compose.material.IconButton
import androidx.compose.material.MaterialTheme import androidx.compose.material.MaterialTheme
import androidx.compose.material.Text import androidx.compose.material.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.*
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.ExperimentalComposeUiApi import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.FocusRequester
import androidx.compose.ui.focus.focusRequester
import androidx.compose.ui.graphics.ColorFilter import androidx.compose.ui.graphics.ColorFilter
import androidx.compose.ui.input.key.Key
import androidx.compose.ui.input.key.key
import androidx.compose.ui.input.key.onKeyEvent
import androidx.compose.ui.input.key.onPreviewKeyEvent
import androidx.compose.ui.input.pointer.PointerIconDefaults import androidx.compose.ui.input.pointer.PointerIconDefaults
import androidx.compose.ui.input.pointer.pointerHoverIcon import androidx.compose.ui.input.pointer.pointerHoverIcon
import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.painterResource
@ -46,9 +50,24 @@ fun FileHistory(
) { ) {
val historyState by historyViewModel.historyState.collectAsState() val historyState by historyViewModel.historyState.collectAsState()
val focusRequester = remember { FocusRequester() }
LaunchedEffect(Unit) {
focusRequester.requestFocus()
}
Column( Column(
modifier = Modifier modifier = Modifier
.fillMaxSize() .fillMaxSize()
.focusRequester(focusRequester)
.focusable()
.onKeyEvent {
if (it.key == Key.Escape) {
onClose()
true
} else
false
},
) { ) {
Header(filePath = historyState.filePath, onClose = onClose) Header(filePath = historyState.filePath, onClose = onClose)

View File

@ -22,7 +22,7 @@ import app.ui.components.TextLink
fun AppInfoDialog( fun AppInfoDialog(
onClose: () -> Unit, onClose: () -> Unit,
) { ) {
MaterialDialog { MaterialDialog(onCloseRequested = onClose) {
Column( Column(
modifier = Modifier modifier = Modifier
.width(600.dp) .width(600.dp)

View File

@ -35,7 +35,7 @@ fun CloneDialog(
val cloneStatus = cloneViewModel.cloneStatus.collectAsState() val cloneStatus = cloneViewModel.cloneStatus.collectAsState()
val cloneStatusValue = cloneStatus.value val cloneStatusValue = cloneStatus.value
MaterialDialog { MaterialDialog(onCloseRequested = onClose) {
Box( Box(
modifier = Modifier modifier = Modifier
.width(400.dp) .width(400.dp)

View File

@ -1,11 +1,9 @@
package app.ui.dialogs package app.ui.dialogs
import androidx.compose.foundation.background import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.layout.* import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.* import androidx.compose.material.*
import androidx.compose.material.icons.Icons import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Clear import androidx.compose.material.icons.filled.Clear
@ -68,6 +66,7 @@ fun EditRemotesDialog(
MaterialDialog( MaterialDialog(
paddingVertical = 8.dp, paddingVertical = 8.dp,
paddingHorizontal = 16.dp, paddingHorizontal = 16.dp,
onCloseRequested = onDismiss
) { ) {
Column( Column(
modifier = Modifier modifier = Modifier
@ -102,11 +101,6 @@ fun EditRemotesDialog(
Row( Row(
modifier = Modifier modifier = Modifier
.padding(bottom = 8.dp) .padding(bottom = 8.dp)
.border(
width = 1.dp,
shape = RoundedCornerShape(5.dp),
color = MaterialTheme.colors.borderColor,
)
.background(MaterialTheme.colors.surface) .background(MaterialTheme.colors.surface)
) { ) {
Column( Column(

View File

@ -1,15 +1,26 @@
@file:OptIn(ExperimentalComposeUiApi::class)
package app.ui.dialogs package app.ui.dialogs
import androidx.compose.foundation.background import androidx.compose.foundation.background
import androidx.compose.foundation.focusable
import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.MaterialTheme import androidx.compose.material.MaterialTheme
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip import androidx.compose.ui.draw.clip
import androidx.compose.ui.focus.FocusRequester
import androidx.compose.ui.focus.focusRequester
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.unit.* import androidx.compose.ui.unit.*
import androidx.compose.ui.window.Popup import androidx.compose.ui.window.Popup
import androidx.compose.ui.window.PopupPositionProvider import androidx.compose.ui.window.PopupPositionProvider
@ -20,6 +31,7 @@ fun MaterialDialog(
alignment: Alignment = Alignment.Center, alignment: Alignment = Alignment.Center,
paddingHorizontal: Dp = 16.dp, paddingHorizontal: Dp = 16.dp,
paddingVertical: Dp = 16.dp, paddingVertical: Dp = 16.dp,
onCloseRequested: () -> Unit = {},
content: @Composable () -> Unit content: @Composable () -> Unit
) { ) {
Popup( Popup(
@ -33,10 +45,26 @@ fun MaterialDialog(
): IntOffset = IntOffset.Zero ): IntOffset = IntOffset.Zero
} }
) { ) {
val focusRequester = remember { FocusRequester() }
LaunchedEffect(Unit) {
focusRequester.requestFocus()
}
Box( Box(
modifier = Modifier modifier = Modifier
.fillMaxSize() .fillMaxSize()
.background(MaterialTheme.colors.dialogOverlay), .background(MaterialTheme.colors.dialogOverlay)
.focusRequester(focusRequester)
.focusable()
.onPreviewKeyEvent {
if (it.key == Key.Escape) {
onCloseRequested()
true
} else
false
},
contentAlignment = alignment, contentAlignment = alignment,
) { ) {
Box( Box(

View File

@ -29,7 +29,7 @@ fun MergeDialog(
) { ) {
var fastForwardCheck by remember { mutableStateOf(fastForward) } var fastForwardCheck by remember { mutableStateOf(fastForward) }
MaterialDialog { MaterialDialog(onCloseRequested = onReject) {
Column( Column(
modifier = Modifier modifier = Modifier
.background(MaterialTheme.colors.background), .background(MaterialTheme.colors.background),

View File

@ -30,7 +30,7 @@ fun NewBranchDialog(
val branchFieldFocusRequester = remember { FocusRequester() } val branchFieldFocusRequester = remember { FocusRequester() }
val buttonFieldFocusRequester = remember { FocusRequester() } val buttonFieldFocusRequester = remember { FocusRequester() }
MaterialDialog { MaterialDialog(onCloseRequested = onReject) {
Column( Column(
modifier = Modifier modifier = Modifier
.background(MaterialTheme.colors.background), .background(MaterialTheme.colors.background),

View File

@ -30,7 +30,7 @@ fun NewTagDialog(
val tagFieldFocusRequester = remember { FocusRequester() } val tagFieldFocusRequester = remember { FocusRequester() }
val buttonFieldFocusRequester = remember { FocusRequester() } val buttonFieldFocusRequester = remember { FocusRequester() }
MaterialDialog { MaterialDialog(onCloseRequested = onReject) {
Column( Column(
modifier = Modifier modifier = Modifier
.background(MaterialTheme.colors.background), .background(MaterialTheme.colors.background),

View File

@ -30,7 +30,7 @@ fun PasswordDialog(
val passwordFieldFocusRequester = remember { FocusRequester() } val passwordFieldFocusRequester = remember { FocusRequester() }
val buttonFieldFocusRequester = remember { FocusRequester() } val buttonFieldFocusRequester = remember { FocusRequester() }
MaterialDialog { MaterialDialog(onCloseRequested = onReject) {
Column( Column(
modifier = Modifier modifier = Modifier
.background(MaterialTheme.colors.background), .background(MaterialTheme.colors.background),

View File

@ -26,7 +26,7 @@ fun RebaseDialog(
onReject: () -> Unit, onReject: () -> Unit,
onAccept: () -> Unit onAccept: () -> Unit
) { ) {
MaterialDialog { MaterialDialog(onCloseRequested = onReject) {
Column( Column(
modifier = Modifier modifier = Modifier
.background(MaterialTheme.colors.background), .background(MaterialTheme.colors.background),

View File

@ -27,7 +27,7 @@ fun ResetBranchDialog(
) { ) {
var resetType by remember { mutableStateOf(ResetType.MIXED) } var resetType by remember { mutableStateOf(ResetType.MIXED) }
MaterialDialog { MaterialDialog(onCloseRequested = onReject) {
Column( Column(
modifier = Modifier modifier = Modifier
.background(MaterialTheme.colors.background), .background(MaterialTheme.colors.background),

View File

@ -28,7 +28,16 @@ fun SettingsDialog(
val commitsLimitEnabled by appPreferences.commitsLimitEnabledFlow.collectAsState() val commitsLimitEnabled by appPreferences.commitsLimitEnabledFlow.collectAsState()
var commitsLimit by remember { mutableStateOf(appPreferences.commitsLimit) } var commitsLimit by remember { mutableStateOf(appPreferences.commitsLimit) }
MaterialDialog { MaterialDialog(
onCloseRequested = {
savePendingSettings(
appPreferences = appPreferences,
commitsLimit = commitsLimit,
)
onDismiss()
}
) {
Column(modifier = Modifier.width(720.dp)) { Column(modifier = Modifier.width(720.dp)) {
Text( Text(
text = "Settings", text = "Settings",

View File

@ -35,7 +35,9 @@ fun UserPasswordDialog(
val acceptDialog = { val acceptDialog = {
onAccept(userField, passwordField) onAccept(userField, passwordField)
} }
MaterialDialog { MaterialDialog(
onCloseRequested = onReject
) {
Column( Column(
modifier = Modifier modifier = Modifier
.background(MaterialTheme.colors.background), .background(MaterialTheme.colors.background),