Add directories to distingish between pixelized apps.

This commit is contained in:
Thomas Andres Gomez 2025-03-02 10:20:52 +01:00
parent 03df369e0b
commit 3f67e342a7
18 changed files with 178 additions and 108 deletions

View file

@ -1,5 +1,5 @@
<component name="ProjectRunConfigurationManager"> <component name="ProjectRunConfigurationManager">
<configuration default="false" name="packageReleaseDmg" type="GradleRunConfiguration" factoryName="Gradle" folderName="App"> <configuration default="false" name="appPackageReleaseDmg" type="GradleRunConfiguration" factoryName="Gradle" folderName="App">
<ExternalSystemSettings> <ExternalSystemSettings>
<option name="executionName" /> <option name="executionName" />
<option name="externalProjectPath" value="$PROJECT_DIR$" /> <option name="externalProjectPath" value="$PROJECT_DIR$" />

View file

@ -1,5 +1,5 @@
<component name="ProjectRunConfigurationManager"> <component name="ProjectRunConfigurationManager">
<configuration default="false" name="packageReleaseMsi" type="GradleRunConfiguration" factoryName="Gradle" folderName="App"> <configuration default="false" name="appPackageReleaseMsi" type="GradleRunConfiguration" factoryName="Gradle" folderName="App">
<ExternalSystemSettings> <ExternalSystemSettings>
<option name="executionName" /> <option name="executionName" />
<option name="externalProjectPath" value="$PROJECT_DIR$" /> <option name="externalProjectPath" value="$PROJECT_DIR$" />

View file

@ -1,5 +1,5 @@
<component name="ProjectRunConfigurationManager"> <component name="ProjectRunConfigurationManager">
<configuration default="false" name="runDebug" type="GradleRunConfiguration" factoryName="Gradle" folderName="App"> <configuration default="false" name="appRunDebug" type="GradleRunConfiguration" factoryName="Gradle" folderName="App">
<ExternalSystemSettings> <ExternalSystemSettings>
<option name="executionName" /> <option name="executionName" />
<option name="externalProjectPath" value="$PROJECT_DIR$" /> <option name="externalProjectPath" value="$PROJECT_DIR$" />

View file

@ -1,5 +1,5 @@
<component name="ProjectRunConfigurationManager"> <component name="ProjectRunConfigurationManager">
<configuration default="false" name="runRelease" type="GradleRunConfiguration" factoryName="Gradle" folderName="App"> <configuration default="false" name="appRunRelease" type="GradleRunConfiguration" factoryName="Gradle" folderName="App">
<ExternalSystemSettings> <ExternalSystemSettings>
<option name="executionName" /> <option name="executionName" />
<option name="externalProjectPath" value="$PROJECT_DIR$" /> <option name="externalProjectPath" value="$PROJECT_DIR$" />

View file

@ -31,6 +31,9 @@ import androidx.compose.ui.unit.dp
import androidx.compose.ui.window.ApplicationScope import androidx.compose.ui.window.ApplicationScope
import androidx.compose.ui.window.Window import androidx.compose.ui.window.Window
import androidx.compose.ui.window.rememberWindowState import androidx.compose.ui.window.rememberWindowState
import coil3.ImageLoader
import coil3.compose.setSingletonImageLoaderFactory
import coil3.request.crossfade
import com.pixelized.desktop.lwa.repository.network.NetworkRepository import com.pixelized.desktop.lwa.repository.network.NetworkRepository
import com.pixelized.desktop.lwa.repository.network.NetworkRepository.Status import com.pixelized.desktop.lwa.repository.network.NetworkRepository.Status
import com.pixelized.desktop.lwa.ui.composable.key.KeyEventHandler import com.pixelized.desktop.lwa.ui.composable.key.KeyEventHandler
@ -85,6 +88,13 @@ fun ApplicationScope.App() {
val windowController = remember { WindowController(maxWindowHeight) } val windowController = remember { WindowController(maxWindowHeight) }
val keyEventHandlers = remember { mutableStateListOf<KeyEventHandler>() } val keyEventHandlers = remember { mutableStateListOf<KeyEventHandler>() }
// Coil configuration
setSingletonImageLoaderFactory { context ->
ImageLoader.Builder(context)
.crossfade(enable = false)
.build()
}
CompositionLocalProvider( CompositionLocalProvider(
LocalSnackHost provides snackHostState, LocalSnackHost provides snackHostState,
LocalErrorSnackHost provides errorSnackHostState, LocalErrorSnackHost provides errorSnackHostState,

View file

@ -33,6 +33,7 @@ import com.pixelized.desktop.lwa.ui.screen.roll.RollViewModel
import com.pixelized.desktop.lwa.ui.screen.rollhistory.RollHistoryViewModel import com.pixelized.desktop.lwa.ui.screen.rollhistory.RollHistoryViewModel
import com.pixelized.desktop.lwa.usecase.SettingsUseCase import com.pixelized.desktop.lwa.usecase.SettingsUseCase
import com.pixelized.shared.lwa.model.campaign.factory.CampaignJsonFactory import com.pixelized.shared.lwa.model.campaign.factory.CampaignJsonFactory
import com.pixelized.shared.lwa.utils.PathProvider
import io.ktor.client.HttpClient import io.ktor.client.HttpClient
import io.ktor.client.engine.okhttp.OkHttp import io.ktor.client.engine.okhttp.OkHttp
import io.ktor.client.plugins.contentnegotiation.ContentNegotiation import io.ktor.client.plugins.contentnegotiation.ContentNegotiation
@ -67,7 +68,12 @@ val toolsDependencies
} }
} }
} }
single<LwaClient> { LwaClientImpl(get(), get()) } single<LwaClient> {
LwaClientImpl(get(), get())
}
single {
PathProvider(appName = "LwaClient")
}
} }
val storeDependencies val storeDependencies

View file

@ -1,9 +1,9 @@
package com.pixelized.desktop.lwa.repository.settings package com.pixelized.desktop.lwa.repository.settings
import com.pixelized.desktop.lwa.usecase.SettingsUseCase
import com.pixelized.desktop.lwa.repository.settings.model.Settings import com.pixelized.desktop.lwa.repository.settings.model.Settings
import com.pixelized.desktop.lwa.repository.settings.model.SettingsJson import com.pixelized.desktop.lwa.repository.settings.model.SettingsJson
import com.pixelized.shared.lwa.storePath import com.pixelized.desktop.lwa.usecase.SettingsUseCase
import com.pixelized.shared.lwa.utils.PathProvider
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job import kotlinx.coroutines.Job
@ -14,6 +14,7 @@ import kotlinx.serialization.json.Json
import java.io.File import java.io.File
class SettingsStore( class SettingsStore(
private val pathProvider: PathProvider,
private val factory: SettingsFactory, private val factory: SettingsFactory,
private val useCase: SettingsUseCase, private val useCase: SettingsUseCase,
private val jsonFormatter: Json, private val jsonFormatter: Json,
@ -24,7 +25,7 @@ class SettingsStore(
init { init {
// create the directory // create the directory
File(storePath()).also { it.mkdirs() } File(pathProvider.storePath()).also { it.mkdirs() }
// load the data. // load the data.
val scope = CoroutineScope(Dispatchers.IO + Job()) val scope = CoroutineScope(Dispatchers.IO + Job())
scope.launch { scope.launch {
@ -80,7 +81,7 @@ class SettingsStore(
} }
private fun settingsFile(): File { private fun settingsFile(): File {
return File("${storePath()}settings.json") return File("${pathProvider.storePath()}settings.json")
} }
sealed class SettingsStoreException(root: Exception) : Exception(root) sealed class SettingsStoreException(root: Exception) : Exception(root)

View file

@ -1,5 +1,12 @@
package com.pixelized.desktop.lwa.ui.screen.campaign.player.ribbon package com.pixelized.desktop.lwa.ui.screen.campaign.player.ribbon
import androidx.compose.animation.AnimatedContent
import androidx.compose.animation.core.EaseOutCirc
import androidx.compose.animation.core.animateFloatAsState
import androidx.compose.animation.core.tween
import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut
import androidx.compose.animation.togetherWith
import androidx.compose.foundation.background import androidx.compose.foundation.background
import androidx.compose.foundation.clickable import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Arrangement
@ -7,7 +14,9 @@ import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.offset import androidx.compose.foundation.layout.offset
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.size
@ -23,8 +32,8 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip import androidx.compose.ui.draw.clip
import androidx.compose.ui.draw.drawWithContent import androidx.compose.ui.draw.drawWithContent
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.FilterQuality import androidx.compose.ui.graphics.FilterQuality
import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.DpSize import androidx.compose.ui.unit.DpSize
@ -36,6 +45,8 @@ import lwacharactersheet.composeapp.generated.resources.Res
import lwacharactersheet.composeapp.generated.resources.ic_heart_24dp import lwacharactersheet.composeapp.generated.resources.ic_heart_24dp
import lwacharactersheet.composeapp.generated.resources.ic_water_drop_24dp import lwacharactersheet.composeapp.generated.resources.ic_water_drop_24dp
import org.jetbrains.compose.resources.painterResource import org.jetbrains.compose.resources.painterResource
import kotlin.math.max
import kotlin.math.min
@Stable @Stable
data class PlayerPortraitUio( data class PlayerPortraitUio(
@ -48,10 +59,17 @@ data class PlayerPortraitUio(
val maxPp: Int, val maxPp: Int,
) )
object PlayerPortrait {
object Default {
val bloodColor = Color(0xbb0a1e).copy(alpha = 0.25f)
}
}
@Composable @Composable
fun PlayerPortrait( fun PlayerPortrait(
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
size: DpSize, size: DpSize,
bloodColor: Color = PlayerPortrait.Default.bloodColor,
character: PlayerPortraitUio, character: PlayerPortraitUio,
onCharacter: (id: Campaign.CharacterInstance.Id) -> Unit, onCharacter: (id: Campaign.CharacterInstance.Id) -> Unit,
) { ) {
@ -64,14 +82,26 @@ fun PlayerPortrait(
.background(color = colorScheme.elevated.base1dp) .background(color = colorScheme.elevated.base1dp)
.clickable { onCharacter(character.id) }, .clickable { onCharacter(character.id) },
) { ) {
AsyncImage( AnimatedContent(
modifier = Modifier.fillMaxSize(), targetState = character.portrait,
model = character.portrait, transitionSpec = { fadeIn() togetherWith fadeOut() },
contentScale = ContentScale.Crop, ) { portrait ->
alignment = Alignment.TopCenter, AsyncImage(
filterQuality = FilterQuality.High, modifier = Modifier.fillMaxSize(),
contentDescription = null, model = portrait,
contentScale = ContentScale.Crop,
alignment = Alignment.TopCenter,
filterQuality = FilterQuality.High,
contentDescription = null,
)
}
BloodOverlay(
bloodColor = bloodColor,
maxHp = character.maxHp.toFloat(),
hp = character.hp.toFloat(),
) )
Column( Column(
modifier = Modifier modifier = Modifier
.fillMaxSize() .fillMaxSize()
@ -128,4 +158,23 @@ fun PlayerPortrait(
} }
} }
} }
}
@Composable
private fun BloodOverlay(
modifier: Modifier = Modifier,
maxHp: Float,
hp: Float,
bloodColor: Color = PlayerPortrait.Default.bloodColor,
) {
val animatedRatio = animateFloatAsState(
targetValue = min(maxHp, max(0f, (maxHp - hp) / maxHp)),
animationSpec = tween(durationMillis = 350, easing = EaseOutCirc)
)
Box(
modifier = modifier
.fillMaxWidth()
.fillMaxHeight(fraction = animatedRatio.value)
.background(color = bloodColor)
)
} }

View file

@ -6,8 +6,8 @@ import com.lordcodes.turtle.shellRun
import com.pixelized.desktop.lwa.repository.campaign.CampaignRepository import com.pixelized.desktop.lwa.repository.campaign.CampaignRepository
import com.pixelized.desktop.lwa.repository.characterSheet.CharacterSheetRepository import com.pixelized.desktop.lwa.repository.characterSheet.CharacterSheetRepository
import com.pixelized.desktop.lwa.repository.network.NetworkRepository import com.pixelized.desktop.lwa.repository.network.NetworkRepository
import com.pixelized.shared.lwa.OperatingSystem import com.pixelized.shared.lwa.utils.OperatingSystem
import com.pixelized.shared.lwa.storePath import com.pixelized.shared.lwa.utils.PathProvider
import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.StateFlow
@ -18,6 +18,7 @@ import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.flow.stateIn
class MainPageViewModel( class MainPageViewModel(
private val pathProvider: PathProvider,
private val characterSheetRepository: CharacterSheetRepository, private val characterSheetRepository: CharacterSheetRepository,
private val campaignRepository: CampaignRepository, private val campaignRepository: CampaignRepository,
networkRepository: NetworkRepository, networkRepository: NetworkRepository,
@ -86,9 +87,10 @@ class MainPageViewModel(
fun openSaveDirectory( fun openSaveDirectory(
os: OperatingSystem = OperatingSystem.current, os: OperatingSystem = OperatingSystem.current,
) { ) {
val path = pathProvider.storePath(os = os)
when (os) { when (os) {
OperatingSystem.Windows -> shellRun("explorer.exe", listOf(storePath(os = os))) OperatingSystem.Windows -> shellRun("explorer.exe", listOf(path))
OperatingSystem.Macintosh -> shellRun("open", listOf(storePath(os = os))) OperatingSystem.Macintosh -> shellRun("open", listOf(path))
} }
} }
} }

View file

@ -3,7 +3,6 @@ package com.pixelized.desktop.lwa
import androidx.compose.ui.window.application import androidx.compose.ui.window.application
import com.pixelized.shared.lwa.sharedModuleDependencies import com.pixelized.shared.lwa.sharedModuleDependencies
import org.koin.compose.KoinContext import org.koin.compose.KoinContext
import org.koin.core.context.loadKoinModules
import org.koin.core.context.startKoin import org.koin.core.context.startKoin
import javax.swing.UIManager import javax.swing.UIManager

View file

@ -5,20 +5,26 @@ import com.pixelized.server.lwa.model.campaign.CampaignStore
import com.pixelized.server.lwa.model.character.CharacterSheetService import com.pixelized.server.lwa.model.character.CharacterSheetService
import com.pixelized.server.lwa.model.character.CharacterSheetStore import com.pixelized.server.lwa.model.character.CharacterSheetStore
import com.pixelized.server.lwa.server.Engine import com.pixelized.server.lwa.server.Engine
import com.pixelized.shared.lwa.utils.PathProvider
import org.koin.core.module.dsl.createdAtStart import org.koin.core.module.dsl.createdAtStart
import org.koin.core.module.dsl.singleOf import org.koin.core.module.dsl.singleOf
import org.koin.dsl.module import org.koin.dsl.module
val serverModuleDependencies val serverModuleDependencies
get() = listOf( get() = listOf(
parserDependencies, toolsDependencies,
factoryDependencies, engineDependencies,
useCaseDependencies,
storeDependencies, storeDependencies,
serviceDependencies, serviceDependencies,
engineDependencies,
) )
val toolsDependencies
get() = module {
single {
PathProvider(appName = "LwaServer")
}
}
val engineDependencies val engineDependencies
get() = module { get() = module {
singleOf(constructor = ::Engine, options = { createdAtStart() }) singleOf(constructor = ::Engine, options = { createdAtStart() })
@ -37,18 +43,3 @@ val serviceDependencies
singleOf(::CampaignService) singleOf(::CampaignService)
singleOf(::AlterationService) singleOf(::AlterationService)
} }
val factoryDependencies
get() = module {
}
val parserDependencies
get() = module {
}
val useCaseDependencies
get() = module {
}

View file

@ -1,9 +1,9 @@
package com.pixelized.server.lwa.model.alteration package com.pixelized.server.lwa.model.alteration
import com.pixelized.shared.lwa.alterationsPath
import com.pixelized.shared.lwa.model.alteration.AlterationJson import com.pixelized.shared.lwa.model.alteration.AlterationJson
import com.pixelized.shared.lwa.model.campaign.Campaign import com.pixelized.shared.lwa.model.campaign.Campaign
import com.pixelized.shared.lwa.model.campaign.factory.CampaignJsonFactory import com.pixelized.shared.lwa.model.campaign.factory.CampaignJsonFactory
import com.pixelized.shared.lwa.utils.PathProvider
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job import kotlinx.coroutines.Job
@ -14,10 +14,11 @@ import kotlinx.serialization.json.Json
import java.io.File import java.io.File
class AlterationStore( class AlterationStore(
private val pathProvider: PathProvider,
private val campaignJsonFactory: CampaignJsonFactory, private val campaignJsonFactory: CampaignJsonFactory,
private val json: Json, private val json: Json,
) { ) {
private val directory = File(alterationsPath()).also { it.mkdirs() } private val directory = File(pathProvider.alterationsPath()).also { it.mkdirs() }
private val alterationsFlow = MutableStateFlow<List<AlterationJson>>(emptyList()) private val alterationsFlow = MutableStateFlow<List<AlterationJson>>(emptyList())
private val activeFlow = MutableStateFlow<Map<String, List<String>>>(emptyMap()) private val activeFlow = MutableStateFlow<Map<String, List<String>>>(emptyMap())
@ -118,13 +119,13 @@ class AlterationStore(
} }
private fun file(): File { private fun file(): File {
return File("${alterationsPath()}alterations.json") return File("${pathProvider.alterationsPath()}alterations.json")
} }
private fun file( private fun file(
id: String, id: String,
): File { ): File {
return File("${alterationsPath()}$id.json") return File("${pathProvider.alterationsPath()}$id.json")
} }
private fun MutableList<String>.toggle(alterationId: String): MutableList<String> { private fun MutableList<String>.toggle(alterationId: String): MutableList<String> {

View file

@ -1,9 +1,9 @@
package com.pixelized.server.lwa.model.campaign package com.pixelized.server.lwa.model.campaign
import com.pixelized.shared.lwa.campaignPath
import com.pixelized.shared.lwa.model.campaign.Campaign import com.pixelized.shared.lwa.model.campaign.Campaign
import com.pixelized.shared.lwa.model.campaign.CampaignJson import com.pixelized.shared.lwa.model.campaign.CampaignJson
import com.pixelized.shared.lwa.model.campaign.factory.CampaignJsonFactory import com.pixelized.shared.lwa.model.campaign.factory.CampaignJsonFactory
import com.pixelized.shared.lwa.utils.PathProvider
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job import kotlinx.coroutines.Job
@ -14,6 +14,7 @@ import kotlinx.serialization.json.Json
import java.io.File import java.io.File
class CampaignStore( class CampaignStore(
private val pathProvider: PathProvider,
private val factory: CampaignJsonFactory, private val factory: CampaignJsonFactory,
private val json: Json, private val json: Json,
) { ) {
@ -21,7 +22,7 @@ class CampaignStore(
init { init {
// create the directory if needed. // create the directory if needed.
File(campaignPath()).also { it.mkdirs() } File(pathProvider.campaignPath()).also { it.mkdirs() }
// build a coroutine scope for async calls // build a coroutine scope for async calls
val scope = CoroutineScope(Dispatchers.IO + Job()) val scope = CoroutineScope(Dispatchers.IO + Job())
// load the initial data // load the initial data
@ -73,6 +74,6 @@ class CampaignStore(
class FileWriteException(root: Exception) : CampaignStoreException(root) class FileWriteException(root: Exception) : CampaignStoreException(root)
private fun file(): File { private fun file(): File {
return File("${campaignPath()}campaign.json") return File("${pathProvider.campaignPath()}campaign.json")
} }
} }

View file

@ -1,25 +1,25 @@
package com.pixelized.server.lwa.model.character package com.pixelized.server.lwa.model.character
import com.pixelized.shared.lwa.characterStorePath
import com.pixelized.shared.lwa.model.characterSheet.CharacterSheet import com.pixelized.shared.lwa.model.characterSheet.CharacterSheet
import com.pixelized.shared.lwa.model.characterSheet.CharacterSheetJson import com.pixelized.shared.lwa.model.characterSheet.CharacterSheetJson
import com.pixelized.shared.lwa.model.characterSheet.CharacterSheetJsonFactory import com.pixelized.shared.lwa.model.characterSheet.CharacterSheetJsonFactory
import com.pixelized.shared.lwa.utils.PathProvider
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job import kotlinx.coroutines.Job
import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json import kotlinx.serialization.json.Json
import java.io.File import java.io.File
import java.text.Collator import java.text.Collator
class CharacterSheetStore( class CharacterSheetStore(
private val pathProvider: PathProvider,
private val factory: CharacterSheetJsonFactory, private val factory: CharacterSheetJsonFactory,
private val json: Json, private val json: Json,
) { ) {
private val directory = File(characterStorePath()).also { it.mkdirs() } private val directory = File(pathProvider.characterStorePath()).also { it.mkdirs() }
private val flow = MutableStateFlow<List<CharacterSheet>>(value = emptyList()) private val flow = MutableStateFlow<List<CharacterSheet>>(value = emptyList())
init { init {
@ -112,7 +112,7 @@ class CharacterSheetStore(
} }
private fun characterSheetFile(id: String): File { private fun characterSheetFile(id: String): File {
return File("${characterStorePath()}${id}.json") return File("${pathProvider.characterStorePath()}${id}.json")
} }
sealed class CharacterSheetStoreException(root: Exception) : Exception(root) sealed class CharacterSheetStoreException(root: Exception) : Exception(root)

View file

@ -1,55 +0,0 @@
package com.pixelized.shared.lwa
enum class OperatingSystem(
val home: String = System.getProperty("user.home"),
) {
Windows,
Macintosh;
companion object {
val current: OperatingSystem = run {
val name = System.getProperty("os.name")
when {
name.contains(other = "win", ignoreCase = true) -> Windows
name.contains(other = "mac", ignoreCase = true) -> Macintosh
else -> error("Unsupported operating system: $name")
}
}
}
}
fun storePath(
os: OperatingSystem = OperatingSystem.current,
): String {
return when (os) {
OperatingSystem.Windows -> "${os.home}\\AppData\\Roaming\\Pixelized\\"
OperatingSystem.Macintosh -> "${os.home}/Library/Pixelized/"
}
}
fun characterStorePath(
os: OperatingSystem = OperatingSystem.current,
): String {
return when (os) {
OperatingSystem.Windows -> "${storePath(os = os)}characters\\"
OperatingSystem.Macintosh -> "${storePath(os = os)}characters/"
}
}
fun campaignPath(
os: OperatingSystem = OperatingSystem.current,
): String {
return when (os) {
OperatingSystem.Windows -> "${storePath(os = os)}campaign\\"
OperatingSystem.Macintosh -> "${storePath(os = os)}campaign/"
}
}
fun alterationsPath(
os: OperatingSystem = OperatingSystem.current,
): String {
return when (os) {
OperatingSystem.Windows -> "${storePath(os = os)}alterations\\"
OperatingSystem.Macintosh -> "${storePath(os = os)}alterations/"
}
}

View file

@ -111,7 +111,7 @@ class CharacterSheetJsonFactory(
CharacterSheetJsonV1.Skill( CharacterSheetJsonV1.Skill(
id = it.id, id = it.id,
label = it.label, label = it.label,
description = null, description = it.description,
base = it.base, base = it.base,
bonus = it.bonus, bonus = it.bonus,
level = it.level, level = it.level,

View file

@ -0,0 +1,19 @@
package com.pixelized.shared.lwa.utils
enum class OperatingSystem(
val home: String = System.getProperty("user.home"),
) {
Windows,
Macintosh;
companion object {
val current: OperatingSystem = run {
val name = System.getProperty("os.name")
when {
name.contains(other = "win", ignoreCase = true) -> Windows
name.contains(other = "mac", ignoreCase = true) -> Macintosh
else -> error("Unsupported operating system: $name")
}
}
}
}

View file

@ -0,0 +1,46 @@
package com.pixelized.shared.lwa.utils
class PathProvider(
private val operatingSystem: OperatingSystem = OperatingSystem.current,
private val appName: String,
) {
fun storePath(
os: OperatingSystem = this.operatingSystem,
app: String = this.appName,
): String {
return when (os) {
OperatingSystem.Windows -> "${os.home}\\AppData\\Roaming\\Pixelized\\$app\\"
OperatingSystem.Macintosh -> "${os.home}/Library/Pixelized/$app/"
}
}
fun characterStorePath(
os: OperatingSystem = this.operatingSystem,
app: String = this.appName,
): String {
return when (os) {
OperatingSystem.Windows -> "${storePath(os = os, app = app)}characters\\"
OperatingSystem.Macintosh -> "${storePath(os = os, app = app)}characters/"
}
}
fun campaignPath(
os: OperatingSystem = this.operatingSystem,
app: String = this.appName,
): String {
return when (os) {
OperatingSystem.Windows -> "${storePath(os = os, app = app)}campaign\\"
OperatingSystem.Macintosh -> "${storePath(os = os, app = app)}campaign/"
}
}
fun alterationsPath(
os: OperatingSystem = this.operatingSystem,
app: String = this.appName,
): String {
return when (os) {
OperatingSystem.Windows -> "${storePath(os = os, app = app)}alterations\\"
OperatingSystem.Macintosh -> "${storePath(os = os, app = app)}alterations/"
}
}
}