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