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
|
|
@ -31,6 +31,9 @@ import androidx.compose.ui.unit.dp
|
|||
import androidx.compose.ui.window.ApplicationScope
|
||||
import androidx.compose.ui.window.Window
|
||||
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.Status
|
||||
import com.pixelized.desktop.lwa.ui.composable.key.KeyEventHandler
|
||||
|
|
@ -85,6 +88,13 @@ fun ApplicationScope.App() {
|
|||
val windowController = remember { WindowController(maxWindowHeight) }
|
||||
val keyEventHandlers = remember { mutableStateListOf<KeyEventHandler>() }
|
||||
|
||||
// Coil configuration
|
||||
setSingletonImageLoaderFactory { context ->
|
||||
ImageLoader.Builder(context)
|
||||
.crossfade(enable = false)
|
||||
.build()
|
||||
}
|
||||
|
||||
CompositionLocalProvider(
|
||||
LocalSnackHost provides snackHostState,
|
||||
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.usecase.SettingsUseCase
|
||||
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.engine.okhttp.OkHttp
|
||||
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
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
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.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.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
|
|
@ -14,6 +14,7 @@ import kotlinx.serialization.json.Json
|
|||
import java.io.File
|
||||
|
||||
class SettingsStore(
|
||||
private val pathProvider: PathProvider,
|
||||
private val factory: SettingsFactory,
|
||||
private val useCase: SettingsUseCase,
|
||||
private val jsonFormatter: Json,
|
||||
|
|
@ -24,7 +25,7 @@ class SettingsStore(
|
|||
|
||||
init {
|
||||
// create the directory
|
||||
File(storePath()).also { it.mkdirs() }
|
||||
File(pathProvider.storePath()).also { it.mkdirs() }
|
||||
// load the data.
|
||||
val scope = CoroutineScope(Dispatchers.IO + Job())
|
||||
scope.launch {
|
||||
|
|
@ -80,7 +81,7 @@ class SettingsStore(
|
|||
}
|
||||
|
||||
private fun settingsFile(): File {
|
||||
return File("${storePath()}settings.json")
|
||||
return File("${pathProvider.storePath()}settings.json")
|
||||
}
|
||||
|
||||
sealed class SettingsStoreException(root: Exception) : Exception(root)
|
||||
|
|
|
|||
|
|
@ -1,5 +1,12 @@
|
|||
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.clickable
|
||||
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.Row
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.fillMaxHeight
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.offset
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
|
|
@ -23,8 +32,8 @@ import androidx.compose.ui.Alignment
|
|||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.draw.drawWithContent
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.graphics.FilterQuality
|
||||
import androidx.compose.ui.graphics.graphicsLayer
|
||||
import androidx.compose.ui.layout.ContentScale
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
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_water_drop_24dp
|
||||
import org.jetbrains.compose.resources.painterResource
|
||||
import kotlin.math.max
|
||||
import kotlin.math.min
|
||||
|
||||
@Stable
|
||||
data class PlayerPortraitUio(
|
||||
|
|
@ -48,10 +59,17 @@ data class PlayerPortraitUio(
|
|||
val maxPp: Int,
|
||||
)
|
||||
|
||||
object PlayerPortrait {
|
||||
object Default {
|
||||
val bloodColor = Color(0xbb0a1e).copy(alpha = 0.25f)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun PlayerPortrait(
|
||||
modifier: Modifier = Modifier,
|
||||
size: DpSize,
|
||||
bloodColor: Color = PlayerPortrait.Default.bloodColor,
|
||||
character: PlayerPortraitUio,
|
||||
onCharacter: (id: Campaign.CharacterInstance.Id) -> Unit,
|
||||
) {
|
||||
|
|
@ -64,14 +82,26 @@ fun PlayerPortrait(
|
|||
.background(color = colorScheme.elevated.base1dp)
|
||||
.clickable { onCharacter(character.id) },
|
||||
) {
|
||||
AsyncImage(
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
model = character.portrait,
|
||||
contentScale = ContentScale.Crop,
|
||||
alignment = Alignment.TopCenter,
|
||||
filterQuality = FilterQuality.High,
|
||||
contentDescription = null,
|
||||
AnimatedContent(
|
||||
targetState = character.portrait,
|
||||
transitionSpec = { fadeIn() togetherWith fadeOut() },
|
||||
) { portrait ->
|
||||
AsyncImage(
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
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(
|
||||
modifier = Modifier
|
||||
.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.characterSheet.CharacterSheetRepository
|
||||
import com.pixelized.desktop.lwa.repository.network.NetworkRepository
|
||||
import com.pixelized.shared.lwa.OperatingSystem
|
||||
import com.pixelized.shared.lwa.storePath
|
||||
import com.pixelized.shared.lwa.utils.OperatingSystem
|
||||
import com.pixelized.shared.lwa.utils.PathProvider
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.flow.SharingStarted
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
|
|
@ -18,6 +18,7 @@ import kotlinx.coroutines.flow.map
|
|||
import kotlinx.coroutines.flow.stateIn
|
||||
|
||||
class MainPageViewModel(
|
||||
private val pathProvider: PathProvider,
|
||||
private val characterSheetRepository: CharacterSheetRepository,
|
||||
private val campaignRepository: CampaignRepository,
|
||||
networkRepository: NetworkRepository,
|
||||
|
|
@ -86,9 +87,10 @@ class MainPageViewModel(
|
|||
fun openSaveDirectory(
|
||||
os: OperatingSystem = OperatingSystem.current,
|
||||
) {
|
||||
val path = pathProvider.storePath(os = os)
|
||||
when (os) {
|
||||
OperatingSystem.Windows -> shellRun("explorer.exe", listOf(storePath(os = os)))
|
||||
OperatingSystem.Macintosh -> shellRun("open", listOf(storePath(os = os)))
|
||||
OperatingSystem.Windows -> shellRun("explorer.exe", listOf(path))
|
||||
OperatingSystem.Macintosh -> shellRun("open", listOf(path))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -3,7 +3,6 @@ package com.pixelized.desktop.lwa
|
|||
import androidx.compose.ui.window.application
|
||||
import com.pixelized.shared.lwa.sharedModuleDependencies
|
||||
import org.koin.compose.KoinContext
|
||||
import org.koin.core.context.loadKoinModules
|
||||
import org.koin.core.context.startKoin
|
||||
import javax.swing.UIManager
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue