Added new side bar

This commit is contained in:
Abdelilah El Aissaoui 2022-10-05 18:55:53 +02:00
parent c6b0250a63
commit 2ffb8d9038
17 changed files with 252 additions and 172 deletions

View File

@ -4,16 +4,12 @@ package com.jetpackduba.gitnuro
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.*
import androidx.compose.material.Icon
import androidx.compose.material.IconButton
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Text
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.ExperimentalComposeUiApi
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.res.painterResource
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.components.RepositoriesTabPanel
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.flow.MutableStateFlow
import kotlinx.coroutines.launch
@ -53,9 +47,6 @@ class App {
@Inject
lateinit var appSettings: AppSettings
@Inject
lateinit var settingsViewModel: SettingsViewModel
init {
appComponent.inject(this)
}
@ -107,25 +98,12 @@ class App {
emptyArray()
CompositionLocalProvider(values = density) {
var showSettingsDialog by remember { mutableStateOf(false) }
AppTheme(
selectedTheme = theme,
customTheme = customTheme,
) {
Box(modifier = Modifier.background(MaterialTheme.colors.background)) {
AppTabs(
onOpenSettings = {
showSettingsDialog = true
}
)
}
if (showSettingsDialog) {
SettingsDialog(
settingsViewModel = settingsViewModel,
onDismiss = { showSettingsDialog = false }
)
AppTabs()
}
}
}
@ -160,9 +138,7 @@ class App {
@Composable
fun AppTabs(
onOpenSettings: () -> Unit,
) {
fun AppTabs() {
val tabs by tabsFlow.collectAsState()
val tabsInformationList = tabs.sortedBy { it.key }
val selectedTabKey = remember { mutableStateOf(0) }
@ -173,7 +149,6 @@ class App {
Tabs(
tabsInformationList = tabsInformationList,
selectedTabKey = selectedTabKey,
onOpenSettings = onOpenSettings,
onAddedTab = { tabInfo ->
addTab(tabInfo)
},
@ -203,11 +178,9 @@ class App {
tabsFlow.value = tabsFlow.value.toMutableList().apply { add(tabInformation) }
}
@OptIn(ExperimentalComposeUiApi::class)
@Composable
fun Tabs(
selectedTabKey: MutableState<Int>,
onOpenSettings: () -> Unit,
tabsInformationList: List<TabInformation>,
onAddedTab: (TabInformation) -> Unit,
onRemoveTab: (Int) -> Unit,
@ -237,20 +210,6 @@ class App {
},
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,
)
}
}
}

View File

@ -3,6 +3,7 @@ package com.jetpackduba.gitnuro.di
import com.jetpackduba.gitnuro.App
import com.jetpackduba.gitnuro.AppStateManager
import com.jetpackduba.gitnuro.preferences.AppSettings
import com.jetpackduba.gitnuro.viewmodels.SettingsViewModel
import dagger.Component
import javax.inject.Singleton
@ -11,6 +12,7 @@ import javax.inject.Singleton
interface AppComponent {
fun inject(main: App)
fun appStateManager(): AppStateManager
fun settingsViewModel(): SettingsViewModel
fun appPreferences(): AppSettings
}

View File

@ -17,11 +17,10 @@ fun Modifier.backgroundIf(condition: Boolean, color: Color): Modifier {
}
}
@OptIn(ExperimentalComposeUiApi::class)
fun Modifier.handMouseClickable(onClick: () -> Unit): Modifier {
return this
.clickable { onClick() }
.pointerHoverIcon(PointerIconDefaults.Hand)
.handOnHover()
}
/**
@ -31,3 +30,8 @@ fun Modifier.handMouseClickable(onClick: () -> Unit): Modifier {
fun Modifier.ignoreKeyEvents(): Modifier {
return this.onPreviewKeyEvent { true }
}
@OptIn(ExperimentalComposeUiApi::class)
fun Modifier.handOnHover(): Modifier {
return this.pointerHoverIcon(PointerIconDefaults.Hand)
}

View File

@ -31,7 +31,7 @@ val lightTheme = ColorsScheme(
val darkBlueTheme = ColorsScheme(
primary = Color(0xFF014F97),
primary = Color(0xFF1074BC),
primaryVariant = Color(0xFF9FD1FF),
onPrimary = Color(0xFFFFFFFFF),
secondary = Color(0xFFe9c754),
@ -39,10 +39,10 @@ val darkBlueTheme = ColorsScheme(
secondaryText = Color(0xFFCCCBCB),
error = Color(0xFFc93838),
onError = Color(0xFFFFFFFF),
background = Color(0xFF0E1621),
background = Color(0xFF16181F),
backgroundSelected = Color(0xFF2f3640),
surface = Color(0xFF15212d),
secondarySurface = Color(0xFF1a2c40),
surface = Color(0xFF202538),
secondarySurface = Color(0xFF122C46),
headerBackground = Color(0xFF0a335c),
borderColor = Color(0xFF989898),
addFile = Color(0xFF32A852),

View File

@ -27,6 +27,7 @@ import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.unit.dp
import com.jetpackduba.gitnuro.extensions.handMouseClickable
import com.jetpackduba.gitnuro.extensions.handOnHover
import com.jetpackduba.gitnuro.extensions.lineAt
import com.jetpackduba.gitnuro.extensions.toStringWithSpaces
import com.jetpackduba.gitnuro.keybindings.KeybindingOption
@ -187,7 +188,7 @@ fun MinimizedBlame(
onClick = onClose,
modifier = Modifier
.padding(horizontal = 16.dp)
.pointerHoverIcon(PointerIconDefaults.Hand)
.handOnHover()
) {
Image(
painter = painterResource("close.svg"),
@ -222,7 +223,7 @@ private fun Header(
IconButton(
onClick = onClose,
modifier = Modifier
.pointerHoverIcon(PointerIconDefaults.Hand)
.handOnHover()
) {
Image(
painter = painterResource("close.svg"),

View File

@ -24,6 +24,7 @@ import androidx.compose.ui.input.pointer.pointerHoverIcon
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.unit.dp
import com.jetpackduba.gitnuro.extensions.handMouseClickable
import com.jetpackduba.gitnuro.extensions.handOnHover
import com.jetpackduba.gitnuro.extensions.toSmartSystemString
import com.jetpackduba.gitnuro.git.diff.DiffResult
import com.jetpackduba.gitnuro.keybindings.KeybindingOption
@ -102,7 +103,7 @@ private fun Header(
IconButton(
onClick = onClose,
modifier = Modifier
.pointerHoverIcon(PointerIconDefaults.Hand)
.handOnHover()
) {
Image(
painter = painterResource("close.svg"),

View File

@ -6,6 +6,7 @@ import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.*
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.ArrowDropDown
@ -13,6 +14,8 @@ import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.ExperimentalComposeUiApi
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.ColorFilter
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.unit.dp
import com.jetpackduba.gitnuro.extensions.handMouseClickable
import com.jetpackduba.gitnuro.extensions.handOnHover
import com.jetpackduba.gitnuro.extensions.ignoreKeyEvents
import com.jetpackduba.gitnuro.theme.primaryTextColor
import com.jetpackduba.gitnuro.ui.context_menu.*
@ -32,7 +36,6 @@ import com.jetpackduba.gitnuro.viewmodels.MenuViewModel
fun Menu(
modifier: Modifier,
menuViewModel: MenuViewModel,
onRepositoryOpen: () -> Unit,
onCreateBranch: () -> Unit,
onStashWithMessage: () -> Unit,
) {
@ -43,15 +46,6 @@ fun Menu(
horizontalArrangement = Arrangement.Center,
verticalAlignment = Alignment.CenterVertically,
) {
MenuButton(
modifier = Modifier.padding(start = 8.dp),
title = "Open",
icon = painterResource("open.svg"),
onClick = {
onRepositoryOpen()
}
)
Spacer(modifier = Modifier.weight(1f))
ExtendedMenuButton(
@ -129,7 +123,6 @@ fun Menu(
val menuOptions = remember {
repositoryAdditionalOptionsMenu(
onOpenRepositoryOnFileExplorer = { menuViewModel.openFolderInFileExplorer() },
onForceRepositoryRefresh = { menuViewModel.refresh() },
)
}
for (item in menuOptions) {
@ -153,34 +146,31 @@ fun MenuButton(
icon: Painter,
onClick: () -> Unit
) {
val iconColor = if (enabled) {
MaterialTheme.colors.primaryVariant
} else {
MaterialTheme.colors.secondaryVariant //todo this color isn't specified anywhere
}
Column(
Row(
modifier = modifier
.ignoreKeyEvents()
.clip(RoundedCornerShape(4.dp))
.background(MaterialTheme.colors.primary)
.handMouseClickable { if (enabled) onClick() }
.padding(vertical = 4.dp, horizontal = 16.dp)
.width(48.dp),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center,
.width(100.dp),
horizontalArrangement = Arrangement.Center,
verticalAlignment = Alignment.CenterVertically,
) {
Image(
Icon(
painter = icon,
contentDescription = title,
modifier = Modifier
.padding(vertical = 2.dp)
.size(24.dp),
colorFilter = ColorFilter.tint(iconColor),
tint = MaterialTheme.colors.onPrimary,
)
Text(
text = title,
style = MaterialTheme.typography.body2,
modifier = Modifier.padding(start = 2.dp, top = 8.dp, bottom = 8.dp),
maxLines = 1,
textAlign = TextAlign.Center,
color = MaterialTheme.colors.onPrimary,
)
}
}
@ -194,44 +184,40 @@ fun ExtendedMenuButton(
onClick: () -> Unit,
extendedListItems: List<DropDownContentData>,
) {
val iconColor = if (enabled) {
MaterialTheme.colors.primaryVariant
} else {
MaterialTheme.colors.secondaryVariant
}
var showDropDownMenu by remember { mutableStateOf(false) }
Row(
modifier = modifier
.height(IntrinsicSize.Min)
.ignoreKeyEvents()
.handMouseClickable { if (enabled) onClick() }
.clip(RoundedCornerShape(4.dp))
.background(MaterialTheme.colors.primary)
) {
Column(
Row(
modifier = Modifier
.padding(top = 4.dp, bottom = 4.dp, start = 16.dp, end = 4.dp)
.width(40.dp),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center,
.width(92.dp)
.handMouseClickable { if (enabled) onClick() },
horizontalArrangement = Arrangement.Center,
verticalAlignment = Alignment.CenterVertically,
) {
Image(
Icon(
painter = icon,
contentDescription = title,
modifier = Modifier
.padding(vertical = 2.dp)
.size(24.dp),
colorFilter = ColorFilter.tint(iconColor),
tint = MaterialTheme.colors.onPrimary,
)
Text(
text = title,
modifier = Modifier.padding(start = 2.dp, top = 8.dp, bottom = 8.dp),
style = MaterialTheme.typography.body2,
color = MaterialTheme.colors.onPrimary,
)
}
Box(
modifier = Modifier
.width(20.dp)
.width(24.dp)
.fillMaxHeight()
.ignoreKeyEvents()
.handMouseClickable {
@ -239,10 +225,18 @@ fun ExtendedMenuButton(
},
contentAlignment = Alignment.Center,
) {
Box(
modifier = Modifier
.fillMaxHeight()
.background(MaterialTheme.colors.onPrimary.copy(alpha = 0.5f))
.width(1.dp)
.align(Alignment.CenterStart)
)
Icon(
Icons.Default.ArrowDropDown,
contentDescription = null,
tint = MaterialTheme.colors.primaryTextColor,
tint = MaterialTheme.colors.onPrimary,
)
DropdownMenu(
@ -275,7 +269,7 @@ fun IconMenuButton(
IconButton(
modifier = modifier
.pointerHoverIcon(PointerIconDefaults.Hand),
.handOnHover(),
enabled = enabled,
onClick = onClick,
) {

View File

@ -16,6 +16,7 @@ import androidx.compose.ui.input.pointer.PointerIconDefaults
import androidx.compose.ui.input.pointer.pointerHoverIcon
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.unit.dp
import com.jetpackduba.gitnuro.extensions.handOnHover
import com.jetpackduba.gitnuro.extensions.simpleName
import com.jetpackduba.gitnuro.theme.primaryTextColor
import com.jetpackduba.gitnuro.ui.components.SideMenuPanel
@ -29,7 +30,6 @@ import com.jetpackduba.gitnuro.viewmodels.RemoteView
import com.jetpackduba.gitnuro.viewmodels.RemotesViewModel
import org.eclipse.jgit.lib.Ref
@OptIn(ExperimentalComposeUiApi::class)
@Composable
fun Remotes(
remotesViewModel: RemotesViewModel,
@ -62,7 +62,7 @@ fun Remotes(
modifier = Modifier
.padding(end = 16.dp)
.size(16.dp)
.pointerHoverIcon(PointerIconDefaults.Hand),
.handOnHover(),
) {
Icon(
painter = painterResource("settings.svg"),

View File

@ -4,27 +4,44 @@ package com.jetpackduba.gitnuro.ui
import androidx.compose.foundation.background
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.shape.RoundedCornerShape
import androidx.compose.material.Icon
import androidx.compose.material.IconButton
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Text
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
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.geometry.Offset
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.input.key.onKeyEvent
import androidx.compose.ui.input.pointer.PointerIcon
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.handOnHover
import com.jetpackduba.gitnuro.git.DiffEntryType
import com.jetpackduba.gitnuro.keybindings.KeybindingOption
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.dialogs.AuthorDialog
import com.jetpackduba.gitnuro.ui.dialogs.NewBranchDialog
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.log.Log
import com.jetpackduba.gitnuro.viewmodels.BlameState
@ -44,7 +61,6 @@ fun RepositoryOpenPage(tabViewModel: TabViewModel) {
val selectedItem by tabViewModel.selectedItem.collectAsState()
val blameState by tabViewModel.blameState.collectAsState()
val showHistory by tabViewModel.showHistory.collectAsState()
val userInfo by tabViewModel.authorInfoSimple.collectAsState()
val showAuthorInfo by tabViewModel.showAuthorInfo.collectAsState()
var showNewBranchDialog by remember { mutableStateOf(false) }
@ -87,40 +103,45 @@ fun RepositoryOpenPage(tabViewModel: TabViewModel) {
LaunchedEffect(selectedItem) {
focusRequester.requestFocus()
}
Column {
Row(modifier = Modifier.weight(1f)) {
SideBar(tabViewModel)
Column(
modifier = Modifier
.focusRequester(focusRequester)
.focusable()
.onKeyEvent { keyEvent ->
if (keyEvent.matchesBinding(KeybindingOption.REFRESH)) {
tabViewModel.refreshAll()
true
Column(
modifier = Modifier
.focusRequester(focusRequester)
.focusable()
.onKeyEvent { keyEvent ->
if (keyEvent.matchesBinding(KeybindingOption.REFRESH)) {
tabViewModel.refreshAll()
true
} else {
false
}
}
) {
val rebaseInteractiveViewModel = tabViewModel.rebaseInteractiveViewModel
if (repositoryState == RepositoryState.REBASING_INTERACTIVE && rebaseInteractiveViewModel != null) {
RebaseInteractive(rebaseInteractiveViewModel)
} 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(
@ -129,27 +150,142 @@ fun RepositoryOpenPage(tabViewModel: TabViewModel) {
.fillMaxWidth()
.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
.fillMaxWidth()
.height(32.dp)
.background(MaterialTheme.colors.surface)
.padding(horizontal = 16.dp),
verticalAlignment = Alignment.CenterVertically,
.fillMaxHeight()
.handMouseClickable { tabViewModel.showAuthorInfoDialog() },
contentAlignment = Alignment.Center,
) {
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(
modifier = Modifier
.fillMaxHeight()
.handMouseClickable { tabViewModel.showAuthorInfoDialog() },
contentAlignment = Alignment.Center,
.clip(RoundedCornerShape(4.dp))
.background(MaterialTheme.colors.background)
) {
Text(
text = "${userInfo.name ?: "Name not set"} <${userInfo.email ?: "Email not set"}>",
style = MaterialTheme.typography.body2,
text = label,
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,
)
}
else -> {
val diffViewModel = tabViewModel.diffViewModel

View File

@ -29,6 +29,7 @@ import com.jetpackduba.gitnuro.AppStateManager
import com.jetpackduba.gitnuro.di.AppComponent
import com.jetpackduba.gitnuro.di.DaggerTabComponent
import com.jetpackduba.gitnuro.extensions.handMouseClickable
import com.jetpackduba.gitnuro.extensions.handOnHover
import com.jetpackduba.gitnuro.theme.primaryTextColor
import com.jetpackduba.gitnuro.viewmodels.TabViewModel
import javax.inject.Inject
@ -117,7 +118,7 @@ fun TabPanel(
onClick = onNewTabClicked,
modifier = Modifier
.size(36.dp)
.pointerHoverIcon(PointerIconDefaults.Hand)
.handOnHover()
.align(Alignment.CenterStart),
) {
Icon(

View File

@ -5,7 +5,6 @@ import androidx.compose.foundation.ExperimentalFoundationApi
@OptIn(ExperimentalFoundationApi::class)
fun repositoryAdditionalOptionsMenu(
onOpenRepositoryOnFileExplorer: () -> Unit,
onForceRepositoryRefresh: () -> Unit,
): List<DropDownContentData> {
return mutableListOf(
DropDownContentData(
@ -13,10 +12,5 @@ fun repositoryAdditionalOptionsMenu(
icon = "source.svg",
onClick = onOpenRepositoryOnFileExplorer,
),
DropDownContentData(
label = "Refresh repository",
icon = "refresh.svg",
onClick = onForceRepositoryRefresh,
),
)
}

View File

@ -16,13 +16,13 @@ import androidx.compose.ui.input.pointer.pointerHoverIcon
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.unit.dp
import com.jetpackduba.gitnuro.extensions.handMouseClickable
import com.jetpackduba.gitnuro.extensions.handOnHover
import com.jetpackduba.gitnuro.theme.*
import com.jetpackduba.gitnuro.ui.components.AdjustableOutlinedTextField
import com.jetpackduba.gitnuro.ui.components.PrimaryButton
import com.jetpackduba.gitnuro.viewmodels.RemotesViewModel
import org.eclipse.jgit.transport.RemoteConfig
@OptIn(ExperimentalComposeUiApi::class)
@Composable
fun EditRemotesDialog(
remotesViewModel: RemotesViewModel,
@ -90,7 +90,7 @@ fun EditRemotesDialog(
IconButton(
onClick = onDismiss,
modifier = Modifier
.pointerHoverIcon(PointerIconDefaults.Hand)
.handOnHover()
) {
Icon(
imageVector = Icons.Default.Clear,
@ -153,7 +153,7 @@ fun EditRemotesDialog(
IconButton(
modifier = Modifier
.size(36.dp)
.pointerHoverIcon(PointerIconDefaults.Hand),
.handOnHover(),
onClick = {
val remotesWithNew = remotesEditorData.listRemotes.toMutableList()
val newRemote = RemoteWrapper(
@ -182,7 +182,7 @@ fun EditRemotesDialog(
IconButton(
modifier = Modifier
.size(36.dp)
.pointerHoverIcon(PointerIconDefaults.Hand),
.handOnHover(),
enabled = selectedRemote != null,
onClick = {
if (selectedRemote != null)

View File

@ -550,7 +550,6 @@ fun HunkHeader(
}
}
@OptIn(ExperimentalComposeUiApi::class)
@Composable
private fun DiffHeader(
diffEntryType: DiffEntryType,
@ -598,7 +597,7 @@ private fun DiffHeader(
IconButton(
onClick = onCloseDiffView,
modifier = Modifier
.pointerHoverIcon(PointerIconDefaults.Hand)
.handOnHover()
) {
Image(
painter = painterResource("close.svg"),
@ -677,7 +676,6 @@ fun UncommitedDiffFileHeaderButtons(
)
}
@OptIn(ExperimentalComposeUiApi::class)
@Composable
private fun PathOnlyDiffHeader(
filePath: String,
@ -703,7 +701,7 @@ private fun PathOnlyDiffHeader(
IconButton(
onClick = onCloseDiffView,
modifier = Modifier
.pointerHoverIcon(PointerIconDefaults.Hand)
.handOnHover()
) {
Image(
painter = painterResource("close.svg"),

View File

@ -333,7 +333,7 @@ fun SearchFilter(
IconButton(
modifier = Modifier
.pointerHoverIcon(PointerIconDefaults.Hand),
.handOnHover(),
onClick = {
scope.launch { logViewModel.selectPreviousFilterCommit() }
}
@ -343,7 +343,7 @@ fun SearchFilter(
IconButton(
modifier = Modifier
.pointerHoverIcon(PointerIconDefaults.Hand),
.handOnHover(),
onClick = {
scope.launch { logViewModel.selectNextFilterCommit() }
}
@ -353,7 +353,7 @@ fun SearchFilter(
IconButton(
modifier = Modifier
.pointerHoverIcon(PointerIconDefaults.Hand)
.handOnHover()
.padding(end = 4.dp),
onClick = { logViewModel.closeSearch() }
) {
@ -613,7 +613,7 @@ fun GraphHeader(
IconButton(
modifier = Modifier
.padding(end = 8.dp)
.pointerHoverIcon(PointerIconDefaults.Hand),
.handOnHover(),
onClick = onShowSearch
) {
Icon(
@ -1135,7 +1135,7 @@ fun RefChip(
.clip(RoundedCornerShape(16.dp))
.border(width = 2.dp, color = color, shape = RoundedCornerShape(16.dp))
.combinedClickable(onDoubleClick = onCheckoutRef, onClick = {})
.pointerHoverIcon(PointerIconDefaults.Hand)
.handOnHover()
) {
ContextMenu(
items = contextMenuItemsList

View File

@ -68,10 +68,4 @@ class MenuViewModel @Inject constructor(
) { git ->
Desktop.getDesktop().open(git.repository.directory.parentFile)
}
fun refresh() = tabState.safeProcessing(
refreshType = RefreshType.ALL_DATA,
) {
// Nothing to do here
}
}

View File

@ -55,6 +55,7 @@ class TabViewModel @Inject constructor(
private val authorViewModelProvider: Provider<AuthorViewModel>,
private val tabState: TabState,
val appStateManager: AppStateManager,
val settingsViewModel: SettingsViewModel,
private val fileChangesWatcher: FileChangesWatcher,
private val updatesRepository: UpdatesRepository,
) {

View File

@ -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"
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>
<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>

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB