Fixed project's formatting
This commit is contained in:
parent
6142ecef5b
commit
a3ff073b54
@ -2,7 +2,8 @@
|
||||
|
||||
A FOSS Git client based on (Jetbrains) Compose and JGit.
|
||||
|
||||
The main goal of Gitnuro is to provide a multiplatform open source Git client without any kind of constraint to how you can use it nor relying on web technologies.
|
||||
The main goal of Gitnuro is to provide a multiplatform open source Git client without any kind of constraint to how you
|
||||
can use it nor relying on web technologies.
|
||||
|
||||
The project it is still in alpha and many features are lacking or missing, but can be good for basic usage.
|
||||
|
||||
@ -46,7 +47,6 @@ Right now you CAN'T:
|
||||
|
||||
I'll create releases once we hit beta stage.
|
||||
|
||||
|
||||
## Steps to build
|
||||
|
||||
Note: Requires minimum JDK 16.
|
||||
@ -56,10 +56,10 @@ Note: Requires minimum JDK 16.
|
||||
- `./gradlew run` to run the project
|
||||
- `./gradlew tasks` to view other build options (native building requires java >=15)
|
||||
|
||||
|
||||
Feel free to open issues for bugs or sugestions.
|
||||
|
||||
## Screenshots (latest update: 01 feb 2022)
|
||||
|
||||

|
||||

|
||||

|
||||
|
@ -49,7 +49,7 @@ class App {
|
||||
|
||||
private val tabsFlow = MutableStateFlow<List<TabInformation>>(emptyList())
|
||||
|
||||
fun start(){
|
||||
fun start() {
|
||||
appStateManager.loadRepositoriesTabs()
|
||||
loadTabs()
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
package app.di
|
||||
|
||||
import app.AppStateManager
|
||||
import app.App
|
||||
import app.AppStateManager
|
||||
import dagger.Component
|
||||
import javax.inject.Singleton
|
||||
|
||||
|
@ -4,7 +4,7 @@ import app.ui.components.TabInformation
|
||||
import dagger.Component
|
||||
|
||||
@TabScope
|
||||
@Component(dependencies = [ AppComponent::class ])
|
||||
@Component(dependencies = [AppComponent::class])
|
||||
interface TabComponent {
|
||||
fun inject(tabInformation: TabInformation)
|
||||
}
|
@ -31,6 +31,6 @@ val String.dirPath: String
|
||||
}
|
||||
|
||||
val String.withoutLineEnding: String
|
||||
get() = this
|
||||
get() = this
|
||||
.removeSuffix("\n")
|
||||
.removeSuffix("\r\n")
|
@ -4,7 +4,9 @@ import app.extensions.isBranch
|
||||
import app.extensions.simpleName
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
import org.eclipse.jgit.api.*
|
||||
import org.eclipse.jgit.api.CreateBranchCommand
|
||||
import org.eclipse.jgit.api.Git
|
||||
import org.eclipse.jgit.api.ListBranchCommand
|
||||
import org.eclipse.jgit.lib.Ref
|
||||
import org.eclipse.jgit.revwalk.RevCommit
|
||||
import javax.inject.Inject
|
||||
|
@ -4,7 +4,6 @@ import app.di.HunkDiffGeneratorFactory
|
||||
import app.di.RawFileManagerFactory
|
||||
import app.extensions.fullData
|
||||
import app.git.diff.DiffResult
|
||||
import app.git.diff.Hunk
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
import org.eclipse.jgit.api.Git
|
||||
|
@ -1,16 +1,10 @@
|
||||
package app.git
|
||||
|
||||
import app.extensions.isBranch
|
||||
import app.extensions.isMerging
|
||||
import app.extensions.simpleName
|
||||
import app.git.graph.GraphCommitList
|
||||
import app.git.graph.GraphWalk
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.ensureActive
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.withContext
|
||||
import org.eclipse.jgit.api.CreateBranchCommand
|
||||
import org.eclipse.jgit.api.Git
|
||||
import org.eclipse.jgit.api.ResetCommand
|
||||
import org.eclipse.jgit.lib.Constants
|
||||
@ -26,7 +20,7 @@ class LogManager @Inject constructor(
|
||||
val commitList = GraphCommitList()
|
||||
val repositoryState = git.repository.repositoryState
|
||||
println("Repository state ${repositoryState.description}")
|
||||
if(currentBranch != null || repositoryState.isRebasing) { // Current branch is null when there is no log (new repo) or rebasing
|
||||
if (currentBranch != null || repositoryState.isRebasing) { // Current branch is null when there is no log (new repo) or rebasing
|
||||
val logList = git.log().setMaxCount(2).call().toList()
|
||||
|
||||
val walk = GraphWalk(git.repository)
|
||||
|
@ -22,10 +22,10 @@ class MergeManager @Inject constructor() {
|
||||
.call()
|
||||
}
|
||||
|
||||
suspend fun abortBranch(git: Git) = withContext(Dispatchers.IO) {
|
||||
git.repository.writeMergeCommitMsg(null);
|
||||
git.repository.writeMergeHeads(null);
|
||||
suspend fun abortMerge(git: Git) = withContext(Dispatchers.IO) {
|
||||
git.repository.writeMergeCommitMsg(null)
|
||||
git.repository.writeMergeHeads(null)
|
||||
|
||||
git.reset().setMode(ResetCommand.ResetType.HARD).call();
|
||||
git.reset().setMode(ResetCommand.ResetType.HARD).call()
|
||||
}
|
||||
}
|
@ -61,14 +61,18 @@ class RawFileManager @AssistedInject constructor(
|
||||
return try {
|
||||
EntryContent.Text(RawText.load(ldr, DEFAULT_BINARY_FILE_THRESHOLD))
|
||||
} catch (ex: BinaryBlobException) {
|
||||
if(isImage(entry)) {
|
||||
if (isImage(entry)) {
|
||||
generateImageBinary(ldr, entry, side)
|
||||
} else
|
||||
EntryContent.Binary
|
||||
}
|
||||
}
|
||||
|
||||
private fun generateImageBinary(ldr: ObjectLoader, entry: DiffEntry, side: DiffEntry.Side): EntryContent.ImageBinary {
|
||||
private fun generateImageBinary(
|
||||
ldr: ObjectLoader,
|
||||
entry: DiffEntry,
|
||||
side: DiffEntry.Side
|
||||
): EntryContent.ImageBinary {
|
||||
println("Data's size is ${ldr.size}")
|
||||
|
||||
val tempDir = createTempDirectory("gitnuro${repository.directory.absolutePath.replace("/", "_")}")
|
||||
@ -99,11 +103,11 @@ class RawFileManager @AssistedInject constructor(
|
||||
}
|
||||
|
||||
sealed class EntryContent {
|
||||
object Missing: EntryContent()
|
||||
object InvalidObjectBlob: EntryContent()
|
||||
data class Text(val rawText: RawText): EntryContent()
|
||||
object Missing : EntryContent()
|
||||
object InvalidObjectBlob : EntryContent()
|
||||
data class Text(val rawText: RawText) : EntryContent()
|
||||
sealed class BinaryContent() : EntryContent()
|
||||
data class ImageBinary(val tempFilePath: Path): BinaryContent()
|
||||
object Binary: BinaryContent()
|
||||
object TooLargeEntry: EntryContent()
|
||||
data class ImageBinary(val tempFilePath: Path) : BinaryContent()
|
||||
object Binary : BinaryContent()
|
||||
object TooLargeEntry : EntryContent()
|
||||
}
|
@ -1,8 +1,6 @@
|
||||
package app.git
|
||||
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.withContext
|
||||
import org.eclipse.jgit.api.Git
|
||||
import org.eclipse.jgit.lib.Ref
|
||||
|
@ -1,8 +1,6 @@
|
||||
package app.git
|
||||
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.withContext
|
||||
import org.eclipse.jgit.api.Git
|
||||
import javax.inject.Inject
|
||||
|
@ -60,7 +60,7 @@ class StatusManager @Inject constructor(
|
||||
val rawFileManager = rawFileManagerFactory.create(git.repository)
|
||||
val entryContent = rawFileManager.getRawContent(DiffEntry.Side.OLD, diffEntry)
|
||||
|
||||
if(entryContent !is EntryContent.Text)
|
||||
if (entryContent !is EntryContent.Text)
|
||||
return@withContext
|
||||
|
||||
val textLines = getTextLines(entryContent.rawText).toMutableList()
|
||||
@ -103,7 +103,7 @@ class StatusManager @Inject constructor(
|
||||
val rawFileManager = rawFileManagerFactory.create(git.repository)
|
||||
val entryContent = rawFileManager.getRawContent(DiffEntry.Side.NEW, diffEntry)
|
||||
|
||||
if(entryContent !is EntryContent.Text)
|
||||
if (entryContent !is EntryContent.Text)
|
||||
return@withContext
|
||||
|
||||
val textLines = getTextLines(entryContent.rawText).toMutableList()
|
||||
@ -224,7 +224,8 @@ class StatusManager @Inject constructor(
|
||||
.call()
|
||||
}
|
||||
|
||||
suspend fun getStaged(git: Git, currentBranch: Ref?, repositoryState: RepositoryState) = withContext(Dispatchers.IO) {
|
||||
suspend fun getStaged(git: Git, currentBranch: Ref?, repositoryState: RepositoryState) =
|
||||
withContext(Dispatchers.IO) {
|
||||
return@withContext git
|
||||
.diff()
|
||||
.setShowNameAndStatusOnly(true).apply {
|
||||
@ -237,7 +238,7 @@ class StatusManager @Inject constructor(
|
||||
// TODO: Grouping and fitlering allows us to remove duplicates when conflicts appear, requires more testing (what happens in windows? /dev/null is a unix thing)
|
||||
// TODO: Test if we should group by old path or new path
|
||||
.groupBy {
|
||||
if(it.newPath != "/dev/null")
|
||||
if (it.newPath != "/dev/null")
|
||||
it.newPath
|
||||
else
|
||||
it.oldPath
|
||||
@ -258,7 +259,7 @@ class StatusManager @Inject constructor(
|
||||
.setShowNameAndStatusOnly(true)
|
||||
.call()
|
||||
.groupBy {
|
||||
if(it.oldPath != "/dev/null")
|
||||
if (it.oldPath != "/dev/null")
|
||||
it.oldPath
|
||||
else
|
||||
it.newPath
|
||||
|
@ -1,8 +1,8 @@
|
||||
package app.git
|
||||
|
||||
import app.ErrorsManager
|
||||
import app.newErrorNow
|
||||
import app.di.TabScope
|
||||
import app.newErrorNow
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.SupervisorJob
|
||||
@ -95,7 +95,8 @@ class TabState @Inject constructor(
|
||||
}
|
||||
}
|
||||
|
||||
fun runOperation(showError: Boolean = false, block: suspend (git: Git) -> RefreshType) = managerScope.launch(Dispatchers.IO) {
|
||||
fun runOperation(showError: Boolean = false, block: suspend (git: Git) -> RefreshType) =
|
||||
managerScope.launch(Dispatchers.IO) {
|
||||
operationRunning = true
|
||||
try {
|
||||
val refreshType = block(safeGit)
|
||||
|
@ -1,8 +1,6 @@
|
||||
package app.git
|
||||
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.withContext
|
||||
import org.eclipse.jgit.api.Git
|
||||
import org.eclipse.jgit.lib.Ref
|
||||
|
@ -14,7 +14,6 @@ import java.io.ByteArrayOutputStream
|
||||
import java.io.IOException
|
||||
import java.io.InvalidObjectException
|
||||
import kotlin.contracts.ExperimentalContracts
|
||||
import kotlin.contracts.contract
|
||||
import kotlin.math.max
|
||||
import kotlin.math.min
|
||||
|
||||
@ -48,7 +47,7 @@ class HunkDiffGenerator @AssistedInject constructor(
|
||||
val rawOld = rawFileManager.getRawContent(DiffEntry.Side.OLD, ent)
|
||||
val rawNew = rawFileManager.getRawContent(DiffEntry.Side.NEW, ent)
|
||||
|
||||
if(rawOld == EntryContent.InvalidObjectBlob || rawNew == EntryContent.InvalidObjectBlob)
|
||||
if (rawOld == EntryContent.InvalidObjectBlob || rawNew == EntryContent.InvalidObjectBlob)
|
||||
throw InvalidObjectException("Invalid object in diff format")
|
||||
|
||||
var diffResult: DiffResult = DiffResult.Text(emptyList())
|
||||
@ -84,7 +83,7 @@ class HunkDiffGenerator @AssistedInject constructor(
|
||||
else -> null
|
||||
}
|
||||
|
||||
return if(rawOldText != null && newOldText != null) {
|
||||
return if (rawOldText != null && newOldText != null) {
|
||||
onText(rawOldText, newOldText)
|
||||
true
|
||||
} else
|
||||
|
@ -53,7 +53,7 @@ object NetworkImageLoader {
|
||||
fun rememberNetworkImageOrNull(url: String, placeHolderImageRes: String? = null): ImageBitmap? {
|
||||
val networkImageLoader = NetworkImageLoader
|
||||
var image by remember(url) {
|
||||
val placeHolderImage = if(placeHolderImageRes != null)
|
||||
val placeHolderImage = if (placeHolderImageRes != null)
|
||||
useResource(placeHolderImageRes) {
|
||||
Image.makeFromEncoded(it.toByteArray()).toComposeImageBitmap()
|
||||
}
|
||||
|
@ -109,8 +109,6 @@ val Colors.unstageButton: Color
|
||||
get() = error
|
||||
|
||||
|
||||
|
||||
|
||||
enum class Themes(val displayName: String) {
|
||||
LIGHT("Light"),
|
||||
DARK("Dark")
|
||||
|
@ -22,10 +22,10 @@ import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import app.LoadingRepository
|
||||
import app.credentials.CredentialsState
|
||||
import app.viewmodels.TabViewModel
|
||||
import app.viewmodels.RepositorySelectionStatus
|
||||
import app.ui.dialogs.PasswordDialog
|
||||
import app.ui.dialogs.UserPasswordDialog
|
||||
import app.viewmodels.RepositorySelectionStatus
|
||||
import app.viewmodels.TabViewModel
|
||||
import kotlinx.coroutines.delay
|
||||
|
||||
// TODO onDispose sometimes is called when changing tabs, therefore losing the tab state
|
||||
|
@ -1,20 +1,24 @@
|
||||
package app.ui
|
||||
|
||||
import androidx.compose.foundation.*
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.lazy.itemsIndexed
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
import androidx.compose.foundation.text.selection.SelectionContainer
|
||||
import androidx.compose.foundation.verticalScroll
|
||||
import androidx.compose.material.*
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.collectAsState
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import app.extensions.*
|
||||
import app.viewmodels.TabViewModel
|
||||
import app.theme.headerBackground
|
||||
import app.theme.headerText
|
||||
import app.theme.primaryTextColor
|
||||
@ -34,7 +38,7 @@ fun CommitChanges(
|
||||
) {
|
||||
val commitChangesStatusState = commitChangesViewModel.commitChangesStatus.collectAsState()
|
||||
|
||||
when(val commitChangesStatus = commitChangesStatusState.value) {
|
||||
when (val commitChangesStatus = commitChangesStatusState.value) {
|
||||
CommitChangesStatus.Loading -> {
|
||||
LinearProgressIndicator(modifier = Modifier.fillMaxWidth())
|
||||
}
|
||||
|
@ -6,8 +6,12 @@ import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.lazy.items
|
||||
import androidx.compose.foundation.text.selection.DisableSelection
|
||||
import androidx.compose.foundation.text.selection.SelectionContainer
|
||||
import androidx.compose.material.*
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.material.IconButton
|
||||
import androidx.compose.material.MaterialTheme
|
||||
import androidx.compose.material.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.collectAsState
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
@ -92,14 +96,14 @@ fun NonTextDiff(diffResult: DiffResult.NonText) {
|
||||
SideTitle("New")
|
||||
SideDiff(newBinaryContent)
|
||||
}
|
||||
} else if(oldBinaryContent != EntryContent.Missing) {
|
||||
} else if (oldBinaryContent != EntryContent.Missing) {
|
||||
Box(
|
||||
modifier = Modifier.fillMaxSize()
|
||||
.padding(all = 24.dp),
|
||||
) {
|
||||
SideDiff(oldBinaryContent)
|
||||
}
|
||||
} else if(newBinaryContent != EntryContent.Missing) {
|
||||
} else if (newBinaryContent != EntryContent.Missing) {
|
||||
Column(
|
||||
modifier = Modifier.fillMaxSize()
|
||||
.padding(all = 24.dp),
|
||||
|
@ -2,7 +2,10 @@
|
||||
|
||||
package app.ui
|
||||
|
||||
import androidx.compose.foundation.*
|
||||
import androidx.compose.foundation.ExperimentalFoundationApi
|
||||
import androidx.compose.foundation.Image
|
||||
import androidx.compose.foundation.border
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material.*
|
||||
@ -18,13 +21,11 @@ import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import app.theme.primaryTextColor
|
||||
import app.ui.context_menu.pullContextMenuItems
|
||||
import app.viewmodels.MenuViewModel
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.setValue
|
||||
import app.ui.context_menu.DropDownContent
|
||||
import app.ui.context_menu.DropDownContentData
|
||||
import app.ui.context_menu.pullContextMenuItems
|
||||
import app.ui.context_menu.pushContextMenuItems
|
||||
import app.viewmodels.MenuViewModel
|
||||
|
||||
// TODO Add tooltips to all the buttons
|
||||
@Composable
|
||||
|
@ -7,9 +7,9 @@ import androidx.compose.runtime.*
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.unit.dp
|
||||
import app.git.DiffEntryType
|
||||
import app.viewmodels.TabViewModel
|
||||
import app.ui.dialogs.NewBranchDialog
|
||||
import app.ui.log.Log
|
||||
import app.viewmodels.TabViewModel
|
||||
import openRepositoryDialog
|
||||
import org.eclipse.jgit.revwalk.RevCommit
|
||||
import org.jetbrains.compose.splitpane.ExperimentalSplitPaneApi
|
||||
|
@ -154,7 +154,7 @@ fun UncommitedChanges(
|
||||
.padding(8.dp)
|
||||
.run {
|
||||
// When rebasing, we don't need a fixed size as we don't show the message TextField
|
||||
if(!repositoryState.isRebasing) {
|
||||
if (!repositoryState.isRebasing) {
|
||||
height(192.dp)
|
||||
} else
|
||||
this
|
||||
|
@ -20,11 +20,11 @@ import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import app.extensions.dirName
|
||||
import app.extensions.dirPath
|
||||
import app.viewmodels.TabViewModel
|
||||
import app.theme.primaryTextColor
|
||||
import app.theme.secondaryTextColor
|
||||
import app.ui.dialogs.CloneDialog
|
||||
import app.ui.dialogs.MaterialDialog
|
||||
import app.viewmodels.TabViewModel
|
||||
import openRepositoryDialog
|
||||
import java.awt.Desktop
|
||||
import java.net.URI
|
||||
|
@ -28,7 +28,7 @@ fun AvatarImage(
|
||||
.clip(CircleShape)
|
||||
) {
|
||||
val avatar = rememberAvatar(personIdent.emailAddress)
|
||||
if(avatar == null) {
|
||||
if (avatar == null) {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
|
@ -2,7 +2,10 @@ package app.ui.components
|
||||
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.foundation.lazy.LazyListScope
|
||||
import androidx.compose.foundation.lazy.LazyRow
|
||||
import androidx.compose.foundation.lazy.items
|
||||
@ -16,16 +19,15 @@ import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.draw.shadow
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.unit.dp
|
||||
import app.AppStateManager
|
||||
import app.di.AppComponent
|
||||
import app.di.DaggerTabComponent
|
||||
import app.theme.primaryTextColor
|
||||
import app.viewmodels.TabViewModel
|
||||
import app.theme.tabColorActive
|
||||
import app.theme.tabColorInactive
|
||||
import app.ui.AppTab
|
||||
import app.viewmodels.TabViewModel
|
||||
import javax.inject.Inject
|
||||
import kotlin.io.path.Path
|
||||
import kotlin.io.path.name
|
||||
@ -65,7 +67,7 @@ fun RepositoriesTabPanel(
|
||||
val index = tabs.indexOf(tab)
|
||||
val nextIndex = if (index == 0 && tabs.count() >= 2) {
|
||||
1 // If the first tab is selected, select the next one
|
||||
} else if (index == tabs.count() -1 && tabs.count() >= 2)
|
||||
} else if (index == tabs.count() - 1 && tabs.count() >= 2)
|
||||
index - 1 // If the last tab is selected, select the previous one
|
||||
else if (tabs.count() >= 2)
|
||||
index + 1 // If any in between tab is selected, select the next one
|
||||
@ -126,7 +128,7 @@ fun TabPanel(
|
||||
|
||||
@Composable
|
||||
fun Tab(title: MutableState<String>, selected: Boolean, onClick: () -> Unit, onCloseTab: () -> Unit) {
|
||||
val elevation = if(selected) {
|
||||
val elevation = if (selected) {
|
||||
3.dp
|
||||
} else
|
||||
0.dp
|
||||
@ -194,7 +196,7 @@ class TabInformation(
|
||||
appStateManager.repositoryTabChanged(key, path)
|
||||
}
|
||||
}
|
||||
if(path != null)
|
||||
if (path != null)
|
||||
tabViewModel.openRepository(path)
|
||||
content = {
|
||||
AppTab(tabViewModel)
|
||||
|
@ -5,16 +5,13 @@ import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material.MaterialTheme
|
||||
import androidx.compose.material.Text
|
||||
import androidx.compose.material.contentColorFor
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import app.theme.primaryTextColor
|
||||
|
||||
@Composable
|
||||
fun SecondaryButton(
|
||||
|
@ -1,6 +1,5 @@
|
||||
package app.ui.components
|
||||
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
|
@ -13,7 +13,6 @@ import androidx.compose.ui.ExperimentalComposeUiApi
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.unit.Dp
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
|
@ -12,8 +12,8 @@ import androidx.compose.ui.text.TextStyle
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import app.git.CloneStatus
|
||||
import app.viewmodels.TabViewModel
|
||||
import app.theme.primaryTextColor
|
||||
import app.viewmodels.TabViewModel
|
||||
import java.io.File
|
||||
|
||||
@Composable
|
||||
|
@ -6,8 +6,11 @@ import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.material.*
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.material.Button
|
||||
import androidx.compose.material.MaterialTheme
|
||||
import androidx.compose.material.Text
|
||||
import androidx.compose.material.TextButton
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
|
@ -210,7 +210,7 @@ fun LogDialogs(
|
||||
}
|
||||
)
|
||||
is LogDialog.RebaseBranch -> {
|
||||
if(currentBranch != null) {
|
||||
if (currentBranch != null) {
|
||||
RebaseDialog(
|
||||
currentBranchName = currentBranch.simpleName,
|
||||
rebaseBranchName = showLogDialog.ref.simpleName,
|
||||
|
@ -5,7 +5,6 @@ import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import org.eclipse.jgit.api.Git
|
||||
import org.eclipse.jgit.lib.Ref
|
||||
import org.eclipse.jgit.revwalk.RevCommit
|
||||
import javax.inject.Inject
|
||||
|
||||
class BranchesViewModel @Inject constructor(
|
||||
@ -29,7 +28,7 @@ class BranchesViewModel @Inject constructor(
|
||||
|
||||
// set selected branch as the first one always
|
||||
val selectedBranch = branchesList.find { it.name == _currentBranch.value }
|
||||
if(selectedBranch != null) {
|
||||
if (selectedBranch != null) {
|
||||
branchesList.remove(selectedBranch)
|
||||
branchesList.add(0, selectedBranch)
|
||||
}
|
||||
@ -51,7 +50,7 @@ class BranchesViewModel @Inject constructor(
|
||||
return@safeProcessing RefreshType.ALL_DATA
|
||||
}
|
||||
|
||||
fun deleteBranch(branch: Ref) =tabState.safeProcessing { git ->
|
||||
fun deleteBranch(branch: Ref) = tabState.safeProcessing { git ->
|
||||
branchesManager.deleteBranch(git, branch)
|
||||
|
||||
return@safeProcessing RefreshType.ALL_DATA
|
||||
|
@ -31,7 +31,7 @@ class DiffViewModel @Inject constructor(
|
||||
_diffResult.value = null
|
||||
|
||||
// If it's a different file or different state (index or workdir), reset the scroll state
|
||||
if(oldDiffEntryType != null &&
|
||||
if (oldDiffEntryType != null &&
|
||||
(oldDiffEntryType.diffEntry.oldPath != diffEntryType.diffEntry.oldPath ||
|
||||
oldDiffEntryType.diffEntry.newPath != diffEntryType.diffEntry.newPath ||
|
||||
oldDiffEntryType::class != diffEntryType::class)
|
||||
|
@ -75,7 +75,7 @@ class LogViewModel @Inject constructor(
|
||||
return@safeProcessing RefreshType.ALL_DATA
|
||||
}
|
||||
|
||||
fun deleteBranch(branch: Ref) =tabState.safeProcessing { git ->
|
||||
fun deleteBranch(branch: Ref) = tabState.safeProcessing { git ->
|
||||
branchesManager.deleteBranch(git, branch)
|
||||
|
||||
return@safeProcessing RefreshType.ALL_DATA
|
||||
@ -100,5 +100,6 @@ class LogViewModel @Inject constructor(
|
||||
|
||||
sealed class LogStatus {
|
||||
object Loading : LogStatus()
|
||||
class Loaded(val hasUncommitedChanges: Boolean, val plotCommitList: GraphCommitList, val currentBranch: Ref?) : LogStatus()
|
||||
class Loaded(val hasUncommitedChanges: Boolean, val plotCommitList: GraphCommitList, val currentBranch: Ref?) :
|
||||
LogStatus()
|
||||
}
|
@ -36,7 +36,7 @@ class MenuViewModel @Inject constructor(
|
||||
return@safeProcessing RefreshType.UNCOMMITED_CHANGES
|
||||
}
|
||||
|
||||
fun openFolderInFileExplorer() = tabState.runOperation (showError = true) { git ->
|
||||
fun openFolderInFileExplorer() = tabState.runOperation(showError = true) { git ->
|
||||
Desktop.getDesktop().open(git.repository.directory.parentFile)
|
||||
|
||||
return@runOperation RefreshType.NONE
|
||||
|
@ -3,14 +3,11 @@ package app.viewmodels
|
||||
import app.git.BranchesManager
|
||||
import app.git.RemoteInfo
|
||||
import app.git.RemotesManager
|
||||
import app.git.TabState
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.withContext
|
||||
import org.eclipse.jgit.api.Git
|
||||
import org.eclipse.jgit.lib.Ref
|
||||
import org.eclipse.jgit.transport.RemoteConfig
|
||||
import javax.inject.Inject
|
||||
|
||||
class RemotesViewModel @Inject constructor(
|
||||
|
@ -135,7 +135,7 @@ class StatusViewModel @Inject constructor(
|
||||
}
|
||||
|
||||
fun abortMerge() = tabState.safeProcessing { git ->
|
||||
mergeManager.abortBranch(git)
|
||||
mergeManager.abortMerge(git)
|
||||
|
||||
return@safeProcessing RefreshType.ALL_DATA
|
||||
}
|
||||
|
@ -2,10 +2,10 @@ package app.viewmodels
|
||||
|
||||
import app.AppStateManager
|
||||
import app.ErrorsManager
|
||||
import app.newErrorNow
|
||||
import app.credentials.CredentialsState
|
||||
import app.credentials.CredentialsStateManager
|
||||
import app.git.*
|
||||
import app.newErrorNow
|
||||
import app.ui.SelectedItem
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.cancel
|
||||
@ -215,7 +215,7 @@ class TabViewModel @Inject constructor(
|
||||
}
|
||||
|
||||
fun newSelectedRef(objectId: ObjectId?) = tabState.runOperation { git ->
|
||||
if(objectId == null) {
|
||||
if (objectId == null) {
|
||||
newSelectedItem(SelectedItem.None)
|
||||
return@runOperation RefreshType.NONE
|
||||
}
|
||||
@ -233,7 +233,7 @@ class TabViewModel @Inject constructor(
|
||||
fun newSelectedItem(selectedItem: SelectedItem) {
|
||||
_selectedItem.value = selectedItem
|
||||
|
||||
if(selectedItem is SelectedItem.CommitBasedItem) {
|
||||
if (selectedItem is SelectedItem.CommitBasedItem) {
|
||||
commitChangesViewModel.loadChanges(selectedItem.revCommit)
|
||||
}
|
||||
}
|
||||
|
@ -1,3 +1,5 @@
|
||||
<svg width="120" height="120" viewBox="0 0 120 120" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M10 0C4.47715 0 0 4.47715 0 10V110C0 115.523 4.47715 120 10 120H110C115.523 120 120 115.523 120 110V10C120 4.47715 115.523 0 110 0H10ZM59.666 55.0039V69.2773C59.666 73.1328 59.2148 76.5371 58.3125 79.4902C57.4375 82.416 56.166 84.8633 54.498 86.832C52.8301 88.8281 50.793 90.332 48.3867 91.3438C45.9805 92.3555 43.2734 92.8613 40.2656 92.8613C37.2852 92.8613 34.5918 92.3555 32.1855 91.3438C29.7793 90.332 27.7422 88.8281 26.0742 86.832C24.3789 84.8633 23.0664 82.416 22.1367 79.4902C21.2344 76.5371 20.7832 73.1328 20.7832 69.2773V55.0039C20.7832 51.1484 21.2344 47.7578 22.1367 44.832C23.0391 41.8789 24.3379 39.4043 26.0332 37.4082C27.7012 35.4395 29.7246 33.9492 32.1035 32.9375C34.5098 31.9258 37.2031 31.4199 40.1836 31.4199C43.1914 31.4199 45.8984 31.9258 48.3047 32.9375C50.7109 33.9492 52.7617 35.4395 54.457 37.4082C56.125 39.4043 57.4102 41.8789 58.3125 44.832C59.2148 47.7578 59.666 51.1484 59.666 55.0039ZM32.2676 62.4277V64.3555L48.1816 52.502C48.127 50.2598 47.8809 48.3457 47.4434 46.7598C47.0332 45.1465 46.418 43.8613 45.5977 42.9043C44.9688 42.1387 44.1895 41.5781 43.2598 41.2227C42.3574 40.8398 41.332 40.6484 40.1836 40.6484C38.8984 40.6484 37.7637 40.8945 36.7793 41.3867C35.8223 41.8516 35.0156 42.5625 34.3594 43.5195C33.6484 44.5312 33.1152 45.8438 32.7598 47.457C32.4316 49.0703 32.2676 50.9844 32.2676 53.1992V59.8027V62.4277ZM47.6484 76.7832C48.0039 75.1426 48.1816 73.2148 48.1816 71V64.0684V62.0996V60.2539L32.2676 72.0664C32.3223 73.8711 32.5 75.4707 32.8008 76.8652C33.1289 78.2598 33.5801 79.4219 34.1543 80.3516C34.8105 81.4727 35.6445 82.3066 36.6562 82.8535C37.668 83.4004 38.8711 83.6738 40.2656 83.6738C41.5508 83.6738 42.6855 83.4414 43.6699 82.9766C44.6543 82.4844 45.4746 81.7461 46.1309 80.7617C46.8145 79.7227 47.3203 78.3965 47.6484 76.7832ZM99.1641 32.2812V92H87.6387V46.1855L72.5449 51.5996V41.6738L98.5488 32.2812H99.1641Z" fill="black"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd"
|
||||
d="M10 0C4.47715 0 0 4.47715 0 10V110C0 115.523 4.47715 120 10 120H110C115.523 120 120 115.523 120 110V10C120 4.47715 115.523 0 110 0H10ZM59.666 55.0039V69.2773C59.666 73.1328 59.2148 76.5371 58.3125 79.4902C57.4375 82.416 56.166 84.8633 54.498 86.832C52.8301 88.8281 50.793 90.332 48.3867 91.3438C45.9805 92.3555 43.2734 92.8613 40.2656 92.8613C37.2852 92.8613 34.5918 92.3555 32.1855 91.3438C29.7793 90.332 27.7422 88.8281 26.0742 86.832C24.3789 84.8633 23.0664 82.416 22.1367 79.4902C21.2344 76.5371 20.7832 73.1328 20.7832 69.2773V55.0039C20.7832 51.1484 21.2344 47.7578 22.1367 44.832C23.0391 41.8789 24.3379 39.4043 26.0332 37.4082C27.7012 35.4395 29.7246 33.9492 32.1035 32.9375C34.5098 31.9258 37.2031 31.4199 40.1836 31.4199C43.1914 31.4199 45.8984 31.9258 48.3047 32.9375C50.7109 33.9492 52.7617 35.4395 54.457 37.4082C56.125 39.4043 57.4102 41.8789 58.3125 44.832C59.2148 47.7578 59.666 51.1484 59.666 55.0039ZM32.2676 62.4277V64.3555L48.1816 52.502C48.127 50.2598 47.8809 48.3457 47.4434 46.7598C47.0332 45.1465 46.418 43.8613 45.5977 42.9043C44.9688 42.1387 44.1895 41.5781 43.2598 41.2227C42.3574 40.8398 41.332 40.6484 40.1836 40.6484C38.8984 40.6484 37.7637 40.8945 36.7793 41.3867C35.8223 41.8516 35.0156 42.5625 34.3594 43.5195C33.6484 44.5312 33.1152 45.8438 32.7598 47.457C32.4316 49.0703 32.2676 50.9844 32.2676 53.1992V59.8027V62.4277ZM47.6484 76.7832C48.0039 75.1426 48.1816 73.2148 48.1816 71V64.0684V62.0996V60.2539L32.2676 72.0664C32.3223 73.8711 32.5 75.4707 32.8008 76.8652C33.1289 78.2598 33.5801 79.4219 34.1543 80.3516C34.8105 81.4727 35.6445 82.3066 36.6562 82.8535C37.668 83.4004 38.8711 83.6738 40.2656 83.6738C41.5508 83.6738 42.6855 83.4414 43.6699 82.9766C44.6543 82.4844 45.4746 81.7461 46.1309 80.7617C46.8145 79.7227 47.3203 78.3965 47.6484 76.7832ZM99.1641 32.2812V92H87.6387V46.1855L72.5449 51.5996V41.6738L98.5488 32.2812H99.1641Z"
|
||||
fill="black"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 2.0 KiB After Width: | Height: | Size: 2.0 KiB |
@ -1 +1,4 @@
|
||||
<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 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12 19 6.41z"/></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 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12 19 6.41z"/>
|
||||
</svg>
|
Before Width: | Height: | Size: 268 B After Width: | Height: | Size: 279 B |
@ -1 +1,7 @@
|
||||
<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><rect fill="none" height="24" width="24"/><path d="M20,6h-8l-2-2H4C2.9,4,2.01,4.9,2.01,6L2,18c0,1.1,0.9,2,2,2h16c1.1,0,2-0.9,2-2V8C22,6.9,21.1,6,20,6z M14,16H6v-2h8V16z M18,12H6v-2h12V12z"/></g></svg>
|
||||
<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>
|
||||
<rect fill="none" height="24" width="24"/>
|
||||
<path d="M20,6h-8l-2-2H4C2.9,4,2.01,4.9,2.01,6L2,18c0,1.1,0.9,2,2,2h16c1.1,0,2-0.9,2-2V8C22,6.9,21.1,6,20,6z M14,16H6v-2h8V16z M18,12H6v-2h12V12z"/>
|
||||
</g>
|
||||
</svg>
|
Before Width: | Height: | Size: 339 B After Width: | Height: | Size: 373 B |
Loading…
Reference in New Issue
Block a user