Refactored remotes in side panel

This commit is contained in:
Abdelilah El Aissaoui 2024-07-19 21:32:30 +02:00
parent 22088a3fbd
commit 81836f44a5
No known key found for this signature in database
GPG Key ID: 7587FC860F594869
10 changed files with 258 additions and 402 deletions

View File

@ -22,6 +22,7 @@ object AppIcons {
const val DOWNLOAD = "download.svg"
const val DRAG = "drag.svg"
const val DROPDOWN = "dropdown.svg"
const val EDIT = "edit.svg"
const val ERROR = "error.svg"
const val EXPAND_MORE = "expand_more.svg"
const val FETCH = "fetch.svg"

View File

@ -14,7 +14,7 @@ import javax.inject.Inject
private const val TAG = "FetchAllBranchesUseCase"
class FetchAllBranchesUseCase @Inject constructor(
class FetchAllRemotesUseCase @Inject constructor(
private val handleTransportUseCase: HandleTransportUseCase,
) {
suspend operator fun invoke(git: Git) = withContext(Dispatchers.IO) {

View File

@ -0,0 +1,32 @@
package com.jetpackduba.gitnuro.models
import org.eclipse.jgit.transport.RemoteConfig
data class RemoteWrapper constructor(
val remoteName: String,
val fetchUri: String,
val pushUri: String,
val isNew: Boolean,
)
fun RemoteConfig.toRemoteWrapper(): RemoteWrapper {
val fetchUri = this.urIs.firstOrNull()
val pushUri = this.pushURIs.firstOrNull()
?: this.urIs.firstOrNull() // If push URI == null, take fetch URI
return RemoteWrapper(
remoteName = this.name,
fetchUri = fetchUri?.toString().orEmpty(),
pushUri = pushUri?.toString().orEmpty(),
isNew = false,
)
}
fun newRemoteWrapper(): RemoteWrapper {
return RemoteWrapper(
remoteName = "",
fetchUri = "",
pushUri = "",
isNew = true,
)
}

View File

@ -17,12 +17,18 @@ import com.jetpackduba.gitnuro.extensions.handOnHover
import com.jetpackduba.gitnuro.extensions.isLocal
import com.jetpackduba.gitnuro.extensions.isValid
import com.jetpackduba.gitnuro.extensions.simpleName
import com.jetpackduba.gitnuro.models.RemoteWrapper
import com.jetpackduba.gitnuro.models.newRemoteWrapper
import com.jetpackduba.gitnuro.models.toRemoteWrapper
import com.jetpackduba.gitnuro.theme.onBackgroundSecondary
import com.jetpackduba.gitnuro.ui.components.*
import com.jetpackduba.gitnuro.ui.components.AdjustableOutlinedTextField
import com.jetpackduba.gitnuro.ui.components.ScrollableLazyColumn
import com.jetpackduba.gitnuro.ui.components.SideMenuHeader
import com.jetpackduba.gitnuro.ui.components.SideMenuSubentry
import com.jetpackduba.gitnuro.ui.components.tooltip.DelayedTooltip
import com.jetpackduba.gitnuro.ui.context_menu.*
import com.jetpackduba.gitnuro.ui.dialogs.AddEditRemoteDialog
import com.jetpackduba.gitnuro.ui.dialogs.AddSubmodulesDialog
import com.jetpackduba.gitnuro.ui.dialogs.EditRemotesDialog
import com.jetpackduba.gitnuro.ui.dialogs.SetDefaultUpstreamBranchDialog
import com.jetpackduba.gitnuro.viewmodels.ChangeDefaultUpstreamBranchViewModel
import com.jetpackduba.gitnuro.viewmodels.sidepanel.*
@ -50,7 +56,7 @@ fun SidePanel(
val stashesState by stashesViewModel.stashesState.collectAsState()
val submodulesState by submodulesViewModel.submodules.collectAsState()
var showEditRemotesDialog by remember { mutableStateOf(false) }
val (showAddEditRemote, setShowAddEditRemote) = remember { mutableStateOf<RemoteWrapper?>(null) }
val (branchToChangeUpstream, setBranchToChangeUpstream) = remember { mutableStateOf<Ref?>(null) }
var showEditSubmodulesDialog by remember { mutableStateOf(false) }
@ -80,7 +86,7 @@ fun SidePanel(
remotes(
remotesState = remotesState,
remotesViewModel = remotesViewModel,
onShowEditRemotesDialog = { showEditRemotesDialog = true },
onShowAddEditRemoteDialog = { setShowAddEditRemote(it) },
)
tags(
@ -103,11 +109,12 @@ fun SidePanel(
}
}
if (showEditRemotesDialog) {
EditRemotesDialog(
if (showAddEditRemote != null) {
AddEditRemoteDialog(
remotesViewModel = remotesViewModel,
remoteWrapper = showAddEditRemote,
onDismiss = {
showEditRemotesDialog = false
setShowAddEditRemote(null)
},
)
}
@ -218,7 +225,7 @@ fun LazyListScope.localBranches(
fun LazyListScope.remotes(
remotesState: RemotesState,
remotesViewModel: RemotesViewModel,
onShowEditRemotesDialog: () -> Unit,
onShowAddEditRemoteDialog: (RemoteWrapper) -> Unit,
) {
val isExpanded = remotesState.isExpanded
val remotes = remotesState.remotes
@ -230,14 +237,14 @@ fun LazyListScope.remotes(
itemsCount = remotes.count(),
hoverIcon = {
IconButton(
onClick = onShowEditRemotesDialog,
onClick = { onShowAddEditRemoteDialog(newRemoteWrapper()) },
modifier = Modifier
.padding(end = 16.dp)
.size(16.dp)
.handOnHover(),
) {
Icon(
painter = painterResource(AppIcons.SETTINGS),
painter = painterResource(AppIcons.ADD),
contentDescription = null,
modifier = Modifier
.fillMaxSize(),
@ -255,7 +262,12 @@ fun LazyListScope.remotes(
item {
Remote(
remote = remote,
onRemoteClicked = { remotesViewModel.onRemoteClicked(remote) }
onEditRemote = {
val wrapper = remote.remoteInfo.remoteConfig.toRemoteWrapper()
onShowAddEditRemoteDialog(wrapper)
},
onDeleteRemote = { remotesViewModel.deleteRemote(remote.remoteInfo.remoteConfig.name) },
onRemoteClicked = { remotesViewModel.onRemoteClicked(remote) },
)
}
@ -461,14 +473,25 @@ private fun Branch(
@Composable
private fun Remote(
remote: RemoteView,
onEditRemote: () -> Unit,
onDeleteRemote: () -> Unit,
onRemoteClicked: () -> Unit,
) {
SideMenuSubentry(
text = remote.remoteInfo.remoteConfig.name,
iconResourcePath = AppIcons.CLOUD,
onClick = onRemoteClicked,
isSelected = false,
)
ContextMenu(
items = {
remoteContextMenu(
onEdit = onEditRemote,
onDelete = onDeleteRemote,
)
}
) {
SideMenuSubentry(
text = remote.remoteInfo.remoteConfig.name,
iconResourcePath = AppIcons.CLOUD,
onClick = onRemoteClicked,
isSelected = false,
)
}
}

View File

@ -1,10 +1,20 @@
package com.jetpackduba.gitnuro.ui.context_menu
import androidx.compose.ui.res.painterResource
import com.jetpackduba.gitnuro.AppIcons
fun remoteContextMenu(
onEditRemotes: () -> Unit,
onEdit: () -> Unit,
onDelete: () -> Unit,
): List<ContextMenuElement> = listOf(
ContextMenuElement.ContextTextEntry(
label = "Edit remotes",
onClick = onEditRemotes
label = "Edit",
icon = { painterResource(AppIcons.EDIT) },
onClick = onEdit
),
ContextMenuElement.ContextTextEntry(
label = "Delete",
icon = { painterResource(AppIcons.DELETE) },
onClick = onDelete
),
)

View File

@ -0,0 +1,159 @@
package com.jetpackduba.gitnuro.ui.dialogs
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.material.icons.Icons
import androidx.compose.material.icons.filled.Clear
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp
import com.jetpackduba.gitnuro.extensions.handOnHover
import com.jetpackduba.gitnuro.models.RemoteWrapper
import com.jetpackduba.gitnuro.theme.outlinedTextFieldColors
import com.jetpackduba.gitnuro.ui.components.AdjustableOutlinedTextField
import com.jetpackduba.gitnuro.ui.components.PrimaryButton
import com.jetpackduba.gitnuro.viewmodels.sidepanel.RemotesViewModel
import kotlinx.coroutines.flow.collectLatest
@Composable
fun AddEditRemoteDialog(
remotesViewModel: RemotesViewModel,
remoteWrapper: RemoteWrapper,
onDismiss: () -> Unit,
) {
var remote: RemoteWrapper by remember(remoteWrapper) { mutableStateOf(remoteWrapper) }
LaunchedEffect(Unit) {
remotesViewModel.remoteUpdated.collectLatest { onDismiss() }
}
MaterialDialog(
paddingVertical = 8.dp,
paddingHorizontal = 16.dp,
background = MaterialTheme.colors.surface,
onCloseRequested = onDismiss
) {
Column(
modifier = Modifier
.width(600.dp),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center,
) {
Row(
modifier = Modifier,
verticalAlignment = Alignment.CenterVertically,
) {
Text(
text = if (remote.isNew) "New remote" else "Edit remote \"${remote.remoteName}\"",
color = MaterialTheme.colors.onBackground,
style = MaterialTheme.typography.h3,
modifier = Modifier
.padding(start = 8.dp, top = 8.dp, bottom = 8.dp)
.fillMaxWidth(),
)
}
Row(
modifier = Modifier
.padding(bottom = 8.dp)
) {
Column(
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 8.dp)
) {
Column {
if (remote.isNew) {
Text(
text = "Remote name",
color = MaterialTheme.colors.onBackground,
modifier = Modifier.padding(top = 8.dp),
)
AdjustableOutlinedTextField(
value = remote.remoteName,
onValueChange = { newValue ->
remote = remote.copy(remoteName = newValue)
},
singleLine = true,
modifier = Modifier
.fillMaxWidth()
.padding(vertical = 8.dp)
)
}
Text(
text = "Fetch URL",
color = MaterialTheme.colors.onBackground,
modifier = Modifier.padding(top = 8.dp),
)
AdjustableOutlinedTextField(
value = remote.fetchUri,
onValueChange = { newValue ->
remote = remote.copy(fetchUri = newValue)
},
singleLine = true,
colors = outlinedTextFieldColors(),
modifier = Modifier
.fillMaxWidth()
.padding(vertical = 8.dp)
)
Text(
text = "Push URL",
color = MaterialTheme.colors.onBackground,
modifier = Modifier.padding(top = 8.dp),
)
AdjustableOutlinedTextField(
value = remote.pushUri,
onValueChange = { newValue ->
remote = remote.copy(pushUri = newValue)
},
singleLine = true,
modifier = Modifier
.fillMaxWidth()
.padding(vertical = 8.dp)
)
Row(
modifier = Modifier
.padding(top = 32.dp)
.align(Alignment.End),
verticalAlignment = Alignment.CenterVertically,
) {
Spacer(modifier = Modifier.weight(1f))
PrimaryButton(
text = "Cancel",
modifier = Modifier.padding(end = 8.dp),
onClick = onDismiss,
backgroundColor = Color.Transparent,
backgroundDisabled = Color.Transparent,
textColor = MaterialTheme.colors.onBackground,
disabledTextColor = MaterialTheme.colors.onBackground.copy(alpha = 0.5f),
)
PrimaryButton(
modifier = Modifier,
onClick = {
if (remote.isNew)
remotesViewModel.addRemote(remote)
else
remotesViewModel.updateRemote(remote)
},
text = "Save changes",
)
}
}
}
}
}
}
}

View File

@ -1,371 +0,0 @@
package com.jetpackduba.gitnuro.ui.dialogs
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.material.Icon
import androidx.compose.material.IconButton
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Text
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Clear
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.unit.dp
import com.jetpackduba.gitnuro.AppIcons
import com.jetpackduba.gitnuro.extensions.handMouseClickable
import com.jetpackduba.gitnuro.extensions.handOnHover
import com.jetpackduba.gitnuro.theme.backgroundSelected
import com.jetpackduba.gitnuro.theme.onBackgroundSecondary
import com.jetpackduba.gitnuro.theme.outlinedTextFieldColors
import com.jetpackduba.gitnuro.ui.components.AdjustableOutlinedTextField
import com.jetpackduba.gitnuro.ui.components.PrimaryButton
import com.jetpackduba.gitnuro.viewmodels.sidepanel.RemotesViewModel
import org.eclipse.jgit.transport.RemoteConfig
@Composable
fun EditRemotesDialog(
remotesViewModel: RemotesViewModel,
onDismiss: () -> Unit,
) {
var remotesEditorData by remember {
mutableStateOf(
RemotesEditorData(
emptyList(),
null,
)
)
}
val remotesState by remotesViewModel.remoteState.collectAsState()
val remotes = remotesState.remotes
var remoteChanged by remember { mutableStateOf(false) }
val selectedRemote = remotesEditorData.selectedRemote
LaunchedEffect(remotes) {
val newRemotesWrappers = remotes.map {
val remoteConfig = it.remoteInfo.remoteConfig
remoteConfig.toRemoteWrapper()
}
val safeSelectedRemote = remotesEditorData.selectedRemote
var newSelectedRemote: RemoteWrapper? = null
if (safeSelectedRemote != null) {
newSelectedRemote = newRemotesWrappers.firstOrNull { it.remoteName == safeSelectedRemote.remoteName }
}
remoteChanged = newSelectedRemote?.haveUrisChanged ?: false
remotesEditorData = remotesEditorData.copy(
listRemotes = newRemotesWrappers,
selectedRemote = newSelectedRemote,
)
}
MaterialDialog(
paddingVertical = 8.dp,
paddingHorizontal = 16.dp,
background = MaterialTheme.colors.surface,
onCloseRequested = onDismiss
) {
Column(
modifier = Modifier
.size(width = 900.dp, height = 600.dp),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center,
) {
Row(
modifier = Modifier,
verticalAlignment = Alignment.CenterVertically,
) {
Text(
text = "Remotes",
color = MaterialTheme.colors.onBackground,
style = MaterialTheme.typography.h3,
modifier = Modifier.padding(vertical = 8.dp),
)
Spacer(modifier = Modifier.weight(1f))
IconButton(
onClick = onDismiss,
modifier = Modifier
.handOnHover()
) {
Icon(
imageVector = Icons.Default.Clear,
contentDescription = null,
tint = MaterialTheme.colors.onBackground,
)
}
}
Row(
modifier = Modifier
.padding(bottom = 8.dp)
) {
Column(
modifier = Modifier
.width(200.dp)
.fillMaxHeight()
.background(MaterialTheme.colors.background),
) {
if (remotesEditorData.listRemotes.isNotEmpty()) {
LazyColumn(
modifier = Modifier.weight(1f)
) {
items(remotesEditorData.listRemotes) { remote ->
val background = if (remote == selectedRemote) {
MaterialTheme.colors.backgroundSelected
} else
MaterialTheme.colors.background
Text(
text = remote.remoteName,
color = MaterialTheme.colors.onBackground,
modifier = Modifier
.fillMaxWidth()
.handMouseClickable {
remotesEditorData = remotesEditorData.copy(selectedRemote = remote)
}
.background(background)
.padding(horizontal = 16.dp, vertical = 8.dp)
)
}
}
} else {
Box(
modifier = Modifier
.weight(1f)
.fillMaxWidth(),
contentAlignment = Alignment.Center,
) {
Text(
text = "No available remotes",
style = MaterialTheme.typography.body2.copy(color = MaterialTheme.colors.onBackgroundSecondary)
)
}
}
Row(
modifier = Modifier
.fillMaxWidth()
) {
IconButton(
modifier = Modifier
.size(36.dp)
.handOnHover(),
onClick = {
val remotesWithNew = remotesEditorData.listRemotes.toMutableList()
val newRemote = RemoteWrapper(
remoteName = "new_remote",
fetchUri = "",
originalFetchUri = "",
pushUri = "",
originalPushUri = "",
isNew = true
)
remotesWithNew.add(newRemote)
remotesEditorData = remotesEditorData.copy(
listRemotes = remotesWithNew,
selectedRemote = newRemote
)
}
) {
Icon(
painter = painterResource(AppIcons.ADD),
contentDescription = null,
tint = MaterialTheme.colors.onBackground,
)
}
IconButton(
modifier = Modifier
.size(36.dp)
.handOnHover(),
enabled = selectedRemote != null,
onClick = {
if (selectedRemote != null)
remotesViewModel.deleteRemote(selectedRemote.remoteName, selectedRemote.isNew)
}
) {
Icon(
painter = painterResource(AppIcons.REMOVE),
contentDescription = null,
tint = if (selectedRemote != null)
MaterialTheme.colors.onBackground
else
MaterialTheme.colors.onBackgroundSecondary,
)
}
}
}
Column(
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 16.dp)
) {
if (selectedRemote != null) {
Column {
if (selectedRemote.isNew) {
Text(
text = "New remote name",
color = MaterialTheme.colors.onBackground,
modifier = Modifier.padding(top = 8.dp),
)
AdjustableOutlinedTextField(
value = selectedRemote.remoteName,
onValueChange = { newValue ->
val newSelectedRemoteConfig = selectedRemote.copy(remoteName = newValue)
val listRemotes = remotesEditorData.listRemotes.toMutableList()
val newRemoteToBeReplacedIndex = listRemotes.indexOfFirst { it.isNew }
listRemotes[newRemoteToBeReplacedIndex] = newSelectedRemoteConfig
remotesEditorData = remotesEditorData.copy(
listRemotes = listRemotes,
selectedRemote = newSelectedRemoteConfig
)
},
singleLine = true,
modifier = Modifier
.fillMaxWidth()
.padding(vertical = 8.dp)
)
}
Text(
text = "Fetch URL",
color = MaterialTheme.colors.onBackground,
modifier = Modifier.padding(top = 8.dp),
)
AdjustableOutlinedTextField(
value = selectedRemote.fetchUri,
onValueChange = { newValue ->
val newSelectedRemoteConfig = selectedRemote.copy(fetchUri = newValue)
remotesEditorData = remotesEditorData.copy(selectedRemote = newSelectedRemoteConfig)
remoteChanged = newSelectedRemoteConfig.haveUrisChanged
},
singleLine = true,
colors = outlinedTextFieldColors(),
modifier = Modifier
.fillMaxWidth()
.padding(vertical = 8.dp)
)
Text(
text = "Push URL",
color = MaterialTheme.colors.onBackground,
modifier = Modifier.padding(top = 8.dp),
)
AdjustableOutlinedTextField(
value = selectedRemote.pushUri,
onValueChange = { newValue ->
val newSelectedRemoteConfig = selectedRemote.copy(pushUri = newValue)
remotesEditorData = remotesEditorData.copy(selectedRemote = newSelectedRemoteConfig)
remoteChanged = newSelectedRemoteConfig.haveUrisChanged
},
singleLine = true,
modifier = Modifier
.fillMaxWidth()
.padding(vertical = 8.dp)
)
Spacer(modifier = Modifier.weight(1f))
Row(
modifier = Modifier
.padding(top = 16.dp)
.align(Alignment.End),
verticalAlignment = Alignment.CenterVertically,
) {
Spacer(modifier = Modifier.weight(1f))
if (!selectedRemote.isNew) {
PrimaryButton(
text = "Discard changes",
modifier = Modifier.padding(end = 8.dp),
onClick = {
remotesEditorData = remotesEditorData.copy(
selectedRemote = selectedRemote.copy(
fetchUri = selectedRemote.originalFetchUri,
pushUri = selectedRemote.originalPushUri,
)
)
remoteChanged = false
},
backgroundColor = Color.Transparent,
backgroundDisabled = Color.Transparent,
enabled = remoteChanged,
textColor = MaterialTheme.colors.onBackground,
disabledTextColor = MaterialTheme.colors.onBackground.copy(alpha = 0.5f),
)
}
val text = if (selectedRemote.isNew)
"Add new remote"
else
"Save ${selectedRemote.remoteName} changes"
PrimaryButton(
modifier = Modifier,
enabled = remoteChanged,
onClick = {
if (selectedRemote.isNew)
remotesViewModel.addRemote(selectedRemote)
else
remotesViewModel.updateRemote(selectedRemote)
},
text = text,
)
}
}
}
}
}
}
}
}
data class RemoteWrapper(
val remoteName: String,
val fetchUri: String,
val originalFetchUri: String,
val pushUri: String,
val originalPushUri: String,
val isNew: Boolean = false,
) {
val haveUrisChanged: Boolean = isNew ||
fetchUri != originalFetchUri ||
pushUri != originalPushUri
}
data class RemotesEditorData(
val listRemotes: List<RemoteWrapper>,
val selectedRemote: RemoteWrapper?,
)
fun RemoteConfig.toRemoteWrapper(): RemoteWrapper {
val fetchUri = this.urIs.firstOrNull()
val pushUri = this.pushURIs.firstOrNull()
?: this.urIs.firstOrNull() // If push URI == null, take fetch URI
return RemoteWrapper(
remoteName = this.name,
fetchUri = fetchUri?.toString().orEmpty(),
originalFetchUri = fetchUri?.toString().orEmpty(),
pushUri = pushUri?.toString().orEmpty(),
originalPushUri = pushUri?.toString().orEmpty(),
)
}

View File

@ -3,7 +3,7 @@ package com.jetpackduba.gitnuro.viewmodels
import com.jetpackduba.gitnuro.TaskType
import com.jetpackduba.gitnuro.git.RefreshType
import com.jetpackduba.gitnuro.git.TabState
import com.jetpackduba.gitnuro.git.remote_operations.FetchAllBranchesUseCase
import com.jetpackduba.gitnuro.git.remote_operations.FetchAllRemotesUseCase
import com.jetpackduba.gitnuro.git.remote_operations.PullBranchUseCase
import com.jetpackduba.gitnuro.git.remote_operations.PullType
import com.jetpackduba.gitnuro.git.remote_operations.PushBranchUseCase
@ -19,7 +19,7 @@ class MenuViewModel @Inject constructor(
private val tabState: TabState,
private val pullBranchUseCase: PullBranchUseCase,
private val pushBranchUseCase: PushBranchUseCase,
private val fetchAllBranchesUseCase: FetchAllBranchesUseCase,
private val fetchAllRemotesUseCase: FetchAllRemotesUseCase,
private val popLastStashUseCase: PopLastStashUseCase,
private val stashChangesUseCase: StashChangesUseCase,
private val stageUntrackedFileUseCase: StageUntrackedFileUseCase,
@ -50,7 +50,7 @@ class MenuViewModel @Inject constructor(
taskType = TaskType.FETCH,
positiveFeedbackText = "Fetch all completed",
) { git ->
fetchAllBranchesUseCase(git)
fetchAllRemotesUseCase(git)
}
fun push(force: Boolean = false, pushTags: Boolean = false) = tabState.safeProcessing(

View File

@ -6,15 +6,11 @@ import com.jetpackduba.gitnuro.extensions.lowercaseContains
import com.jetpackduba.gitnuro.extensions.simpleName
import com.jetpackduba.gitnuro.git.RefreshType
import com.jetpackduba.gitnuro.git.TabState
import com.jetpackduba.gitnuro.git.branches.CheckoutRefUseCase
import com.jetpackduba.gitnuro.git.branches.DeleteLocallyRemoteBranchesUseCase
import com.jetpackduba.gitnuro.git.branches.GetCurrentBranchUseCase
import com.jetpackduba.gitnuro.git.branches.GetRemoteBranchesUseCase
import com.jetpackduba.gitnuro.git.remote_operations.DeleteRemoteBranchUseCase
import com.jetpackduba.gitnuro.git.remote_operations.PullFromSpecificBranchUseCase
import com.jetpackduba.gitnuro.git.remote_operations.PushToSpecificBranchUseCase
import com.jetpackduba.gitnuro.git.remotes.*
import com.jetpackduba.gitnuro.ui.dialogs.RemoteWrapper
import com.jetpackduba.gitnuro.models.RemoteWrapper
import com.jetpackduba.gitnuro.viewmodels.ISharedRemotesViewModel
import com.jetpackduba.gitnuro.viewmodels.SharedRemotesViewModel
import dagger.assisted.Assisted
@ -45,6 +41,9 @@ class RemotesViewModel @AssistedInject constructor(
private val remotes = MutableStateFlow<List<RemoteView>>(listOf())
private val currentBranch = MutableStateFlow<Ref?>(null)
private val _remoteUpdated = MutableSharedFlow<Unit>()
val remoteUpdated = _remoteUpdated.asSharedFlow()
val remoteState: StateFlow<RemotesState> =
combine(remotes, isExpanded, filter, currentBranch) { remotes, isExpanded, filter, currentBranch ->
val remotesFiltered = remotes.map { remote ->
@ -115,8 +114,8 @@ class RemotesViewModel @AssistedInject constructor(
tabState.newSelectedRef(ref, ref.objectId)
}
fun deleteRemote(remoteName: String, isNew: Boolean) = tabState.safeProcessing(
refreshType = if (isNew) RefreshType.REMOTES else RefreshType.ALL_DATA,
fun deleteRemote(remoteName: String) = tabState.safeProcessing(
refreshType = RefreshType.ALL_DATA,
taskType = TaskType.DELETE_REMOTE,
positiveFeedbackText = "Remote $remoteName deleted",
) { git ->
@ -176,6 +175,8 @@ class RemotesViewModel @AssistedInject constructor(
uri = selectedRemoteConfig.pushUri,
uriType = RemoteSetUrlCommand.UriType.PUSH
)
_remoteUpdated.emit(Unit)
}
}

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#e8eaed"><path d="M200-200h57l391-391-57-57-391 391v57Zm-80 80v-170l528-527q12-11 26.5-17t30.5-6q16 0 31 6t26 18l55 56q12 11 17.5 26t5.5 30q0 16-5.5 30.5T817-647L290-120H120Zm640-584-56-56 56 56Zm-141 85-28-29 57 57-29-28Z"/></svg>

After

Width:  |  Height:  |  Size: 329 B