Add directories to distingish between pixelized apps.
This commit is contained in:
parent
03df369e0b
commit
3f67e342a7
18 changed files with 178 additions and 108 deletions
|
|
@ -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$" />
|
||||||
|
|
@ -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$" />
|
||||||
|
|
@ -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$" />
|
||||||
|
|
@ -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$" />
|
||||||
|
|
@ -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,
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
@ -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))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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 {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -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> {
|
||||||
|
|
|
||||||
|
|
@ -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")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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/"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -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,
|
||||||
|
|
|
||||||
|
|
@ -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")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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/"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue