Added change upstream branch option
This commit is contained in:
parent
5fd29fbc39
commit
91094a8771
@ -0,0 +1,8 @@
|
|||||||
|
package com.jetpackduba.gitnuro.git.branches
|
||||||
|
|
||||||
|
object BranchesConstants {
|
||||||
|
/**
|
||||||
|
* Prefix added before the upstream branch name in .git/config
|
||||||
|
*/
|
||||||
|
const val UPSTREAM_BRANCH_CONFIG_PREFIX = "refs/heads/"
|
||||||
|
}
|
@ -0,0 +1,26 @@
|
|||||||
|
package com.jetpackduba.gitnuro.git.branches
|
||||||
|
|
||||||
|
import com.jetpackduba.gitnuro.extensions.simpleName
|
||||||
|
import org.eclipse.jgit.api.Git
|
||||||
|
import org.eclipse.jgit.lib.Config
|
||||||
|
import org.eclipse.jgit.lib.Ref
|
||||||
|
import org.eclipse.jgit.lib.Repository
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
class GetTrackingBranchUseCase @Inject constructor() {
|
||||||
|
operator fun invoke(git: Git, ref: Ref): TrackingBranch? {
|
||||||
|
val repository: Repository = git.repository
|
||||||
|
|
||||||
|
val config: Config = repository.config
|
||||||
|
val remote: String? = config.getString("branch", ref.simpleName, "remote")
|
||||||
|
val branch: String? = config.getString("branch", ref.simpleName, "merge")
|
||||||
|
|
||||||
|
if (remote != null && branch != null) {
|
||||||
|
return TrackingBranch(remote, branch.removePrefix(BranchesConstants.UPSTREAM_BRANCH_CONFIG_PREFIX))
|
||||||
|
}
|
||||||
|
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
data class TrackingBranch(val remote: String, val branch: String)
|
@ -0,0 +1,31 @@
|
|||||||
|
package com.jetpackduba.gitnuro.git.branches
|
||||||
|
|
||||||
|
import com.jetpackduba.gitnuro.extensions.simpleName
|
||||||
|
import org.eclipse.jgit.api.Git
|
||||||
|
import org.eclipse.jgit.lib.Config
|
||||||
|
import org.eclipse.jgit.lib.Ref
|
||||||
|
import org.eclipse.jgit.lib.Repository
|
||||||
|
import org.eclipse.jgit.lib.StoredConfig
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
class SetTrackingBranchUseCase @Inject constructor() {
|
||||||
|
operator fun invoke(git: Git, ref: Ref, remoteName: String?, remoteBranch: Ref?) {
|
||||||
|
val repository: Repository = git.repository
|
||||||
|
val config: StoredConfig = repository.config
|
||||||
|
|
||||||
|
if (remoteName == null || remoteBranch == null) {
|
||||||
|
config.unset("branch", ref.simpleName, "remote")
|
||||||
|
config.unset("branch", ref.simpleName, "merge")
|
||||||
|
} else {
|
||||||
|
config.setString("branch", ref.simpleName, "remote", remoteName)
|
||||||
|
config.setString(
|
||||||
|
"branch",
|
||||||
|
ref.simpleName,
|
||||||
|
"merge",
|
||||||
|
BranchesConstants.UPSTREAM_BRANCH_CONFIG_PREFIX + remoteBranch.simpleName
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
config.save()
|
||||||
|
}
|
||||||
|
}
|
@ -80,19 +80,16 @@ val Colors.isDark: Boolean
|
|||||||
get() = !this.isLight
|
get() = !this.isLight
|
||||||
|
|
||||||
|
|
||||||
enum class Theme(val displayName: String) : DropDownOption {
|
enum class Theme(val displayName: String) {
|
||||||
LIGHT("Light"),
|
LIGHT("Light"),
|
||||||
DARK("Dark"),
|
DARK("Dark"),
|
||||||
DARK_GRAY("Dark gray"),
|
DARK_GRAY("Dark gray"),
|
||||||
CUSTOM("Custom");
|
CUSTOM("Custom");
|
||||||
|
|
||||||
override val optionName: String
|
|
||||||
get() = displayName
|
|
||||||
}
|
}
|
||||||
|
|
||||||
val themeLists = listOf(
|
val themeLists = listOf(
|
||||||
Theme.LIGHT,
|
DropDownOption(Theme.LIGHT, Theme.LIGHT.displayName),
|
||||||
Theme.DARK,
|
DropDownOption(Theme.DARK, Theme.DARK.displayName),
|
||||||
Theme.DARK_GRAY,
|
DropDownOption(Theme.DARK_GRAY, Theme.DARK_GRAY.displayName),
|
||||||
Theme.CUSTOM,
|
DropDownOption(Theme.CUSTOM, Theme.CUSTOM.displayName),
|
||||||
)
|
)
|
@ -18,6 +18,7 @@ import com.jetpackduba.gitnuro.extensions.simpleName
|
|||||||
import com.jetpackduba.gitnuro.theme.onBackgroundSecondary
|
import com.jetpackduba.gitnuro.theme.onBackgroundSecondary
|
||||||
import com.jetpackduba.gitnuro.ui.components.*
|
import com.jetpackduba.gitnuro.ui.components.*
|
||||||
import com.jetpackduba.gitnuro.ui.context_menu.*
|
import com.jetpackduba.gitnuro.ui.context_menu.*
|
||||||
|
import com.jetpackduba.gitnuro.ui.dialogs.SetDefaultUpstreamBranchDialog
|
||||||
import com.jetpackduba.gitnuro.ui.dialogs.EditRemotesDialog
|
import com.jetpackduba.gitnuro.ui.dialogs.EditRemotesDialog
|
||||||
import com.jetpackduba.gitnuro.viewmodels.sidepanel.*
|
import com.jetpackduba.gitnuro.viewmodels.sidepanel.*
|
||||||
import org.eclipse.jgit.lib.Ref
|
import org.eclipse.jgit.lib.Ref
|
||||||
@ -42,6 +43,7 @@ fun SidePanel(
|
|||||||
val submodulesState by submodulesViewModel.submodules.collectAsState()
|
val submodulesState by submodulesViewModel.submodules.collectAsState()
|
||||||
|
|
||||||
var showEditRemotesDialog by remember { mutableStateOf(false) }
|
var showEditRemotesDialog by remember { mutableStateOf(false) }
|
||||||
|
val (branchToChangeUpstream, setBranchToChangeUpstream) = remember { mutableStateOf<Ref?>(null) }
|
||||||
|
|
||||||
Column {
|
Column {
|
||||||
FilterTextField(
|
FilterTextField(
|
||||||
@ -62,6 +64,7 @@ fun SidePanel(
|
|||||||
localBranches(
|
localBranches(
|
||||||
branchesState = branchesState,
|
branchesState = branchesState,
|
||||||
branchesViewModel = branchesViewModel,
|
branchesViewModel = branchesViewModel,
|
||||||
|
onChangeDefaultUpstreamBranch = { setBranchToChangeUpstream(it) }
|
||||||
)
|
)
|
||||||
|
|
||||||
remotes(
|
remotes(
|
||||||
@ -95,6 +98,14 @@ fun SidePanel(
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (branchToChangeUpstream != null) {
|
||||||
|
SetDefaultUpstreamBranchDialog(
|
||||||
|
viewModel = gitnuroDynamicViewModel(),
|
||||||
|
branch = branchToChangeUpstream,
|
||||||
|
onClose = { setBranchToChangeUpstream(null) }
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
@ -123,6 +134,7 @@ fun FilterTextField(value: String, onValueChange: (String) -> Unit, modifier: Mo
|
|||||||
fun LazyListScope.localBranches(
|
fun LazyListScope.localBranches(
|
||||||
branchesState: BranchesState,
|
branchesState: BranchesState,
|
||||||
branchesViewModel: BranchesViewModel,
|
branchesViewModel: BranchesViewModel,
|
||||||
|
onChangeDefaultUpstreamBranch: (Ref) -> Unit,
|
||||||
) {
|
) {
|
||||||
val isExpanded = branchesState.isExpanded
|
val isExpanded = branchesState.isExpanded
|
||||||
val branches = branchesState.branches
|
val branches = branchesState.branches
|
||||||
@ -157,6 +169,7 @@ fun LazyListScope.localBranches(
|
|||||||
onRebaseBranch = { branchesViewModel.rebaseBranch(branch) },
|
onRebaseBranch = { branchesViewModel.rebaseBranch(branch) },
|
||||||
onPushToRemoteBranch = { branchesViewModel.pushToRemoteBranch(branch) },
|
onPushToRemoteBranch = { branchesViewModel.pushToRemoteBranch(branch) },
|
||||||
onPullFromRemoteBranch = { branchesViewModel.pullFromRemoteBranch(branch) },
|
onPullFromRemoteBranch = { branchesViewModel.pullFromRemoteBranch(branch) },
|
||||||
|
onChangeDefaultUpstreamBranch = { onChangeDefaultUpstreamBranch(branch) }
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -344,6 +357,7 @@ private fun Branch(
|
|||||||
onDeleteBranch: () -> Unit,
|
onDeleteBranch: () -> Unit,
|
||||||
onPushToRemoteBranch: () -> Unit,
|
onPushToRemoteBranch: () -> Unit,
|
||||||
onPullFromRemoteBranch: () -> Unit,
|
onPullFromRemoteBranch: () -> Unit,
|
||||||
|
onChangeDefaultUpstreamBranch: () -> Unit,
|
||||||
) {
|
) {
|
||||||
ContextMenu(
|
ContextMenu(
|
||||||
items = {
|
items = {
|
||||||
@ -358,6 +372,7 @@ private fun Branch(
|
|||||||
onRebaseBranch = onRebaseBranch,
|
onRebaseBranch = onRebaseBranch,
|
||||||
onPushToRemoteBranch = onPushToRemoteBranch,
|
onPushToRemoteBranch = onPushToRemoteBranch,
|
||||||
onPullFromRemoteBranch = onPullFromRemoteBranch,
|
onPullFromRemoteBranch = onPullFromRemoteBranch,
|
||||||
|
onChangeDefaultUpstreamBranch = onChangeDefaultUpstreamBranch
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
) {
|
) {
|
||||||
|
@ -0,0 +1,106 @@
|
|||||||
|
package com.jetpackduba.gitnuro.ui.components
|
||||||
|
|
||||||
|
import androidx.compose.desktop.ui.tooling.preview.Preview
|
||||||
|
import androidx.compose.foundation.focusable
|
||||||
|
import androidx.compose.foundation.layout.Box
|
||||||
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
|
import androidx.compose.foundation.layout.width
|
||||||
|
import androidx.compose.material.*
|
||||||
|
import androidx.compose.runtime.*
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.focus.FocusRequester
|
||||||
|
import androidx.compose.ui.focus.focusRequester
|
||||||
|
import androidx.compose.ui.res.painterResource
|
||||||
|
import androidx.compose.ui.unit.Dp
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import com.jetpackduba.gitnuro.AppIcons
|
||||||
|
import com.jetpackduba.gitnuro.extensions.lowercaseContains
|
||||||
|
import com.jetpackduba.gitnuro.ui.dropdowns.DropDownOption
|
||||||
|
|
||||||
|
@Preview
|
||||||
|
@Composable
|
||||||
|
fun FilterDropdownPreview() {
|
||||||
|
val items = listOf(
|
||||||
|
DropDownOption("","Test1"),
|
||||||
|
DropDownOption("","Test2"),
|
||||||
|
DropDownOption("","Test3"),
|
||||||
|
DropDownOption("","Test4"),
|
||||||
|
)
|
||||||
|
|
||||||
|
FilterDropdown(
|
||||||
|
dropdownItems = items,
|
||||||
|
currentOption = items[0],
|
||||||
|
onOptionSelected = {}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun <T> FilterDropdown(
|
||||||
|
dropdownItems: List<DropDownOption<T>>,
|
||||||
|
currentOption: DropDownOption<T>?,
|
||||||
|
width: Dp = 240.dp,
|
||||||
|
onOptionSelected: (DropDownOption<T>) -> Unit,
|
||||||
|
) {
|
||||||
|
var showDropdown by remember { mutableStateOf(false) }
|
||||||
|
var filter by remember { mutableStateOf("") }
|
||||||
|
val filterFocusRequester = remember { FocusRequester() }
|
||||||
|
val filteredDropdownItems = remember(filter, dropdownItems) { dropdownItems.filter { it.optionName.lowercaseContains(filter) } }
|
||||||
|
|
||||||
|
Box {
|
||||||
|
OutlinedButton(
|
||||||
|
onClick = { showDropdown = true },
|
||||||
|
colors = ButtonDefaults.outlinedButtonColors(backgroundColor = MaterialTheme.colors.background),
|
||||||
|
modifier = Modifier.width(width)
|
||||||
|
) {
|
||||||
|
Text(
|
||||||
|
text = currentOption?.optionName ?: "",
|
||||||
|
style = MaterialTheme.typography.body1,
|
||||||
|
color = MaterialTheme.colors.onBackground,
|
||||||
|
modifier = Modifier.weight(1f),
|
||||||
|
maxLines = 1
|
||||||
|
)
|
||||||
|
|
||||||
|
Icon(
|
||||||
|
painter = painterResource(AppIcons.DROPDOWN),
|
||||||
|
contentDescription = null,
|
||||||
|
tint = MaterialTheme.colors.onBackground,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
DropdownMenu(
|
||||||
|
expanded = showDropdown,
|
||||||
|
onDismissRequest = { showDropdown = false },
|
||||||
|
modifier = Modifier.width(width),
|
||||||
|
) {
|
||||||
|
DropdownMenuItem(
|
||||||
|
onClick = {},
|
||||||
|
modifier = Modifier.fillMaxWidth()
|
||||||
|
) {
|
||||||
|
AdjustableOutlinedTextField(
|
||||||
|
value = filter,
|
||||||
|
onValueChange = { filter = it },
|
||||||
|
modifier = Modifier.focusable(showDropdown)
|
||||||
|
.focusRequester(filterFocusRequester)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
for (dropDownOption in filteredDropdownItems) {
|
||||||
|
DropdownMenuItem(
|
||||||
|
modifier = Modifier.fillMaxWidth(),
|
||||||
|
onClick = {
|
||||||
|
onOptionSelected(dropDownOption)
|
||||||
|
showDropdown = false
|
||||||
|
}
|
||||||
|
) {
|
||||||
|
Text(dropDownOption.optionName, style = MaterialTheme.typography.body2)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LaunchedEffect(showDropdown) {
|
||||||
|
if (showDropdown) {
|
||||||
|
filterFocusRequester.requestFocus()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -262,4 +262,10 @@ inline fun <reified T> gitnuroViewModel(): T {
|
|||||||
return remember(tab) {
|
return remember(tab) {
|
||||||
tab.tabViewModelsHolder.viewModels[T::class] as T
|
tab.tabViewModelsHolder.viewModels[T::class] as T
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
@Composable
|
||||||
|
inline fun <reified T> gitnuroDynamicViewModel(): T {
|
||||||
|
val tab = LocalTabScope.current
|
||||||
|
|
||||||
|
return tab.tabViewModelsHolder.dynamicViewModel(T::class) as T
|
||||||
}
|
}
|
@ -18,6 +18,7 @@ fun branchContextMenuItems(
|
|||||||
onDeleteRemoteBranch: () -> Unit = {},
|
onDeleteRemoteBranch: () -> Unit = {},
|
||||||
onPushToRemoteBranch: () -> Unit,
|
onPushToRemoteBranch: () -> Unit,
|
||||||
onPullFromRemoteBranch: () -> Unit,
|
onPullFromRemoteBranch: () -> Unit,
|
||||||
|
onChangeDefaultUpstreamBranch: () -> Unit,
|
||||||
): List<ContextMenuElement> {
|
): List<ContextMenuElement> {
|
||||||
return mutableListOf<ContextMenuElement>().apply {
|
return mutableListOf<ContextMenuElement>().apply {
|
||||||
if (!isCurrentBranch) {
|
if (!isCurrentBranch) {
|
||||||
@ -68,6 +69,16 @@ fun branchContextMenuItems(
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(isLocal) {
|
||||||
|
add(
|
||||||
|
ContextMenuElement.ContextTextEntry(
|
||||||
|
label = "Change default upstream branch",
|
||||||
|
onClick = onChangeDefaultUpstreamBranch
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
if (!isLocal) {
|
if (!isLocal) {
|
||||||
add(
|
add(
|
||||||
ContextMenuElement.ContextTextEntry(
|
ContextMenuElement.ContextTextEntry(
|
||||||
|
@ -0,0 +1,196 @@
|
|||||||
|
package com.jetpackduba.gitnuro.ui.dialogs
|
||||||
|
|
||||||
|
import androidx.compose.desktop.ui.tooling.preview.Preview
|
||||||
|
import androidx.compose.foundation.layout.*
|
||||||
|
import androidx.compose.material.Icon
|
||||||
|
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.graphics.Color
|
||||||
|
import androidx.compose.ui.res.painterResource
|
||||||
|
import androidx.compose.ui.text.font.FontWeight
|
||||||
|
import androidx.compose.ui.text.style.TextAlign
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import com.jetpackduba.gitnuro.AppIcons
|
||||||
|
import com.jetpackduba.gitnuro.extensions.simpleName
|
||||||
|
import com.jetpackduba.gitnuro.git.remotes.RemoteInfo
|
||||||
|
import com.jetpackduba.gitnuro.ui.components.FilterDropdown
|
||||||
|
import com.jetpackduba.gitnuro.ui.components.PrimaryButton
|
||||||
|
import com.jetpackduba.gitnuro.ui.dropdowns.DropDownOption
|
||||||
|
import com.jetpackduba.gitnuro.viewmodels.ChangeDefaultUpstreamBranchViewModel
|
||||||
|
import com.jetpackduba.gitnuro.viewmodels.SetDefaultUpstreamBranchState
|
||||||
|
import org.eclipse.jgit.lib.ObjectIdRef
|
||||||
|
import org.eclipse.jgit.lib.Ref
|
||||||
|
|
||||||
|
@Preview
|
||||||
|
@Composable
|
||||||
|
fun SetDefaultUpstreamBranchDialogPreview() {
|
||||||
|
SetDefaultUpstreamBranchDialogView(
|
||||||
|
state = SetDefaultUpstreamBranchState.Loaded(
|
||||||
|
ObjectIdRef.PeeledNonTag(null, "TestBranch", null),
|
||||||
|
null,
|
||||||
|
emptyList(),
|
||||||
|
null,
|
||||||
|
null
|
||||||
|
),
|
||||||
|
onClose = {},
|
||||||
|
setSelectedRemote = {},
|
||||||
|
setSelectedBranch = {},
|
||||||
|
changeDefaultUpstreamBranch = {}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun SetDefaultUpstreamBranchDialog(
|
||||||
|
viewModel: ChangeDefaultUpstreamBranchViewModel,
|
||||||
|
branch: Ref,
|
||||||
|
onClose: () -> Unit,
|
||||||
|
) {
|
||||||
|
LaunchedEffect(branch) {
|
||||||
|
viewModel.init(branch)
|
||||||
|
}
|
||||||
|
|
||||||
|
val setDefaultUpstreamBranchState = viewModel.setDefaultUpstreamBranchState.collectAsState().value
|
||||||
|
LaunchedEffect(setDefaultUpstreamBranchState) {
|
||||||
|
if (setDefaultUpstreamBranchState is SetDefaultUpstreamBranchState.UpstreamChanged) {
|
||||||
|
onClose()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MaterialDialog(onCloseRequested = onClose) {
|
||||||
|
SetDefaultUpstreamBranchDialogView(
|
||||||
|
state = setDefaultUpstreamBranchState,
|
||||||
|
onClose = onClose,
|
||||||
|
setSelectedRemote = { viewModel.setSelectedRemote(it) },
|
||||||
|
setSelectedBranch = { viewModel.setSelectedBranch(it) },
|
||||||
|
changeDefaultUpstreamBranch = { viewModel.changeDefaultUpstreamBranch() }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
private fun SetDefaultUpstreamBranchDialogView(
|
||||||
|
state: SetDefaultUpstreamBranchState,
|
||||||
|
onClose: () -> Unit,
|
||||||
|
setSelectedRemote: (RemoteInfo) -> Unit,
|
||||||
|
setSelectedBranch: (Ref) -> Unit,
|
||||||
|
changeDefaultUpstreamBranch: () -> Unit,
|
||||||
|
) {
|
||||||
|
|
||||||
|
Column(
|
||||||
|
horizontalAlignment = Alignment.CenterHorizontally,
|
||||||
|
) {
|
||||||
|
Icon(
|
||||||
|
painterResource(AppIcons.BRANCH),
|
||||||
|
contentDescription = null,
|
||||||
|
modifier = Modifier
|
||||||
|
.padding(bottom = 16.dp)
|
||||||
|
.size(64.dp),
|
||||||
|
tint = MaterialTheme.colors.onBackground,
|
||||||
|
)
|
||||||
|
|
||||||
|
Text(
|
||||||
|
text = "Change upstream branch",
|
||||||
|
modifier = Modifier
|
||||||
|
.padding(bottom = 8.dp),
|
||||||
|
color = MaterialTheme.colors.onBackground,
|
||||||
|
style = MaterialTheme.typography.body1,
|
||||||
|
fontWeight = FontWeight.SemiBold,
|
||||||
|
)
|
||||||
|
|
||||||
|
Text(
|
||||||
|
text = "Set the upstream remote branch",
|
||||||
|
modifier = Modifier
|
||||||
|
.padding(bottom = 16.dp),
|
||||||
|
color = MaterialTheme.colors.onBackground,
|
||||||
|
style = MaterialTheme.typography.body2,
|
||||||
|
textAlign = TextAlign.Center,
|
||||||
|
)
|
||||||
|
|
||||||
|
Column(
|
||||||
|
verticalArrangement = Arrangement.spacedBy(8.dp)
|
||||||
|
) {
|
||||||
|
|
||||||
|
if (state is SetDefaultUpstreamBranchState.Loaded) {
|
||||||
|
|
||||||
|
val remotesDropDown =
|
||||||
|
state.remotes.map { DropDownOption(it, it.remoteConfig.name) }
|
||||||
|
|
||||||
|
val selectedRemote = state.selectedRemote
|
||||||
|
val selectedRemoteOption = if (selectedRemote != null) {
|
||||||
|
DropDownOption(selectedRemote, selectedRemote.remoteConfig.name)
|
||||||
|
} else {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
|
||||||
|
val selectedBranch = state.selectedBranch
|
||||||
|
val selectedBranchOption = if (selectedBranch != null) {
|
||||||
|
DropDownOption(selectedBranch, selectedBranch.simpleName)
|
||||||
|
} else {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
|
||||||
|
val branchesDropDown = remember(selectedRemote) {
|
||||||
|
selectedRemote?.branchesList?.map { ref ->
|
||||||
|
DropDownOption(ref, ref.simpleName)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Text(
|
||||||
|
text = "Remote",
|
||||||
|
modifier = Modifier
|
||||||
|
.padding(top = 8.dp),
|
||||||
|
color = MaterialTheme.colors.onBackground,
|
||||||
|
style = MaterialTheme.typography.body1,
|
||||||
|
textAlign = TextAlign.Center,
|
||||||
|
)
|
||||||
|
|
||||||
|
FilterDropdown(
|
||||||
|
remotesDropDown,
|
||||||
|
selectedRemoteOption,
|
||||||
|
width = 400.dp,
|
||||||
|
onOptionSelected = { setSelectedRemote(it.value) }
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
Text(
|
||||||
|
text = "Branch",
|
||||||
|
modifier = Modifier
|
||||||
|
.padding(top = 8.dp),
|
||||||
|
color = MaterialTheme.colors.onBackground,
|
||||||
|
style = MaterialTheme.typography.body1,
|
||||||
|
textAlign = TextAlign.Center,
|
||||||
|
)
|
||||||
|
|
||||||
|
FilterDropdown(
|
||||||
|
branchesDropDown ?: emptyList(),
|
||||||
|
selectedBranchOption,
|
||||||
|
width = 400.dp,
|
||||||
|
onOptionSelected = { setSelectedBranch(it.value) }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Row(
|
||||||
|
modifier = Modifier
|
||||||
|
.padding(top = 16.dp)
|
||||||
|
.align(Alignment.End)
|
||||||
|
) {
|
||||||
|
PrimaryButton(
|
||||||
|
text = "Cancel",
|
||||||
|
modifier = Modifier.padding(end = 8.dp),
|
||||||
|
onClick = onClose,
|
||||||
|
backgroundColor = Color.Transparent,
|
||||||
|
textColor = MaterialTheme.colors.onBackground,
|
||||||
|
)
|
||||||
|
PrimaryButton(
|
||||||
|
onClick = {
|
||||||
|
changeDefaultUpstreamBranch()
|
||||||
|
},
|
||||||
|
text = "Change"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -24,7 +24,6 @@ import com.jetpackduba.gitnuro.ui.components.gitnuroViewModel
|
|||||||
import com.jetpackduba.gitnuro.ui.dialogs.ErrorDialog
|
import com.jetpackduba.gitnuro.ui.dialogs.ErrorDialog
|
||||||
import com.jetpackduba.gitnuro.ui.dialogs.MaterialDialog
|
import com.jetpackduba.gitnuro.ui.dialogs.MaterialDialog
|
||||||
import com.jetpackduba.gitnuro.ui.dropdowns.DropDownOption
|
import com.jetpackduba.gitnuro.ui.dropdowns.DropDownOption
|
||||||
import com.jetpackduba.gitnuro.ui.dropdowns.ScaleDropDown
|
|
||||||
import com.jetpackduba.gitnuro.viewmodels.SettingsViewModel
|
import com.jetpackduba.gitnuro.viewmodels.SettingsViewModel
|
||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
@ -168,9 +167,9 @@ fun UiSettings(settingsViewModel: SettingsViewModel) {
|
|||||||
title = "Theme",
|
title = "Theme",
|
||||||
subtitle = "Select the UI theme between light and dark mode",
|
subtitle = "Select the UI theme between light and dark mode",
|
||||||
dropDownOptions = themeLists,
|
dropDownOptions = themeLists,
|
||||||
currentOption = currentTheme,
|
currentOption = DropDownOption(currentTheme, currentTheme.displayName),
|
||||||
onOptionSelected = { theme ->
|
onOptionSelected = { themeDropDown ->
|
||||||
settingsViewModel.theme = theme
|
settingsViewModel.theme = themeDropDown.value
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -199,12 +198,12 @@ fun UiSettings(settingsViewModel: SettingsViewModel) {
|
|||||||
var options by remember {
|
var options by remember {
|
||||||
mutableStateOf(
|
mutableStateOf(
|
||||||
listOf(
|
listOf(
|
||||||
ScaleDropDown(1f, "100%"),
|
DropDownOption(1f, "100%"),
|
||||||
ScaleDropDown(1.25f, "125%"),
|
DropDownOption(1.25f, "125%"),
|
||||||
ScaleDropDown(1.5f, "150%"),
|
DropDownOption(1.5f, "150%"),
|
||||||
ScaleDropDown(2f, "200%"),
|
DropDownOption(2f, "200%"),
|
||||||
ScaleDropDown(2.5f, "250%"),
|
DropDownOption(2.5f, "250%"),
|
||||||
ScaleDropDown(3f, "300%"),
|
DropDownOption(3f, "300%"),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -221,7 +220,7 @@ fun UiSettings(settingsViewModel: SettingsViewModel) {
|
|||||||
|
|
||||||
if (matchingOption == null) { // Scale that we haven't taken in consideration
|
if (matchingOption == null) { // Scale that we haven't taken in consideration
|
||||||
// Create a new scale and add it to the options list
|
// Create a new scale and add it to the options list
|
||||||
matchingOption = ScaleDropDown(scaleUi, "${(scaleUi * 100).toInt()}%")
|
matchingOption = DropDownOption(scaleUi, "${(scaleUi * 100).toInt()}%")
|
||||||
val newOptions = options.toMutableList()
|
val newOptions = options.toMutableList()
|
||||||
newOptions.add(matchingOption)
|
newOptions.add(matchingOption)
|
||||||
newOptions.sortBy { it.value }
|
newOptions.sortBy { it.value }
|
||||||
@ -275,12 +274,12 @@ fun Category(
|
|||||||
|
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun <T : DropDownOption> SettingDropDown(
|
fun <T> SettingDropDown(
|
||||||
title: String,
|
title: String,
|
||||||
subtitle: String,
|
subtitle: String,
|
||||||
dropDownOptions: List<T>,
|
dropDownOptions: List<DropDownOption<T>>,
|
||||||
onOptionSelected: (T) -> Unit,
|
onOptionSelected: (DropDownOption<T>) -> Unit,
|
||||||
currentOption: T,
|
currentOption: DropDownOption<T>,
|
||||||
) {
|
) {
|
||||||
var showThemeDropdown by remember { mutableStateOf(false) }
|
var showThemeDropdown by remember { mutableStateOf(false) }
|
||||||
Row(
|
Row(
|
||||||
|
@ -1,5 +1,3 @@
|
|||||||
package com.jetpackduba.gitnuro.ui.dropdowns
|
package com.jetpackduba.gitnuro.ui.dropdowns
|
||||||
|
|
||||||
interface DropDownOption {
|
data class DropDownOption<T>(val value: T, val optionName: String)
|
||||||
val optionName: String
|
|
||||||
}
|
|
@ -1,3 +0,0 @@
|
|||||||
package com.jetpackduba.gitnuro.ui.dropdowns
|
|
||||||
|
|
||||||
class ScaleDropDown(val value: Float, override val optionName: String) : DropDownOption
|
|
@ -48,11 +48,13 @@ import com.jetpackduba.gitnuro.theme.*
|
|||||||
import com.jetpackduba.gitnuro.ui.SelectedItem
|
import com.jetpackduba.gitnuro.ui.SelectedItem
|
||||||
import com.jetpackduba.gitnuro.ui.components.AvatarImage
|
import com.jetpackduba.gitnuro.ui.components.AvatarImage
|
||||||
import com.jetpackduba.gitnuro.ui.components.ScrollableLazyColumn
|
import com.jetpackduba.gitnuro.ui.components.ScrollableLazyColumn
|
||||||
|
import com.jetpackduba.gitnuro.ui.components.gitnuroDynamicViewModel
|
||||||
import com.jetpackduba.gitnuro.ui.components.gitnuroViewModel
|
import com.jetpackduba.gitnuro.ui.components.gitnuroViewModel
|
||||||
import com.jetpackduba.gitnuro.ui.context_menu.*
|
import com.jetpackduba.gitnuro.ui.context_menu.*
|
||||||
import com.jetpackduba.gitnuro.ui.dialogs.NewBranchDialog
|
import com.jetpackduba.gitnuro.ui.dialogs.NewBranchDialog
|
||||||
import com.jetpackduba.gitnuro.ui.dialogs.NewTagDialog
|
import com.jetpackduba.gitnuro.ui.dialogs.NewTagDialog
|
||||||
import com.jetpackduba.gitnuro.ui.dialogs.ResetBranchDialog
|
import com.jetpackduba.gitnuro.ui.dialogs.ResetBranchDialog
|
||||||
|
import com.jetpackduba.gitnuro.ui.dialogs.SetDefaultUpstreamBranchDialog
|
||||||
import com.jetpackduba.gitnuro.viewmodels.LogSearch
|
import com.jetpackduba.gitnuro.viewmodels.LogSearch
|
||||||
import com.jetpackduba.gitnuro.viewmodels.LogStatus
|
import com.jetpackduba.gitnuro.viewmodels.LogStatus
|
||||||
import com.jetpackduba.gitnuro.viewmodels.LogViewModel
|
import com.jetpackduba.gitnuro.viewmodels.LogViewModel
|
||||||
@ -436,6 +438,7 @@ fun MessagesList(
|
|||||||
onRebaseBranch = onRebase,
|
onRebaseBranch = onRebase,
|
||||||
onRebaseInteractive = { logViewModel.rebaseInteractive(graphNode) },
|
onRebaseInteractive = { logViewModel.rebaseInteractive(graphNode) },
|
||||||
onRevCommitSelected = { logViewModel.selectLogLine(graphNode) },
|
onRevCommitSelected = { logViewModel.selectLogLine(graphNode) },
|
||||||
|
onChangeDefaultUpstreamBranch = { onShowLogDialog(LogDialog.ChangeDefaultBranch(it)) }
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -587,6 +590,14 @@ fun LogDialogs(
|
|||||||
|
|
||||||
LogDialog.None -> {
|
LogDialog.None -> {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
is LogDialog.ChangeDefaultBranch -> {
|
||||||
|
SetDefaultUpstreamBranchDialog(
|
||||||
|
viewModel = gitnuroDynamicViewModel(),
|
||||||
|
branch = showLogDialog.ref,
|
||||||
|
onClose = { onResetShowLogDialog() },
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -772,6 +783,7 @@ fun CommitLine(
|
|||||||
onRebaseBranch: (Ref) -> Unit,
|
onRebaseBranch: (Ref) -> Unit,
|
||||||
onRevCommitSelected: () -> Unit,
|
onRevCommitSelected: () -> Unit,
|
||||||
onRebaseInteractive: () -> Unit,
|
onRebaseInteractive: () -> Unit,
|
||||||
|
onChangeDefaultUpstreamBranch: (Ref) -> Unit,
|
||||||
) {
|
) {
|
||||||
val isLastCommitOfCurrentBranch = currentBranch?.objectId?.name == graphNode.id.name
|
val isLastCommitOfCurrentBranch = currentBranch?.objectId?.name == graphNode.id.name
|
||||||
|
|
||||||
@ -828,6 +840,7 @@ fun CommitLine(
|
|||||||
onRebaseBranch = { ref -> onRebaseBranch(ref) },
|
onRebaseBranch = { ref -> onRebaseBranch(ref) },
|
||||||
onPushRemoteBranch = { ref -> logViewModel.pushToRemoteBranch(ref) },
|
onPushRemoteBranch = { ref -> logViewModel.pushToRemoteBranch(ref) },
|
||||||
onPullRemoteBranch = { ref -> logViewModel.pullFromRemoteBranch(ref) },
|
onPullRemoteBranch = { ref -> logViewModel.pullFromRemoteBranch(ref) },
|
||||||
|
onChangeDefaultUpstreamBranch = { ref -> onChangeDefaultUpstreamBranch(ref) },
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -849,6 +862,7 @@ fun CommitMessage(
|
|||||||
onDeleteTag: (ref: Ref) -> Unit,
|
onDeleteTag: (ref: Ref) -> Unit,
|
||||||
onPushRemoteBranch: (ref: Ref) -> Unit,
|
onPushRemoteBranch: (ref: Ref) -> Unit,
|
||||||
onPullRemoteBranch: (ref: Ref) -> Unit,
|
onPullRemoteBranch: (ref: Ref) -> Unit,
|
||||||
|
onChangeDefaultUpstreamBranch: (ref: Ref) -> Unit,
|
||||||
) {
|
) {
|
||||||
Row(
|
Row(
|
||||||
modifier = Modifier.fillMaxSize(),
|
modifier = Modifier.fillMaxSize(),
|
||||||
@ -884,6 +898,7 @@ fun CommitMessage(
|
|||||||
onRebaseBranch = { onRebaseBranch(ref) },
|
onRebaseBranch = { onRebaseBranch(ref) },
|
||||||
onPullRemoteBranch = { onPullRemoteBranch(ref) },
|
onPullRemoteBranch = { onPullRemoteBranch(ref) },
|
||||||
onPushRemoteBranch = { onPushRemoteBranch(ref) },
|
onPushRemoteBranch = { onPushRemoteBranch(ref) },
|
||||||
|
onChangeDefaultUpstreamBranch = { onChangeDefaultUpstreamBranch(ref) },
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1092,6 +1107,7 @@ fun BranchChip(
|
|||||||
onRebaseBranch: () -> Unit,
|
onRebaseBranch: () -> Unit,
|
||||||
onPushRemoteBranch: () -> Unit,
|
onPushRemoteBranch: () -> Unit,
|
||||||
onPullRemoteBranch: () -> Unit,
|
onPullRemoteBranch: () -> Unit,
|
||||||
|
onChangeDefaultUpstreamBranch: () -> Unit,
|
||||||
color: Color,
|
color: Color,
|
||||||
) {
|
) {
|
||||||
val contextMenuItemsList = {
|
val contextMenuItemsList = {
|
||||||
@ -1107,6 +1123,7 @@ fun BranchChip(
|
|||||||
onRebaseBranch = onRebaseBranch,
|
onRebaseBranch = onRebaseBranch,
|
||||||
onPushToRemoteBranch = onPushRemoteBranch,
|
onPushToRemoteBranch = onPushRemoteBranch,
|
||||||
onPullFromRemoteBranch = onPullRemoteBranch,
|
onPullFromRemoteBranch = onPullRemoteBranch,
|
||||||
|
onChangeDefaultUpstreamBranch = onChangeDefaultUpstreamBranch,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,10 +1,12 @@
|
|||||||
package com.jetpackduba.gitnuro.ui.log
|
package com.jetpackduba.gitnuro.ui.log
|
||||||
|
|
||||||
import com.jetpackduba.gitnuro.git.graph.GraphNode
|
import com.jetpackduba.gitnuro.git.graph.GraphNode
|
||||||
|
import org.eclipse.jgit.lib.Ref
|
||||||
|
|
||||||
sealed class LogDialog {
|
sealed class LogDialog {
|
||||||
object None : LogDialog()
|
object None : LogDialog()
|
||||||
data class NewBranch(val graphNode: GraphNode) : LogDialog()
|
data class NewBranch(val graphNode: GraphNode) : LogDialog()
|
||||||
data class NewTag(val graphNode: GraphNode) : LogDialog()
|
data class NewTag(val graphNode: GraphNode) : LogDialog()
|
||||||
data class ResetBranch(val graphNode: GraphNode) : LogDialog()
|
data class ResetBranch(val graphNode: GraphNode) : LogDialog()
|
||||||
|
data class ChangeDefaultBranch(val ref: Ref) : LogDialog()
|
||||||
}
|
}
|
@ -0,0 +1,111 @@
|
|||||||
|
package com.jetpackduba.gitnuro.viewmodels
|
||||||
|
|
||||||
|
import com.jetpackduba.gitnuro.extensions.simpleName
|
||||||
|
import com.jetpackduba.gitnuro.git.RefreshType
|
||||||
|
import com.jetpackduba.gitnuro.git.TabState
|
||||||
|
import com.jetpackduba.gitnuro.git.branches.GetRemoteBranchesUseCase
|
||||||
|
import com.jetpackduba.gitnuro.git.branches.GetTrackingBranchUseCase
|
||||||
|
import com.jetpackduba.gitnuro.git.branches.SetTrackingBranchUseCase
|
||||||
|
import com.jetpackduba.gitnuro.git.branches.TrackingBranch
|
||||||
|
import com.jetpackduba.gitnuro.git.remotes.GetRemotesUseCase
|
||||||
|
import com.jetpackduba.gitnuro.git.remotes.RemoteInfo
|
||||||
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
|
import kotlinx.coroutines.flow.StateFlow
|
||||||
|
import org.eclipse.jgit.lib.Ref
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
class ChangeDefaultUpstreamBranchViewModel @Inject constructor(
|
||||||
|
private val tabState: TabState,
|
||||||
|
private val getRemoteBranchesUseCase: GetRemoteBranchesUseCase,
|
||||||
|
private val getRemotesUseCase: GetRemotesUseCase,
|
||||||
|
private val getTrackingBranchUseCase: GetTrackingBranchUseCase,
|
||||||
|
private val setTrackingBranchUseCase: SetTrackingBranchUseCase,
|
||||||
|
) {
|
||||||
|
private val _setDefaultUpstreamBranchState =
|
||||||
|
MutableStateFlow<SetDefaultUpstreamBranchState>(SetDefaultUpstreamBranchState.Loading)
|
||||||
|
val setDefaultUpstreamBranchState: StateFlow<SetDefaultUpstreamBranchState> =
|
||||||
|
_setDefaultUpstreamBranchState
|
||||||
|
|
||||||
|
fun init(branch: Ref) = tabState.runOperation(
|
||||||
|
refreshType = RefreshType.NONE
|
||||||
|
) { git ->
|
||||||
|
_setDefaultUpstreamBranchState.value = SetDefaultUpstreamBranchState.Loading
|
||||||
|
|
||||||
|
val trackingBranch = getTrackingBranchUseCase(git, branch)
|
||||||
|
val remoteBranches = getRemoteBranchesUseCase(git)
|
||||||
|
val remotes = getRemotesUseCase(git, remoteBranches)
|
||||||
|
|
||||||
|
var remote: RemoteInfo? = null
|
||||||
|
var remoteBranch: Ref? = null
|
||||||
|
|
||||||
|
if (trackingBranch != null) {
|
||||||
|
remote = remotes.firstOrNull { it.remoteConfig.name == trackingBranch.remote }
|
||||||
|
remoteBranch = remote?.branchesList?.firstOrNull { it.simpleName == trackingBranch.branch }
|
||||||
|
}
|
||||||
|
|
||||||
|
_setDefaultUpstreamBranchState.value =
|
||||||
|
SetDefaultUpstreamBranchState.Loaded(
|
||||||
|
branch = branch,
|
||||||
|
trackingBranch = trackingBranch,
|
||||||
|
remotes = remotes,
|
||||||
|
selectedRemote = remote,
|
||||||
|
selectedBranch = remoteBranch
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun changeDefaultUpstreamBranch() = tabState.runOperation(
|
||||||
|
refreshType = RefreshType.NONE,
|
||||||
|
) { git ->
|
||||||
|
val state = _setDefaultUpstreamBranchState.value
|
||||||
|
|
||||||
|
if (state is SetDefaultUpstreamBranchState.Loaded) {
|
||||||
|
setTrackingBranchUseCase(
|
||||||
|
git = git,
|
||||||
|
ref = state.branch,
|
||||||
|
remoteName = state.selectedRemote?.remoteConfig?.name,
|
||||||
|
remoteBranch = state.selectedBranch
|
||||||
|
)
|
||||||
|
|
||||||
|
_setDefaultUpstreamBranchState.value = SetDefaultUpstreamBranchState.UpstreamChanged
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun setSelectedBranch(branchOption: Ref) {
|
||||||
|
val state = _setDefaultUpstreamBranchState.value
|
||||||
|
|
||||||
|
if (state is SetDefaultUpstreamBranchState.Loaded) {
|
||||||
|
_setDefaultUpstreamBranchState.value = state.copy(selectedBranch = branchOption)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun setSelectedRemote(remote: RemoteInfo) {
|
||||||
|
val state = setDefaultUpstreamBranchState.value
|
||||||
|
val remoteConfig = remote.remoteConfig
|
||||||
|
|
||||||
|
if (state is SetDefaultUpstreamBranchState.Loaded) {
|
||||||
|
val branch = if (remoteConfig.name == state.trackingBranch?.remote) {
|
||||||
|
remote.branchesList.firstOrNull { it.simpleName == state.trackingBranch?.branch }
|
||||||
|
} else {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
|
||||||
|
_setDefaultUpstreamBranchState.value = state.copy(
|
||||||
|
selectedRemote = remote,
|
||||||
|
selectedBranch = branch,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sealed interface SetDefaultUpstreamBranchState {
|
||||||
|
object Loading : SetDefaultUpstreamBranchState
|
||||||
|
data class Loaded(
|
||||||
|
val branch: Ref,
|
||||||
|
val trackingBranch: TrackingBranch?,
|
||||||
|
val remotes: List<RemoteInfo>,
|
||||||
|
val selectedRemote: RemoteInfo?,
|
||||||
|
val selectedBranch: Ref?,
|
||||||
|
) : SetDefaultUpstreamBranchState
|
||||||
|
|
||||||
|
object UpstreamChanged : SetDefaultUpstreamBranchState
|
||||||
|
}
|
@ -4,6 +4,7 @@ import com.jetpackduba.gitnuro.di.TabScope
|
|||||||
import com.jetpackduba.gitnuro.viewmodels.sidepanel.SidePanelViewModel
|
import com.jetpackduba.gitnuro.viewmodels.sidepanel.SidePanelViewModel
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import javax.inject.Provider
|
import javax.inject.Provider
|
||||||
|
import kotlin.reflect.KClass
|
||||||
|
|
||||||
@TabScope
|
@TabScope
|
||||||
class TabViewModelsHolder @Inject constructor(
|
class TabViewModelsHolder @Inject constructor(
|
||||||
@ -19,7 +20,8 @@ class TabViewModelsHolder @Inject constructor(
|
|||||||
private val rebaseInteractiveViewModelProvider: Provider<RebaseInteractiveViewModel>,
|
private val rebaseInteractiveViewModelProvider: Provider<RebaseInteractiveViewModel>,
|
||||||
private val historyViewModelProvider: Provider<HistoryViewModel>,
|
private val historyViewModelProvider: Provider<HistoryViewModel>,
|
||||||
private val authorViewModelProvider: Provider<AuthorViewModel>,
|
private val authorViewModelProvider: Provider<AuthorViewModel>,
|
||||||
) {
|
private val changeDefaultUpstreamBranchViewModelProvider: Provider<ChangeDefaultUpstreamBranchViewModel>,
|
||||||
|
) {
|
||||||
val viewModels = mapOf(
|
val viewModels = mapOf(
|
||||||
logViewModel::class to logViewModel,
|
logViewModel::class to logViewModel,
|
||||||
sidePanelViewModel::class to sidePanelViewModel,
|
sidePanelViewModel::class to sidePanelViewModel,
|
||||||
@ -29,4 +31,16 @@ class TabViewModelsHolder @Inject constructor(
|
|||||||
cloneViewModel::class to cloneViewModel,
|
cloneViewModel::class to cloneViewModel,
|
||||||
settingsViewModel::class to settingsViewModel,
|
settingsViewModel::class to settingsViewModel,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// TODO Call this when required
|
||||||
|
fun dynamicViewModel(type: KClass<*>): Any {
|
||||||
|
return when(type) {
|
||||||
|
DiffViewModel::class -> diffViewModelProvider.get()
|
||||||
|
RebaseInteractiveViewModel::class -> rebaseInteractiveViewModelProvider.get()
|
||||||
|
HistoryViewModel::class -> historyViewModelProvider.get()
|
||||||
|
AuthorViewModel::class -> authorViewModelProvider.get()
|
||||||
|
ChangeDefaultUpstreamBranchViewModel::class -> changeDefaultUpstreamBranchViewModelProvider.get()
|
||||||
|
else -> throw NotImplementedError("View model provider not implemented")
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
@ -52,7 +52,6 @@ class BranchesViewModel @AssistedInject constructor(
|
|||||||
)
|
)
|
||||||
|
|
||||||
init {
|
init {
|
||||||
|
|
||||||
tabScope.launch {
|
tabScope.launch {
|
||||||
tabState.refreshFlowFiltered(RefreshType.ALL_DATA)
|
tabState.refreshFlowFiltered(RefreshType.ALL_DATA)
|
||||||
{
|
{
|
||||||
|
@ -0,0 +1,54 @@
|
|||||||
|
package com.jetpackduba.gitnuro.git.branches
|
||||||
|
|
||||||
|
import io.mockk.every
|
||||||
|
import io.mockk.mockk
|
||||||
|
import org.eclipse.jgit.api.Git
|
||||||
|
import org.eclipse.jgit.lib.ObjectId
|
||||||
|
import org.eclipse.jgit.lib.Ref
|
||||||
|
import org.eclipse.jgit.lib.Repository
|
||||||
|
import org.eclipse.jgit.lib.StoredConfig
|
||||||
|
import org.junit.jupiter.api.Assertions.assertEquals
|
||||||
|
import org.junit.jupiter.api.Assertions.assertNull
|
||||||
|
import org.junit.jupiter.api.BeforeEach
|
||||||
|
import org.junit.jupiter.api.Test
|
||||||
|
|
||||||
|
class GetTrackingBranchUseCaseTest {
|
||||||
|
private val gitMock: Git = mockk(relaxed = true)
|
||||||
|
private val repositoryMock: Repository = mockk(relaxed = true)
|
||||||
|
private val configMock: StoredConfig = mockk(relaxed = true)
|
||||||
|
private val refMock: Ref = mockk(relaxed = true)
|
||||||
|
|
||||||
|
private val localBranchName = "feature-branch"
|
||||||
|
private val remoteName = "origin"
|
||||||
|
private val remoteBranchFullName = "refs/heads/main"
|
||||||
|
private val remoteBranchShortName = "main"
|
||||||
|
private val objectId = ObjectId.zeroId()
|
||||||
|
|
||||||
|
@BeforeEach
|
||||||
|
fun setUp() {
|
||||||
|
every { gitMock.repository } returns repositoryMock
|
||||||
|
every { refMock.name } returns "refs/heads/$localBranchName"
|
||||||
|
every { refMock.objectId } returns objectId
|
||||||
|
every { repositoryMock.config } returns configMock
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `invoke returns null when remote not found`() {
|
||||||
|
every { configMock.getString("branch", localBranchName, "remote") } returns null
|
||||||
|
every { configMock.getString("branch", localBranchName, "merge") } returns null
|
||||||
|
|
||||||
|
val result = GetTrackingBranchUseCase()(gitMock, refMock)
|
||||||
|
|
||||||
|
assertNull(result)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `invoke returns tracking branch when local and remote branches exist`() {
|
||||||
|
every { configMock.getString("branch", localBranchName, "remote") } returns remoteName
|
||||||
|
every { configMock.getString("branch", localBranchName, "merge") } returns remoteBranchFullName
|
||||||
|
|
||||||
|
val result = GetTrackingBranchUseCase()(gitMock, refMock)
|
||||||
|
|
||||||
|
assertEquals(TrackingBranch(remoteName, remoteBranchShortName), result)
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user