Skip to content

Commit

Permalink
Add ability to import local assets
Browse files Browse the repository at this point in the history
  • Loading branch information
abueide committed Apr 17, 2022
1 parent aa88e00 commit 82f91f9
Show file tree
Hide file tree
Showing 9 changed files with 117 additions and 43 deletions.
1 change: 0 additions & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ dependencies {
implementation("io.ktor:ktor-serialization-kotlinx-json:$ktorVersion")
implementation("io.ktor:ktor-client-core:$ktorVersion")
implementation("io.ktor:ktor-client-cio:$ktorVersion")
implementation("io.ktor:ktor-client-apache:$ktorVersion")
implementation("io.ktor:ktor-client-logging:$ktorVersion")
implementation("io.ktor:ktor-client-okhttp:$ktorVersion")
implementation("org.jsoup:jsoup:1.14.3")
Expand Down
7 changes: 3 additions & 4 deletions src/main/kotlin/com/abysl/assetmanager/Prefs.kt
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,8 @@ import java.io.File

object Prefs {

val HOME_FOLDER = System.getProperty("user.home").toPath().toFile()
.resolve(".abysl/assetmanager")
.also { it.mkdirs() }
val USER_FOLDER = System.getProperty("user.home").toPath().toFile()
val HOME_FOLDER = USER_FOLDER.resolve(".abysl/assetmanager").also { it.mkdirs() }
val DB_FILE = HOME_FOLDER.resolve("assetmanager.sqlite").also { it.createNewFile() }
val IMAGE_PATH = HOME_FOLDER.resolve("images").also { it.mkdirs() }
val IMAGE_CACHE = IMAGE_PATH.resolve("cache").also { it.mkdirs() }
Expand All @@ -30,7 +29,7 @@ object Prefs {
var darkMode: Boolean
get() = PreferencesTable["darkMode"] != "0"
set(value) {
PreferencesTable["darkMode"] = if(value) "1" else "0"
PreferencesTable["darkMode"] = if (value) "1" else "0"
}

}
1 change: 1 addition & 0 deletions src/main/kotlin/com/abysl/assetmanager/model/Asset.kt
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ data class Asset(
when (sourcePlatform) {
SourcePlatform.HUMBLE -> Prefs.jsonFormat.decodeFromString<HumbleProduct>(sourceData)
SourcePlatform.ITCH -> Prefs.jsonFormat.decodeFromString<ItchGame>(sourceData)
SourcePlatform.LOCAL -> File(sourceData)
else -> null
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,16 @@ package com.abysl.assetmanager.services

import com.abysl.assetmanager.Prefs
import com.abysl.assetmanager.db.tables.AssetTable
import com.abysl.assetmanager.model.Asset
import com.abysl.assetmanager.ui.components.assetimport.SourcePlatform
import com.abysl.humble.model.HumbleProduct
import com.abysl.itch.Itch
import com.abysl.itch.model.ItchGame
import kotlinx.coroutines.*
import kotlinx.serialization.encodeToString
import org.jetbrains.exposed.sql.batchInsert
import org.jetbrains.exposed.sql.insert
import org.jetbrains.exposed.sql.select
import org.jetbrains.exposed.sql.*
import org.jetbrains.exposed.sql.transactions.transaction
import org.jetbrains.exposed.sql.update
import java.io.File

class AssetImportService() {
fun importItchAssets() {
Expand Down Expand Up @@ -82,4 +81,31 @@ class AssetImportService() {
}
}
}

fun importLocalAsset(name: String, creator: String, file: File) {
val existingAsset = transaction {
AssetTable
.select { (AssetTable.name eq name) and (AssetTable.creator eq creator) }
.map(AssetTable::fromRow)
}.firstOrNull()
transaction {
if (existingAsset != null) {
AssetTable.update({ AssetTable.id eq existingAsset.id }) {
it[AssetTable.name] = name
it[AssetTable.creator] = creator
it[downloaded] = false
it[sourcePlatform] = Prefs.jsonFormat.encodeToString(SourcePlatform.LOCAL)
it[sourceData] = file.path
}
} else {
AssetTable.insert {
it[AssetTable.name] = name
it[AssetTable.creator] = creator
it[downloaded] = false
it[sourcePlatform] = Prefs.jsonFormat.encodeToString(SourcePlatform.LOCAL)
it[sourceData] = file.path
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ class DownloadService(val maxJobs: Int = 5) : KoinComponent {
val downloadSuccess: Boolean = when (asset.sourceObject) {
is ItchGame -> downloadItchAsset(asset.dir, asset.sourceObject)
is HumbleProduct -> downloadHumbleAsset(asset.dir, asset.sourceObject)
is File -> copyLocalAsset(asset.dir, asset.sourceObject)
else -> true
}
indexAsset(asset)
Expand Down Expand Up @@ -142,6 +143,10 @@ class DownloadService(val maxJobs: Int = 5) : KoinComponent {
return success
}

fun copyLocalAsset(saveDir: File, assetSource: File): Boolean {
return assetSource.copyRecursively(target = saveDir, overwrite = true)
}

suspend fun downloadFile(
saveLocation: File,
fileUrl: String,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,10 @@ import com.abysl.assetmanager.Prefs
import com.abysl.assetmanager.ui.components.Component
import com.abysl.assetmanager.ui.components.shared.dropdown.DropDownComponent
import com.abysl.assetmanager.ui.components.shared.util.AbyslComponents.LinkText
import com.abysl.assetmanager.util.folderDialog
import org.koin.core.component.KoinComponent
import java.io.File
import java.util.Arrays

class AssetImportComponent(val ctx: AssetImportContext = AssetImportContext()) : Component(), KoinComponent {

Expand Down Expand Up @@ -80,7 +83,47 @@ class AssetImportComponent(val ctx: AssetImportContext = AssetImportContext()) :

@Composable
fun localImportForm() {
Text("Not implemented yet")
var assetPath by remember { mutableStateOf("") }
var assetName by remember { mutableStateOf("") }
var creator by remember { mutableStateOf("") }

var fileChooserOpen by remember { mutableStateOf(false) }
Column(verticalArrangement = Arrangement.spacedBy(15.dp)) {
Row(horizontalArrangement = Arrangement.spacedBy(15.dp), verticalAlignment = Alignment.CenterVertically) {
TextField(value = assetPath, onValueChange = { assetPath = it }, modifier = Modifier.weight(1f))
Button(onClick = {
fileChooserOpen = true
}) {
Text("Choose File")
}
}
if (fileChooserOpen) {
folderDialog {
fileChooserOpen = false
it?.let { assetPath = it.path }
it?.let { assetName = it.name }
}
}
val assetDir = File(assetPath)
if (assetDir.exists()) {
formField("Asset Name", assetName) { assetName = it }
formField("Creator", creator) { creator = it }
importButton {
ctx.importService.importLocalAsset(assetName, creator, assetDir)
}
}
}

}

@Composable
fun formField(title: String, initialValue: String, onValueChange: (String) -> Unit) {
Column(horizontalAlignment = Alignment.CenterHorizontally) {
Text(title)
Row {
TextField(initialValue, onValueChange, modifier = Modifier.weight(1f))
}
}
}

@Composable
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import kotlinx.serialization.decodeFromString
import kotlinx.serialization.json.Json
import org.koin.core.component.KoinComponent
import org.koin.core.component.inject
import java.io.File

class AssetImportContext: KoinComponent {
var selectedImportType by mutableStateOf(SourcePlatform.values().first())
Expand Down
Original file line number Diff line number Diff line change
@@ -1,54 +1,46 @@
package com.abysl.assetmanager.ui.components.shared.dropdown

import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.width
import androidx.compose.material.*
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.ArrowForward
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import androidx.compose.runtime.*
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Path
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import com.abysl.assetmanager.ui.components.Component
import com.abysl.assetmanager.ui.util.Theme

class DropDownComponent<C: Iterable<T>, T>(
class DropDownComponent<C : Iterable<T>, T>(
val items: C,
val onItemSelect: (T) -> Unit = {},
val fieldSize: Dp = 200.dp
) : Component() {

var expanded by mutableStateOf(false)
var selectedItem by mutableStateOf(items.firstOrNull())

@Composable
override fun view() {
Column {
button()
menu()
var selectedItem by remember { mutableStateOf(items.first()) }
button(selectedItem)
menu { selectedItem = it }
}
}

@Composable
fun button() {
fun button(selectedItem: T?) {
Button(
onClick = { expanded = !expanded },
modifier = Modifier
.width(fieldSize)
) {
Text(selectedItem.toString())
Text(selectedItem.toString())
}
}

@Composable
fun menu() {
fun menu(internalOnSelect: (T) -> Unit) {
DropdownMenu(
expanded = expanded,
onDismissRequest = { expanded = false },
Expand All @@ -58,8 +50,9 @@ class DropDownComponent<C: Iterable<T>, T>(
) {
for (item in items) {
DropdownMenuItem(onClick = {
println(item)
onItemSelect(item)
selectedItem = item
internalOnSelect(item)
expanded = false
}) {
Text(item.toString())
Expand Down
39 changes: 23 additions & 16 deletions src/main/kotlin/com/abysl/assetmanager/util/FileUtil.kt
Original file line number Diff line number Diff line change
@@ -1,18 +1,11 @@
package com.abysl.assetmanager.util

import androidx.compose.ui.graphics.ImageBitmap
import androidx.compose.ui.graphics.toComposeImageBitmap
import io.ktor.client.*
import io.ktor.client.request.*
import io.ktor.client.statement.*
import io.ktor.utils.io.core.*
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.withContext
import org.jetbrains.skia.Image
import androidx.compose.runtime.Composable
import com.abysl.assetmanager.Prefs
import java.io.File
import java.io.InputStream
import java.util.*
import javax.swing.JFileChooser
import javax.swing.filechooser.FileSystemView


fun String.asResourceStream(): InputStream =
Expand All @@ -27,8 +20,22 @@ fun parseFileNameFromUrl(url: String): String {
return test
}






@Composable
fun folderDialog(
title: String = "Select a folder",
mode: Int = JFileChooser.DIRECTORIES_ONLY,
onResult: (result: File?) -> Unit,
) {
val fileChooser = JFileChooser(FileSystemView.getFileSystemView())
fileChooser.currentDirectory = Prefs.USER_FOLDER
fileChooser.dialogTitle = title
fileChooser.fileSelectionMode = mode
fileChooser.isAcceptAllFileFilterUsed = true
fileChooser.selectedFile = null
fileChooser.currentDirectory = null
if (fileChooser.showOpenDialog(null) == JFileChooser.APPROVE_OPTION) {
onResult(fileChooser.selectedFile)
} else {
onResult(null)
}
}

0 comments on commit 82f91f9

Please sign in to comment.