diff --git a/src/main/kotlin/com/jetpackduba/gitnuro/ui/AppTab.kt b/src/main/kotlin/com/jetpackduba/gitnuro/ui/AppTab.kt index 7d90ca7..6c509f4 100644 --- a/src/main/kotlin/com/jetpackduba/gitnuro/ui/AppTab.kt +++ b/src/main/kotlin/com/jetpackduba/gitnuro/ui/AppTab.kt @@ -1,14 +1,9 @@ package com.jetpackduba.gitnuro.ui -import androidx.compose.animation.AnimatedVisibility import androidx.compose.animation.Crossfade -import androidx.compose.animation.fadeIn -import androidx.compose.animation.fadeOut import androidx.compose.foundation.background -import androidx.compose.foundation.clickable -import androidx.compose.foundation.interaction.MutableInteractionSource import androidx.compose.foundation.layout.* -import androidx.compose.material.Card +import androidx.compose.material.Icon import androidx.compose.material.LinearProgressIndicator import androidx.compose.material.MaterialTheme import androidx.compose.material.Text @@ -16,6 +11,7 @@ import androidx.compose.runtime.* import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.input.key.onPreviewKeyEvent +import androidx.compose.ui.res.painterResource import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp @@ -24,11 +20,11 @@ import com.jetpackduba.gitnuro.LocalTabScope import com.jetpackduba.gitnuro.credentials.CredentialsAccepted import com.jetpackduba.gitnuro.credentials.CredentialsRequested import com.jetpackduba.gitnuro.credentials.CredentialsState +import com.jetpackduba.gitnuro.ui.components.PrimaryButton import com.jetpackduba.gitnuro.ui.dialogs.* import com.jetpackduba.gitnuro.ui.dialogs.settings.SettingsDialog import com.jetpackduba.gitnuro.viewmodels.RepositorySelectionStatus import com.jetpackduba.gitnuro.viewmodels.TabViewModel -import kotlinx.coroutines.delay @Composable fun AppTab( @@ -38,14 +34,6 @@ fun AppTab( val lastError by errorManager.error.collectAsState(null) val showError by tabViewModel.showError.collectAsState() - if (lastError != null) { - LaunchedEffect(lastError) { - tabViewModel.showError.value = true - delay(5000) - tabViewModel.showError.value = false - } - } - val repositorySelectionStatus = tabViewModel.repositorySelectionStatus.collectAsState() val repositorySelectionStatusValue = repositorySelectionStatus.value val isProcessing by tabViewModel.processing.collectAsState() @@ -117,7 +105,6 @@ fun AppTab( contentAlignment = Alignment.Center, ) { Column { - LinearProgressIndicator( modifier = Modifier.width(340.dp), color = MaterialTheme.colors.secondary, @@ -128,48 +115,45 @@ fun AppTab( val safeLastError = lastError - if (safeLastError != null) { - AnimatedVisibility( - visible = showError, - enter = fadeIn(), - exit = fadeOut(), - modifier = Modifier - .align(Alignment.BottomEnd) - .padding(end = 32.dp, bottom = 32.dp) - ) { - val interactionSource = remember { MutableInteractionSource() } - // TODO: Rework popup to appear on top of every other UI component, even dialogs - Card( + if (safeLastError != null && showError) { + MaterialDialog { + Column( modifier = Modifier - .defaultMinSize(minWidth = 200.dp, minHeight = 100.dp) - .clickable( - enabled = true, - onClick = {}, - interactionSource = interactionSource, - indication = null - ), - backgroundColor = MaterialTheme.colors.error, + .width(580.dp) ) { - Column( - modifier = Modifier - .padding(horizontal = 32.dp) - ) { + Row { Text( text = "Error", - fontSize = 20.sp, - fontWeight = FontWeight.Medium, - modifier = Modifier - .padding(top = 16.dp), - color = MaterialTheme.colors.onError, - ) // TODO Add more descriptive title - - Text( - text = lastError?.message ?: "", - color = MaterialTheme.colors.onError, - modifier = Modifier - .padding(top = 8.dp, bottom = 16.dp) - .widthIn(max = 600.dp) + fontSize = 16.sp, + fontWeight = FontWeight.SemiBold, + color = MaterialTheme.colors.onBackground, ) + + Spacer(modifier = Modifier.weight(1f)) + + Icon( + painterResource("error.svg"), + contentDescription = null, + tint = MaterialTheme.colors.error, + modifier = Modifier.size(24.dp) + ) + } + + Text( + text = lastError?.message ?: "", + color = MaterialTheme.colors.onBackground, + modifier = Modifier + .padding(top = 16.dp) + .widthIn(max = 600.dp), + style = MaterialTheme.typography.body2, + ) + + Row( + modifier = Modifier + .align(Alignment.End) + .padding(top = 32.dp) + ) { + PrimaryButton(text = "OK", onClick = { tabViewModel.showError.value = false }) } } } @@ -192,6 +176,7 @@ fun CredentialsDialog(gitManager: TabViewModel) { } ) } + CredentialsRequested.SshCredentialsRequested -> { SshPasswordDialog( onReject = { @@ -202,6 +187,7 @@ fun CredentialsDialog(gitManager: TabViewModel) { } ) } + is CredentialsRequested.GpgCredentialsRequested -> { GpgPasswordDialog( gpgCredentialsRequested = credentialsStateValue, @@ -214,6 +200,7 @@ fun CredentialsDialog(gitManager: TabViewModel) { ) } - is CredentialsAccepted, CredentialsState.None, CredentialsState.CredentialsDenied -> { /* Nothing to do */ } + is CredentialsAccepted, CredentialsState.None, CredentialsState.CredentialsDenied -> { /* Nothing to do */ + } } } diff --git a/src/main/kotlin/com/jetpackduba/gitnuro/viewmodels/TabViewModel.kt b/src/main/kotlin/com/jetpackduba/gitnuro/viewmodels/TabViewModel.kt index de709a0..9eec338 100644 --- a/src/main/kotlin/com/jetpackduba/gitnuro/viewmodels/TabViewModel.kt +++ b/src/main/kotlin/com/jetpackduba/gitnuro/viewmodels/TabViewModel.kt @@ -136,6 +136,12 @@ class TabViewModel @Inject constructor( loadRepositoryState(tabState.git) } } + + launch { + errorsManager.error.collect { + showError.value = true + } + } } } diff --git a/src/main/resources/error.svg b/src/main/resources/error.svg new file mode 100644 index 0000000..5d4e432 --- /dev/null +++ b/src/main/resources/error.svg @@ -0,0 +1 @@ + \ No newline at end of file