Added basic implementation of error manager
This commit is contained in:
parent
469fe530ee
commit
40fe4c694f
34
src/main/kotlin/app/ErrorsManager.kt
Normal file
34
src/main/kotlin/app/ErrorsManager.kt
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
package app.app
|
||||||
|
|
||||||
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
|
import kotlinx.coroutines.flow.StateFlow
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
class ErrorsManager @Inject constructor() {
|
||||||
|
private val _errorsList = MutableStateFlow(listOf<Error>())
|
||||||
|
val errorsList: StateFlow<List<Error>>
|
||||||
|
get() = _errorsList
|
||||||
|
|
||||||
|
private val _lastError = MutableStateFlow<Error?>(null)
|
||||||
|
val lastError: StateFlow<Error?>
|
||||||
|
get() = _lastError
|
||||||
|
|
||||||
|
fun addError(error: Error) {
|
||||||
|
_errorsList.value = _errorsList.value.toMutableList().apply {
|
||||||
|
add(error)
|
||||||
|
}
|
||||||
|
|
||||||
|
_lastError.value = error
|
||||||
|
}
|
||||||
|
|
||||||
|
fun removeError(error: Error) {
|
||||||
|
_errorsList.value = _errorsList.value.toMutableList().apply {
|
||||||
|
remove(error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
data class Error(val date: Long, val exception: Exception, val message: String)
|
||||||
|
|
||||||
|
fun newErrorNow(exception: Exception,message: String) = Error(System.currentTimeMillis(), exception, message)
|
@ -12,6 +12,9 @@ import org.eclipse.jgit.lib.Repository
|
|||||||
import org.eclipse.jgit.revwalk.RevCommit
|
import org.eclipse.jgit.revwalk.RevCommit
|
||||||
import org.eclipse.jgit.storage.file.FileRepositoryBuilder
|
import org.eclipse.jgit.storage.file.FileRepositoryBuilder
|
||||||
import app.AppStateManager
|
import app.AppStateManager
|
||||||
|
import app.app.Error
|
||||||
|
import app.app.ErrorsManager
|
||||||
|
import app.app.newErrorNow
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
@ -23,6 +26,7 @@ class GitManager @Inject constructor(
|
|||||||
private val branchesManager: BranchesManager,
|
private val branchesManager: BranchesManager,
|
||||||
private val stashManager: StashManager,
|
private val stashManager: StashManager,
|
||||||
private val diffManager: DiffManager,
|
private val diffManager: DiffManager,
|
||||||
|
val errorsManager: ErrorsManager,
|
||||||
val appStateManager: AppStateManager,
|
val appStateManager: AppStateManager,
|
||||||
) {
|
) {
|
||||||
val repositoryName: String
|
val repositoryName: String
|
||||||
@ -109,7 +113,7 @@ class GitManager @Inject constructor(
|
|||||||
} catch (ex: Exception) {
|
} catch (ex: Exception) {
|
||||||
ex.printStackTrace()
|
ex.printStackTrace()
|
||||||
onRepositoryChanged(null)
|
onRepositoryChanged(null)
|
||||||
|
errorsManager.addError(newErrorNow(ex, ex.localizedMessage))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -192,8 +196,10 @@ class GitManager @Inject constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun createBranch(branchName: String) = managerScope.launch {
|
fun createBranch(branchName: String) = managerScope.launch {
|
||||||
branchesManager.createBranch(safeGit, branchName)
|
safeProcessing {
|
||||||
coLoadLog()
|
branchesManager.createBranch(safeGit, branchName)
|
||||||
|
coLoadLog()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun deleteBranch(branch: Ref) = managerScope.launch {
|
fun deleteBranch(branch: Ref) = managerScope.launch {
|
||||||
@ -238,6 +244,8 @@ class GitManager @Inject constructor(
|
|||||||
_processing.value = true
|
_processing.value = true
|
||||||
try {
|
try {
|
||||||
callback()
|
callback()
|
||||||
|
} catch (ex: Exception) {
|
||||||
|
errorsManager.addError(newErrorNow(ex, ex.localizedMessage))
|
||||||
} finally {
|
} finally {
|
||||||
_processing.value = false
|
_processing.value = false
|
||||||
}
|
}
|
||||||
|
@ -1,30 +1,63 @@
|
|||||||
package app.ui
|
package app.ui
|
||||||
|
|
||||||
|
import androidx.compose.animation.AnimatedVisibility
|
||||||
import androidx.compose.animation.Crossfade
|
import androidx.compose.animation.Crossfade
|
||||||
|
import androidx.compose.animation.ExperimentalAnimationApi
|
||||||
import androidx.compose.foundation.background
|
import androidx.compose.foundation.background
|
||||||
import androidx.compose.foundation.layout.Box
|
import androidx.compose.foundation.clickable
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.interaction.MutableInteractionSource
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
import androidx.compose.foundation.layout.*
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.material.Card
|
||||||
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.runtime.*
|
import androidx.compose.runtime.*
|
||||||
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.draw.alpha
|
import androidx.compose.ui.draw.alpha
|
||||||
|
import androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.graphics.DefaultAlpha
|
import androidx.compose.ui.graphics.DefaultAlpha
|
||||||
|
import androidx.compose.ui.text.font.FontWeight
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import androidx.compose.ui.unit.sp
|
||||||
import app.DialogManager
|
import app.DialogManager
|
||||||
import app.LoadingRepository
|
import app.LoadingRepository
|
||||||
import app.git.GitManager
|
import app.git.GitManager
|
||||||
import app.git.RepositorySelectionStatus
|
import app.git.RepositorySelectionStatus
|
||||||
|
import app.ui.components.DialogBox
|
||||||
|
import kotlinx.coroutines.delay
|
||||||
|
|
||||||
|
|
||||||
|
@OptIn(ExperimentalAnimationApi::class)
|
||||||
@Composable
|
@Composable
|
||||||
fun AppTab(gitManager: GitManager, dialogManager: DialogManager, repositoryPath: String?, tabName: MutableState<String>) {
|
fun AppTab(
|
||||||
|
gitManager: GitManager,
|
||||||
|
dialogManager: DialogManager,
|
||||||
|
repositoryPath: String?,
|
||||||
|
tabName: MutableState<String>
|
||||||
|
) {
|
||||||
LaunchedEffect(gitManager) {
|
LaunchedEffect(gitManager) {
|
||||||
if (repositoryPath != null)
|
if (repositoryPath != null)
|
||||||
gitManager.openRepository(repositoryPath)
|
gitManager.openRepository(repositoryPath)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val errorManager = remember(gitManager) { // TODO Is remember here necessary?
|
||||||
|
gitManager.errorsManager
|
||||||
|
}
|
||||||
|
|
||||||
|
val lastError by errorManager.lastError.collectAsState()
|
||||||
|
|
||||||
|
var showError by remember {
|
||||||
|
mutableStateOf(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lastError != null)
|
||||||
|
LaunchedEffect(lastError) {
|
||||||
|
showError = true
|
||||||
|
delay(5000)
|
||||||
|
showError = false
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
val repositorySelectionStatus by gitManager.repositorySelectionStatus.collectAsState()
|
val repositorySelectionStatus by gitManager.repositorySelectionStatus.collectAsState()
|
||||||
val isProcessing by gitManager.processing.collectAsState()
|
val isProcessing by gitManager.processing.collectAsState()
|
||||||
@ -33,42 +66,87 @@ fun AppTab(gitManager: GitManager, dialogManager: DialogManager, repositoryPath:
|
|||||||
tabName.value = gitManager.repositoryName
|
tabName.value = gitManager.repositoryName
|
||||||
}
|
}
|
||||||
|
|
||||||
Column(
|
Box {
|
||||||
modifier = Modifier
|
Column(
|
||||||
.background(MaterialTheme.colors.background)
|
|
||||||
.fillMaxSize()
|
|
||||||
) {
|
|
||||||
|
|
||||||
val linearProgressAlpha = if (isProcessing)
|
|
||||||
DefaultAlpha
|
|
||||||
else
|
|
||||||
0f
|
|
||||||
|
|
||||||
LinearProgressIndicator(
|
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxWidth()
|
.background(MaterialTheme.colors.background)
|
||||||
.alpha(linearProgressAlpha)
|
.fillMaxSize()
|
||||||
)
|
) {
|
||||||
|
|
||||||
Box(modifier = Modifier.fillMaxSize()) {
|
val linearProgressAlpha = if (isProcessing)
|
||||||
Crossfade(targetState = repositorySelectionStatus) {
|
DefaultAlpha
|
||||||
|
else
|
||||||
|
0f
|
||||||
|
|
||||||
@Suppress("UnnecessaryVariable") // Don't inline it because smart cast won't work
|
LinearProgressIndicator(
|
||||||
when (repositorySelectionStatus) {
|
modifier = Modifier
|
||||||
RepositorySelectionStatus.None -> {
|
.fillMaxWidth()
|
||||||
WelcomePage(gitManager = gitManager)
|
.alpha(linearProgressAlpha)
|
||||||
|
)
|
||||||
|
|
||||||
|
Box(modifier = Modifier.fillMaxSize()) {
|
||||||
|
Crossfade(targetState = repositorySelectionStatus) {
|
||||||
|
|
||||||
|
@Suppress("UnnecessaryVariable") // Don't inline it because smart cast won't work
|
||||||
|
when (repositorySelectionStatus) {
|
||||||
|
RepositorySelectionStatus.None -> {
|
||||||
|
WelcomePage(gitManager = gitManager)
|
||||||
|
}
|
||||||
|
RepositorySelectionStatus.Loading -> {
|
||||||
|
LoadingRepository()
|
||||||
|
}
|
||||||
|
is RepositorySelectionStatus.Open -> {
|
||||||
|
RepositoryOpenPage(gitManager = gitManager, dialogManager = dialogManager)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
RepositorySelectionStatus.Loading -> {
|
}
|
||||||
LoadingRepository()
|
|
||||||
}
|
if (isProcessing)
|
||||||
is RepositorySelectionStatus.Open -> {
|
Box(modifier = Modifier.fillMaxSize()) //TODO this should block of the mouse/keyboard events while visible
|
||||||
RepositoryOpenPage(gitManager = gitManager, dialogManager = dialogManager)
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val safeLastError = lastError
|
||||||
|
if (safeLastError != null) {
|
||||||
|
AnimatedVisibility(
|
||||||
|
visible = showError,
|
||||||
|
modifier = Modifier
|
||||||
|
.align(Alignment.BottomEnd)
|
||||||
|
.padding(end = 32.dp, bottom = 32.dp)
|
||||||
|
) {
|
||||||
|
val interactionSource = remember { MutableInteractionSource() }
|
||||||
|
|
||||||
|
Card(
|
||||||
|
modifier = Modifier
|
||||||
|
.defaultMinSize(minWidth = 200.dp, minHeight = 100.dp)
|
||||||
|
.clickable(
|
||||||
|
enabled = true,
|
||||||
|
onClick = {},
|
||||||
|
interactionSource = interactionSource,
|
||||||
|
indication = null
|
||||||
|
),
|
||||||
|
backgroundColor = MaterialTheme.colors.error,
|
||||||
|
) {
|
||||||
|
Column(
|
||||||
|
modifier = Modifier
|
||||||
|
.padding(horizontal = 32.dp)
|
||||||
|
) {
|
||||||
|
Text(
|
||||||
|
text = "Error",
|
||||||
|
fontSize = 20.sp,
|
||||||
|
fontWeight = FontWeight.Medium,
|
||||||
|
modifier = Modifier
|
||||||
|
.padding(top = 16.dp)
|
||||||
|
) // TODO Add more descriptive title
|
||||||
|
|
||||||
|
Text(
|
||||||
|
text = safeLastError.message,
|
||||||
|
modifier = Modifier
|
||||||
|
.padding(top = 8.dp)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isProcessing)
|
|
||||||
Box(modifier = Modifier.fillMaxSize()) //TODO this should block of the mouse/keyboard events while visible
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user