Code cleanup
2
.github/FUNDING.yml
vendored
@ -1,6 +1,6 @@
|
|||||||
# These are supported funding model platforms
|
# These are supported funding model platforms
|
||||||
|
|
||||||
github: [JetpackDuba] # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
|
github: [ JetpackDuba ] # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
|
||||||
patreon: # Replace with a single Patreon username
|
patreon: # Replace with a single Patreon username
|
||||||
open_collective: # Replace with a single Open Collective username
|
open_collective: # Replace with a single Open Collective username
|
||||||
ko_fi: # Replace with a single Ko-fi username
|
ko_fi: # Replace with a single Ko-fi username
|
||||||
|
@ -2,12 +2,16 @@
|
|||||||
|
|
||||||
## Requirements
|
## Requirements
|
||||||
|
|
||||||
- **JDK 17 or higher**: You don't need this if you only use the JDK installed by IntelliJ IDEA. If you want to build using the CLI, check this [section](#alternative-setting-up-jdk-for-use-on-cli).
|
- **JDK 17 or higher**: You don't need this if you only use the JDK installed by IntelliJ IDEA. If you want to build
|
||||||
- **Rust:** Gitnuro is mainly written in Kotlin (JVM) but also uses Rust for some specific tasks. To set up your Rust environment,
|
using the CLI, check this [section](#alternative-setting-up-jdk-for-use-on-cli).
|
||||||
please read [its documentation](https://www.rust-lang.org/). `cargo` and `rustc` must be available in the path in order to build Gitnuro properly.
|
- **Rust:** Gitnuro is mainly written in Kotlin (JVM) but also uses Rust for some specific tasks. To set up your Rust
|
||||||
|
environment,
|
||||||
|
please read [its documentation](https://www.rust-lang.org/). `cargo` and `rustc` must be available in the path in
|
||||||
|
order to build Gitnuro properly.
|
||||||
- **Perl:** Perl is required to build openssl (which is required for LibSSH to work).
|
- **Perl:** Perl is required to build openssl (which is required for LibSSH to work).
|
||||||
- **Packages for Linux ARM64/aarch64**: You need to install the `aarch64-linux-gnu-gcc` package to cross compile the
|
- **Packages for Linux ARM64/aarch64**: You need to install the `aarch64-linux-gnu-gcc` package to cross compile the
|
||||||
Rust components to ARM from x86_64. You will also need to use `rustup` to add a new target: `rustup target add aarch64-unknown-linux-gnu`
|
Rust components to ARM from x86_64. You will also need to use `rustup` to add a new
|
||||||
|
target: `rustup target add aarch64-unknown-linux-gnu`
|
||||||
|
|
||||||
## Setting up an IDE
|
## Setting up an IDE
|
||||||
|
|
||||||
@ -16,9 +20,12 @@ If you don't have another preference, the recommendation is to download and inst
|
|||||||
(possibly through the JetBrains Toolbox, if you have it already). The recommended plugins to improve the DX are:
|
(possibly through the JetBrains Toolbox, if you have it already). The recommended plugins to improve the DX are:
|
||||||
|
|
||||||
- [Compose Multiplatform IDE Support](https://plugins.jetbrains.com/plugin/16541-compose-multiplatform-ide-support)
|
- [Compose Multiplatform IDE Support](https://plugins.jetbrains.com/plugin/16541-compose-multiplatform-ide-support)
|
||||||
- [Rust Plugin](https://plugins.jetbrains.com/plugin/8182-rust) (deprecated due to [RustRover IDE](https://blog.jetbrains.com/rust/2023/09/13/introducing-rustrover-a-standalone-rust-ide-by-jetbrains/) but still works).
|
- [Rust Plugin](https://plugins.jetbrains.com/plugin/8182-rust) (deprecated due
|
||||||
|
to [RustRover IDE](https://blog.jetbrains.com/rust/2023/09/13/introducing-rustrover-a-standalone-rust-ide-by-jetbrains/)
|
||||||
|
but still works).
|
||||||
|
|
||||||
By default, the JDK used by "IntelliJ IDEA Community Edition (2023.1.3)" is "JetBrains Runtime version 21" which is not currently supported by the project.
|
By default, the JDK used by "IntelliJ IDEA Community Edition (2023.1.3)" is "JetBrains Runtime version 21" which is not
|
||||||
|
currently supported by the project.
|
||||||
|
|
||||||
## Alternative: Setting up JDK for use on CLI
|
## Alternative: Setting up JDK for use on CLI
|
||||||
|
|
||||||
@ -32,7 +39,8 @@ sudo apt install openjdk-17-jre openjdk-17-jdk
|
|||||||
export JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64
|
export JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64
|
||||||
```
|
```
|
||||||
|
|
||||||
Once it works (e.g. `./gradlew build`). On Linux, you may want to add that latter line to your `/etc/environment` or user-specific files such as `.profile` or `.bashrc`.
|
Once it works (e.g. `./gradlew build`). On Linux, you may want to add that latter line to your `/etc/environment` or
|
||||||
|
user-specific files such as `.profile` or `.bashrc`.
|
||||||
|
|
||||||
## Running the app / unit tests
|
## Running the app / unit tests
|
||||||
|
|
||||||
|
@ -15,7 +15,8 @@ Linux:
|
|||||||
|
|
||||||
- Available as Flatpak [here](https://flathub.org/apps/details/com.jetpackduba.Gitnuro) or by
|
- Available as Flatpak [here](https://flathub.org/apps/details/com.jetpackduba.Gitnuro) or by
|
||||||
running `flatpak install com.jetpackduba.Gitnuro` if you have Flatpak & Flathub already setup.
|
running `flatpak install com.jetpackduba.Gitnuro` if you have Flatpak & Flathub already setup.
|
||||||
- If Flathub is not set up, you can add the source with the following command `flatpak remote-add --if-not-exists flathub https://dl.flathub.org/repo/flathub.flatpakrepo`.
|
- If Flathub is not set up, you can add the source with the following
|
||||||
|
command `flatpak remote-add --if-not-exists flathub https://dl.flathub.org/repo/flathub.flatpakrepo`.
|
||||||
- JAR file can be executed as a portable version (Requires JRE 17).
|
- JAR file can be executed as a portable version (Requires JRE 17).
|
||||||
|
|
||||||
Windows:
|
Windows:
|
||||||
@ -139,6 +140,7 @@ it if it's a very requested feature but not for now.
|
|||||||
> Authentication has failed. What's wrong?
|
> Authentication has failed. What's wrong?
|
||||||
|
|
||||||
Currently there are some limitations regarding this topic. Here are some known problematic setups:
|
Currently there are some limitations regarding this topic. Here are some known problematic setups:
|
||||||
|
|
||||||
- Multicast DNS remote URL (https://github.com/JetpackDuba/Gitnuro/issues/19) with this
|
- Multicast DNS remote URL (https://github.com/JetpackDuba/Gitnuro/issues/19) with this
|
||||||
workaround (https://github.com/JetpackDuba/Gitnuro/issues/19#issuecomment-1374431720).
|
workaround (https://github.com/JetpackDuba/Gitnuro/issues/19#issuecomment-1374431720).
|
||||||
- Self signed server certificate (https://github.com/JetpackDuba/Gitnuro/issues/48)
|
- Self signed server certificate (https://github.com/JetpackDuba/Gitnuro/issues/48)
|
||||||
|
@ -11,10 +11,10 @@ name = "gitnuro_rs"
|
|||||||
uniffi = { version = "0.25.0" }
|
uniffi = { version = "0.25.0" }
|
||||||
notify = "6.0.1"
|
notify = "6.0.1"
|
||||||
thiserror = "1.0.43"
|
thiserror = "1.0.43"
|
||||||
libssh-rs = { version = "0.2.2", features = [ "vendored", "vendored-openssl" ] }
|
libssh-rs = { version = "0.2.2", features = ["vendored", "vendored-openssl"] }
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
uniffi = { version = "0.25.0", features = [ "build" ] }
|
uniffi = { version = "0.25.0", features = ["build"] }
|
||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
name = "uniffi-bindgen"
|
name = "uniffi-bindgen"
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
mod ssh;
|
|
||||||
mod watch_directory;
|
|
||||||
|
|
||||||
use watch_directory::{ * };
|
|
||||||
use ssh::{ * };
|
|
||||||
#[allow(unused_imports)] // Needed to map it to the enum in the UDL file
|
#[allow(unused_imports)] // Needed to map it to the enum in the UDL file
|
||||||
use libssh_rs::AuthStatus;
|
use libssh_rs::AuthStatus;
|
||||||
|
|
||||||
|
use ssh::{*};
|
||||||
|
use watch_directory::{*};
|
||||||
|
|
||||||
|
mod ssh;
|
||||||
|
mod watch_directory;
|
||||||
|
|
||||||
uniffi::include_scaffolding!("gitnuro");
|
uniffi::include_scaffolding!("gitnuro");
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
use libssh_rs::{AuthStatus, PollStatus, SshOption};
|
use std::io::Write;
|
||||||
use std::sync::{Arc, RwLock};
|
use std::sync::{Arc, RwLock};
|
||||||
use std::io::{Write};
|
|
||||||
|
use libssh_rs::{AuthStatus, PollStatus, SshOption};
|
||||||
|
|
||||||
const ACCEPTED_SSH_TYPES: &str = "ssh-ed25519,ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,ssh-rsa,rsa-sha2-512,rsa-sha2-256,ssh-dss";
|
const ACCEPTED_SSH_TYPES: &str = "ssh-ed25519,ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,ssh-rsa,rsa-sha2-512,rsa-sha2-256,ssh-dss";
|
||||||
|
|
||||||
@ -63,6 +64,7 @@ pub struct Channel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
unsafe impl Send for Channel {}
|
unsafe impl Send for Channel {}
|
||||||
|
|
||||||
unsafe impl Sync for Channel {}
|
unsafe impl Sync for Channel {}
|
||||||
|
|
||||||
impl Channel {
|
impl Channel {
|
||||||
@ -105,7 +107,7 @@ impl Channel {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn read(&self, is_stderr: bool, len: u64) -> ReadResult {
|
pub fn read(&self, is_stderr: bool, len: u64) -> ReadResult {
|
||||||
let ulen = len as usize;
|
let ulen = len as usize;
|
||||||
|
|
||||||
let channel = self.channel.write().unwrap();
|
let channel = self.channel.write().unwrap();
|
||||||
|
@ -4,6 +4,7 @@ use std::fmt::Debug;
|
|||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
use std::sync::mpsc::{channel, RecvTimeoutError};
|
use std::sync::mpsc::{channel, RecvTimeoutError};
|
||||||
use std::time::{Duration, SystemTime, UNIX_EPOCH};
|
use std::time::{Duration, SystemTime, UNIX_EPOCH};
|
||||||
|
|
||||||
use notify::{Config, Error, ErrorKind, Event, RecommendedWatcher, RecursiveMode, Watcher};
|
use notify::{Config, Error, ErrorKind, Event, RecommendedWatcher, RecursiveMode, Watcher};
|
||||||
|
|
||||||
const MIN_TIME_IN_MS_BETWEEN_REFRESHES: u128 = 500;
|
const MIN_TIME_IN_MS_BETWEEN_REFRESHES: u128 = 500;
|
||||||
|
@ -2,7 +2,8 @@
|
|||||||
|
|
||||||
package com.jetpackduba.gitnuro
|
package com.jetpackduba.gitnuro
|
||||||
|
|
||||||
import androidx.compose.foundation.*
|
import androidx.compose.foundation.ExperimentalFoundationApi
|
||||||
|
import androidx.compose.foundation.background
|
||||||
import androidx.compose.foundation.layout.*
|
import androidx.compose.foundation.layout.*
|
||||||
import androidx.compose.foundation.text.LocalTextContextMenu
|
import androidx.compose.foundation.text.LocalTextContextMenu
|
||||||
import androidx.compose.material.MaterialTheme
|
import androidx.compose.material.MaterialTheme
|
||||||
@ -17,7 +18,9 @@ import androidx.compose.ui.unit.Density
|
|||||||
import androidx.compose.ui.unit.DpSize
|
import androidx.compose.ui.unit.DpSize
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.unit.sp
|
import androidx.compose.ui.unit.sp
|
||||||
import androidx.compose.ui.window.*
|
import androidx.compose.ui.window.Window
|
||||||
|
import androidx.compose.ui.window.application
|
||||||
|
import androidx.compose.ui.window.rememberWindowState
|
||||||
import com.jetpackduba.gitnuro.di.DaggerAppComponent
|
import com.jetpackduba.gitnuro.di.DaggerAppComponent
|
||||||
import com.jetpackduba.gitnuro.extensions.preferenceValue
|
import com.jetpackduba.gitnuro.extensions.preferenceValue
|
||||||
import com.jetpackduba.gitnuro.extensions.toWindowPlacement
|
import com.jetpackduba.gitnuro.extensions.toWindowPlacement
|
||||||
@ -44,7 +47,6 @@ import java.io.File
|
|||||||
import java.net.Authenticator
|
import java.net.Authenticator
|
||||||
import java.net.PasswordAuthentication
|
import java.net.PasswordAuthentication
|
||||||
import java.nio.file.Paths
|
import java.nio.file.Paths
|
||||||
import java.util.*
|
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
|
||||||
|
@ -15,6 +15,7 @@ private const val KEY_LENGTH = 16
|
|||||||
class CredentialsCacheRepository @Inject constructor() {
|
class CredentialsCacheRepository @Inject constructor() {
|
||||||
private val credentialsCached = mutableListOf<CredentialsType>()
|
private val credentialsCached = mutableListOf<CredentialsType>()
|
||||||
private val credentialsLock = Mutex(false)
|
private val credentialsLock = Mutex(false)
|
||||||
|
|
||||||
// having a random key to encrypt the password may help in case of a memory dump attack
|
// having a random key to encrypt the password may help in case of a memory dump attack
|
||||||
private val encryptionKey = getRandomKey()
|
private val encryptionKey = getRandomKey()
|
||||||
|
|
||||||
|
@ -19,7 +19,7 @@ class GSessionManager @Inject constructor(
|
|||||||
|
|
||||||
class MySessionFactory @Inject constructor(
|
class MySessionFactory @Inject constructor(
|
||||||
private val sessionProvider: Provider<SshRemoteSession>
|
private val sessionProvider: Provider<SshRemoteSession>
|
||||||
) : SshSessionFactory(), CredentialsCache {
|
) : SshSessionFactory(), CredentialsCache {
|
||||||
override fun getSession(
|
override fun getSession(
|
||||||
uri: URIish,
|
uri: URIish,
|
||||||
credentialsProvider: CredentialsProvider?,
|
credentialsProvider: CredentialsProvider?,
|
||||||
|
@ -11,9 +11,7 @@ import org.eclipse.jgit.api.Git
|
|||||||
import org.eclipse.jgit.internal.JGitText
|
import org.eclipse.jgit.internal.JGitText
|
||||||
import org.eclipse.jgit.lib.Config
|
import org.eclipse.jgit.lib.Config
|
||||||
import org.eclipse.jgit.transport.CredentialItem
|
import org.eclipse.jgit.transport.CredentialItem
|
||||||
import org.eclipse.jgit.transport.CredentialItem.Password
|
import org.eclipse.jgit.transport.CredentialItem.*
|
||||||
import org.eclipse.jgit.transport.CredentialItem.Username
|
|
||||||
import org.eclipse.jgit.transport.CredentialItem.YesNoType
|
|
||||||
import org.eclipse.jgit.transport.CredentialsProvider
|
import org.eclipse.jgit.transport.CredentialsProvider
|
||||||
import org.eclipse.jgit.transport.URIish
|
import org.eclipse.jgit.transport.URIish
|
||||||
import java.io.*
|
import java.io.*
|
||||||
|
@ -1,7 +1,5 @@
|
|||||||
package com.jetpackduba.gitnuro.di
|
package com.jetpackduba.gitnuro.di
|
||||||
|
|
||||||
import com.jetpackduba.gitnuro.di.modules.NetworkModule
|
|
||||||
import com.jetpackduba.gitnuro.di.modules.ShellModule
|
|
||||||
import com.jetpackduba.gitnuro.di.modules.TabModule
|
import com.jetpackduba.gitnuro.di.modules.TabModule
|
||||||
import com.jetpackduba.gitnuro.ui.components.TabInformation
|
import com.jetpackduba.gitnuro.ui.components.TabInformation
|
||||||
import dagger.Component
|
import dagger.Component
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
package com.jetpackduba.gitnuro.exceptions
|
package com.jetpackduba.gitnuro.exceptions
|
||||||
|
|
||||||
class FetchException(msg: String): GitnuroException(msg)
|
class FetchException(msg: String) : GitnuroException(msg)
|
@ -1,7 +1,10 @@
|
|||||||
package com.jetpackduba.gitnuro.extensions
|
package com.jetpackduba.gitnuro.extensions
|
||||||
|
|
||||||
import androidx.compose.foundation.*
|
import androidx.compose.foundation.*
|
||||||
import androidx.compose.foundation.gestures.*
|
import androidx.compose.foundation.gestures.awaitEachGesture
|
||||||
|
import androidx.compose.foundation.gestures.awaitFirstDown
|
||||||
|
import androidx.compose.foundation.gestures.detectTapGestures
|
||||||
|
import androidx.compose.foundation.gestures.waitForUpOrCancellation
|
||||||
import androidx.compose.foundation.interaction.MutableInteractionSource
|
import androidx.compose.foundation.interaction.MutableInteractionSource
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
@ -95,17 +98,17 @@ fun Modifier.onDoubleClick(
|
|||||||
@Composable
|
@Composable
|
||||||
fun Modifier.onMiddleMouseButtonClick(key: Any = Unit, key2: Any = Unit, onClick: () -> Unit) =
|
fun Modifier.onMiddleMouseButtonClick(key: Any = Unit, key2: Any = Unit, onClick: () -> Unit) =
|
||||||
this.pointerInput(key, key2) {
|
this.pointerInput(key, key2) {
|
||||||
while (true) {
|
while (true) {
|
||||||
val lastMouseEvent = awaitPointerEventScope { awaitFirstDownEvent() }
|
val lastMouseEvent = awaitPointerEventScope { awaitFirstDownEvent() }
|
||||||
val mouseEvent = lastMouseEvent.awtEventOrNull
|
val mouseEvent = lastMouseEvent.awtEventOrNull
|
||||||
|
|
||||||
if (mouseEvent != null) {
|
if (mouseEvent != null) {
|
||||||
if (lastMouseEvent.button.isTertiary) {
|
if (lastMouseEvent.button.isTertiary) {
|
||||||
onClick()
|
onClick()
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun Modifier.hoverBackground(): Modifier {
|
private fun Modifier.hoverBackground(): Modifier {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
package com.jetpackduba.gitnuro.git
|
package com.jetpackduba.gitnuro.git
|
||||||
|
|
||||||
import com.jetpackduba.gitnuro.managers.TempFilesManager
|
|
||||||
import com.jetpackduba.gitnuro.extensions.fileName
|
import com.jetpackduba.gitnuro.extensions.fileName
|
||||||
|
import com.jetpackduba.gitnuro.managers.TempFilesManager
|
||||||
import org.eclipse.jgit.diff.ContentSource
|
import org.eclipse.jgit.diff.ContentSource
|
||||||
import org.eclipse.jgit.diff.DiffEntry
|
import org.eclipse.jgit.diff.DiffEntry
|
||||||
import org.eclipse.jgit.diff.RawText
|
import org.eclipse.jgit.diff.RawText
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
package com.jetpackduba.gitnuro.git
|
package com.jetpackduba.gitnuro.git
|
||||||
|
|
||||||
import com.jetpackduba.gitnuro.ui.SelectedItem
|
import com.jetpackduba.gitnuro.ui.SelectedItem
|
||||||
import org.eclipse.jgit.revwalk.RevCommit
|
|
||||||
|
|
||||||
sealed interface TaskEvent {
|
sealed interface TaskEvent {
|
||||||
data class ScrollToGraphItem(val selectedItem: SelectedItem) : TaskEvent
|
data class ScrollToGraphItem(val selectedItem: SelectedItem) : TaskEvent
|
||||||
|
@ -2,7 +2,6 @@ package com.jetpackduba.gitnuro.git.branches
|
|||||||
|
|
||||||
import com.jetpackduba.gitnuro.extensions.simpleName
|
import com.jetpackduba.gitnuro.extensions.simpleName
|
||||||
import org.eclipse.jgit.api.Git
|
import org.eclipse.jgit.api.Git
|
||||||
import org.eclipse.jgit.lib.Config
|
|
||||||
import org.eclipse.jgit.lib.Ref
|
import org.eclipse.jgit.lib.Ref
|
||||||
import org.eclipse.jgit.lib.Repository
|
import org.eclipse.jgit.lib.Repository
|
||||||
import org.eclipse.jgit.lib.StoredConfig
|
import org.eclipse.jgit.lib.StoredConfig
|
||||||
|
@ -10,7 +10,8 @@ object LocalConfigConstants {
|
|||||||
|
|
||||||
const val DEFAULT_SIGN_OFF_FORMAT_USER = "%user"
|
const val DEFAULT_SIGN_OFF_FORMAT_USER = "%user"
|
||||||
const val DEFAULT_SIGN_OFF_FORMAT_EMAIL = "%email"
|
const val DEFAULT_SIGN_OFF_FORMAT_EMAIL = "%email"
|
||||||
const val DEFAULT_SIGN_OFF_FORMAT = "Signed-off-by: $DEFAULT_SIGN_OFF_FORMAT_USER <$DEFAULT_SIGN_OFF_FORMAT_EMAIL>"
|
const val DEFAULT_SIGN_OFF_FORMAT =
|
||||||
|
"Signed-off-by: $DEFAULT_SIGN_OFF_FORMAT_USER <$DEFAULT_SIGN_OFF_FORMAT_EMAIL>"
|
||||||
const val DEFAULT_SIGN_OFF_ENABLED = false
|
const val DEFAULT_SIGN_OFF_ENABLED = false
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -7,7 +7,7 @@ import org.eclipse.jgit.submodule.SubmoduleStatus
|
|||||||
sealed class DiffResult(
|
sealed class DiffResult(
|
||||||
val diffEntry: DiffEntry,
|
val diffEntry: DiffEntry,
|
||||||
) {
|
) {
|
||||||
sealed class TextDiff(diffEntry: DiffEntry): DiffResult(diffEntry)
|
sealed class TextDiff(diffEntry: DiffEntry) : DiffResult(diffEntry)
|
||||||
|
|
||||||
class Text(
|
class Text(
|
||||||
diffEntry: DiffEntry,
|
diffEntry: DiffEntry,
|
||||||
|
@ -54,7 +54,7 @@ class GetLogUseCase @Inject constructor() {
|
|||||||
private fun cachedGraphWalk(repository: Repository): GraphWalk {
|
private fun cachedGraphWalk(repository: Repository): GraphWalk {
|
||||||
val graphWalkCached = this.graphWalkCached
|
val graphWalkCached = this.graphWalkCached
|
||||||
|
|
||||||
return if(graphWalkCached != null) {
|
return if (graphWalkCached != null) {
|
||||||
graphWalkCached
|
graphWalkCached
|
||||||
} else {
|
} else {
|
||||||
val newGraphWalk = GraphWalk(repository)
|
val newGraphWalk = GraphWalk(repository)
|
||||||
|
@ -23,6 +23,7 @@ class GetRebaseInteractiveStateUseCase @Inject constructor(
|
|||||||
|
|
||||||
RebaseInteractiveState.ProcessingCommits(commitId)
|
RebaseInteractiveState.ProcessingCommits(commitId)
|
||||||
}
|
}
|
||||||
|
|
||||||
else -> RebaseInteractiveState.AwaitingInteraction
|
else -> RebaseInteractiveState.AwaitingInteraction
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
package com.jetpackduba.gitnuro.git.remote_operations
|
package com.jetpackduba.gitnuro.git.remote_operations
|
||||||
|
|
||||||
import com.jetpackduba.gitnuro.exceptions.FetchException
|
import com.jetpackduba.gitnuro.exceptions.FetchException
|
||||||
import com.jetpackduba.gitnuro.exceptions.GitnuroException
|
|
||||||
import com.jetpackduba.gitnuro.logging.printError
|
import com.jetpackduba.gitnuro.logging.printError
|
||||||
import kotlinx.coroutines.CancellationException
|
import kotlinx.coroutines.CancellationException
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
@ -48,13 +47,13 @@ class FetchAllBranchesUseCase @Inject constructor(
|
|||||||
} catch (ex: Exception) {
|
} catch (ex: Exception) {
|
||||||
printError(TAG, "Fetch failed for remote ${remote.name} with error ${ex.message}", ex)
|
printError(TAG, "Fetch failed for remote ${remote.name} with error ${ex.message}", ex)
|
||||||
|
|
||||||
if(ex.message != "Cancelled authentication" && ex !is CancellationException) {
|
if (ex.message != "Cancelled authentication" && ex !is CancellationException) {
|
||||||
errors.add(remote to ex)
|
errors.add(remote to ex)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(errors.isNotEmpty()) {
|
if (errors.isNotEmpty()) {
|
||||||
val errorText = errors.joinToString("\n") {
|
val errorText = errors.joinToString("\n") {
|
||||||
"Fetch failed for remote ${it.first.name}: ${it.second.message}"
|
"Fetch failed for remote ${it.first.name}: ${it.second.message}"
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,7 @@ class HandleTransportUseCase @Inject constructor(
|
|||||||
suspend operator fun invoke(git: Git?, block: suspend CredentialsHandler.() -> Unit) {
|
suspend operator fun invoke(git: Git?, block: suspend CredentialsHandler.() -> Unit) {
|
||||||
var cache: CredentialsCache? = null
|
var cache: CredentialsCache? = null
|
||||||
|
|
||||||
val credentialsHandler = object: CredentialsHandler {
|
val credentialsHandler = object : CredentialsHandler {
|
||||||
override fun handleTransport(transport: Transport?) {
|
override fun handleTransport(transport: Transport?) {
|
||||||
cache = when (transport) {
|
cache = when (transport) {
|
||||||
is SshTransport -> {
|
is SshTransport -> {
|
||||||
@ -41,6 +41,7 @@ class HandleTransportUseCase @Inject constructor(
|
|||||||
cache?.cacheCredentialsIfNeeded()
|
cache?.cacheCredentialsIfNeeded()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
interface CredentialsCache {
|
interface CredentialsCache {
|
||||||
suspend fun cacheCredentialsIfNeeded()
|
suspend fun cacheCredentialsIfNeeded()
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,6 @@ import com.jetpackduba.gitnuro.preferences.AppSettings
|
|||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import org.eclipse.jgit.api.Git
|
import org.eclipse.jgit.api.Git
|
||||||
import org.eclipse.jgit.api.PullResult
|
|
||||||
import org.eclipse.jgit.api.RebaseResult
|
import org.eclipse.jgit.api.RebaseResult
|
||||||
import org.eclipse.jgit.transport.CredentialsProvider
|
import org.eclipse.jgit.transport.CredentialsProvider
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
@ -23,7 +22,7 @@ class PullBranchUseCase @Inject constructor(
|
|||||||
handleTransportUseCase(git) {
|
handleTransportUseCase(git) {
|
||||||
val pullResult = git
|
val pullResult = git
|
||||||
.pull()
|
.pull()
|
||||||
.setTransportConfigCallback {this.handleTransport(it) }
|
.setTransportConfigCallback { this.handleTransport(it) }
|
||||||
.setRebase(pullWithRebase)
|
.setRebase(pullWithRebase)
|
||||||
.setCredentialsProvider(CredentialsProvider.getDefault())
|
.setCredentialsProvider(CredentialsProvider.getDefault())
|
||||||
.call()
|
.call()
|
||||||
|
@ -18,7 +18,8 @@ class OpenSubmoduleRepositoryUseCase @Inject constructor(
|
|||||||
|
|
||||||
val repository = openRepositoryUseCase(parent)
|
val repository = openRepositoryUseCase(parent)
|
||||||
|
|
||||||
val submoduleRelativePath = directory.absolutePath.removePrefix("${repository.directory.parent}$systemSeparator")
|
val submoduleRelativePath =
|
||||||
|
directory.absolutePath.removePrefix("${repository.directory.parent}$systemSeparator")
|
||||||
|
|
||||||
return@withContext SubmoduleWalk.getSubmoduleRepository(repository, submoduleRelativePath)
|
return@withContext SubmoduleWalk.getSubmoduleRepository(repository, submoduleRelativePath)
|
||||||
?: throw InvalidDirectoryException("Invalid submodule directory. Check if the submodule has been initialized before trying to open it.")
|
?: throw InvalidDirectoryException("Invalid submodule directory. Check if the submodule has been initialized before trying to open it.")
|
||||||
|
@ -3,7 +3,6 @@ package com.jetpackduba.gitnuro.git.submodules
|
|||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import org.eclipse.jgit.api.Git
|
import org.eclipse.jgit.api.Git
|
||||||
import org.eclipse.jgit.lib.Config
|
|
||||||
import org.eclipse.jgit.storage.file.FileBasedConfig
|
import org.eclipse.jgit.storage.file.FileBasedConfig
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
@ -25,7 +25,7 @@ class DoCommitUseCase @Inject constructor(
|
|||||||
): RevCommit = withContext(Dispatchers.IO) {
|
): RevCommit = withContext(Dispatchers.IO) {
|
||||||
val signOffConfig = loadSignOffConfigUseCase(git.repository)
|
val signOffConfig = loadSignOffConfigUseCase(git.repository)
|
||||||
|
|
||||||
val finalMessage = if(signOffConfig.isEnabled) {
|
val finalMessage = if (signOffConfig.isEnabled) {
|
||||||
val authorToSign = author ?: loadAuthorUseCase(git).toPersonIdent()
|
val authorToSign = author ?: loadAuthorUseCase(git).toPersonIdent()
|
||||||
|
|
||||||
val signature = signOffConfig.format
|
val signature = signOffConfig.format
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
package com.jetpackduba.gitnuro.git.workspace
|
package com.jetpackduba.gitnuro.git.workspace
|
||||||
|
|
||||||
import com.jetpackduba.gitnuro.extensions.lineDelimiter
|
|
||||||
import com.jetpackduba.gitnuro.git.diff.Hunk
|
import com.jetpackduba.gitnuro.git.diff.Hunk
|
||||||
import com.jetpackduba.gitnuro.git.diff.LineType
|
import com.jetpackduba.gitnuro.git.diff.LineType
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
package com.jetpackduba.gitnuro.managers
|
package com.jetpackduba.gitnuro.managers
|
||||||
|
|
||||||
|
import com.jetpackduba.gitnuro.logging.printError
|
||||||
import com.jetpackduba.gitnuro.system.OS
|
import com.jetpackduba.gitnuro.system.OS
|
||||||
import com.jetpackduba.gitnuro.system.currentOs
|
import com.jetpackduba.gitnuro.system.currentOs
|
||||||
import com.jetpackduba.gitnuro.logging.printError
|
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
package com.jetpackduba.gitnuro.managers
|
package com.jetpackduba.gitnuro.managers
|
||||||
|
|
||||||
import com.jetpackduba.gitnuro.di.TabScope
|
|
||||||
import com.jetpackduba.gitnuro.extensions.openDirectory
|
import com.jetpackduba.gitnuro.extensions.openDirectory
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
@ -1,9 +1,5 @@
|
|||||||
package com.jetpackduba.gitnuro.models
|
package com.jetpackduba.gitnuro.models
|
||||||
|
|
||||||
import kotlinx.coroutines.flow.SharedFlow
|
|
||||||
import kotlinx.coroutines.withContext
|
|
||||||
import org.eclipse.jgit.lib.ProgressMonitor
|
|
||||||
|
|
||||||
sealed interface ProgressMonitorInfo {
|
sealed interface ProgressMonitorInfo {
|
||||||
object Loading : ProgressMonitorInfo
|
object Loading : ProgressMonitorInfo
|
||||||
|
|
||||||
|
@ -40,7 +40,12 @@ class OpenFilePickerUseCase @Inject constructor(
|
|||||||
|
|
||||||
if (isZenityInstalled) {
|
if (isZenityInstalled) {
|
||||||
val command = when (pickerType) {
|
val command = when (pickerType) {
|
||||||
PickerType.FILES, PickerType.FILES_AND_DIRECTORIES -> listOf("zenity", "--file-selection", "--title=Open")
|
PickerType.FILES, PickerType.FILES_AND_DIRECTORIES -> listOf(
|
||||||
|
"zenity",
|
||||||
|
"--file-selection",
|
||||||
|
"--title=Open"
|
||||||
|
)
|
||||||
|
|
||||||
PickerType.DIRECTORIES -> listOf("zenity", "--file-selection", "--title=Open", "--directory")
|
PickerType.DIRECTORIES -> listOf("zenity", "--file-selection", "--title=Open", "--directory")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,6 +19,9 @@ class MacTerminalProvider @Inject constructor(
|
|||||||
|
|
||||||
override fun startTerminal(terminalEmulator: TerminalEmulator, repositoryPath: String) {
|
override fun startTerminal(terminalEmulator: TerminalEmulator, repositoryPath: String) {
|
||||||
// TODO Check if passing the path as argument is required for other terminal emulators
|
// TODO Check if passing the path as argument is required for other terminal emulators
|
||||||
shellManager.runCommandInPath(listOf("open", "-a", terminalEmulator.path, "-n", "--args", repositoryPath), repositoryPath)
|
shellManager.runCommandInPath(
|
||||||
|
listOf("open", "-a", terminalEmulator.path, "-n", "--args", repositoryPath),
|
||||||
|
repositoryPath
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,7 +1,6 @@
|
|||||||
package com.jetpackduba.gitnuro.terminal
|
package com.jetpackduba.gitnuro.terminal
|
||||||
|
|
||||||
import com.jetpackduba.gitnuro.managers.IShellManager
|
import com.jetpackduba.gitnuro.managers.IShellManager
|
||||||
import java.io.File
|
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class WindowsTerminalProvider @Inject constructor(
|
class WindowsTerminalProvider @Inject constructor(
|
||||||
|
@ -27,7 +27,9 @@ import androidx.compose.ui.input.key.type
|
|||||||
import androidx.compose.ui.res.painterResource
|
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.AppIcons
|
||||||
import com.jetpackduba.gitnuro.extensions.*
|
import com.jetpackduba.gitnuro.extensions.handOnHover
|
||||||
|
import com.jetpackduba.gitnuro.extensions.lineAt
|
||||||
|
import com.jetpackduba.gitnuro.extensions.toStringWithSpaces
|
||||||
import com.jetpackduba.gitnuro.keybindings.KeybindingOption
|
import com.jetpackduba.gitnuro.keybindings.KeybindingOption
|
||||||
import com.jetpackduba.gitnuro.keybindings.matchesBinding
|
import com.jetpackduba.gitnuro.keybindings.matchesBinding
|
||||||
import com.jetpackduba.gitnuro.theme.notoSansMonoFontFamily
|
import com.jetpackduba.gitnuro.theme.notoSansMonoFontFamily
|
||||||
|
@ -1,11 +1,14 @@
|
|||||||
package com.jetpackduba.gitnuro.ui
|
package com.jetpackduba.gitnuro.ui
|
||||||
|
|
||||||
import androidx.compose.foundation.*
|
import androidx.compose.foundation.ExperimentalFoundationApi
|
||||||
|
import androidx.compose.foundation.ScrollState
|
||||||
|
import androidx.compose.foundation.background
|
||||||
import androidx.compose.foundation.layout.*
|
import androidx.compose.foundation.layout.*
|
||||||
import androidx.compose.foundation.lazy.LazyListState
|
import androidx.compose.foundation.lazy.LazyListState
|
||||||
import androidx.compose.foundation.lazy.items
|
import androidx.compose.foundation.lazy.items
|
||||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||||
import androidx.compose.foundation.text.selection.SelectionContainer
|
import androidx.compose.foundation.text.selection.SelectionContainer
|
||||||
|
import androidx.compose.foundation.verticalScroll
|
||||||
import androidx.compose.material.*
|
import androidx.compose.material.*
|
||||||
import androidx.compose.runtime.*
|
import androidx.compose.runtime.*
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
@ -23,7 +26,9 @@ import androidx.compose.ui.unit.dp
|
|||||||
import com.jetpackduba.gitnuro.AppIcons
|
import com.jetpackduba.gitnuro.AppIcons
|
||||||
import com.jetpackduba.gitnuro.extensions.*
|
import com.jetpackduba.gitnuro.extensions.*
|
||||||
import com.jetpackduba.gitnuro.git.DiffEntryType
|
import com.jetpackduba.gitnuro.git.DiffEntryType
|
||||||
import com.jetpackduba.gitnuro.theme.*
|
import com.jetpackduba.gitnuro.theme.backgroundSelected
|
||||||
|
import com.jetpackduba.gitnuro.theme.onBackgroundSecondary
|
||||||
|
import com.jetpackduba.gitnuro.theme.tertiarySurface
|
||||||
import com.jetpackduba.gitnuro.ui.components.*
|
import com.jetpackduba.gitnuro.ui.components.*
|
||||||
import com.jetpackduba.gitnuro.ui.context_menu.ContextMenu
|
import com.jetpackduba.gitnuro.ui.context_menu.ContextMenu
|
||||||
import com.jetpackduba.gitnuro.ui.context_menu.committedChangesEntriesContextMenuItems
|
import com.jetpackduba.gitnuro.ui.context_menu.committedChangesEntriesContextMenuItems
|
||||||
|
@ -21,10 +21,10 @@ import com.jetpackduba.gitnuro.ui.dropdowns.DropDownOption
|
|||||||
@Composable
|
@Composable
|
||||||
fun FilterDropdownPreview() {
|
fun FilterDropdownPreview() {
|
||||||
val items = listOf(
|
val items = listOf(
|
||||||
DropDownOption("","Test1"),
|
DropDownOption("", "Test1"),
|
||||||
DropDownOption("","Test2"),
|
DropDownOption("", "Test2"),
|
||||||
DropDownOption("","Test3"),
|
DropDownOption("", "Test3"),
|
||||||
DropDownOption("","Test4"),
|
DropDownOption("", "Test4"),
|
||||||
)
|
)
|
||||||
|
|
||||||
FilterDropdown(
|
FilterDropdown(
|
||||||
@ -44,7 +44,8 @@ fun <T> FilterDropdown(
|
|||||||
var showDropdown by remember { mutableStateOf(false) }
|
var showDropdown by remember { mutableStateOf(false) }
|
||||||
var filter by remember { mutableStateOf("") }
|
var filter by remember { mutableStateOf("") }
|
||||||
val filterFocusRequester = remember { FocusRequester() }
|
val filterFocusRequester = remember { FocusRequester() }
|
||||||
val filteredDropdownItems = remember(filter, dropdownItems) { dropdownItems.filter { it.optionName.lowercaseContains(filter) } }
|
val filteredDropdownItems =
|
||||||
|
remember(filter, dropdownItems) { dropdownItems.filter { it.optionName.lowercaseContains(filter) } }
|
||||||
|
|
||||||
Box {
|
Box {
|
||||||
OutlinedButton(
|
OutlinedButton(
|
||||||
|
@ -8,7 +8,10 @@ import androidx.compose.foundation.lazy.LazyRow
|
|||||||
import androidx.compose.foundation.lazy.itemsIndexed
|
import androidx.compose.foundation.lazy.itemsIndexed
|
||||||
import androidx.compose.foundation.lazy.rememberLazyListState
|
import androidx.compose.foundation.lazy.rememberLazyListState
|
||||||
import androidx.compose.foundation.v2.maxScrollOffset
|
import androidx.compose.foundation.v2.maxScrollOffset
|
||||||
import androidx.compose.material.*
|
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.Icons
|
||||||
import androidx.compose.material.icons.filled.Add
|
import androidx.compose.material.icons.filled.Add
|
||||||
import androidx.compose.runtime.*
|
import androidx.compose.runtime.*
|
||||||
@ -19,7 +22,8 @@ import androidx.compose.ui.res.painterResource
|
|||||||
import androidx.compose.ui.text.style.TextOverflow
|
import androidx.compose.ui.text.style.TextOverflow
|
||||||
import androidx.compose.ui.unit.Dp
|
import androidx.compose.ui.unit.Dp
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import com.jetpackduba.gitnuro.*
|
import com.jetpackduba.gitnuro.AppIcons
|
||||||
|
import com.jetpackduba.gitnuro.LocalTabScope
|
||||||
import com.jetpackduba.gitnuro.di.AppComponent
|
import com.jetpackduba.gitnuro.di.AppComponent
|
||||||
import com.jetpackduba.gitnuro.di.DaggerTabComponent
|
import com.jetpackduba.gitnuro.di.DaggerTabComponent
|
||||||
import com.jetpackduba.gitnuro.di.TabComponent
|
import com.jetpackduba.gitnuro.di.TabComponent
|
||||||
|
@ -2,7 +2,8 @@
|
|||||||
|
|
||||||
package com.jetpackduba.gitnuro.ui.components
|
package com.jetpackduba.gitnuro.ui.components
|
||||||
|
|
||||||
import androidx.compose.foundation.*
|
import androidx.compose.foundation.ExperimentalFoundationApi
|
||||||
|
import androidx.compose.foundation.clickable
|
||||||
import androidx.compose.foundation.layout.*
|
import androidx.compose.foundation.layout.*
|
||||||
import androidx.compose.material.Icon
|
import androidx.compose.material.Icon
|
||||||
import androidx.compose.material.MaterialTheme
|
import androidx.compose.material.MaterialTheme
|
||||||
|
@ -4,7 +4,6 @@ import androidx.compose.foundation.hoverable
|
|||||||
import androidx.compose.foundation.interaction.MutableInteractionSource
|
import androidx.compose.foundation.interaction.MutableInteractionSource
|
||||||
import androidx.compose.foundation.interaction.collectIsHoveredAsState
|
import androidx.compose.foundation.interaction.collectIsHoveredAsState
|
||||||
import androidx.compose.material.MaterialTheme
|
import androidx.compose.material.MaterialTheme
|
||||||
import androidx.compose.material.Text
|
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
|
@ -61,7 +61,7 @@ fun branchContextMenuItems(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
if(isLocal) {
|
if (isLocal) {
|
||||||
add(
|
add(
|
||||||
ContextMenuElement.ContextTextEntry(
|
ContextMenuElement.ContextTextEntry(
|
||||||
label = "Change default upstream branch",
|
label = "Change default upstream branch",
|
||||||
|
@ -24,7 +24,8 @@ import androidx.compose.ui.graphics.painter.Painter
|
|||||||
import androidx.compose.ui.input.InputMode
|
import androidx.compose.ui.input.InputMode
|
||||||
import androidx.compose.ui.input.InputModeManager
|
import androidx.compose.ui.input.InputModeManager
|
||||||
import androidx.compose.ui.input.key.*
|
import androidx.compose.ui.input.key.*
|
||||||
import androidx.compose.ui.input.pointer.*
|
import androidx.compose.ui.input.pointer.isSecondary
|
||||||
|
import androidx.compose.ui.input.pointer.pointerInput
|
||||||
import androidx.compose.ui.layout.onGloballyPositioned
|
import androidx.compose.ui.layout.onGloballyPositioned
|
||||||
import androidx.compose.ui.platform.LocalFocusManager
|
import androidx.compose.ui.platform.LocalFocusManager
|
||||||
import androidx.compose.ui.platform.LocalInputModeManager
|
import androidx.compose.ui.platform.LocalInputModeManager
|
||||||
|
@ -56,7 +56,7 @@ fun submoduleContextMenuItems(
|
|||||||
// )
|
// )
|
||||||
}
|
}
|
||||||
|
|
||||||
if(isNotEmpty()) {
|
if (isNotEmpty()) {
|
||||||
add(
|
add(
|
||||||
ContextMenuElement.ContextSeparator,
|
ContextMenuElement.ContextSeparator,
|
||||||
)
|
)
|
||||||
|
@ -148,7 +148,7 @@ fun AddSubmodulesDialog(
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
AnimatedVisibility (error.isNotBlank()) {
|
AnimatedVisibility(error.isNotBlank()) {
|
||||||
Box(
|
Box(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
|
@ -7,7 +7,9 @@ import androidx.compose.foundation.layout.*
|
|||||||
import androidx.compose.foundation.onClick
|
import androidx.compose.foundation.onClick
|
||||||
import androidx.compose.foundation.shape.CircleShape
|
import androidx.compose.foundation.shape.CircleShape
|
||||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||||
import androidx.compose.material.*
|
import androidx.compose.material.Icon
|
||||||
|
import androidx.compose.material.MaterialTheme
|
||||||
|
import androidx.compose.material.Text
|
||||||
import androidx.compose.runtime.*
|
import androidx.compose.runtime.*
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
|
@ -5,7 +5,10 @@ import androidx.compose.foundation.layout.*
|
|||||||
import androidx.compose.material.Icon
|
import androidx.compose.material.Icon
|
||||||
import androidx.compose.material.MaterialTheme
|
import androidx.compose.material.MaterialTheme
|
||||||
import androidx.compose.material.Text
|
import androidx.compose.material.Text
|
||||||
import androidx.compose.runtime.*
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
|
import androidx.compose.runtime.collectAsState
|
||||||
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
|
@ -22,7 +22,7 @@ class UpdatesRepository @Inject constructor(
|
|||||||
fun hasUpdatesFlow() = flow {
|
fun hasUpdatesFlow() = flow {
|
||||||
val latestReleaseJson = updatesWebService.release(AppConstants.VERSION_CHECK_URL)
|
val latestReleaseJson = updatesWebService.release(AppConstants.VERSION_CHECK_URL)
|
||||||
|
|
||||||
while(coroutineContext.isActive) {
|
while (coroutineContext.isActive) {
|
||||||
val update = updateJson.decodeFromString<Update?>(latestReleaseJson)
|
val update = updateJson.decodeFromString<Update?>(latestReleaseJson)
|
||||||
|
|
||||||
if (update != null && update.appCode > AppConstants.APP_VERSION_CODE) {
|
if (update != null && update.appCode > AppConstants.APP_VERSION_CODE) {
|
||||||
|
@ -86,7 +86,7 @@ class CommitChangesViewModel @Inject constructor(
|
|||||||
if (untrackedFilesCommit != null) {
|
if (untrackedFilesCommit != null) {
|
||||||
val untrackedFilesChanges = getCommitDiffEntriesUseCase(git, untrackedFilesCommit)
|
val untrackedFilesChanges = getCommitDiffEntriesUseCase(git, untrackedFilesCommit)
|
||||||
|
|
||||||
if(untrackedFilesChanges.all { it.changeType == DiffEntry.ChangeType.ADD }) { // All files should be new
|
if (untrackedFilesChanges.all { it.changeType == DiffEntry.ChangeType.ADD }) { // All files should be new
|
||||||
changes.addAll(untrackedFilesChanges)
|
changes.addAll(untrackedFilesChanges)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -54,22 +54,22 @@ class DiffViewModel @Inject constructor(
|
|||||||
diffTypeFlow
|
diffTypeFlow
|
||||||
.drop(1) // Ignore the first time the flow triggers, we only care about updates
|
.drop(1) // Ignore the first time the flow triggers, we only care about updates
|
||||||
.collect {
|
.collect {
|
||||||
val diffEntryType = this@DiffViewModel.diffEntryType
|
val diffEntryType = this@DiffViewModel.diffEntryType
|
||||||
if (diffEntryType != null) {
|
if (diffEntryType != null) {
|
||||||
updateDiff(diffEntryType)
|
updateDiff(diffEntryType)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
tabScope.launch {
|
tabScope.launch {
|
||||||
isDisplayFullFile
|
isDisplayFullFile
|
||||||
.drop(1) // Ignore the first time the flow triggers, we only care about updates
|
.drop(1) // Ignore the first time the flow triggers, we only care about updates
|
||||||
.collect {
|
.collect {
|
||||||
val diffEntryType = this@DiffViewModel.diffEntryType
|
val diffEntryType = this@DiffViewModel.diffEntryType
|
||||||
if (diffEntryType != null) {
|
if (diffEntryType != null) {
|
||||||
updateDiff(diffEntryType)
|
updateDiff(diffEntryType)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
tabScope.launch {
|
tabScope.launch {
|
||||||
|
@ -108,7 +108,11 @@ class HistoryViewModel @Inject constructor(
|
|||||||
|
|
||||||
val diffEntryType = DiffEntryType.CommitDiff(diffEntry)
|
val diffEntryType = DiffEntryType.CommitDiff(diffEntry)
|
||||||
|
|
||||||
val diffResult = formatDiffUseCase(git, diffEntryType, false) // TODO This hardcoded false should be changed when the UI is implemented
|
val diffResult = formatDiffUseCase(
|
||||||
|
git,
|
||||||
|
diffEntryType,
|
||||||
|
false
|
||||||
|
) // TODO This hardcoded false should be changed when the UI is implemented
|
||||||
val textDiffType = settings.textDiffType
|
val textDiffType = settings.textDiffType
|
||||||
|
|
||||||
val formattedDiffResult = if (textDiffType == TextDiffType.SPLIT && diffResult is DiffResult.Text) {
|
val formattedDiffResult = if (textDiffType == TextDiffType.SPLIT && diffResult is DiffResult.Text) {
|
||||||
|
@ -71,7 +71,7 @@ class LogViewModel @Inject constructor(
|
|||||||
private val appSettings: AppSettings,
|
private val appSettings: AppSettings,
|
||||||
private val tabScope: CoroutineScope,
|
private val tabScope: CoroutineScope,
|
||||||
private val sharedStashViewModel: SharedStashViewModel,
|
private val sharedStashViewModel: SharedStashViewModel,
|
||||||
) : ViewModel, ISharedStashViewModel by sharedStashViewModel {
|
) : ViewModel, ISharedStashViewModel by sharedStashViewModel {
|
||||||
private val _logStatus = MutableStateFlow<LogStatus>(LogStatus.Loading)
|
private val _logStatus = MutableStateFlow<LogStatus>(LogStatus.Loading)
|
||||||
|
|
||||||
val logStatus: StateFlow<LogStatus>
|
val logStatus: StateFlow<LogStatus>
|
||||||
|
@ -140,7 +140,11 @@ class SettingsViewModel @Inject constructor(
|
|||||||
null
|
null
|
||||||
} catch (ex: Exception) {
|
} catch (ex: Exception) {
|
||||||
ex.printStackTrace()
|
ex.printStackTrace()
|
||||||
newErrorNow(ex, "Saving theme failed", "Failed to parse selected theme JSON. Please check if it's valid and try again.")
|
newErrorNow(
|
||||||
|
ex,
|
||||||
|
"Saving theme failed",
|
||||||
|
"Failed to parse selected theme JSON. Please check if it's valid and try again."
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,11 +11,12 @@ import com.jetpackduba.gitnuro.git.RefreshType
|
|||||||
import com.jetpackduba.gitnuro.git.TabState
|
import com.jetpackduba.gitnuro.git.TabState
|
||||||
import com.jetpackduba.gitnuro.git.author.LoadAuthorUseCase
|
import com.jetpackduba.gitnuro.git.author.LoadAuthorUseCase
|
||||||
import com.jetpackduba.gitnuro.git.author.SaveAuthorUseCase
|
import com.jetpackduba.gitnuro.git.author.SaveAuthorUseCase
|
||||||
import com.jetpackduba.gitnuro.git.log.CheckHasPreviousCommitsUseCase
|
|
||||||
import com.jetpackduba.gitnuro.git.log.GetLastCommitMessageUseCase
|
import com.jetpackduba.gitnuro.git.log.GetLastCommitMessageUseCase
|
||||||
import com.jetpackduba.gitnuro.git.log.GetSpecificCommitMessageUseCase
|
import com.jetpackduba.gitnuro.git.log.GetSpecificCommitMessageUseCase
|
||||||
import com.jetpackduba.gitnuro.git.rebase.*
|
import com.jetpackduba.gitnuro.git.rebase.AbortRebaseUseCase
|
||||||
import com.jetpackduba.gitnuro.git.repository.GetRepositoryStateUseCase
|
import com.jetpackduba.gitnuro.git.rebase.ContinueRebaseUseCase
|
||||||
|
import com.jetpackduba.gitnuro.git.rebase.RebaseInteractiveState
|
||||||
|
import com.jetpackduba.gitnuro.git.rebase.SkipRebaseUseCase
|
||||||
import com.jetpackduba.gitnuro.git.repository.ResetRepositoryStateUseCase
|
import com.jetpackduba.gitnuro.git.repository.ResetRepositoryStateUseCase
|
||||||
import com.jetpackduba.gitnuro.git.workspace.*
|
import com.jetpackduba.gitnuro.git.workspace.*
|
||||||
import com.jetpackduba.gitnuro.models.AuthorInfo
|
import com.jetpackduba.gitnuro.models.AuthorInfo
|
||||||
|
@ -201,6 +201,7 @@ class TabViewModel @Inject constructor(
|
|||||||
_showAuthorInfo.value = false
|
_showAuthorInfo.value = false
|
||||||
authorViewModel = null
|
authorViewModel = null
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sometimes external apps can run filesystem multiple operations in a fraction of a second.
|
* Sometimes external apps can run filesystem multiple operations in a fraction of a second.
|
||||||
* To prevent excessive updates, we add a slight delay between updates emission to prevent slowing down
|
* To prevent excessive updates, we add a slight delay between updates emission to prevent slowing down
|
||||||
|
@ -24,7 +24,7 @@ class TabViewModelsHolder @Inject constructor(
|
|||||||
private val changeDefaultUpstreamBranchViewModelProvider: Provider<ChangeDefaultUpstreamBranchViewModel>,
|
private val changeDefaultUpstreamBranchViewModelProvider: Provider<ChangeDefaultUpstreamBranchViewModel>,
|
||||||
private val submoduleDialogViewModelProvider: Provider<SubmoduleDialogViewModel>,
|
private val submoduleDialogViewModelProvider: Provider<SubmoduleDialogViewModel>,
|
||||||
private val signOffDialogViewModelProvider: Provider<SignOffDialogViewModel>,
|
private val signOffDialogViewModelProvider: Provider<SignOffDialogViewModel>,
|
||||||
) {
|
) {
|
||||||
val viewModels = mapOf(
|
val viewModels = mapOf(
|
||||||
logViewModel::class to logViewModel,
|
logViewModel::class to logViewModel,
|
||||||
sidePanelViewModel::class to sidePanelViewModel,
|
sidePanelViewModel::class to sidePanelViewModel,
|
||||||
@ -38,7 +38,7 @@ class TabViewModelsHolder @Inject constructor(
|
|||||||
|
|
||||||
// TODO Call this when required
|
// TODO Call this when required
|
||||||
fun dynamicViewModel(type: KClass<*>): Any {
|
fun dynamicViewModel(type: KClass<*>): Any {
|
||||||
return when(type) {
|
return when (type) {
|
||||||
DiffViewModel::class -> diffViewModelProvider.get()
|
DiffViewModel::class -> diffViewModelProvider.get()
|
||||||
HistoryViewModel::class -> historyViewModelProvider.get()
|
HistoryViewModel::class -> historyViewModelProvider.get()
|
||||||
AuthorViewModel::class -> authorViewModelProvider.get()
|
AuthorViewModel::class -> authorViewModelProvider.get()
|
||||||
|
@ -9,7 +9,6 @@ import com.jetpackduba.gitnuro.viewmodels.SharedStashViewModel
|
|||||||
import dagger.assisted.Assisted
|
import dagger.assisted.Assisted
|
||||||
import dagger.assisted.AssistedInject
|
import dagger.assisted.AssistedInject
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.Job
|
|
||||||
import kotlinx.coroutines.flow.*
|
import kotlinx.coroutines.flow.*
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import org.eclipse.jgit.api.Git
|
import org.eclipse.jgit.api.Git
|
||||||
|
@ -2,8 +2,10 @@ package com.jetpackduba.gitnuro.viewmodels.sidepanel
|
|||||||
|
|
||||||
import com.jetpackduba.gitnuro.git.RefreshType
|
import com.jetpackduba.gitnuro.git.RefreshType
|
||||||
import com.jetpackduba.gitnuro.git.TabState
|
import com.jetpackduba.gitnuro.git.TabState
|
||||||
import dagger.assisted.AssistedInject
|
import kotlinx.coroutines.flow.MutableSharedFlow
|
||||||
import kotlinx.coroutines.flow.*
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
|
import kotlinx.coroutines.flow.asSharedFlow
|
||||||
|
import kotlinx.coroutines.flow.asStateFlow
|
||||||
import org.eclipse.jgit.transport.URIish
|
import org.eclipse.jgit.transport.URIish
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
@ -43,7 +43,11 @@ class SubmodulesViewModel @AssistedInject constructor(
|
|||||||
|
|
||||||
init {
|
init {
|
||||||
tabScope.launch {
|
tabScope.launch {
|
||||||
tabState.refreshFlowFiltered(RefreshType.ALL_DATA, RefreshType.UNCOMMITTED_CHANGES, RefreshType.SUBMODULES) {
|
tabState.refreshFlowFiltered(
|
||||||
|
RefreshType.ALL_DATA,
|
||||||
|
RefreshType.UNCOMMITTED_CHANGES,
|
||||||
|
RefreshType.SUBMODULES
|
||||||
|
) {
|
||||||
refresh(tabState.git)
|
refresh(tabState.git)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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 0h24v24H0z" fill="none"/><path d="M16 1H4c-1.1 0-2 .9-2 2v14h2V3h12V1zm3 4H8c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h11c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2zm0 16H8V7h11v14z"/></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000">
|
||||||
|
<path d="M0 0h24v24H0z" fill="none"/>
|
||||||
|
<path d="M16 1H4c-1.1 0-2 .9-2 2v14h2V3h12V1zm3 4H8c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h11c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2zm0 16H8V7h11v14z"/>
|
||||||
|
</svg>
|
Before Width: | Height: | Size: 284 B After Width: | Height: | Size: 295 B |
@ -1 +1,7 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><path d="M0 0h24v24H0z" fill="none"/><circle cx="6" cy="18" fill="none" r="2"/><circle cx="12" cy="12" fill="none" r=".5"/><circle cx="6" cy="6" fill="none" r="2"/><path d="M9.64 7.64c.23-.5.36-1.05.36-1.64 0-2.21-1.79-4-4-4S2 3.79 2 6s1.79 4 4 4c.59 0 1.14-.13 1.64-.36L10 12l-2.36 2.36C7.14 14.13 6.59 14 6 14c-2.21 0-4 1.79-4 4s1.79 4 4 4 4-1.79 4-4c0-.59-.13-1.14-.36-1.64L12 14l7 7h3v-1L9.64 7.64zM6 8c-1.1 0-2-.89-2-2s.9-2 2-2 2 .89 2 2-.9 2-2 2zm0 12c-1.1 0-2-.89-2-2s.9-2 2-2 2 .89 2 2-.9 2-2 2zm6-7.5c-.28 0-.5-.22-.5-.5s.22-.5.5-.5.5.22.5.5-.22.5-.5.5zM19 3l-6 6 2 2 7-7V3z"/></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000">
|
||||||
|
<path d="M0 0h24v24H0z" fill="none"/>
|
||||||
|
<circle cx="6" cy="18" fill="none" r="2"/>
|
||||||
|
<circle cx="12" cy="12" fill="none" r=".5"/>
|
||||||
|
<circle cx="6" cy="6" fill="none" r="2"/>
|
||||||
|
<path d="M9.64 7.64c.23-.5.36-1.05.36-1.64 0-2.21-1.79-4-4-4S2 3.79 2 6s1.79 4 4 4c.59 0 1.14-.13 1.64-.36L10 12l-2.36 2.36C7.14 14.13 6.59 14 6 14c-2.21 0-4 1.79-4 4s1.79 4 4 4 4-1.79 4-4c0-.59-.13-1.14-.36-1.64L12 14l7 7h3v-1L9.64 7.64zM6 8c-1.1 0-2-.89-2-2s.9-2 2-2 2 .89 2 2-.9 2-2 2zm0 12c-1.1 0-2-.89-2-2s.9-2 2-2 2 .89 2 2-.9 2-2 2zm6-7.5c-.28 0-.5-.22-.5-.5s.22-.5.5-.5.5.22.5.5-.22.5-.5.5zM19 3l-6 6 2 2 7-7V3z"/>
|
||||||
|
</svg>
|
Before Width: | Height: | Size: 694 B After Width: | Height: | Size: 720 B |
@ -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="M8 16h8v2H8zm0-4h8v2H8zm6-10H6c-1.1 0-2 .9-2 2v16c0 1.1.89 2 1.99 2H18c1.1 0 2-.9 2-2V8l-6-6zm4 18H6V4h7v5h5v11z"/></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="M8 16h8v2H8zm0-4h8v2H8zm6-10H6c-1.1 0-2 .9-2 2v16c0 1.1.89 2 1.99 2H18c1.1 0 2-.9 2-2V8l-6-6zm4 18H6V4h7v5h5v11z"/>
|
||||||
|
</svg>
|
Before Width: | Height: | Size: 271 B After Width: | Height: | Size: 282 B |
@ -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 0h24v24H0z" fill="none"/><path d="M18 7l-1.41-1.41-6.34 6.34 1.41 1.41L18 7zm4.24-1.41L11.66 16.17 7.48 12l-1.41 1.41L11.66 19l12-12-1.42-1.41zM.41 13.41L6 19l1.41-1.41L1.83 12 .41 13.41z"/></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000">
|
||||||
|
<path d="M0 0h24v24H0z" fill="none"/>
|
||||||
|
<path d="M18 7l-1.41-1.41-6.34 6.34 1.41 1.41L18 7zm4.24-1.41L11.66 16.17 7.48 12l-1.41 1.41L11.66 19l12-12-1.42-1.41zM.41 13.41L6 19l1.41-1.41L1.83 12 .41 13.41z"/>
|
||||||
|
</svg>
|
Before Width: | Height: | Size: 310 B After Width: | Height: | Size: 321 B |
@ -1 +1,3 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" height="48" viewBox="0 -960 960 960" width="48"><path d="M160-390v-60h640v60H160Zm0-120v-60h640v60H160Z"/></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" height="48" viewBox="0 -960 960 960" width="48">
|
||||||
|
<path d="M160-390v-60h640v60H160Zm0-120v-60h640v60H160Z"/>
|
||||||
|
</svg>
|
Before Width: | Height: | Size: 152 B After Width: | Height: | Size: 158 B |
@ -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 15v2H5v-2h14m2-10H3v2h18V5zm0 4H3v2h18V9zm0 4H3v6h18v-6z"/></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 15v2H5v-2h14m2-10H3v2h18V5zm0 4H3v2h18V9zm0 4H3v6h18v-6z"/>
|
||||||
|
</svg>
|
Before Width: | Height: | Size: 219 B After Width: | Height: | Size: 230 B |
@ -1 +1,5 @@
|
|||||||
<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"><rect fill="none" height="24" width="24"/><path d="M19,3H5C3.9,3,3,3.9,3,5v14c0,1.1,0.9,2,2,2h14c1.1,0,2-0.9,2-2V5C21,3.9,20.1,3,19,3z M5,19V5h6v14H5z M19,19h-6v-7h6V19z M19,10h-6V5h6V10z"/></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">
|
||||||
|
<rect fill="none" height="24" width="24"/>
|
||||||
|
<path d="M19,3H5C3.9,3,3,3.9,3,5v14c0,1.1,0.9,2,2,2h14c1.1,0,2-0.9,2-2V5C21,3.9,20.1,3,19,3z M5,19V5h6v14H5z M19,19h-6v-7h6V19z M19,10h-6V5h6V10z"/>
|
||||||
|
</svg>
|
Before Width: | Height: | Size: 332 B After Width: | Height: | Size: 348 B |
@ -1 +1,7 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><g fill="none"><path d="M0 0h24v24H0V0z"/><path d="M0 0h24v24H0V0z" opacity=".87"/></g><path d="M3 13h2v-2H3v2zm0 4h2v-2H3v2zm0-8h2V7H3v2zm4 4h14v-2H7v2zm0 4h14v-2H7v2zM7 7v2h14V7H7zm-4 6h2v-2H3v2zm0 4h2v-2H3v2zm0-8h2V7H3v2zm4 4h14v-2H7v2zm0 4h14v-2H7v2zM7 7v2h14V7H7z"/></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000">
|
||||||
|
<g fill="none">
|
||||||
|
<path d="M0 0h24v24H0V0z"/>
|
||||||
|
<path d="M0 0h24v24H0V0z" opacity=".87"/>
|
||||||
|
</g>
|
||||||
|
<path d="M3 13h2v-2H3v2zm0 4h2v-2H3v2zm0-8h2V7H3v2zm4 4h14v-2H7v2zm0 4h14v-2H7v2zM7 7v2h14V7H7zm-4 6h2v-2H3v2zm0 4h2v-2H3v2zm0-8h2V7H3v2zm4 4h14v-2H7v2zm0 4h14v-2H7v2zM7 7v2h14V7H7z"/>
|
||||||
|
</svg>
|
Before Width: | Height: | Size: 379 B After Width: | Height: | Size: 413 B |
@ -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="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zM4 12c0-.61.08-1.21.21-1.78L8.99 15v1c0 1.1.9 2 2 2v1.93C7.06 19.43 4 16.07 4 12zm13.89 5.4c-.26-.81-1-1.4-1.9-1.4h-1v-3c0-.55-.45-1-1-1h-6v-2h2c.55 0 1-.45 1-1V7h2c1.1 0 2-.9 2-2v-.41C17.92 5.77 20 8.65 20 12c0 2.08-.81 3.98-2.11 5.4z"/></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="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zM4 12c0-.61.08-1.21.21-1.78L8.99 15v1c0 1.1.9 2 2 2v1.93C7.06 19.43 4 16.07 4 12zm13.89 5.4c-.26-.81-1-1.4-1.9-1.4h-1v-3c0-.55-.45-1-1-1h-6v-2h2c.55 0 1-.45 1-1V7h2c1.1 0 2-.9 2-2v-.41C17.92 5.77 20 8.65 20 12c0 2.08-.81 3.98-2.11 5.4z"/>
|
||||||
|
</svg>
|
Before Width: | Height: | Size: 460 B After Width: | Height: | Size: 471 B |
@ -1 +1,19 @@
|
|||||||
<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"/></g><g><g><g><g><path d="M12,22C6.49,22,2,17.51,2,12S6.49,2,12,2s10,4.04,10,9c0,3.31-2.69,6-6,6h-1.77c-0.28,0-0.5,0.22-0.5,0.5 c0,0.12,0.05,0.23,0.13,0.33c0.41,0.47,0.64,1.06,0.64,1.67C14.5,20.88,13.38,22,12,22z M12,4c-4.41,0-8,3.59-8,8s3.59,8,8,8 c0.28,0,0.5-0.22,0.5-0.5c0-0.16-0.08-0.28-0.14-0.35c-0.41-0.46-0.63-1.05-0.63-1.65c0-1.38,1.12-2.5,2.5-2.5H16 c2.21,0,4-1.79,4-4C20,7.14,16.41,4,12,4z"/><circle cx="6.5" cy="11.5" r="1.5"/><circle cx="9.5" cy="7.5" r="1.5"/><circle cx="14.5" cy="7.5" r="1.5"/><circle cx="17.5" cy="11.5" r="1.5"/></g></g></g></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"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<g>
|
||||||
|
<g>
|
||||||
|
<g>
|
||||||
|
<path d="M12,22C6.49,22,2,17.51,2,12S6.49,2,12,2s10,4.04,10,9c0,3.31-2.69,6-6,6h-1.77c-0.28,0-0.5,0.22-0.5,0.5 c0,0.12,0.05,0.23,0.13,0.33c0.41,0.47,0.64,1.06,0.64,1.67C14.5,20.88,13.38,22,12,22z M12,4c-4.41,0-8,3.59-8,8s3.59,8,8,8 c0.28,0,0.5-0.22,0.5-0.5c0-0.16-0.08-0.28-0.14-0.35c-0.41-0.46-0.63-1.05-0.63-1.65c0-1.38,1.12-2.5,2.5-2.5H16 c2.21,0,4-1.79,4-4C20,7.14,16.41,4,12,4z"/>
|
||||||
|
<circle cx="6.5" cy="11.5" r="1.5"/>
|
||||||
|
<circle cx="9.5" cy="7.5" r="1.5"/>
|
||||||
|
<circle cx="14.5" cy="7.5" r="1.5"/>
|
||||||
|
<circle cx="17.5" cy="11.5" r="1.5"/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
Before Width: | Height: | Size: 748 B After Width: | Height: | Size: 966 B |
@ -1 +1,3 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" height="48" viewBox="0 -960 960 960" width="48"><path d="M80-200v-61h800v61H80Zm38-254-40-22 40-68H40v-45h78l-40-68 40-22 38 67 38-67 40 22-40 68h78v45h-78l40 68-40 22-38-67-38 67Zm324 0-40-24 40-68h-78v-45h78l-40-68 40-22 38 67 38-67 40 22-40 68h78v45h-78l40 68-40 24-38-67-38 67Zm324 0-40-24 40-68h-78v-45h78l-40-68 40-22 38 67 38-67 40 22-40 68h78v45h-78l40 68-40 24-38-67-38 67Z"/></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" height="48" viewBox="0 -960 960 960" width="48">
|
||||||
|
<path d="M80-200v-61h800v61H80Zm38-254-40-22 40-68H40v-45h78l-40-68 40-22 38 67 38-67 40 22-40 68h78v45h-78l40 68-40 22-38-67-38 67Zm324 0-40-24 40-68h-78v-45h78l-40-68 40-22 38 67 38-67 40 22-40 68h78v45h-78l40 68-40 24-38-67-38 67Zm324 0-40-24 40-68h-78v-45h78l-40-68 40-22 38 67 38-67 40 22-40 68h78v45h-78l40 68-40 24-38-67-38 67Z"/>
|
||||||
|
</svg>
|
Before Width: | Height: | Size: 431 B After Width: | Height: | Size: 437 B |
@ -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 0h24v24H0z" fill="none"/><path d="M19 2h-4.18C14.4.84 13.3 0 12 0c-1.3 0-2.4.84-2.82 2H5c-1.1 0-2 .9-2 2v16c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm-7 0c.55 0 1 .45 1 1s-.45 1-1 1-1-.45-1-1 .45-1 1-1zm7 18H5V4h2v3h10V4h2v16z"/></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000">
|
||||||
|
<path d="M0 0h24v24H0z" fill="none"/>
|
||||||
|
<path d="M19 2h-4.18C14.4.84 13.3 0 12 0c-1.3 0-2.4.84-2.82 2H5c-1.1 0-2 .9-2 2v16c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm-7 0c.55 0 1 .45 1 1s-.45 1-1 1-1-.45-1-1 .45-1 1-1zm7 18H5V4h2v3h10V4h2v16z"/>
|
||||||
|
</svg>
|
Before Width: | Height: | Size: 357 B After Width: | Height: | Size: 368 B |
@ -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 0h24v24H0zm0 0h24v24H0V0z" fill="none"/><path d="M1.79 12l5.58 5.59L5.96 19 .37 13.41 1.79 12zm.45-7.78L12.9 14.89l-1.28 1.28L7.44 12l-1.41 1.41L11.62 19l2.69-2.69 4.89 4.89 1.41-1.41L3.65 2.81 2.24 4.22zm14.9 9.27L23.62 7 22.2 5.59l-6.48 6.48 1.42 1.42zM17.96 7l-1.41-1.41-3.65 3.66 1.41 1.41L17.96 7z"/></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000">
|
||||||
|
<path d="M0 0h24v24H0zm0 0h24v24H0V0z" fill="none"/>
|
||||||
|
<path d="M1.79 12l5.58 5.59L5.96 19 .37 13.41 1.79 12zm.45-7.78L12.9 14.89l-1.28 1.28L7.44 12l-1.41 1.41L11.62 19l2.69-2.69 4.89 4.89 1.41-1.41L3.65 2.81 2.24 4.22zm14.9 9.27L23.62 7 22.2 5.59l-6.48 6.48 1.42 1.42zM17.96 7l-1.41-1.41-3.65 3.66 1.41 1.41L17.96 7z"/>
|
||||||
|
</svg>
|
Before Width: | Height: | Size: 425 B After Width: | Height: | Size: 436 B |
@ -1 +1,3 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 -960 960 960" width="24"><path d="M480-80q-139-35-229.5-159.5T160-516v-244l320-120 320 120v244q0 152-90.5 276.5T480-80Zm0-84q97-30 162-118.5T718-480H480v-315l-240 90v207q0 7 2 18h238v316Z"/></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 -960 960 960" width="24">
|
||||||
|
<path d="M480-80q-139-35-229.5-159.5T160-516v-244l320-120 320 120v244q0 152-90.5 276.5T480-80Zm0-84q97-30 162-118.5T718-480H480v-315l-240 90v207q0 7 2 18h238v316Z"/>
|
||||||
|
</svg>
|
Before Width: | Height: | Size: 259 B After Width: | Height: | Size: 265 B |
@ -1 +1,13 @@
|
|||||||
<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"/></g><g><g><path d="M16.81,8.94l-3.75-3.75L4,14.25V18h3.75L16.81,8.94z M6,16v-0.92l7.06-7.06l0.92,0.92L6.92,16H6z"/><path d="M19.71,6.04c0.39-0.39,0.39-1.02,0-1.41l-2.34-2.34C17.17,2.09,16.92,2,16.66,2c-0.25,0-0.51,0.1-0.7,0.29l-1.83,1.83 l3.75,3.75L19.71,6.04z"/><rect height="4" width="20" x="2" y="20"/></g></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"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<g>
|
||||||
|
<path d="M16.81,8.94l-3.75-3.75L4,14.25V18h3.75L16.81,8.94z M6,16v-0.92l7.06-7.06l0.92,0.92L6.92,16H6z"/>
|
||||||
|
<path d="M19.71,6.04c0.39-0.39,0.39-1.02,0-1.41l-2.34-2.34C17.17,2.09,16.92,2,16.66,2c-0.25,0-0.51,0.1-0.7,0.29l-1.83,1.83 l3.75,3.75L19.71,6.04z"/>
|
||||||
|
<rect height="4" width="20" x="2" y="20"/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
Before Width: | Height: | Size: 500 B After Width: | Height: | Size: 592 B |
@ -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 0h24v24H0z" fill="none"/><path d="M12 4V1L8 5l4 4V6c3.31 0 6 2.69 6 6 0 1.01-.25 1.97-.7 2.8l1.46 1.46C19.54 15.03 20 13.57 20 12c0-4.42-3.58-8-8-8zm0 14c-3.31 0-6-2.69-6-6 0-1.01.25-1.97.7-2.8L5.24 7.74C4.46 8.97 4 10.43 4 12c0 4.42 3.58 8 8 8v3l4-4-4-4v3z"/></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000">
|
||||||
|
<path d="M0 0h24v24H0z" fill="none"/>
|
||||||
|
<path d="M12 4V1L8 5l4 4V6c3.31 0 6 2.69 6 6 0 1.01-.25 1.97-.7 2.8l1.46 1.46C19.54 15.03 20 13.57 20 12c0-4.42-3.58-8-8-8zm0 14c-3.31 0-6-2.69-6-6 0-1.01.25-1.97.7-2.8L5.24 7.74C4.46 8.97 4 10.43 4 12c0 4.42 3.58 8 8 8v3l4-4-4-4v3z"/>
|
||||||
|
</svg>
|
Before Width: | Height: | Size: 380 B After Width: | Height: | Size: 391 B |
@ -1,10 +1,10 @@
|
|||||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
<g clip-path="url(#clip0_402_2142)">
|
<g clip-path="url(#clip0_402_2142)">
|
||||||
<path d="M4 13H20V15H4V13ZM4 17H20V19H4V17ZM4 9H20V11H4V9ZM4 5H20V7H4V5Z" fill="black"/>
|
<path d="M4 13H20V15H4V13ZM4 17H20V19H4V17ZM4 9H20V11H4V9ZM4 5H20V7H4V5Z" fill="black"/>
|
||||||
</g>
|
</g>
|
||||||
<defs>
|
<defs>
|
||||||
<clipPath id="clip0_402_2142">
|
<clipPath id="clip0_402_2142">
|
||||||
<rect width="24" height="24" fill="white"/>
|
<rect width="24" height="24" fill="white"/>
|
||||||
</clipPath>
|
</clipPath>
|
||||||
</defs>
|
</defs>
|
||||||
</svg>
|
</svg>
|
||||||
|
Before Width: | Height: | Size: 336 B After Width: | Height: | Size: 388 B |
@ -1 +1,13 @@
|
|||||||
<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" x="0"/></g><g><g><g><path d="M21,10.12h-6.78l2.74-2.82c-2.73-2.7-7.15-2.8-9.88-0.1c-2.73,2.71-2.73,7.08,0,9.79s7.15,2.71,9.88,0 C18.32,15.65,19,14.08,19,12.1h2c0,1.98-0.88,4.55-2.64,6.29c-3.51,3.48-9.21,3.48-12.72,0c-3.5-3.47-3.53-9.11-0.02-12.58 s9.14-3.47,12.65,0L21,3V10.12z M12.5,8v4.25l3.5,2.08l-0.72,1.21L11,13V8H12.5z"/></g></g></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" x="0"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<g>
|
||||||
|
<g>
|
||||||
|
<path d="M21,10.12h-6.78l2.74-2.82c-2.73-2.7-7.15-2.8-9.88-0.1c-2.73,2.71-2.73,7.08,0,9.79s7.15,2.71,9.88,0 C18.32,15.65,19,14.08,19,12.1h2c0,1.98-0.88,4.55-2.64,6.29c-3.51,3.48-9.21,3.48-12.72,0c-3.5-3.47-3.53-9.11-0.02-12.58 s9.14-3.47,12.65,0L21,3V10.12z M12.5,8v4.25l3.5,2.08l-0.72,1.21L11,13V8H12.5z"/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
Before Width: | Height: | Size: 525 B After Width: | Height: | Size: 621 B |
@ -1,11 +1,11 @@
|
|||||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
<g clip-path="url(#clip0_402_2113)">
|
<g clip-path="url(#clip0_402_2113)">
|
||||||
<path d="M3 13H11V15H3V13ZM3 17H11V19H3V17ZM3 9H11V11H3V9ZM3 5H11V7H3V5Z" fill="black"/>
|
<path d="M3 13H11V15H3V13ZM3 17H11V19H3V17ZM3 9H11V11H3V9ZM3 5H11V7H3V5Z" fill="black"/>
|
||||||
<path d="M13 13H21V15H13V13ZM13 17H21V19H13V17ZM13 9H21V11H13V9ZM13 5H21V7H13V5Z" fill="black"/>
|
<path d="M13 13H21V15H13V13ZM13 17H21V19H13V17ZM13 9H21V11H13V9ZM13 5H21V7H13V5Z" fill="black"/>
|
||||||
</g>
|
</g>
|
||||||
<defs>
|
<defs>
|
||||||
<clipPath id="clip0_402_2113">
|
<clipPath id="clip0_402_2113">
|
||||||
<rect width="24" height="24" fill="white"/>
|
<rect width="24" height="24" fill="white"/>
|
||||||
</clipPath>
|
</clipPath>
|
||||||
</defs>
|
</defs>
|
||||||
</svg>
|
</svg>
|
||||||
|
Before Width: | Height: | Size: 433 B After Width: | Height: | Size: 493 B |
@ -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="M12 6c3.79 0 7.17 2.13 8.82 5.5C19.17 14.87 15.79 17 12 17s-7.17-2.13-8.82-5.5C4.83 8.13 8.21 6 12 6m0-2C7 4 2.73 7.11 1 11.5 2.73 15.89 7 19 12 19s9.27-3.11 11-7.5C21.27 7.11 17 4 12 4zm0 5c1.38 0 2.5 1.12 2.5 2.5S13.38 14 12 14s-2.5-1.12-2.5-2.5S10.62 9 12 9m0-2c-2.48 0-4.5 2.02-4.5 4.5S9.52 16 12 16s4.5-2.02 4.5-4.5S14.48 7 12 7z"/></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="M12 6c3.79 0 7.17 2.13 8.82 5.5C19.17 14.87 15.79 17 12 17s-7.17-2.13-8.82-5.5C4.83 8.13 8.21 6 12 6m0-2C7 4 2.73 7.11 1 11.5 2.73 15.89 7 19 12 19s9.27-3.11 11-7.5C21.27 7.11 17 4 12 4zm0 5c1.38 0 2.5 1.12 2.5 2.5S13.38 14 12 14s-2.5-1.12-2.5-2.5S10.62 9 12 9m0-2c-2.48 0-4.5 2.02-4.5 4.5S9.52 16 12 16s4.5-2.02 4.5-4.5S14.48 7 12 7z"/>
|
||||||
|
</svg>
|
Before Width: | Height: | Size: 493 B After Width: | Height: | Size: 504 B |
@ -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 0h24v24H0V0zm0 0h24v24H0V0zm0 0h24v24H0V0zm0 0h24v24H0V0z" fill="none"/><path d="M12 6c3.79 0 7.17 2.13 8.82 5.5-.59 1.22-1.42 2.27-2.41 3.12l1.41 1.41c1.39-1.23 2.49-2.77 3.18-4.53C21.27 7.11 17 4 12 4c-1.27 0-2.49.2-3.64.57l1.65 1.65C10.66 6.09 11.32 6 12 6zm-1.07 1.14L13 9.21c.57.25 1.03.71 1.28 1.28l2.07 2.07c.08-.34.14-.7.14-1.07C16.5 9.01 14.48 7 12 7c-.37 0-.72.05-1.07.14zM2.01 3.87l2.68 2.68C3.06 7.83 1.77 9.53 1 11.5 2.73 15.89 7 19 12 19c1.52 0 2.98-.29 4.32-.82l3.42 3.42 1.41-1.41L3.42 2.45 2.01 3.87zm7.5 7.5l2.61 2.61c-.04.01-.08.02-.12.02-1.38 0-2.5-1.12-2.5-2.5 0-.05.01-.08.01-.13zm-3.4-3.4l1.75 1.75c-.23.55-.36 1.15-.36 1.78 0 2.48 2.02 4.5 4.5 4.5.63 0 1.23-.13 1.77-.36l.98.98c-.88.24-1.8.38-2.75.38-3.79 0-7.17-2.13-8.82-5.5.7-1.43 1.72-2.61 2.93-3.53z"/></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000">
|
||||||
|
<path d="M0 0h24v24H0V0zm0 0h24v24H0V0zm0 0h24v24H0V0zm0 0h24v24H0V0z" fill="none"/>
|
||||||
|
<path d="M12 6c3.79 0 7.17 2.13 8.82 5.5-.59 1.22-1.42 2.27-2.41 3.12l1.41 1.41c1.39-1.23 2.49-2.77 3.18-4.53C21.27 7.11 17 4 12 4c-1.27 0-2.49.2-3.64.57l1.65 1.65C10.66 6.09 11.32 6 12 6zm-1.07 1.14L13 9.21c.57.25 1.03.71 1.28 1.28l2.07 2.07c.08-.34.14-.7.14-1.07C16.5 9.01 14.48 7 12 7c-.37 0-.72.05-1.07.14zM2.01 3.87l2.68 2.68C3.06 7.83 1.77 9.53 1 11.5 2.73 15.89 7 19 12 19c1.52 0 2.98-.29 4.32-.82l3.42 3.42 1.41-1.41L3.42 2.45 2.01 3.87zm7.5 7.5l2.61 2.61c-.04.01-.08.02-.12.02-1.38 0-2.5-1.12-2.5-2.5 0-.05.01-.08.01-.13zm-3.4-3.4l1.75 1.75c-.23.55-.36 1.15-.36 1.78 0 2.48 2.02 4.5 4.5 4.5.63 0 1.23-.13 1.77-.36l.98.98c-.88.24-1.8.38-2.75.38-3.79 0-7.17-2.13-8.82-5.5.7-1.43 1.72-2.61 2.93-3.53z"/>
|
||||||
|
</svg>
|
Before Width: | Height: | Size: 901 B After Width: | Height: | Size: 912 B |
@ -1,14 +1,13 @@
|
|||||||
package com.jetpackduba.gitnuro.git.branches
|
package com.jetpackduba.gitnuro.git.branches
|
||||||
|
|
||||||
import com.jetpackduba.gitnuro.extensions.isBranch
|
import io.mockk.every
|
||||||
import com.jetpackduba.gitnuro.extensions.simpleName
|
import io.mockk.mockk
|
||||||
import io.mockk.*
|
import io.mockk.verify
|
||||||
import kotlinx.coroutines.runBlocking
|
import kotlinx.coroutines.runBlocking
|
||||||
import org.eclipse.jgit.api.CheckoutCommand
|
import org.eclipse.jgit.api.CheckoutCommand
|
||||||
import org.eclipse.jgit.api.CreateBranchCommand
|
import org.eclipse.jgit.api.CreateBranchCommand
|
||||||
import org.eclipse.jgit.api.Git
|
import org.eclipse.jgit.api.Git
|
||||||
import org.eclipse.jgit.lib.ObjectIdRef
|
import org.eclipse.jgit.lib.ObjectIdRef
|
||||||
import org.junit.jupiter.api.BeforeEach
|
|
||||||
import org.junit.jupiter.api.Test
|
import org.junit.jupiter.api.Test
|
||||||
|
|
||||||
class CheckoutRefUseCaseTest {
|
class CheckoutRefUseCaseTest {
|
||||||
@ -18,7 +17,7 @@ class CheckoutRefUseCaseTest {
|
|||||||
@Test
|
@Test
|
||||||
fun `invokes git checkout when ref is a local branch`() {
|
fun `invokes git checkout when ref is a local branch`() {
|
||||||
val checkoutCommand = mockk<CheckoutCommand>(relaxed = true)
|
val checkoutCommand = mockk<CheckoutCommand>(relaxed = true)
|
||||||
val branchName ="refs/heads/feature-branch"
|
val branchName = "refs/heads/feature-branch"
|
||||||
every { refMock.name } returns branchName
|
every { refMock.name } returns branchName
|
||||||
every { gitMock.checkout() } returns checkoutCommand
|
every { gitMock.checkout() } returns checkoutCommand
|
||||||
|
|
||||||
|
@ -1,10 +1,9 @@
|
|||||||
package com.jetpackduba.gitnuro.git.diff
|
package com.jetpackduba.gitnuro.git.diff
|
||||||
|
|
||||||
import io.mockk.mockk
|
import io.mockk.mockk
|
||||||
|
import org.junit.jupiter.api.Assertions.assertEquals
|
||||||
import org.junit.jupiter.api.Test
|
import org.junit.jupiter.api.Test
|
||||||
|
|
||||||
import org.junit.jupiter.api.Assertions.*
|
|
||||||
|
|
||||||
class GenerateSplitHunkFromDiffResultUseCaseTest {
|
class GenerateSplitHunkFromDiffResultUseCaseTest {
|
||||||
|
|
||||||
private val generateSplitHunkFromDiffResultUseCase = GenerateSplitHunkFromDiffResultUseCase()
|
private val generateSplitHunkFromDiffResultUseCase = GenerateSplitHunkFromDiffResultUseCase()
|
||||||
|