Skip to content

Commit

Permalink
Merge pull request #267 from spipau/#264-copy-branch-name
Browse files Browse the repository at this point in the history
#264  Copy Branch Name
  • Loading branch information
JetpackDuba authored Feb 15, 2025
2 parents 4132a4a + cccbae2 commit 169863b
Show file tree
Hide file tree
Showing 9 changed files with 108 additions and 8 deletions.
3 changes: 3 additions & 0 deletions src/main/kotlin/com/jetpackduba/gitnuro/di/AppComponent.kt
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import com.jetpackduba.gitnuro.ui.VerticalSplitPaneConfig
import com.jetpackduba.gitnuro.updates.UpdatesRepository
import com.jetpackduba.gitnuro.viewmodels.SettingsViewModel
import dagger.Component
import org.jetbrains.skiko.ClipboardManager
import javax.inject.Singleton

@Singleton
Expand Down Expand Up @@ -50,4 +51,6 @@ interface AppComponent {
fun updatesRepository(): UpdatesRepository

fun credentialsCacheRepository(): CredentialsCacheRepository

fun clipboardManager(): ClipboardManager
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,14 @@ import dagger.Provides
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.SupervisorJob
import org.jetbrains.skiko.ClipboardManager

@Module
class AppModule {
@Provides
@AppCoroutineScope
fun provideAppScope(): CoroutineScope = CoroutineScope(SupervisorJob() + Dispatchers.IO)

@Provides
fun provideClipboardManager(): ClipboardManager = ClipboardManager()
}
13 changes: 10 additions & 3 deletions src/main/kotlin/com/jetpackduba/gitnuro/ui/SidePanel.kt
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,9 @@ fun LazyListScope.localBranches(
onMergeBranch = { branchesViewModel.mergeBranch(branch) },
onRebaseBranch = { branchesViewModel.rebaseBranch(branch) },
onDeleteBranch = { branchesViewModel.deleteBranch(branch) },
) { onChangeDefaultUpstreamBranch(branch) }
onChangeDefaultUpstreamBranch = { onChangeDefaultUpstreamBranch(branch) },
onCopyBranchNameToClipboard = { branchesViewModel.copyBranchNameToClipboard(branch) },
)
}
}
}
Expand Down Expand Up @@ -288,7 +290,7 @@ fun LazyListScope.remotes(
onEditRemote = {
val wrapper = remote.remoteInfo.remoteConfig.toRemoteWrapper()
onShowAddEditRemoteDialog(wrapper)
},
},
onDeleteRemote = { remotesViewModel.deleteRemote(remote.remoteInfo.remoteConfig.name) },
onRemoteClicked = { remotesViewModel.onRemoteClicked(remote) },
)
Expand All @@ -306,6 +308,7 @@ fun LazyListScope.remotes(
onPullRemoteBranch = { remotesViewModel.pullFromRemoteBranch(remoteBranch) },
onRebaseRemoteBranch = { remotesViewModel.rebaseBranch(remoteBranch) },
onMergeRemoteBranch = { remotesViewModel.mergeBranch(remoteBranch) },
onCopyBranchNameToClipboard = { remotesViewModel.copyBranchNameToClipboard(remoteBranch) }
)
}
}
Expand Down Expand Up @@ -453,6 +456,7 @@ private fun Branch(
onRebaseBranch: () -> Unit,
onDeleteBranch: () -> Unit,
onChangeDefaultUpstreamBranch: () -> Unit,
onCopyBranchNameToClipboard: () -> Unit,
) {
val isCurrentBranch = currentBranch?.name == branch.name

Expand All @@ -469,7 +473,8 @@ private fun Branch(
onRebaseBranch = onRebaseBranch,
onPushToRemoteBranch = {},
onPullFromRemoteBranch = {},
onChangeDefaultUpstreamBranch = onChangeDefaultUpstreamBranch
onChangeDefaultUpstreamBranch = onChangeDefaultUpstreamBranch,
onCopyBranchNameToClipboard = onCopyBranchNameToClipboard
)
}
) {
Expand Down Expand Up @@ -531,6 +536,7 @@ private fun RemoteBranches(
onPullRemoteBranch: () -> Unit,
onRebaseRemoteBranch: () -> Unit,
onMergeRemoteBranch: () -> Unit,
onCopyBranchNameToClipboard: () -> Unit
) {
ContextMenu(
items = {
Expand All @@ -547,6 +553,7 @@ private fun RemoteBranches(
onPushToRemoteBranch = onPushRemoteBranch,
onPullFromRemoteBranch = onPullRemoteBranch,
onChangeDefaultUpstreamBranch = {},
onCopyBranchNameToClipboard = onCopyBranchNameToClipboard
)
}
) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,11 @@ import androidx.compose.ui.res.painterResource
import com.jetpackduba.gitnuro.AppIcons
import com.jetpackduba.gitnuro.extensions.isHead
import com.jetpackduba.gitnuro.extensions.simpleLogName
import com.jetpackduba.gitnuro.extensions.simpleName
import com.jetpackduba.gitnuro.models.Notification
import com.jetpackduba.gitnuro.models.positiveNotification
import org.eclipse.jgit.lib.Ref
import org.jetbrains.skiko.ClipboardManager

fun branchContextMenuItems(
branch: Ref,
Expand All @@ -19,7 +23,9 @@ fun branchContextMenuItems(
onPushToRemoteBranch: () -> Unit,
onPullFromRemoteBranch: () -> Unit,
onChangeDefaultUpstreamBranch: () -> Unit,
onCopyBranchNameToClipboard: () -> Unit
): List<ContextMenuElement> {

return mutableListOf<ContextMenuElement>().apply {
if (!isCurrentBranch) {
add(
Expand Down Expand Up @@ -90,8 +96,23 @@ fun branchContextMenuItems(
)
}

if (lastOrNull() == ContextMenuElement.ContextSeparator) {
removeLast()
}
add(
ContextMenuElement.ContextTextEntry(
label = "Copy branch name",
icon = { painterResource(AppIcons.COPY) },
onClick = {
onCopyBranchNameToClipboard()
}
)
)
}
}

internal fun copyBranchNameToClipboardAndGetNotification(
branch: Ref,
clipboardManager: ClipboardManager
): Notification {
val branchName = branch.simpleName
clipboardManager.setText(branchName)
return positiveNotification("\"${branchName}\" copied to clipboard")
}
10 changes: 9 additions & 1 deletion src/main/kotlin/com/jetpackduba/gitnuro/ui/log/Log.kt
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,7 @@ private fun LogLoaded(
onDeleteTag = { logViewModel.deleteTag(it) },
onPushToRemoteBranch = { logViewModel.pushToRemoteBranch(it) },
onPullFromRemoteBranch = { logViewModel.pullFromRemoteBranch(it) },
onCopyBranchNameToClipboard = { ref -> logViewModel.copyBranchNameToClipboard(ref) }
)

val density = LocalDensity.current.density
Expand Down Expand Up @@ -505,6 +506,7 @@ fun CommitsList(
onPushToRemoteBranch: (Ref) -> Unit,
onPullFromRemoteBranch: (Ref) -> Unit,
onShowLogDialog: (LogDialog) -> Unit,
onCopyBranchNameToClipboard: (Ref) -> Unit,
graphWidth: Dp,
horizontalScrollState: ScrollState,
) {
Expand Down Expand Up @@ -584,6 +586,7 @@ fun CommitsList(
onCherryPickCommit = { onCherryPickCommit(graphNode) },
onCheckoutRemoteBranch = onCheckoutRemoteBranch,
onCheckoutRef = onCheckoutRef,
onCopyBranchNameToClipboard = onCopyBranchNameToClipboard,
)
}

Expand Down Expand Up @@ -824,6 +827,7 @@ private fun CommitLine(
onCheckoutRemoteBranch: (Ref) -> Unit,
onCheckoutRef: (Ref) -> Unit,
onChangeDefaultUpstreamBranch: (Ref) -> Unit,
onCopyBranchNameToClipboard: (Ref) -> Unit,
horizontalScrollState: ScrollState,
) {
val isLastCommitOfCurrentBranch = currentBranch?.objectId?.name == graphNode.id.name
Expand Down Expand Up @@ -918,6 +922,7 @@ private fun CommitLine(
onPushRemoteBranch = { ref -> onPushToRemoteBranch(ref) },
onPullRemoteBranch = { ref -> onPullFromRemoteBranch(ref) },
onChangeDefaultUpstreamBranch = { ref -> onChangeDefaultUpstreamBranch(ref) },
onCopyBranchNameToClipboard = { ref -> onCopyBranchNameToClipboard(ref) },
)
}
}
Expand All @@ -940,6 +945,7 @@ fun CommitMessage(
onPushRemoteBranch: (ref: Ref) -> Unit,
onPullRemoteBranch: (ref: Ref) -> Unit,
onChangeDefaultUpstreamBranch: (ref: Ref) -> Unit,
onCopyBranchNameToClipboard: (ref: Ref) -> Unit,
) {
Row(
modifier = Modifier.fillMaxSize()
Expand Down Expand Up @@ -981,6 +987,7 @@ fun CommitMessage(
onPullRemoteBranch = { onPullRemoteBranch(ref) },
onPushRemoteBranch = { onPushRemoteBranch(ref) },
onChangeDefaultUpstreamBranch = { onChangeDefaultUpstreamBranch(ref) },
onCopyBranchNameToClipboard = { onCopyBranchNameToClipboard(ref) },
)
}
}
Expand Down Expand Up @@ -1203,7 +1210,6 @@ fun UncommittedChangesGraphNode(
}
}

@OptIn(ExperimentalFoundationApi::class)
@Composable
fun BranchChip(
modifier: Modifier = Modifier,
Expand All @@ -1218,6 +1224,7 @@ fun BranchChip(
onPushRemoteBranch: () -> Unit,
onPullRemoteBranch: () -> Unit,
onChangeDefaultUpstreamBranch: () -> Unit,
onCopyBranchNameToClipboard: () -> Unit,
color: Color,
) {
val contextMenuItemsList = {
Expand All @@ -1234,6 +1241,7 @@ fun BranchChip(
onPushToRemoteBranch = onPushRemoteBranch,
onPullFromRemoteBranch = onPullRemoteBranch,
onChangeDefaultUpstreamBranch = onChangeDefaultUpstreamBranch,
onCopyBranchNameToClipboard = onCopyBranchNameToClipboard,
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import com.jetpackduba.gitnuro.git.workspace.StatusSummary
import com.jetpackduba.gitnuro.models.positiveNotification
import com.jetpackduba.gitnuro.repositories.AppSettingsRepository
import com.jetpackduba.gitnuro.ui.SelectedItem
import com.jetpackduba.gitnuro.ui.context_menu.copyBranchNameToClipboardAndGetNotification
import com.jetpackduba.gitnuro.ui.log.LogDialog
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.*
Expand All @@ -30,6 +31,7 @@ import org.eclipse.jgit.api.Git
import org.eclipse.jgit.api.errors.CheckoutConflictException
import org.eclipse.jgit.lib.Ref
import org.eclipse.jgit.revwalk.RevCommit
import org.jetbrains.skiko.ClipboardManager
import javax.inject.Inject

/**
Expand Down Expand Up @@ -63,6 +65,7 @@ class LogViewModel @Inject constructor(
private val tabState: TabState,
private val appSettingsRepository: AppSettingsRepository,
private val tabScope: CoroutineScope,
private val clipboardManager: ClipboardManager,
sharedStashViewModel: SharedStashViewModel,
sharedBranchesViewModel: SharedBranchesViewModel,
sharedRemotesViewModel: SharedRemotesViewModel,
Expand Down Expand Up @@ -136,7 +139,6 @@ class LogViewModel @Inject constructor(
}
}


private suspend fun loadLog(git: Git) = delayedStateChange(
delayMs = LOG_MIN_TIME_IN_MS_TO_SHOW_LOAD,
onDelayTriggered = {
Expand Down Expand Up @@ -418,6 +420,16 @@ class LogViewModel @Inject constructor(
_logStatus.value =
LogStatus.Loaded(hasUncommittedChanges, log, currentBranch, statusSummary)
}

override fun copyBranchNameToClipboard(branch: Ref) = tabState.safeProcessing(
refreshType = RefreshType.NONE,
taskType = TaskType.UNSPECIFIED
) {
copyBranchNameToClipboardAndGetNotification(
branch,
clipboardManager
)
}
}

sealed interface LogStatus {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,21 @@ import com.jetpackduba.gitnuro.git.rebase.RebaseBranchUseCase
import com.jetpackduba.gitnuro.models.positiveNotification
import com.jetpackduba.gitnuro.models.warningNotification
import com.jetpackduba.gitnuro.repositories.AppSettingsRepository
import com.jetpackduba.gitnuro.ui.context_menu.copyBranchNameToClipboardAndGetNotification
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.launch
import org.eclipse.jgit.lib.Ref
import org.jetbrains.skiko.ClipboardManager
import javax.inject.Inject

interface ISharedBranchesViewModel {
fun mergeBranch(ref: Ref): Job
fun deleteBranch(branch: Ref): Job
fun checkoutRef(ref: Ref): Job
fun rebaseBranch(ref: Ref): Job
fun copyBranchNameToClipboard(branch: Ref): Job
}

class SharedBranchesViewModel @Inject constructor(
Expand All @@ -29,6 +35,7 @@ class SharedBranchesViewModel @Inject constructor(
private val mergeBranchUseCase: MergeBranchUseCase,
private val deleteBranchUseCase: DeleteBranchUseCase,
private val checkoutRefUseCase: CheckoutRefUseCase,
private val clipboardManager: ClipboardManager
) : ISharedBranchesViewModel {

override fun mergeBranch(ref: Ref) = tabState.safeProcessing(
Expand Down Expand Up @@ -80,4 +87,14 @@ class SharedBranchesViewModel @Inject constructor(
positiveNotification("\"${ref.simpleName}\" rebased")
}
}

override fun copyBranchNameToClipboard(branch: Ref) = tabState.safeProcessing(
refreshType = RefreshType.NONE,
taskType = TaskType.UNSPECIFIED
) {
copyBranchNameToClipboardAndGetNotification(
branch,
clipboardManager
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,18 @@ import com.jetpackduba.gitnuro.git.remote_operations.PullFromSpecificBranchUseCa
import com.jetpackduba.gitnuro.git.remote_operations.PushToSpecificBranchUseCase
import com.jetpackduba.gitnuro.models.positiveNotification
import com.jetpackduba.gitnuro.models.warningNotification
import com.jetpackduba.gitnuro.ui.context_menu.copyBranchNameToClipboardAndGetNotification
import kotlinx.coroutines.Job
import org.eclipse.jgit.lib.Ref
import org.jetbrains.skiko.ClipboardManager
import javax.inject.Inject

interface ISharedRemotesViewModel {
fun deleteRemoteBranch(ref: Ref): Job
fun checkoutRemoteBranch(remoteBranch: Ref): Job
fun pushToRemoteBranch(branch: Ref): Job
fun pullFromRemoteBranch(branch: Ref): Job
fun copyBranchNameToClipboard(branch: Ref): Job
}

class SharedRemotesViewModel @Inject constructor(
Expand All @@ -27,7 +30,9 @@ class SharedRemotesViewModel @Inject constructor(
private val checkoutRefUseCase: CheckoutRefUseCase,
private val pushToSpecificBranchUseCase: PushToSpecificBranchUseCase,
private val pullFromSpecificBranchUseCase: PullFromSpecificBranchUseCase,
private val clipboardManager: ClipboardManager,
) : ISharedRemotesViewModel {

override fun deleteRemoteBranch(ref: Ref) = tabState.safeProcessing(
refreshType = RefreshType.ALL_DATA,
title = "Deleting remote branch",
Expand Down Expand Up @@ -76,4 +81,14 @@ class SharedRemotesViewModel @Inject constructor(
positiveNotification("Pulled from \"${branch.simpleName}\"")
}
}

override fun copyBranchNameToClipboard(branch: Ref) = tabState.safeProcessing(
refreshType = RefreshType.NONE,
taskType = TaskType.UNSPECIFIED
) {
copyBranchNameToClipboardAndGetNotification(
branch,
clipboardManager
)
}
}
Loading

0 comments on commit 169863b

Please sign in to comment.