Added new side bar
This commit is contained in:
parent
c6b0250a63
commit
2ffb8d9038
@ -4,16 +4,12 @@ package com.jetpackduba.gitnuro
|
|||||||
|
|
||||||
import androidx.compose.foundation.background
|
import androidx.compose.foundation.background
|
||||||
import androidx.compose.foundation.layout.*
|
import androidx.compose.foundation.layout.*
|
||||||
import androidx.compose.material.Icon
|
|
||||||
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.*
|
import androidx.compose.runtime.*
|
||||||
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.input.pointer.PointerIconDefaults
|
|
||||||
import androidx.compose.ui.input.pointer.pointerHoverIcon
|
|
||||||
import androidx.compose.ui.platform.LocalDensity
|
import androidx.compose.ui.platform.LocalDensity
|
||||||
import androidx.compose.ui.res.painterResource
|
import androidx.compose.ui.res.painterResource
|
||||||
import androidx.compose.ui.unit.Density
|
import androidx.compose.ui.unit.Density
|
||||||
@ -35,8 +31,6 @@ import com.jetpackduba.gitnuro.theme.secondaryTextColor
|
|||||||
import com.jetpackduba.gitnuro.ui.AppTab
|
import com.jetpackduba.gitnuro.ui.AppTab
|
||||||
import com.jetpackduba.gitnuro.ui.components.RepositoriesTabPanel
|
import com.jetpackduba.gitnuro.ui.components.RepositoriesTabPanel
|
||||||
import com.jetpackduba.gitnuro.ui.components.TabInformation
|
import com.jetpackduba.gitnuro.ui.components.TabInformation
|
||||||
import com.jetpackduba.gitnuro.ui.dialogs.settings.SettingsDialog
|
|
||||||
import com.jetpackduba.gitnuro.viewmodels.SettingsViewModel
|
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
@ -53,9 +47,6 @@ class App {
|
|||||||
@Inject
|
@Inject
|
||||||
lateinit var appSettings: AppSettings
|
lateinit var appSettings: AppSettings
|
||||||
|
|
||||||
@Inject
|
|
||||||
lateinit var settingsViewModel: SettingsViewModel
|
|
||||||
|
|
||||||
init {
|
init {
|
||||||
appComponent.inject(this)
|
appComponent.inject(this)
|
||||||
}
|
}
|
||||||
@ -107,25 +98,12 @@ class App {
|
|||||||
emptyArray()
|
emptyArray()
|
||||||
|
|
||||||
CompositionLocalProvider(values = density) {
|
CompositionLocalProvider(values = density) {
|
||||||
var showSettingsDialog by remember { mutableStateOf(false) }
|
|
||||||
|
|
||||||
AppTheme(
|
AppTheme(
|
||||||
selectedTheme = theme,
|
selectedTheme = theme,
|
||||||
customTheme = customTheme,
|
customTheme = customTheme,
|
||||||
) {
|
) {
|
||||||
Box(modifier = Modifier.background(MaterialTheme.colors.background)) {
|
Box(modifier = Modifier.background(MaterialTheme.colors.background)) {
|
||||||
AppTabs(
|
AppTabs()
|
||||||
onOpenSettings = {
|
|
||||||
showSettingsDialog = true
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (showSettingsDialog) {
|
|
||||||
SettingsDialog(
|
|
||||||
settingsViewModel = settingsViewModel,
|
|
||||||
onDismiss = { showSettingsDialog = false }
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -160,9 +138,7 @@ class App {
|
|||||||
|
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun AppTabs(
|
fun AppTabs() {
|
||||||
onOpenSettings: () -> Unit,
|
|
||||||
) {
|
|
||||||
val tabs by tabsFlow.collectAsState()
|
val tabs by tabsFlow.collectAsState()
|
||||||
val tabsInformationList = tabs.sortedBy { it.key }
|
val tabsInformationList = tabs.sortedBy { it.key }
|
||||||
val selectedTabKey = remember { mutableStateOf(0) }
|
val selectedTabKey = remember { mutableStateOf(0) }
|
||||||
@ -173,7 +149,6 @@ class App {
|
|||||||
Tabs(
|
Tabs(
|
||||||
tabsInformationList = tabsInformationList,
|
tabsInformationList = tabsInformationList,
|
||||||
selectedTabKey = selectedTabKey,
|
selectedTabKey = selectedTabKey,
|
||||||
onOpenSettings = onOpenSettings,
|
|
||||||
onAddedTab = { tabInfo ->
|
onAddedTab = { tabInfo ->
|
||||||
addTab(tabInfo)
|
addTab(tabInfo)
|
||||||
},
|
},
|
||||||
@ -203,11 +178,9 @@ class App {
|
|||||||
tabsFlow.value = tabsFlow.value.toMutableList().apply { add(tabInformation) }
|
tabsFlow.value = tabsFlow.value.toMutableList().apply { add(tabInformation) }
|
||||||
}
|
}
|
||||||
|
|
||||||
@OptIn(ExperimentalComposeUiApi::class)
|
|
||||||
@Composable
|
@Composable
|
||||||
fun Tabs(
|
fun Tabs(
|
||||||
selectedTabKey: MutableState<Int>,
|
selectedTabKey: MutableState<Int>,
|
||||||
onOpenSettings: () -> Unit,
|
|
||||||
tabsInformationList: List<TabInformation>,
|
tabsInformationList: List<TabInformation>,
|
||||||
onAddedTab: (TabInformation) -> Unit,
|
onAddedTab: (TabInformation) -> Unit,
|
||||||
onRemoveTab: (Int) -> Unit,
|
onRemoveTab: (Int) -> Unit,
|
||||||
@ -237,20 +210,6 @@ class App {
|
|||||||
},
|
},
|
||||||
onTabClosed = onRemoveTab
|
onTabClosed = onRemoveTab
|
||||||
)
|
)
|
||||||
IconButton(
|
|
||||||
modifier = Modifier
|
|
||||||
.padding(horizontal = 8.dp)
|
|
||||||
.size(24.dp)
|
|
||||||
.pointerHoverIcon(PointerIconDefaults.Hand),
|
|
||||||
onClick = onOpenSettings
|
|
||||||
) {
|
|
||||||
Icon(
|
|
||||||
painter = painterResource("settings.svg"),
|
|
||||||
contentDescription = null,
|
|
||||||
modifier = Modifier.fillMaxSize(),
|
|
||||||
tint = MaterialTheme.colors.primaryVariant,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,6 +3,7 @@ package com.jetpackduba.gitnuro.di
|
|||||||
import com.jetpackduba.gitnuro.App
|
import com.jetpackduba.gitnuro.App
|
||||||
import com.jetpackduba.gitnuro.AppStateManager
|
import com.jetpackduba.gitnuro.AppStateManager
|
||||||
import com.jetpackduba.gitnuro.preferences.AppSettings
|
import com.jetpackduba.gitnuro.preferences.AppSettings
|
||||||
|
import com.jetpackduba.gitnuro.viewmodels.SettingsViewModel
|
||||||
import dagger.Component
|
import dagger.Component
|
||||||
import javax.inject.Singleton
|
import javax.inject.Singleton
|
||||||
|
|
||||||
@ -11,6 +12,7 @@ import javax.inject.Singleton
|
|||||||
interface AppComponent {
|
interface AppComponent {
|
||||||
fun inject(main: App)
|
fun inject(main: App)
|
||||||
fun appStateManager(): AppStateManager
|
fun appStateManager(): AppStateManager
|
||||||
|
fun settingsViewModel(): SettingsViewModel
|
||||||
|
|
||||||
fun appPreferences(): AppSettings
|
fun appPreferences(): AppSettings
|
||||||
}
|
}
|
@ -17,11 +17,10 @@ fun Modifier.backgroundIf(condition: Boolean, color: Color): Modifier {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@OptIn(ExperimentalComposeUiApi::class)
|
|
||||||
fun Modifier.handMouseClickable(onClick: () -> Unit): Modifier {
|
fun Modifier.handMouseClickable(onClick: () -> Unit): Modifier {
|
||||||
return this
|
return this
|
||||||
.clickable { onClick() }
|
.clickable { onClick() }
|
||||||
.pointerHoverIcon(PointerIconDefaults.Hand)
|
.handOnHover()
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -30,4 +29,9 @@ fun Modifier.handMouseClickable(onClick: () -> Unit): Modifier {
|
|||||||
*/
|
*/
|
||||||
fun Modifier.ignoreKeyEvents(): Modifier {
|
fun Modifier.ignoreKeyEvents(): Modifier {
|
||||||
return this.onPreviewKeyEvent { true }
|
return this.onPreviewKeyEvent { true }
|
||||||
|
}
|
||||||
|
|
||||||
|
@OptIn(ExperimentalComposeUiApi::class)
|
||||||
|
fun Modifier.handOnHover(): Modifier {
|
||||||
|
return this.pointerHoverIcon(PointerIconDefaults.Hand)
|
||||||
}
|
}
|
@ -31,7 +31,7 @@ val lightTheme = ColorsScheme(
|
|||||||
|
|
||||||
|
|
||||||
val darkBlueTheme = ColorsScheme(
|
val darkBlueTheme = ColorsScheme(
|
||||||
primary = Color(0xFF014F97),
|
primary = Color(0xFF1074BC),
|
||||||
primaryVariant = Color(0xFF9FD1FF),
|
primaryVariant = Color(0xFF9FD1FF),
|
||||||
onPrimary = Color(0xFFFFFFFFF),
|
onPrimary = Color(0xFFFFFFFFF),
|
||||||
secondary = Color(0xFFe9c754),
|
secondary = Color(0xFFe9c754),
|
||||||
@ -39,10 +39,10 @@ val darkBlueTheme = ColorsScheme(
|
|||||||
secondaryText = Color(0xFFCCCBCB),
|
secondaryText = Color(0xFFCCCBCB),
|
||||||
error = Color(0xFFc93838),
|
error = Color(0xFFc93838),
|
||||||
onError = Color(0xFFFFFFFF),
|
onError = Color(0xFFFFFFFF),
|
||||||
background = Color(0xFF0E1621),
|
background = Color(0xFF16181F),
|
||||||
backgroundSelected = Color(0xFF2f3640),
|
backgroundSelected = Color(0xFF2f3640),
|
||||||
surface = Color(0xFF15212d),
|
surface = Color(0xFF202538),
|
||||||
secondarySurface = Color(0xFF1a2c40),
|
secondarySurface = Color(0xFF122C46),
|
||||||
headerBackground = Color(0xFF0a335c),
|
headerBackground = Color(0xFF0a335c),
|
||||||
borderColor = Color(0xFF989898),
|
borderColor = Color(0xFF989898),
|
||||||
addFile = Color(0xFF32A852),
|
addFile = Color(0xFF32A852),
|
||||||
|
@ -27,6 +27,7 @@ import androidx.compose.ui.res.painterResource
|
|||||||
import androidx.compose.ui.text.font.FontFamily
|
import androidx.compose.ui.text.font.FontFamily
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import com.jetpackduba.gitnuro.extensions.handMouseClickable
|
import com.jetpackduba.gitnuro.extensions.handMouseClickable
|
||||||
|
import com.jetpackduba.gitnuro.extensions.handOnHover
|
||||||
import com.jetpackduba.gitnuro.extensions.lineAt
|
import com.jetpackduba.gitnuro.extensions.lineAt
|
||||||
import com.jetpackduba.gitnuro.extensions.toStringWithSpaces
|
import com.jetpackduba.gitnuro.extensions.toStringWithSpaces
|
||||||
import com.jetpackduba.gitnuro.keybindings.KeybindingOption
|
import com.jetpackduba.gitnuro.keybindings.KeybindingOption
|
||||||
@ -187,7 +188,7 @@ fun MinimizedBlame(
|
|||||||
onClick = onClose,
|
onClick = onClose,
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.padding(horizontal = 16.dp)
|
.padding(horizontal = 16.dp)
|
||||||
.pointerHoverIcon(PointerIconDefaults.Hand)
|
.handOnHover()
|
||||||
) {
|
) {
|
||||||
Image(
|
Image(
|
||||||
painter = painterResource("close.svg"),
|
painter = painterResource("close.svg"),
|
||||||
@ -222,7 +223,7 @@ private fun Header(
|
|||||||
IconButton(
|
IconButton(
|
||||||
onClick = onClose,
|
onClick = onClose,
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.pointerHoverIcon(PointerIconDefaults.Hand)
|
.handOnHover()
|
||||||
) {
|
) {
|
||||||
Image(
|
Image(
|
||||||
painter = painterResource("close.svg"),
|
painter = painterResource("close.svg"),
|
||||||
|
@ -24,6 +24,7 @@ import androidx.compose.ui.input.pointer.pointerHoverIcon
|
|||||||
import androidx.compose.ui.res.painterResource
|
import androidx.compose.ui.res.painterResource
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import com.jetpackduba.gitnuro.extensions.handMouseClickable
|
import com.jetpackduba.gitnuro.extensions.handMouseClickable
|
||||||
|
import com.jetpackduba.gitnuro.extensions.handOnHover
|
||||||
import com.jetpackduba.gitnuro.extensions.toSmartSystemString
|
import com.jetpackduba.gitnuro.extensions.toSmartSystemString
|
||||||
import com.jetpackduba.gitnuro.git.diff.DiffResult
|
import com.jetpackduba.gitnuro.git.diff.DiffResult
|
||||||
import com.jetpackduba.gitnuro.keybindings.KeybindingOption
|
import com.jetpackduba.gitnuro.keybindings.KeybindingOption
|
||||||
@ -102,7 +103,7 @@ private fun Header(
|
|||||||
IconButton(
|
IconButton(
|
||||||
onClick = onClose,
|
onClick = onClose,
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.pointerHoverIcon(PointerIconDefaults.Hand)
|
.handOnHover()
|
||||||
) {
|
) {
|
||||||
Image(
|
Image(
|
||||||
painter = painterResource("close.svg"),
|
painter = painterResource("close.svg"),
|
||||||
|
@ -6,6 +6,7 @@ import androidx.compose.foundation.ExperimentalFoundationApi
|
|||||||
import androidx.compose.foundation.Image
|
import androidx.compose.foundation.Image
|
||||||
import androidx.compose.foundation.background
|
import androidx.compose.foundation.background
|
||||||
import androidx.compose.foundation.layout.*
|
import androidx.compose.foundation.layout.*
|
||||||
|
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.ArrowDropDown
|
import androidx.compose.material.icons.filled.ArrowDropDown
|
||||||
@ -13,6 +14,8 @@ import androidx.compose.runtime.*
|
|||||||
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.draw.alpha
|
||||||
|
import androidx.compose.ui.draw.clip
|
||||||
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.graphics.painter.Painter
|
import androidx.compose.ui.graphics.painter.Painter
|
||||||
@ -22,6 +25,7 @@ import androidx.compose.ui.res.painterResource
|
|||||||
import androidx.compose.ui.text.style.TextAlign
|
import androidx.compose.ui.text.style.TextAlign
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import com.jetpackduba.gitnuro.extensions.handMouseClickable
|
import com.jetpackduba.gitnuro.extensions.handMouseClickable
|
||||||
|
import com.jetpackduba.gitnuro.extensions.handOnHover
|
||||||
import com.jetpackduba.gitnuro.extensions.ignoreKeyEvents
|
import com.jetpackduba.gitnuro.extensions.ignoreKeyEvents
|
||||||
import com.jetpackduba.gitnuro.theme.primaryTextColor
|
import com.jetpackduba.gitnuro.theme.primaryTextColor
|
||||||
import com.jetpackduba.gitnuro.ui.context_menu.*
|
import com.jetpackduba.gitnuro.ui.context_menu.*
|
||||||
@ -32,7 +36,6 @@ import com.jetpackduba.gitnuro.viewmodels.MenuViewModel
|
|||||||
fun Menu(
|
fun Menu(
|
||||||
modifier: Modifier,
|
modifier: Modifier,
|
||||||
menuViewModel: MenuViewModel,
|
menuViewModel: MenuViewModel,
|
||||||
onRepositoryOpen: () -> Unit,
|
|
||||||
onCreateBranch: () -> Unit,
|
onCreateBranch: () -> Unit,
|
||||||
onStashWithMessage: () -> Unit,
|
onStashWithMessage: () -> Unit,
|
||||||
) {
|
) {
|
||||||
@ -43,15 +46,6 @@ fun Menu(
|
|||||||
horizontalArrangement = Arrangement.Center,
|
horizontalArrangement = Arrangement.Center,
|
||||||
verticalAlignment = Alignment.CenterVertically,
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
) {
|
) {
|
||||||
MenuButton(
|
|
||||||
modifier = Modifier.padding(start = 8.dp),
|
|
||||||
title = "Open",
|
|
||||||
icon = painterResource("open.svg"),
|
|
||||||
onClick = {
|
|
||||||
onRepositoryOpen()
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
Spacer(modifier = Modifier.weight(1f))
|
Spacer(modifier = Modifier.weight(1f))
|
||||||
|
|
||||||
ExtendedMenuButton(
|
ExtendedMenuButton(
|
||||||
@ -129,7 +123,6 @@ fun Menu(
|
|||||||
val menuOptions = remember {
|
val menuOptions = remember {
|
||||||
repositoryAdditionalOptionsMenu(
|
repositoryAdditionalOptionsMenu(
|
||||||
onOpenRepositoryOnFileExplorer = { menuViewModel.openFolderInFileExplorer() },
|
onOpenRepositoryOnFileExplorer = { menuViewModel.openFolderInFileExplorer() },
|
||||||
onForceRepositoryRefresh = { menuViewModel.refresh() },
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
for (item in menuOptions) {
|
for (item in menuOptions) {
|
||||||
@ -153,34 +146,31 @@ fun MenuButton(
|
|||||||
icon: Painter,
|
icon: Painter,
|
||||||
onClick: () -> Unit
|
onClick: () -> Unit
|
||||||
) {
|
) {
|
||||||
val iconColor = if (enabled) {
|
Row(
|
||||||
MaterialTheme.colors.primaryVariant
|
|
||||||
} else {
|
|
||||||
MaterialTheme.colors.secondaryVariant //todo this color isn't specified anywhere
|
|
||||||
}
|
|
||||||
|
|
||||||
Column(
|
|
||||||
modifier = modifier
|
modifier = modifier
|
||||||
.ignoreKeyEvents()
|
.ignoreKeyEvents()
|
||||||
|
.clip(RoundedCornerShape(4.dp))
|
||||||
|
.background(MaterialTheme.colors.primary)
|
||||||
.handMouseClickable { if (enabled) onClick() }
|
.handMouseClickable { if (enabled) onClick() }
|
||||||
.padding(vertical = 4.dp, horizontal = 16.dp)
|
.width(100.dp),
|
||||||
.width(48.dp),
|
horizontalArrangement = Arrangement.Center,
|
||||||
horizontalAlignment = Alignment.CenterHorizontally,
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
verticalArrangement = Arrangement.Center,
|
|
||||||
) {
|
) {
|
||||||
Image(
|
Icon(
|
||||||
painter = icon,
|
painter = icon,
|
||||||
contentDescription = title,
|
contentDescription = title,
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.padding(vertical = 2.dp)
|
.padding(vertical = 2.dp)
|
||||||
.size(24.dp),
|
.size(24.dp),
|
||||||
colorFilter = ColorFilter.tint(iconColor),
|
tint = MaterialTheme.colors.onPrimary,
|
||||||
)
|
)
|
||||||
Text(
|
Text(
|
||||||
text = title,
|
text = title,
|
||||||
style = MaterialTheme.typography.body2,
|
style = MaterialTheme.typography.body2,
|
||||||
|
modifier = Modifier.padding(start = 2.dp, top = 8.dp, bottom = 8.dp),
|
||||||
maxLines = 1,
|
maxLines = 1,
|
||||||
textAlign = TextAlign.Center,
|
textAlign = TextAlign.Center,
|
||||||
|
color = MaterialTheme.colors.onPrimary,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -194,44 +184,40 @@ fun ExtendedMenuButton(
|
|||||||
onClick: () -> Unit,
|
onClick: () -> Unit,
|
||||||
extendedListItems: List<DropDownContentData>,
|
extendedListItems: List<DropDownContentData>,
|
||||||
) {
|
) {
|
||||||
val iconColor = if (enabled) {
|
|
||||||
MaterialTheme.colors.primaryVariant
|
|
||||||
} else {
|
|
||||||
MaterialTheme.colors.secondaryVariant
|
|
||||||
}
|
|
||||||
|
|
||||||
var showDropDownMenu by remember { mutableStateOf(false) }
|
var showDropDownMenu by remember { mutableStateOf(false) }
|
||||||
|
|
||||||
Row(
|
Row(
|
||||||
modifier = modifier
|
modifier = modifier
|
||||||
.height(IntrinsicSize.Min)
|
.height(IntrinsicSize.Min)
|
||||||
.ignoreKeyEvents()
|
.ignoreKeyEvents()
|
||||||
.handMouseClickable { if (enabled) onClick() }
|
.clip(RoundedCornerShape(4.dp))
|
||||||
|
.background(MaterialTheme.colors.primary)
|
||||||
) {
|
) {
|
||||||
Column(
|
Row(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.padding(top = 4.dp, bottom = 4.dp, start = 16.dp, end = 4.dp)
|
.width(92.dp)
|
||||||
.width(40.dp),
|
.handMouseClickable { if (enabled) onClick() },
|
||||||
horizontalAlignment = Alignment.CenterHorizontally,
|
horizontalArrangement = Arrangement.Center,
|
||||||
verticalArrangement = Arrangement.Center,
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
) {
|
) {
|
||||||
Image(
|
Icon(
|
||||||
painter = icon,
|
painter = icon,
|
||||||
contentDescription = title,
|
contentDescription = title,
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.padding(vertical = 2.dp)
|
|
||||||
.size(24.dp),
|
.size(24.dp),
|
||||||
colorFilter = ColorFilter.tint(iconColor),
|
tint = MaterialTheme.colors.onPrimary,
|
||||||
)
|
)
|
||||||
Text(
|
Text(
|
||||||
text = title,
|
text = title,
|
||||||
|
modifier = Modifier.padding(start = 2.dp, top = 8.dp, bottom = 8.dp),
|
||||||
style = MaterialTheme.typography.body2,
|
style = MaterialTheme.typography.body2,
|
||||||
|
color = MaterialTheme.colors.onPrimary,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
Box(
|
Box(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.width(20.dp)
|
.width(24.dp)
|
||||||
.fillMaxHeight()
|
.fillMaxHeight()
|
||||||
.ignoreKeyEvents()
|
.ignoreKeyEvents()
|
||||||
.handMouseClickable {
|
.handMouseClickable {
|
||||||
@ -239,10 +225,18 @@ fun ExtendedMenuButton(
|
|||||||
},
|
},
|
||||||
contentAlignment = Alignment.Center,
|
contentAlignment = Alignment.Center,
|
||||||
) {
|
) {
|
||||||
|
Box(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxHeight()
|
||||||
|
.background(MaterialTheme.colors.onPrimary.copy(alpha = 0.5f))
|
||||||
|
.width(1.dp)
|
||||||
|
.align(Alignment.CenterStart)
|
||||||
|
)
|
||||||
|
|
||||||
Icon(
|
Icon(
|
||||||
Icons.Default.ArrowDropDown,
|
Icons.Default.ArrowDropDown,
|
||||||
contentDescription = null,
|
contentDescription = null,
|
||||||
tint = MaterialTheme.colors.primaryTextColor,
|
tint = MaterialTheme.colors.onPrimary,
|
||||||
)
|
)
|
||||||
|
|
||||||
DropdownMenu(
|
DropdownMenu(
|
||||||
@ -275,7 +269,7 @@ fun IconMenuButton(
|
|||||||
|
|
||||||
IconButton(
|
IconButton(
|
||||||
modifier = modifier
|
modifier = modifier
|
||||||
.pointerHoverIcon(PointerIconDefaults.Hand),
|
.handOnHover(),
|
||||||
enabled = enabled,
|
enabled = enabled,
|
||||||
onClick = onClick,
|
onClick = onClick,
|
||||||
) {
|
) {
|
||||||
|
@ -16,6 +16,7 @@ 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
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
|
import com.jetpackduba.gitnuro.extensions.handOnHover
|
||||||
import com.jetpackduba.gitnuro.extensions.simpleName
|
import com.jetpackduba.gitnuro.extensions.simpleName
|
||||||
import com.jetpackduba.gitnuro.theme.primaryTextColor
|
import com.jetpackduba.gitnuro.theme.primaryTextColor
|
||||||
import com.jetpackduba.gitnuro.ui.components.SideMenuPanel
|
import com.jetpackduba.gitnuro.ui.components.SideMenuPanel
|
||||||
@ -29,7 +30,6 @@ import com.jetpackduba.gitnuro.viewmodels.RemoteView
|
|||||||
import com.jetpackduba.gitnuro.viewmodels.RemotesViewModel
|
import com.jetpackduba.gitnuro.viewmodels.RemotesViewModel
|
||||||
import org.eclipse.jgit.lib.Ref
|
import org.eclipse.jgit.lib.Ref
|
||||||
|
|
||||||
@OptIn(ExperimentalComposeUiApi::class)
|
|
||||||
@Composable
|
@Composable
|
||||||
fun Remotes(
|
fun Remotes(
|
||||||
remotesViewModel: RemotesViewModel,
|
remotesViewModel: RemotesViewModel,
|
||||||
@ -62,7 +62,7 @@ fun Remotes(
|
|||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.padding(end = 16.dp)
|
.padding(end = 16.dp)
|
||||||
.size(16.dp)
|
.size(16.dp)
|
||||||
.pointerHoverIcon(PointerIconDefaults.Hand),
|
.handOnHover(),
|
||||||
) {
|
) {
|
||||||
Icon(
|
Icon(
|
||||||
painter = painterResource("settings.svg"),
|
painter = painterResource("settings.svg"),
|
||||||
|
@ -4,27 +4,44 @@ package com.jetpackduba.gitnuro.ui
|
|||||||
|
|
||||||
import androidx.compose.foundation.background
|
import androidx.compose.foundation.background
|
||||||
import androidx.compose.foundation.focusable
|
import androidx.compose.foundation.focusable
|
||||||
|
import androidx.compose.foundation.hoverable
|
||||||
|
import androidx.compose.foundation.interaction.MutableInteractionSource
|
||||||
|
import androidx.compose.foundation.interaction.collectIsHoveredAsState
|
||||||
import androidx.compose.foundation.layout.*
|
import androidx.compose.foundation.layout.*
|
||||||
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||||
|
import androidx.compose.material.Icon
|
||||||
|
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.*
|
import androidx.compose.runtime.*
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
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.focus.focusRequester
|
import androidx.compose.ui.focus.focusRequester
|
||||||
|
import androidx.compose.ui.geometry.Offset
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.input.key.onKeyEvent
|
import androidx.compose.ui.input.key.onKeyEvent
|
||||||
import androidx.compose.ui.input.pointer.PointerIcon
|
import androidx.compose.ui.input.pointer.PointerIcon
|
||||||
import androidx.compose.ui.input.pointer.pointerHoverIcon
|
import androidx.compose.ui.input.pointer.pointerHoverIcon
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.layout.onGloballyPositioned
|
||||||
|
import androidx.compose.ui.layout.positionInRoot
|
||||||
|
import androidx.compose.ui.res.painterResource
|
||||||
|
import androidx.compose.ui.unit.*
|
||||||
|
import androidx.compose.ui.window.Popup
|
||||||
|
import androidx.compose.ui.window.PopupPositionProvider
|
||||||
import com.jetpackduba.gitnuro.extensions.handMouseClickable
|
import com.jetpackduba.gitnuro.extensions.handMouseClickable
|
||||||
|
import com.jetpackduba.gitnuro.extensions.handOnHover
|
||||||
import com.jetpackduba.gitnuro.git.DiffEntryType
|
import com.jetpackduba.gitnuro.git.DiffEntryType
|
||||||
import com.jetpackduba.gitnuro.keybindings.KeybindingOption
|
import com.jetpackduba.gitnuro.keybindings.KeybindingOption
|
||||||
import com.jetpackduba.gitnuro.keybindings.matchesBinding
|
import com.jetpackduba.gitnuro.keybindings.matchesBinding
|
||||||
|
import com.jetpackduba.gitnuro.theme.primaryTextColor
|
||||||
|
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.StashWithMessageDialog
|
import com.jetpackduba.gitnuro.ui.dialogs.StashWithMessageDialog
|
||||||
|
import com.jetpackduba.gitnuro.ui.dialogs.settings.SettingsDialog
|
||||||
import com.jetpackduba.gitnuro.ui.diff.Diff
|
import com.jetpackduba.gitnuro.ui.diff.Diff
|
||||||
import com.jetpackduba.gitnuro.ui.log.Log
|
import com.jetpackduba.gitnuro.ui.log.Log
|
||||||
import com.jetpackduba.gitnuro.viewmodels.BlameState
|
import com.jetpackduba.gitnuro.viewmodels.BlameState
|
||||||
@ -44,7 +61,6 @@ fun RepositoryOpenPage(tabViewModel: TabViewModel) {
|
|||||||
val selectedItem by tabViewModel.selectedItem.collectAsState()
|
val selectedItem by tabViewModel.selectedItem.collectAsState()
|
||||||
val blameState by tabViewModel.blameState.collectAsState()
|
val blameState by tabViewModel.blameState.collectAsState()
|
||||||
val showHistory by tabViewModel.showHistory.collectAsState()
|
val showHistory by tabViewModel.showHistory.collectAsState()
|
||||||
val userInfo by tabViewModel.authorInfoSimple.collectAsState()
|
|
||||||
val showAuthorInfo by tabViewModel.showAuthorInfo.collectAsState()
|
val showAuthorInfo by tabViewModel.showAuthorInfo.collectAsState()
|
||||||
|
|
||||||
var showNewBranchDialog by remember { mutableStateOf(false) }
|
var showNewBranchDialog by remember { mutableStateOf(false) }
|
||||||
@ -87,40 +103,45 @@ fun RepositoryOpenPage(tabViewModel: TabViewModel) {
|
|||||||
LaunchedEffect(selectedItem) {
|
LaunchedEffect(selectedItem) {
|
||||||
focusRequester.requestFocus()
|
focusRequester.requestFocus()
|
||||||
}
|
}
|
||||||
|
Column {
|
||||||
|
Row(modifier = Modifier.weight(1f)) {
|
||||||
|
SideBar(tabViewModel)
|
||||||
|
|
||||||
Column(
|
Column(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.focusRequester(focusRequester)
|
.focusRequester(focusRequester)
|
||||||
.focusable()
|
.focusable()
|
||||||
.onKeyEvent { keyEvent ->
|
.onKeyEvent { keyEvent ->
|
||||||
if (keyEvent.matchesBinding(KeybindingOption.REFRESH)) {
|
if (keyEvent.matchesBinding(KeybindingOption.REFRESH)) {
|
||||||
tabViewModel.refreshAll()
|
tabViewModel.refreshAll()
|
||||||
true
|
true
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
) {
|
||||||
|
val rebaseInteractiveViewModel = tabViewModel.rebaseInteractiveViewModel
|
||||||
|
|
||||||
|
if (repositoryState == RepositoryState.REBASING_INTERACTIVE && rebaseInteractiveViewModel != null) {
|
||||||
|
RebaseInteractive(rebaseInteractiveViewModel)
|
||||||
} else {
|
} else {
|
||||||
false
|
Column(modifier = Modifier.weight(1f)) {
|
||||||
|
Menu(
|
||||||
|
modifier = Modifier
|
||||||
|
.padding(
|
||||||
|
top = 12.dp,
|
||||||
|
bottom = 16.dp
|
||||||
|
) // Linear progress bar already take 4 additional dp for top
|
||||||
|
.fillMaxWidth(),
|
||||||
|
menuViewModel = tabViewModel.menuViewModel,
|
||||||
|
onCreateBranch = { showNewBranchDialog = true },
|
||||||
|
onStashWithMessage = { showStashWithMessageDialog = true },
|
||||||
|
)
|
||||||
|
|
||||||
|
RepoContent(tabViewModel, diffSelected, selectedItem, repositoryState, blameState, showHistory)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
) {
|
|
||||||
val rebaseInteractiveViewModel = tabViewModel.rebaseInteractiveViewModel
|
|
||||||
|
|
||||||
if (repositoryState == RepositoryState.REBASING_INTERACTIVE && rebaseInteractiveViewModel != null) {
|
|
||||||
RebaseInteractive(rebaseInteractiveViewModel)
|
|
||||||
} else {
|
|
||||||
Column(modifier = Modifier.weight(1f)) {
|
|
||||||
Menu(
|
|
||||||
modifier = Modifier
|
|
||||||
.padding(top = 4.dp, bottom = 8.dp) // Linear progress bar already take 4 additional dp for top
|
|
||||||
.fillMaxWidth(),
|
|
||||||
menuViewModel = tabViewModel.menuViewModel,
|
|
||||||
onRepositoryOpen = {
|
|
||||||
openRepositoryDialog(tabViewModel = tabViewModel)
|
|
||||||
},
|
|
||||||
onCreateBranch = { showNewBranchDialog = true },
|
|
||||||
onStashWithMessage = { showStashWithMessageDialog = true },
|
|
||||||
)
|
|
||||||
|
|
||||||
RepoContent(tabViewModel, diffSelected, selectedItem, repositoryState, blameState, showHistory)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Spacer(
|
Spacer(
|
||||||
@ -129,27 +150,142 @@ fun RepositoryOpenPage(tabViewModel: TabViewModel) {
|
|||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
.background(MaterialTheme.colors.primaryVariant.copy(alpha = 0.2f))
|
.background(MaterialTheme.colors.primaryVariant.copy(alpha = 0.2f))
|
||||||
)
|
)
|
||||||
Row(
|
|
||||||
|
BottomInfoBar(tabViewModel)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun SideBar(tabViewModel: TabViewModel) {
|
||||||
|
var showSettingsDialog by remember { mutableStateOf(false) }
|
||||||
|
if (showSettingsDialog) {
|
||||||
|
SettingsDialog(
|
||||||
|
settingsViewModel = tabViewModel.settingsViewModel,
|
||||||
|
onDismiss = { showSettingsDialog = false }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
Column(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxHeight()
|
||||||
|
.width(48.dp)
|
||||||
|
.background(MaterialTheme.colors.secondarySurface)
|
||||||
|
.padding(vertical = 16.dp),
|
||||||
|
horizontalAlignment = Alignment.CenterHorizontally,
|
||||||
|
) {
|
||||||
|
SideBarButton(
|
||||||
|
painterName = "open.svg",
|
||||||
|
label = "Open a new repository",
|
||||||
|
onClick = {
|
||||||
|
openRepositoryDialog(tabViewModel = tabViewModel)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
SideBarButton(
|
||||||
|
modifier = Modifier.padding(top = 16.dp),
|
||||||
|
painterName = "refresh.svg",
|
||||||
|
label = "Refresh repository information",
|
||||||
|
onClick = {
|
||||||
|
tabViewModel.refreshAll()
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
Spacer(modifier = Modifier.weight(1f))
|
||||||
|
|
||||||
|
SideBarButton(
|
||||||
|
painterName = "settings.svg",
|
||||||
|
label = "Settings",
|
||||||
|
onClick = { showSettingsDialog = true }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
private fun BottomInfoBar(tabViewModel: TabViewModel) {
|
||||||
|
val userInfo by tabViewModel.authorInfoSimple.collectAsState()
|
||||||
|
|
||||||
|
Row(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.height(32.dp)
|
||||||
|
.background(MaterialTheme.colors.surface)
|
||||||
|
.padding(horizontal = 16.dp),
|
||||||
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
|
) {
|
||||||
|
Box(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxWidth()
|
.fillMaxHeight()
|
||||||
.height(32.dp)
|
.handMouseClickable { tabViewModel.showAuthorInfoDialog() },
|
||||||
.background(MaterialTheme.colors.surface)
|
contentAlignment = Alignment.Center,
|
||||||
.padding(horizontal = 16.dp),
|
) {
|
||||||
verticalAlignment = Alignment.CenterVertically,
|
Text(
|
||||||
|
text = "${userInfo.name ?: "Name not set"} <${userInfo.email ?: "Email not set"}>",
|
||||||
|
style = MaterialTheme.typography.body2,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun SideBarButton(
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
|
painterName: String,
|
||||||
|
label: String,
|
||||||
|
onClick: () -> Unit
|
||||||
|
) {
|
||||||
|
val hoverInteraction = remember { MutableInteractionSource() }
|
||||||
|
val isHovered by hoverInteraction.collectIsHoveredAsState()
|
||||||
|
|
||||||
|
val (buttonCoordinates, setButtonCoordinates) = remember { mutableStateOf<Pair<Offset, IntSize>?>(null) }
|
||||||
|
|
||||||
|
if (isHovered && buttonCoordinates != null) {
|
||||||
|
Popup(
|
||||||
|
popupPositionProvider = object : PopupPositionProvider {
|
||||||
|
override fun calculatePosition(
|
||||||
|
anchorBounds: IntRect,
|
||||||
|
windowSize: IntSize,
|
||||||
|
layoutDirection: LayoutDirection,
|
||||||
|
popupContentSize: IntSize
|
||||||
|
): IntOffset {
|
||||||
|
val position = buttonCoordinates.first
|
||||||
|
val size = buttonCoordinates.second
|
||||||
|
val x = position.x + size.width + 8
|
||||||
|
val y = position.y + (size.height / 2) - (popupContentSize.height / 2)
|
||||||
|
|
||||||
|
return IntOffset(x.toInt(), y.toInt())
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
) {
|
) {
|
||||||
Box(
|
Box(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxHeight()
|
.clip(RoundedCornerShape(4.dp))
|
||||||
.handMouseClickable { tabViewModel.showAuthorInfoDialog() },
|
.background(MaterialTheme.colors.background)
|
||||||
contentAlignment = Alignment.Center,
|
|
||||||
) {
|
) {
|
||||||
Text(
|
Text(
|
||||||
text = "${userInfo.name ?: "Name not set"} <${userInfo.email ?: "Email not set"}>",
|
text = label,
|
||||||
style = MaterialTheme.typography.body2,
|
color = MaterialTheme.colors.onBackground,
|
||||||
|
modifier = Modifier.padding(horizontal = 8.dp, vertical = 4.dp)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
IconButton(
|
||||||
|
onClick = onClick,
|
||||||
|
modifier = modifier
|
||||||
|
.handOnHover()
|
||||||
|
.hoverable(hoverInteraction)
|
||||||
|
.size(24.dp)
|
||||||
|
.onGloballyPositioned { layoutCoordinates ->
|
||||||
|
setButtonCoordinates(layoutCoordinates.positionInRoot() to layoutCoordinates.size)
|
||||||
|
}
|
||||||
|
) {
|
||||||
|
Icon(
|
||||||
|
painter = painterResource(painterName),
|
||||||
|
contentDescription = null,
|
||||||
|
modifier = Modifier,
|
||||||
|
tint = MaterialTheme.colors.primaryTextColor,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -246,6 +382,7 @@ fun MainContentView(
|
|||||||
repositoryState = repositoryState,
|
repositoryState = repositoryState,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
else -> {
|
else -> {
|
||||||
val diffViewModel = tabViewModel.diffViewModel
|
val diffViewModel = tabViewModel.diffViewModel
|
||||||
|
|
||||||
|
@ -29,6 +29,7 @@ import com.jetpackduba.gitnuro.AppStateManager
|
|||||||
import com.jetpackduba.gitnuro.di.AppComponent
|
import com.jetpackduba.gitnuro.di.AppComponent
|
||||||
import com.jetpackduba.gitnuro.di.DaggerTabComponent
|
import com.jetpackduba.gitnuro.di.DaggerTabComponent
|
||||||
import com.jetpackduba.gitnuro.extensions.handMouseClickable
|
import com.jetpackduba.gitnuro.extensions.handMouseClickable
|
||||||
|
import com.jetpackduba.gitnuro.extensions.handOnHover
|
||||||
import com.jetpackduba.gitnuro.theme.primaryTextColor
|
import com.jetpackduba.gitnuro.theme.primaryTextColor
|
||||||
import com.jetpackduba.gitnuro.viewmodels.TabViewModel
|
import com.jetpackduba.gitnuro.viewmodels.TabViewModel
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
@ -117,7 +118,7 @@ fun TabPanel(
|
|||||||
onClick = onNewTabClicked,
|
onClick = onNewTabClicked,
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.size(36.dp)
|
.size(36.dp)
|
||||||
.pointerHoverIcon(PointerIconDefaults.Hand)
|
.handOnHover()
|
||||||
.align(Alignment.CenterStart),
|
.align(Alignment.CenterStart),
|
||||||
) {
|
) {
|
||||||
Icon(
|
Icon(
|
||||||
|
@ -5,7 +5,6 @@ import androidx.compose.foundation.ExperimentalFoundationApi
|
|||||||
@OptIn(ExperimentalFoundationApi::class)
|
@OptIn(ExperimentalFoundationApi::class)
|
||||||
fun repositoryAdditionalOptionsMenu(
|
fun repositoryAdditionalOptionsMenu(
|
||||||
onOpenRepositoryOnFileExplorer: () -> Unit,
|
onOpenRepositoryOnFileExplorer: () -> Unit,
|
||||||
onForceRepositoryRefresh: () -> Unit,
|
|
||||||
): List<DropDownContentData> {
|
): List<DropDownContentData> {
|
||||||
return mutableListOf(
|
return mutableListOf(
|
||||||
DropDownContentData(
|
DropDownContentData(
|
||||||
@ -13,10 +12,5 @@ fun repositoryAdditionalOptionsMenu(
|
|||||||
icon = "source.svg",
|
icon = "source.svg",
|
||||||
onClick = onOpenRepositoryOnFileExplorer,
|
onClick = onOpenRepositoryOnFileExplorer,
|
||||||
),
|
),
|
||||||
DropDownContentData(
|
|
||||||
label = "Refresh repository",
|
|
||||||
icon = "refresh.svg",
|
|
||||||
onClick = onForceRepositoryRefresh,
|
|
||||||
),
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -16,13 +16,13 @@ import androidx.compose.ui.input.pointer.pointerHoverIcon
|
|||||||
import androidx.compose.ui.res.painterResource
|
import androidx.compose.ui.res.painterResource
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import com.jetpackduba.gitnuro.extensions.handMouseClickable
|
import com.jetpackduba.gitnuro.extensions.handMouseClickable
|
||||||
|
import com.jetpackduba.gitnuro.extensions.handOnHover
|
||||||
import com.jetpackduba.gitnuro.theme.*
|
import com.jetpackduba.gitnuro.theme.*
|
||||||
import com.jetpackduba.gitnuro.ui.components.AdjustableOutlinedTextField
|
import com.jetpackduba.gitnuro.ui.components.AdjustableOutlinedTextField
|
||||||
import com.jetpackduba.gitnuro.ui.components.PrimaryButton
|
import com.jetpackduba.gitnuro.ui.components.PrimaryButton
|
||||||
import com.jetpackduba.gitnuro.viewmodels.RemotesViewModel
|
import com.jetpackduba.gitnuro.viewmodels.RemotesViewModel
|
||||||
import org.eclipse.jgit.transport.RemoteConfig
|
import org.eclipse.jgit.transport.RemoteConfig
|
||||||
|
|
||||||
@OptIn(ExperimentalComposeUiApi::class)
|
|
||||||
@Composable
|
@Composable
|
||||||
fun EditRemotesDialog(
|
fun EditRemotesDialog(
|
||||||
remotesViewModel: RemotesViewModel,
|
remotesViewModel: RemotesViewModel,
|
||||||
@ -90,7 +90,7 @@ fun EditRemotesDialog(
|
|||||||
IconButton(
|
IconButton(
|
||||||
onClick = onDismiss,
|
onClick = onDismiss,
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.pointerHoverIcon(PointerIconDefaults.Hand)
|
.handOnHover()
|
||||||
) {
|
) {
|
||||||
Icon(
|
Icon(
|
||||||
imageVector = Icons.Default.Clear,
|
imageVector = Icons.Default.Clear,
|
||||||
@ -153,7 +153,7 @@ fun EditRemotesDialog(
|
|||||||
IconButton(
|
IconButton(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.size(36.dp)
|
.size(36.dp)
|
||||||
.pointerHoverIcon(PointerIconDefaults.Hand),
|
.handOnHover(),
|
||||||
onClick = {
|
onClick = {
|
||||||
val remotesWithNew = remotesEditorData.listRemotes.toMutableList()
|
val remotesWithNew = remotesEditorData.listRemotes.toMutableList()
|
||||||
val newRemote = RemoteWrapper(
|
val newRemote = RemoteWrapper(
|
||||||
@ -182,7 +182,7 @@ fun EditRemotesDialog(
|
|||||||
IconButton(
|
IconButton(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.size(36.dp)
|
.size(36.dp)
|
||||||
.pointerHoverIcon(PointerIconDefaults.Hand),
|
.handOnHover(),
|
||||||
enabled = selectedRemote != null,
|
enabled = selectedRemote != null,
|
||||||
onClick = {
|
onClick = {
|
||||||
if (selectedRemote != null)
|
if (selectedRemote != null)
|
||||||
|
@ -550,7 +550,6 @@ fun HunkHeader(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@OptIn(ExperimentalComposeUiApi::class)
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun DiffHeader(
|
private fun DiffHeader(
|
||||||
diffEntryType: DiffEntryType,
|
diffEntryType: DiffEntryType,
|
||||||
@ -598,7 +597,7 @@ private fun DiffHeader(
|
|||||||
IconButton(
|
IconButton(
|
||||||
onClick = onCloseDiffView,
|
onClick = onCloseDiffView,
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.pointerHoverIcon(PointerIconDefaults.Hand)
|
.handOnHover()
|
||||||
) {
|
) {
|
||||||
Image(
|
Image(
|
||||||
painter = painterResource("close.svg"),
|
painter = painterResource("close.svg"),
|
||||||
@ -677,7 +676,6 @@ fun UncommitedDiffFileHeaderButtons(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@OptIn(ExperimentalComposeUiApi::class)
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun PathOnlyDiffHeader(
|
private fun PathOnlyDiffHeader(
|
||||||
filePath: String,
|
filePath: String,
|
||||||
@ -703,7 +701,7 @@ private fun PathOnlyDiffHeader(
|
|||||||
IconButton(
|
IconButton(
|
||||||
onClick = onCloseDiffView,
|
onClick = onCloseDiffView,
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.pointerHoverIcon(PointerIconDefaults.Hand)
|
.handOnHover()
|
||||||
) {
|
) {
|
||||||
Image(
|
Image(
|
||||||
painter = painterResource("close.svg"),
|
painter = painterResource("close.svg"),
|
||||||
|
@ -333,7 +333,7 @@ fun SearchFilter(
|
|||||||
|
|
||||||
IconButton(
|
IconButton(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.pointerHoverIcon(PointerIconDefaults.Hand),
|
.handOnHover(),
|
||||||
onClick = {
|
onClick = {
|
||||||
scope.launch { logViewModel.selectPreviousFilterCommit() }
|
scope.launch { logViewModel.selectPreviousFilterCommit() }
|
||||||
}
|
}
|
||||||
@ -343,7 +343,7 @@ fun SearchFilter(
|
|||||||
|
|
||||||
IconButton(
|
IconButton(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.pointerHoverIcon(PointerIconDefaults.Hand),
|
.handOnHover(),
|
||||||
onClick = {
|
onClick = {
|
||||||
scope.launch { logViewModel.selectNextFilterCommit() }
|
scope.launch { logViewModel.selectNextFilterCommit() }
|
||||||
}
|
}
|
||||||
@ -353,7 +353,7 @@ fun SearchFilter(
|
|||||||
|
|
||||||
IconButton(
|
IconButton(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.pointerHoverIcon(PointerIconDefaults.Hand)
|
.handOnHover()
|
||||||
.padding(end = 4.dp),
|
.padding(end = 4.dp),
|
||||||
onClick = { logViewModel.closeSearch() }
|
onClick = { logViewModel.closeSearch() }
|
||||||
) {
|
) {
|
||||||
@ -613,7 +613,7 @@ fun GraphHeader(
|
|||||||
IconButton(
|
IconButton(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.padding(end = 8.dp)
|
.padding(end = 8.dp)
|
||||||
.pointerHoverIcon(PointerIconDefaults.Hand),
|
.handOnHover(),
|
||||||
onClick = onShowSearch
|
onClick = onShowSearch
|
||||||
) {
|
) {
|
||||||
Icon(
|
Icon(
|
||||||
@ -1135,7 +1135,7 @@ fun RefChip(
|
|||||||
.clip(RoundedCornerShape(16.dp))
|
.clip(RoundedCornerShape(16.dp))
|
||||||
.border(width = 2.dp, color = color, shape = RoundedCornerShape(16.dp))
|
.border(width = 2.dp, color = color, shape = RoundedCornerShape(16.dp))
|
||||||
.combinedClickable(onDoubleClick = onCheckoutRef, onClick = {})
|
.combinedClickable(onDoubleClick = onCheckoutRef, onClick = {})
|
||||||
.pointerHoverIcon(PointerIconDefaults.Hand)
|
.handOnHover()
|
||||||
) {
|
) {
|
||||||
ContextMenu(
|
ContextMenu(
|
||||||
items = contextMenuItemsList
|
items = contextMenuItemsList
|
||||||
|
@ -68,10 +68,4 @@ class MenuViewModel @Inject constructor(
|
|||||||
) { git ->
|
) { git ->
|
||||||
Desktop.getDesktop().open(git.repository.directory.parentFile)
|
Desktop.getDesktop().open(git.repository.directory.parentFile)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun refresh() = tabState.safeProcessing(
|
|
||||||
refreshType = RefreshType.ALL_DATA,
|
|
||||||
) {
|
|
||||||
// Nothing to do here
|
|
||||||
}
|
|
||||||
}
|
}
|
@ -55,6 +55,7 @@ class TabViewModel @Inject constructor(
|
|||||||
private val authorViewModelProvider: Provider<AuthorViewModel>,
|
private val authorViewModelProvider: Provider<AuthorViewModel>,
|
||||||
private val tabState: TabState,
|
private val tabState: TabState,
|
||||||
val appStateManager: AppStateManager,
|
val appStateManager: AppStateManager,
|
||||||
|
val settingsViewModel: SettingsViewModel,
|
||||||
private val fileChangesWatcher: FileChangesWatcher,
|
private val fileChangesWatcher: FileChangesWatcher,
|
||||||
private val updatesRepository: UpdatesRepository,
|
private val updatesRepository: UpdatesRepository,
|
||||||
) {
|
) {
|
||||||
|
@ -1,7 +1 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 24 24" height="24px" viewBox="0 0 24 24" width="24px"
|
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><path d="M0 0h24v24H0V0z" fill="none"/><path d="M19.43 12.98c.04-.32.07-.64.07-.98 0-.34-.03-.66-.07-.98l2.11-1.65c.19-.15.24-.42.12-.64l-2-3.46c-.09-.16-.26-.25-.44-.25-.06 0-.12.01-.17.03l-2.49 1c-.52-.4-1.08-.73-1.69-.98l-.38-2.65C14.46 2.18 14.25 2 14 2h-4c-.25 0-.46.18-.49.42l-.38 2.65c-.61.25-1.17.59-1.69.98l-2.49-1c-.06-.02-.12-.03-.18-.03-.17 0-.34.09-.43.25l-2 3.46c-.13.22-.07.49.12.64l2.11 1.65c-.04.32-.07.65-.07.98 0 .33.03.66.07.98l-2.11 1.65c-.19.15-.24.42-.12.64l2 3.46c.09.16.26.25.44.25.06 0 .12-.01.17-.03l2.49-1c.52.4 1.08.73 1.69.98l.38 2.65c.03.24.24.42.49.42h4c.25 0 .46-.18.49-.42l.38-2.65c.61-.25 1.17-.59 1.69-.98l2.49 1c.06.02.12.03.18.03.17 0 .34-.09.43-.25l2-3.46c.12-.22.07-.49-.12-.64l-2.11-1.65zm-1.98-1.71c.04.31.05.52.05.73 0 .21-.02.43-.05.73l-.14 1.13.89.7 1.08.84-.7 1.21-1.27-.51-1.04-.42-.9.68c-.43.32-.84.56-1.25.73l-1.06.43-.16 1.13-.2 1.35h-1.4l-.19-1.35-.16-1.13-1.06-.43c-.43-.18-.83-.41-1.23-.71l-.91-.7-1.06.43-1.27.51-.7-1.21 1.08-.84.89-.7-.14-1.13c-.03-.31-.05-.54-.05-.74s.02-.43.05-.73l.14-1.13-.89-.7-1.08-.84.7-1.21 1.27.51 1.04.42.9-.68c.43-.32.84-.56 1.25-.73l1.06-.43.16-1.13.2-1.35h1.39l.19 1.35.16 1.13 1.06.43c.43.18.83.41 1.23.71l.91.7 1.06-.43 1.27-.51.7 1.21-1.07.85-.89.7.14 1.13zM12 8c-2.21 0-4 1.79-4 4s1.79 4 4 4 4-1.79 4-4-1.79-4-4-4zm0 6c-1.1 0-2-.9-2-2s.9-2 2-2 2 .9 2 2-.9 2-2 2z"/></svg>
|
||||||
fill="#000000">
|
|
||||||
<g>
|
|
||||||
<path d="M0,0h24v24H0V0z" fill="none"/>
|
|
||||||
<path d="M19.14,12.94c0.04-0.3,0.06-0.61,0.06-0.94c0-0.32-0.02-0.64-0.07-0.94l2.03-1.58c0.18-0.14,0.23-0.41,0.12-0.61 l-1.92-3.32c-0.12-0.22-0.37-0.29-0.59-0.22l-2.39,0.96c-0.5-0.38-1.03-0.7-1.62-0.94L14.4,2.81c-0.04-0.24-0.24-0.41-0.48-0.41 h-3.84c-0.24,0-0.43,0.17-0.47,0.41L9.25,5.35C8.66,5.59,8.12,5.92,7.63,6.29L5.24,5.33c-0.22-0.08-0.47,0-0.59,0.22L2.74,8.87 C2.62,9.08,2.66,9.34,2.86,9.48l2.03,1.58C4.84,11.36,4.8,11.69,4.8,12s0.02,0.64,0.07,0.94l-2.03,1.58 c-0.18,0.14-0.23,0.41-0.12,0.61l1.92,3.32c0.12,0.22,0.37,0.29,0.59,0.22l2.39-0.96c0.5,0.38,1.03,0.7,1.62,0.94l0.36,2.54 c0.05,0.24,0.24,0.41,0.48,0.41h3.84c0.24,0,0.44-0.17,0.47-0.41l0.36-2.54c0.59-0.24,1.13-0.56,1.62-0.94l2.39,0.96 c0.22,0.08,0.47,0,0.59-0.22l1.92-3.32c0.12-0.22,0.07-0.47-0.12-0.61L19.14,12.94z M12,15.6c-1.98,0-3.6-1.62-3.6-3.6 s1.62-3.6,3.6-3.6s3.6,1.62,3.6,3.6S13.98,15.6,12,15.6z"/>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.4 KiB |
Loading…
Reference in New Issue
Block a user