Fixed images viewing in system default image viewer not working

This commit is contained in:
Abdelilah El Aissaoui 2022-11-10 18:27:48 +01:00
parent 45ad7f64ac
commit 1bfa65b740
6 changed files with 92 additions and 29 deletions

View File

@ -0,0 +1,43 @@
package com.jetpackduba.gitnuro
import com.jetpackduba.gitnuro.extensions.OS
import com.jetpackduba.gitnuro.extensions.getCurrentOs
import com.jetpackduba.gitnuro.logging.printLog
import java.io.File
import javax.inject.Inject
private const val TAG = "AppFilesManager"
class AppFilesManager @Inject constructor() {
fun getAppFolder(): File {
val baseFolderPath = when (getCurrentOs()) {
OS.LINUX -> {
var configFolder: String? = System.getenv("XDG_CONFIG_HOME")
if (configFolder.isNullOrEmpty())
configFolder = "${System.getenv("HOME")}/.config"
configFolder
}
OS.WINDOWS -> System.getenv("APPDATA").orEmpty()
OS.MAC -> System.getProperty("user.home") + "/Library/Application"
else -> {
printLog(TAG, "Unknown OS")
throw Exception("Invalid OS")
}
}
val baseFolder = File(baseFolderPath)
baseFolder.mkdirs()
val appFolder = File(baseFolder, "gitnuro")
// TODO test if mkdir fails for some reason
if(!appFolder.exists() || !appFolder.isDirectory)
appFolder.mkdir()
return appFolder
}
}

View File

@ -1,20 +1,23 @@
package com.jetpackduba.gitnuro
import com.jetpackduba.gitnuro.di.TabScope
import com.jetpackduba.gitnuro.extensions.openDirectory
import java.io.File
import java.nio.file.Files
import javax.inject.Inject
import kotlin.io.path.createTempDirectory
import kotlin.io.path.deleteIfExists
@TabScope
class TempFilesManager @Inject constructor() {
val tempDir by lazy {
val tempDirPath = createTempDirectory("gitnuro_")
tempDirPath.toFile().deleteOnExit()
class TempFilesManager @Inject constructor(
private val appFilesManager: AppFilesManager,
) {
fun tempDir(): File {
val appDataDir = appFilesManager.getAppFolder()
val tempDir = appDataDir.openDirectory("tmp")
tempDirPath
if(!tempDir.exists() || !tempDir.isDirectory) {
tempDir.mkdir()
}
fun removeTempDir() {
tempDir.deleteIfExists()
return tempDir
}
}

View File

@ -0,0 +1,13 @@
package com.jetpackduba.gitnuro.extensions
import java.io.File
fun File.openDirectory(dirName: String): File {
val newDir = File(this, dirName)
if (!newDir.exists() || !newDir.isDirectory) {
newDir.mkdir()
}
return newDir
}

View File

@ -28,7 +28,7 @@ fun runCommand(command: String): String? {
fun runCommandWithoutResult(command: String, args: String, file: String): Boolean {
val parts: Array<String> = prepareCommand(command, args, file)
printLog(TAG, "Running command $parts")
printLog(TAG, "Running command ${parts.joinToString( )}")
return try {
val p = Runtime.getRuntime().exec(parts) ?: return false

View File

@ -1,7 +1,7 @@
package com.jetpackduba.gitnuro.git
import com.jetpackduba.gitnuro.TempFilesManager
import com.jetpackduba.gitnuro.extensions.systemSeparator
import com.jetpackduba.gitnuro.extensions.fileName
import org.eclipse.jgit.diff.ContentSource
import org.eclipse.jgit.diff.DiffEntry
import org.eclipse.jgit.diff.RawText
@ -11,16 +11,21 @@ import org.eclipse.jgit.storage.pack.PackConfig
import org.eclipse.jgit.treewalk.AbstractTreeIterator
import org.eclipse.jgit.treewalk.WorkingTreeIterator
import org.eclipse.jgit.util.LfsFactory
import java.io.File
import java.io.FileOutputStream
import java.nio.file.Files
import java.nio.file.Path
import javax.inject.Inject
import kotlin.io.path.createTempFile
private const val DEFAULT_BINARY_FILE_THRESHOLD = PackConfig.DEFAULT_BIG_FILE_THRESHOLD
private const val IMAGE_CONTENT_TYPE = "image/"
/**
* Max of chars that a file name can have. Used to avoid issues with OS chars limit in file names.
*/
private const val FILE_NAME_MAX_LENGTH = 250
val animatedImages = arrayOf(
"image/gif",
"image/webp"
@ -76,17 +81,21 @@ class RawFileManager @Inject constructor(
entry: DiffEntry,
side: DiffEntry.Side
): EntryContent.ImageBinary {
val tempDir = tempFilesManager.tempDir
val tempDir = tempFilesManager.tempDir()
val tempFile = createTempFile(tempDir, prefix = "${entry.newPath.replace(systemSeparator, "_")}_${side.name}")
tempFile.toFile().deleteOnExit()
val prefix = "${entry.getId(side).name().take(20)}_${side.name}_"
val tempFileName = prefix + entry.fileName.take(FILE_NAME_MAX_LENGTH - prefix.length)
val out = FileOutputStream(tempFile.toFile())
val tempFile = File(tempDir, tempFileName)
tempFile.deleteOnExit()
val out = FileOutputStream(tempFile)
out.use {
ldr.copyTo(out)
}
return EntryContent.ImageBinary(tempFile, Files.probeContentType(Path.of(entry.newPath)).orEmpty())
return EntryContent.ImageBinary(tempFile.absolutePath, Files.probeContentType(Path.of(entry.newPath)).orEmpty())
}
private fun isImage(entry: DiffEntry): Boolean {
@ -102,7 +111,7 @@ sealed class EntryContent {
object InvalidObjectBlob : EntryContent()
data class Text(val rawText: RawText) : EntryContent()
sealed class BinaryContent : EntryContent()
data class ImageBinary(val tempFilePath: Path, val contentType: String) : BinaryContent()
data class ImageBinary(val imagePath: String, val contentType: String) : BinaryContent()
object Binary : BinaryContent()
object TooLargeEntry : EntryContent()
}

View File

@ -27,7 +27,6 @@ import androidx.compose.ui.input.pointer.PointerEventType
import androidx.compose.ui.input.pointer.onPointerEvent
import androidx.compose.ui.res.loadImageBitmap
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
@ -58,8 +57,6 @@ import org.jetbrains.compose.animatedimage.animate
import org.jetbrains.compose.animatedimage.loadAnimatedImage
import org.jetbrains.compose.resources.loadOrNull
import java.io.FileInputStream
import java.nio.file.Path
import kotlin.io.path.absolutePathString
import kotlin.math.max
private const val MAX_MOVES_COUNT = 5
@ -253,7 +250,7 @@ fun SideTitle(text: String) {
fun SideDiff(entryContent: EntryContent) {
when (entryContent) {
EntryContent.Binary -> BinaryDiff()
is EntryContent.ImageBinary -> ImageDiff(entryContent.tempFilePath, entryContent.contentType)
is EntryContent.ImageBinary -> ImageDiff(entryContent.imagePath, entryContent.contentType)
else -> {
}
// is EntryContent.Text -> //TODO maybe have a text view if the file was a binary before?
@ -262,9 +259,7 @@ fun SideDiff(entryContent: EntryContent) {
}
@Composable
private fun ImageDiff(tempImagePath: Path, contentType: String) {
val imagePath = tempImagePath.absolutePathString()
private fun ImageDiff(imagePath: String, contentType: String) {
if (animatedImages.contains(contentType)) {
AnimatedImage(imagePath)
} else {
@ -305,13 +300,13 @@ private fun StaticImage(tempImagePath: String) {
}
@Composable
private fun AnimatedImage(tempImagePath: String) {
private fun AnimatedImage(iamgePath: String) {
Image(
bitmap = loadOrNull(tempImagePath) { loadAnimatedImage(tempImagePath) }?.animate() ?: ImageBitmap.Blank,
bitmap = loadOrNull(iamgePath) { loadAnimatedImage(iamgePath) }?.animate() ?: ImageBitmap.Blank,
contentDescription = null,
modifier = Modifier.fillMaxSize()
.handMouseClickable {
openFileWithExternalApp(tempImagePath)
openFileWithExternalApp(iamgePath)
}
)
}