230 lines
8.0 KiB
Kotlin
230 lines
8.0 KiB
Kotlin
package app
|
|
|
|
import androidx.compose.animation.Crossfade
|
|
import androidx.compose.foundation.background
|
|
import androidx.compose.foundation.layout.*
|
|
import androidx.compose.foundation.lazy.LazyColumn
|
|
import androidx.compose.foundation.lazy.items
|
|
import androidx.compose.material.*
|
|
import androidx.compose.runtime.*
|
|
import androidx.compose.ui.Alignment
|
|
import androidx.compose.ui.Modifier
|
|
import androidx.compose.ui.draw.alpha
|
|
import androidx.compose.ui.graphics.DefaultAlpha
|
|
import androidx.compose.ui.res.painterResource
|
|
import androidx.compose.ui.unit.dp
|
|
import androidx.compose.ui.window.*
|
|
import androidx.compose.ui.zIndex
|
|
import app.di.DaggerAppComponent
|
|
import app.git.GitManager
|
|
import app.git.RepositorySelectionStatus
|
|
import app.theme.AppTheme
|
|
import app.ui.RepositoryOpenPage
|
|
import app.ui.WelcomePage
|
|
import app.ui.components.RepositoriesTabPanel
|
|
import app.ui.components.TabInformation
|
|
import javax.inject.Inject
|
|
import javax.inject.Provider
|
|
|
|
class Main {
|
|
val appComponent = DaggerAppComponent.create()
|
|
|
|
@Inject
|
|
lateinit var gitManagerProvider: Provider<GitManager>
|
|
|
|
@Inject
|
|
lateinit var appStateManager: AppStateManager
|
|
|
|
init {
|
|
appComponent.inject(this)
|
|
|
|
appStateManager.loadRepositoriesTabs()
|
|
}
|
|
|
|
fun start() = application {
|
|
var isOpen by remember { mutableStateOf(true) }
|
|
|
|
if (isOpen) {
|
|
Window(
|
|
title = "Gitnuro",
|
|
onCloseRequest = {
|
|
isOpen = false
|
|
},
|
|
state = rememberWindowState(
|
|
placement = WindowPlacement.Maximized,
|
|
size = WindowSize(1280.dp, 720.dp)
|
|
)
|
|
) {
|
|
AppTheme {
|
|
val tabs = remember {
|
|
|
|
val repositoriesSavedTabs = appStateManager.openRepositoriesPathsTabs
|
|
var repoTabs = repositoriesSavedTabs.map { repositoryTab ->
|
|
newAppTab(key = repositoryTab.key, path = repositoryTab.value)
|
|
}
|
|
|
|
if (repoTabs.isEmpty()) {
|
|
repoTabs = listOf(
|
|
newAppTab()
|
|
)
|
|
}
|
|
|
|
mutableStateOf(repoTabs)
|
|
}
|
|
|
|
var selectedTabKey by remember { mutableStateOf(0) }
|
|
Column(
|
|
modifier =
|
|
Modifier.background(MaterialTheme.colors.surface)
|
|
) {
|
|
Row(
|
|
modifier = Modifier
|
|
.padding(top = 4.dp, bottom = 2.dp, start = 4.dp, end = 4.dp)
|
|
.fillMaxWidth(),
|
|
verticalAlignment = Alignment.CenterVertically,
|
|
) {
|
|
RepositoriesTabPanel(
|
|
modifier = Modifier
|
|
.weight(1f),
|
|
tabs = tabs.value,
|
|
selectedTabKey = selectedTabKey,
|
|
onTabSelected = { newSelectedTabKey ->
|
|
selectedTabKey = newSelectedTabKey
|
|
},
|
|
newTabContent = { key ->
|
|
newAppTab(key)
|
|
},
|
|
onTabsUpdated = { tabInformationList ->
|
|
tabs.value = tabInformationList
|
|
},
|
|
onTabClosed = { key ->
|
|
appStateManager.repositoryTabRemoved(key)
|
|
}
|
|
)
|
|
IconButton(
|
|
modifier = Modifier
|
|
.padding(horizontal = 8.dp)
|
|
.size(24.dp),
|
|
onClick = {}
|
|
) {
|
|
Icon(
|
|
painter = painterResource("settings.svg"),
|
|
contentDescription = null,
|
|
modifier = Modifier.fillMaxSize(),
|
|
tint = MaterialTheme.colors.primary,
|
|
)
|
|
}
|
|
}
|
|
|
|
LazyColumn(
|
|
modifier = Modifier
|
|
.fillMaxSize(),
|
|
) {
|
|
items(items = tabs.value, key = { it.key }) {
|
|
val isItemSelected = it.key == selectedTabKey
|
|
|
|
var tabMod: Modifier = if (!isItemSelected)
|
|
Modifier.size(0.dp)
|
|
else
|
|
Modifier
|
|
.fillParentMaxSize()
|
|
|
|
tabMod = tabMod.background(MaterialTheme.colors.primary)
|
|
.alpha(if (isItemSelected) 1f else -1f)
|
|
.zIndex(if (isItemSelected) 1f else -1f)
|
|
Box(
|
|
modifier = tabMod,
|
|
) {
|
|
it.content(it)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private fun newAppTab(
|
|
key: Int = 0,
|
|
tabName: MutableState<String> = mutableStateOf("New tab"),
|
|
path: String? = null,
|
|
): TabInformation {
|
|
|
|
return TabInformation(
|
|
title = tabName,
|
|
key = key
|
|
) {
|
|
val gitManager = remember { gitManagerProvider.get() }
|
|
gitManager.onRepositoryChanged = { path ->
|
|
if (path == null) {
|
|
appStateManager.repositoryTabRemoved(key)
|
|
} else
|
|
appStateManager.repositoryTabChanged(key, path)
|
|
}
|
|
|
|
App(gitManager, path, tabName)
|
|
}
|
|
}
|
|
}
|
|
|
|
@Composable
|
|
fun App(gitManager: GitManager, repositoryPath: String?, tabName: MutableState<String>) {
|
|
LaunchedEffect(gitManager) {
|
|
if (repositoryPath != null)
|
|
gitManager.openRepository(repositoryPath)
|
|
}
|
|
|
|
|
|
val repositorySelectionStatus by gitManager.repositorySelectionStatus.collectAsState()
|
|
val isProcessing by gitManager.processing.collectAsState()
|
|
|
|
if (repositorySelectionStatus is RepositorySelectionStatus.Open) {
|
|
tabName.value = gitManager.repositoryName
|
|
}
|
|
|
|
Column(
|
|
modifier = Modifier
|
|
.background(MaterialTheme.colors.background)
|
|
.fillMaxSize()
|
|
) {
|
|
|
|
val linearProgressAlpha = if (isProcessing)
|
|
DefaultAlpha
|
|
else
|
|
0f
|
|
|
|
LinearProgressIndicator(
|
|
modifier = Modifier
|
|
.fillMaxWidth()
|
|
.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)
|
|
}
|
|
}
|
|
}
|
|
|
|
if (isProcessing)
|
|
Box(modifier = Modifier.fillMaxSize()) //TODO this should block of the mouse/keyboard events while visible
|
|
}
|
|
}
|
|
}
|
|
|
|
@Composable
|
|
fun LoadingRepository() {
|
|
Box { }
|
|
}
|