Fix a crash related to default network config.
This commit is contained in:
		
							parent
							
								
									a617d4ba7b
								
							
						
					
					
						commit
						e2b3b54f88
					
				
					 18 changed files with 153 additions and 119 deletions
				
			
		| 
						 | 
				
			
			@ -36,7 +36,7 @@ class DataSyncViewModel(
 | 
			
		|||
 | 
			
		||||
        networkRepository.status
 | 
			
		||||
            .filter { status -> status == NetworkRepository.Status.CONNECTED }
 | 
			
		||||
            .onEach { campaignRepository.update() }
 | 
			
		||||
            .onEach { campaignRepository.campaign(update = true) }
 | 
			
		||||
            .launchIn(this)
 | 
			
		||||
 | 
			
		||||
        networkRepository.status
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -16,27 +16,27 @@ import com.pixelized.desktop.lwa.repository.settings.SettingsStore
 | 
			
		|||
import com.pixelized.desktop.lwa.ui.composable.character.characteristic.CharacterDetailCharacteristicDialogViewModel
 | 
			
		||||
import com.pixelized.desktop.lwa.ui.composable.character.characteristic.CharacterSheetCharacteristicDialogFactory
 | 
			
		||||
import com.pixelized.desktop.lwa.ui.overlay.roll.RollViewModel
 | 
			
		||||
import com.pixelized.desktop.lwa.ui.screen.campaign.toolbar.CampaignToolbarViewModel
 | 
			
		||||
import com.pixelized.desktop.lwa.ui.screen.campaign.text.CampaignChatViewModel
 | 
			
		||||
import com.pixelized.desktop.lwa.ui.screen.campaign.text.TextMessageFactory
 | 
			
		||||
import com.pixelized.desktop.lwa.ui.screen.campaign.network.NetworkFactory
 | 
			
		||||
import com.pixelized.desktop.lwa.ui.screen.campaign.network.NetworkViewModel
 | 
			
		||||
import com.pixelized.desktop.lwa.ui.screen.campaign.player.CharacterRibbonFactory
 | 
			
		||||
import com.pixelized.desktop.lwa.ui.screen.campaign.player.detail.CharacterDetailFactory
 | 
			
		||||
import com.pixelized.desktop.lwa.ui.screen.campaign.player.detail.CharacterDetailViewModel
 | 
			
		||||
import com.pixelized.desktop.lwa.ui.screen.campaign.player.detail.CharacterDiminishedViewModel
 | 
			
		||||
import com.pixelized.desktop.lwa.ui.screen.campaign.player.CharacterRibbonFactory
 | 
			
		||||
import com.pixelized.desktop.lwa.ui.screen.campaign.player.ribbon.npc.NpcRibbonViewModel
 | 
			
		||||
import com.pixelized.desktop.lwa.ui.screen.campaign.player.ribbon.player.PlayerRibbonViewModel
 | 
			
		||||
import com.pixelized.desktop.lwa.ui.screen.campaign.text.CampaignChatViewModel
 | 
			
		||||
import com.pixelized.desktop.lwa.ui.screen.campaign.text.TextMessageFactory
 | 
			
		||||
import com.pixelized.desktop.lwa.ui.screen.campaign.toolbar.CampaignToolbarViewModel
 | 
			
		||||
import com.pixelized.desktop.lwa.ui.screen.characterSheet.detail.CharacterSheetFactory
 | 
			
		||||
import com.pixelized.desktop.lwa.ui.screen.characterSheet.detail.CharacterSheetViewModel
 | 
			
		||||
import com.pixelized.desktop.lwa.ui.screen.characterSheet.edit.CharacterSheetEditFactory
 | 
			
		||||
import com.pixelized.desktop.lwa.ui.screen.characterSheet.edit.CharacterSheetEditViewModel
 | 
			
		||||
import com.pixelized.desktop.lwa.ui.screen.characterSheet.edit.common.SkillFieldFactory
 | 
			
		||||
import com.pixelized.desktop.lwa.ui.screen.levelup.LevelUpFactory
 | 
			
		||||
import com.pixelized.desktop.lwa.ui.screen.levelup.LevelUpViewModel
 | 
			
		||||
import com.pixelized.desktop.lwa.ui.screen.campaign.network.NetworkFactory
 | 
			
		||||
import com.pixelized.desktop.lwa.ui.screen.campaign.network.NetworkViewModel
 | 
			
		||||
import com.pixelized.desktop.lwa.ui.screen.campaign.player.ribbon.npc.NpcRibbonViewModel
 | 
			
		||||
import com.pixelized.desktop.lwa.ui.screen.gamemaster.GameMasterActionUseCase
 | 
			
		||||
import com.pixelized.desktop.lwa.ui.screen.gamemaster.GameMasterFactory
 | 
			
		||||
import com.pixelized.desktop.lwa.ui.screen.gamemaster.GameMasterViewModel
 | 
			
		||||
import com.pixelized.desktop.lwa.ui.screen.levelup.LevelUpFactory
 | 
			
		||||
import com.pixelized.desktop.lwa.ui.screen.levelup.LevelUpViewModel
 | 
			
		||||
import com.pixelized.desktop.lwa.ui.screen.rollhistory.RollHistoryViewModel
 | 
			
		||||
import com.pixelized.desktop.lwa.ui.screen.settings.SettingsViewModel
 | 
			
		||||
import com.pixelized.desktop.lwa.usecase.SettingsUseCase
 | 
			
		||||
| 
						 | 
				
			
			@ -77,7 +77,9 @@ val toolsDependencies
 | 
			
		|||
            }
 | 
			
		||||
        }
 | 
			
		||||
        single<LwaClient> {
 | 
			
		||||
            LwaClientImpl(get(), get())
 | 
			
		||||
            val client: HttpClient = get()
 | 
			
		||||
            val setting: SettingsRepository = get()
 | 
			
		||||
            LwaClientImpl(client, setting)
 | 
			
		||||
        }
 | 
			
		||||
        single {
 | 
			
		||||
            PathProvider(appName = "LwaClient")
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -17,8 +17,8 @@ class CampaignRepository(
 | 
			
		|||
 | 
			
		||||
    val campaignFlow get() = store.campaignFlow
 | 
			
		||||
 | 
			
		||||
    suspend fun update() {
 | 
			
		||||
        store.update()
 | 
			
		||||
    suspend fun campaign(update: Boolean) {
 | 
			
		||||
        store.campaign(update = update)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fun instanceFlow(
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -30,57 +30,78 @@ class CampaignStore(
 | 
			
		|||
    init {
 | 
			
		||||
        val scope = CoroutineScope(Dispatchers.IO + Job())
 | 
			
		||||
        scope.launch {
 | 
			
		||||
            update()
 | 
			
		||||
            campaign(update = true)
 | 
			
		||||
        }
 | 
			
		||||
        scope.launch {
 | 
			
		||||
            network.data.collect(::handleMessage)
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    suspend fun update() {
 | 
			
		||||
        _campaignFlow.value = load()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private suspend fun load(): Campaign {
 | 
			
		||||
    suspend fun campaign(update: Boolean): Campaign {
 | 
			
		||||
        val campaign = _campaignFlow.value
 | 
			
		||||
        if (update || campaign == Campaign.EMPTY) {
 | 
			
		||||
            val data = try {
 | 
			
		||||
                val request = client.campaign()
 | 
			
		||||
        val data = factory.convertFromJson(json = request)
 | 
			
		||||
        return data
 | 
			
		||||
                factory.convertFromJson(json = request)
 | 
			
		||||
            } catch (exception: Exception) {
 | 
			
		||||
                println(exception) // TODO
 | 
			
		||||
                Campaign.EMPTY
 | 
			
		||||
            }
 | 
			
		||||
            return _campaignFlow.update(data)
 | 
			
		||||
        }
 | 
			
		||||
        return campaign
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    suspend fun addCharacter(
 | 
			
		||||
        characterSheetId: String,
 | 
			
		||||
    ) {
 | 
			
		||||
        try {
 | 
			
		||||
            client.campaignAddCharacter(
 | 
			
		||||
                characterSheetId = characterSheetId
 | 
			
		||||
            )
 | 
			
		||||
        } catch (exception: Exception) {
 | 
			
		||||
            println(exception) // TODO
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    suspend fun removeCharacter(
 | 
			
		||||
        characterSheetId: String,
 | 
			
		||||
        instanceId: Int,
 | 
			
		||||
    ) {
 | 
			
		||||
        try {
 | 
			
		||||
            client.campaignRemoveCharacter(
 | 
			
		||||
                characterSheetId = characterSheetId,
 | 
			
		||||
                instanceId = instanceId,
 | 
			
		||||
            )
 | 
			
		||||
        } catch (exception: Exception) {
 | 
			
		||||
            println(exception) // TODO
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    suspend fun addNpc(
 | 
			
		||||
        characterSheetId: String,
 | 
			
		||||
    ) {
 | 
			
		||||
        try {
 | 
			
		||||
            client.campaignAddNpc(
 | 
			
		||||
                characterSheetId = characterSheetId
 | 
			
		||||
            )
 | 
			
		||||
        } catch (exception: Exception) {
 | 
			
		||||
            println(exception) // TODO
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    suspend fun removeNpc(
 | 
			
		||||
        characterSheetId: String,
 | 
			
		||||
        instanceId: Int,
 | 
			
		||||
    ) {
 | 
			
		||||
        try {
 | 
			
		||||
            client.campaignRemoveNpc(
 | 
			
		||||
                characterSheetId = characterSheetId,
 | 
			
		||||
                instanceId = instanceId,
 | 
			
		||||
            )
 | 
			
		||||
        } catch (exception: Exception) {
 | 
			
		||||
            println(exception) // TODO
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // region : WebSocket message Handling.
 | 
			
		||||
| 
						 | 
				
			
			@ -88,7 +109,7 @@ class CampaignStore(
 | 
			
		|||
    private suspend fun handleMessage(message: Message) {
 | 
			
		||||
        when (val payload = message.value) {
 | 
			
		||||
            is RestSynchronisation.Campaign -> {
 | 
			
		||||
                update()
 | 
			
		||||
                campaign(update = true)
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            is CampaignMessage -> {
 | 
			
		||||
| 
						 | 
				
			
			@ -177,4 +198,9 @@ class CampaignStore(
 | 
			
		|||
    }
 | 
			
		||||
 | 
			
		||||
    // endregion
 | 
			
		||||
 | 
			
		||||
    private fun MutableStateFlow<Campaign>.update(campaign: Campaign): Campaign {
 | 
			
		||||
        value = campaign
 | 
			
		||||
        return campaign
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,6 +1,6 @@
 | 
			
		|||
package com.pixelized.desktop.lwa.repository.characterSheet
 | 
			
		||||
 | 
			
		||||
import com.pixelized.desktop.lwa.repository.campaign.model.CharacterSheetPreview
 | 
			
		||||
import com.pixelized.shared.lwa.model.characterSheet.CharacterSheetPreview
 | 
			
		||||
import com.pixelized.shared.lwa.model.characterSheet.CharacterSheet
 | 
			
		||||
import kotlinx.coroutines.CoroutineScope
 | 
			
		||||
import kotlinx.coroutines.Dispatchers
 | 
			
		||||
| 
						 | 
				
			
			@ -20,7 +20,7 @@ class CharacterSheetRepository(
 | 
			
		|||
    val characterDetailFlow get() = store.detailFlow
 | 
			
		||||
 | 
			
		||||
    suspend fun updateCharacterPreviews() {
 | 
			
		||||
        store.updateCharacterPreviews()
 | 
			
		||||
        store.charactersPreview()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fun characterPreview(characterId: String?): CharacterSheetPreview? {
 | 
			
		||||
| 
						 | 
				
			
			@ -33,8 +33,8 @@ class CharacterSheetRepository(
 | 
			
		|||
    ): CharacterSheet? {
 | 
			
		||||
        return try {
 | 
			
		||||
            characterSheetId?.let {
 | 
			
		||||
                store.characterDetail(
 | 
			
		||||
                    characterId = it,
 | 
			
		||||
                store.getCharacterSheet(
 | 
			
		||||
                    characterSheetId = it,
 | 
			
		||||
                    forceUpdate = forceUpdate
 | 
			
		||||
                )
 | 
			
		||||
            }
 | 
			
		||||
| 
						 | 
				
			
			@ -61,12 +61,12 @@ class CharacterSheetRepository(
 | 
			
		|||
    suspend fun updateCharacter(
 | 
			
		||||
        characterSheet: CharacterSheet,
 | 
			
		||||
    ) {
 | 
			
		||||
        store.updateCharacter(sheet = characterSheet)
 | 
			
		||||
        store.updateCharacterSheet(sheet = characterSheet)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    suspend fun deleteCharacter(
 | 
			
		||||
        characterId: String,
 | 
			
		||||
    ) {
 | 
			
		||||
        store.deleteCharacter(characterId = characterId)
 | 
			
		||||
        store.deleteCharacterSheet(characterId = characterId)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,10 +1,10 @@
 | 
			
		|||
package com.pixelized.desktop.lwa.repository.characterSheet
 | 
			
		||||
 | 
			
		||||
import com.pixelized.desktop.lwa.network.LwaClient
 | 
			
		||||
import com.pixelized.desktop.lwa.repository.campaign.model.CharacterSheetPreview
 | 
			
		||||
import com.pixelized.desktop.lwa.repository.network.NetworkRepository
 | 
			
		||||
import com.pixelized.shared.lwa.model.characterSheet.CharacterSheet
 | 
			
		||||
import com.pixelized.shared.lwa.model.characterSheet.CharacterSheetJsonFactory
 | 
			
		||||
import com.pixelized.shared.lwa.model.characterSheet.CharacterSheetPreview
 | 
			
		||||
import com.pixelized.shared.lwa.protocol.websocket.Message
 | 
			
		||||
import com.pixelized.shared.lwa.protocol.websocket.payload.RestSynchronisation
 | 
			
		||||
import com.pixelized.shared.lwa.protocol.websocket.payload.UpdateSkillUsageMessage
 | 
			
		||||
| 
						 | 
				
			
			@ -32,7 +32,7 @@ class CharacterSheetStore(
 | 
			
		|||
        val scope = CoroutineScope(Dispatchers.IO + Job())
 | 
			
		||||
        // initial data loading.
 | 
			
		||||
        scope.launch {
 | 
			
		||||
            updateCharacterPreviews()
 | 
			
		||||
            charactersPreview()
 | 
			
		||||
        }
 | 
			
		||||
        // data update through WebSocket.
 | 
			
		||||
        scope.launch {
 | 
			
		||||
| 
						 | 
				
			
			@ -42,58 +42,55 @@ class CharacterSheetStore(
 | 
			
		|||
 | 
			
		||||
    // region Rest
 | 
			
		||||
 | 
			
		||||
    suspend fun updateCharacterPreviews() {
 | 
			
		||||
        _previewFlow.value = charactersPreview()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    suspend fun charactersPreview(): List<CharacterSheetPreview> {
 | 
			
		||||
        val request = client.characters()
 | 
			
		||||
        val data = request.map {
 | 
			
		||||
            CharacterSheetPreview(
 | 
			
		||||
                characterSheetId = it.id,
 | 
			
		||||
                name = it.name,
 | 
			
		||||
                level = it.level,
 | 
			
		||||
            )
 | 
			
		||||
        val request = try {
 | 
			
		||||
            client.characters()
 | 
			
		||||
        } catch (exception: Exception) {
 | 
			
		||||
            println(exception) // TODO
 | 
			
		||||
            emptyList()
 | 
			
		||||
        }
 | 
			
		||||
        return data
 | 
			
		||||
        val characters = request.map { factory.convertFromJson(it) }
 | 
			
		||||
        return _previewFlow.update(characters)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    suspend fun characterDetail(
 | 
			
		||||
        characterId: String,
 | 
			
		||||
    suspend fun getCharacterSheet(
 | 
			
		||||
        characterSheetId: String,
 | 
			
		||||
        forceUpdate: Boolean = false,
 | 
			
		||||
    ): CharacterSheet {
 | 
			
		||||
        val character = _detailFlow.value[characterId]
 | 
			
		||||
    ): CharacterSheet? {
 | 
			
		||||
        val character = _detailFlow.value[characterSheetId]
 | 
			
		||||
        if (forceUpdate || character == null) {
 | 
			
		||||
            val request = client.character(id = characterId)
 | 
			
		||||
            try {
 | 
			
		||||
                val request = client.character(id = characterSheetId)
 | 
			
		||||
                val data = factory.convertFromJson(json = request)
 | 
			
		||||
            // update the local detail flow.
 | 
			
		||||
                return _detailFlow.update(data)
 | 
			
		||||
        } else {
 | 
			
		||||
            } catch (exception: Exception) {
 | 
			
		||||
                println(exception) // TODO
 | 
			
		||||
                return null
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return character
 | 
			
		||||
    }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    suspend fun updateCharacter(
 | 
			
		||||
    suspend fun updateCharacterSheet(
 | 
			
		||||
        sheet: CharacterSheet,
 | 
			
		||||
    ) {
 | 
			
		||||
        val json = factory.convertToJson(sheet = sheet)
 | 
			
		||||
        try {
 | 
			
		||||
            client.updateCharacter(sheet = json)
 | 
			
		||||
        } catch (exception: Exception) {
 | 
			
		||||
            // TODO
 | 
			
		||||
            println(exception)
 | 
			
		||||
            println(exception) // TODO
 | 
			
		||||
        }
 | 
			
		||||
        _detailFlow.update(sheet = sheet)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    suspend fun deleteCharacter(
 | 
			
		||||
    suspend fun deleteCharacterSheet(
 | 
			
		||||
        characterId: String,
 | 
			
		||||
    ) {
 | 
			
		||||
        try {
 | 
			
		||||
            client.deleteCharacterSheet(id = characterId)
 | 
			
		||||
            _detailFlow.delete(characterId = characterId)
 | 
			
		||||
        } catch (exception: Exception) {
 | 
			
		||||
            // TODO
 | 
			
		||||
            println(exception) // TODO
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -102,8 +99,8 @@ class CharacterSheetStore(
 | 
			
		|||
 | 
			
		||||
    private suspend fun handleMessage(message: Message) {
 | 
			
		||||
        when (val payload = message.value) {
 | 
			
		||||
            is RestSynchronisation.CharacterUpdate -> characterDetail(
 | 
			
		||||
                characterId = payload.id,
 | 
			
		||||
            is RestSynchronisation.CharacterUpdate -> getCharacterSheet(
 | 
			
		||||
                characterSheetId = payload.id,
 | 
			
		||||
                forceUpdate = true
 | 
			
		||||
            )
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -130,24 +127,38 @@ class CharacterSheetStore(
 | 
			
		|||
        skillId: String,
 | 
			
		||||
        used: Boolean,
 | 
			
		||||
    ) {
 | 
			
		||||
        val sheet = getCharacterSheet(characterSheetId = characterId) ?: return
 | 
			
		||||
 | 
			
		||||
        val character = useCase.updateSkillUsage(
 | 
			
		||||
            character = characterDetail(characterId = characterId),
 | 
			
		||||
            character = sheet,
 | 
			
		||||
            skillId = skillId,
 | 
			
		||||
            used = used,
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
        _detailFlow.update(character)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // endregion
 | 
			
		||||
 | 
			
		||||
    private fun MutableStateFlow<Map<String, CharacterSheet>>.update(sheet: CharacterSheet): CharacterSheet {
 | 
			
		||||
    private fun MutableStateFlow<List<CharacterSheetPreview>>.update(
 | 
			
		||||
        previews: List<CharacterSheetPreview>,
 | 
			
		||||
    ): List<CharacterSheetPreview> {
 | 
			
		||||
        value = previews
 | 
			
		||||
        return previews
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private fun MutableStateFlow<Map<String, CharacterSheet>>.update(
 | 
			
		||||
        sheet: CharacterSheet,
 | 
			
		||||
    ): CharacterSheet {
 | 
			
		||||
        value = value.toMutableMap().also {
 | 
			
		||||
            it[sheet.id] = sheet
 | 
			
		||||
        }
 | 
			
		||||
        return sheet
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private fun MutableStateFlow<Map<String, CharacterSheet>>.delete(characterId: String) {
 | 
			
		||||
    private fun MutableStateFlow<Map<String, CharacterSheet>>.delete(
 | 
			
		||||
        characterId: String,
 | 
			
		||||
    ) {
 | 
			
		||||
        value = value.toMutableMap().also {
 | 
			
		||||
            it.remove(characterId)
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -22,7 +22,7 @@ class SettingsFactory(
 | 
			
		|||
            autoShowChat = settings.autoShowChat,
 | 
			
		||||
            autoScrollChat = settings.autoScrollChat,
 | 
			
		||||
            isAdmin = settings.isAdmin,
 | 
			
		||||
            isGM = settings.isGM,
 | 
			
		||||
            isGameMaster = settings.isGameMaster,
 | 
			
		||||
        )
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -48,7 +48,7 @@ class SettingsFactory(
 | 
			
		|||
            autoShowChat = json.autoShowChat ?: default.autoShowChat,
 | 
			
		||||
            autoScrollChat = json.autoScrollChat ?: default.autoScrollChat,
 | 
			
		||||
            isAdmin = json.isAdmin ?: default.isAdmin,
 | 
			
		||||
            isGM = json.isGM ?: default.isGM,
 | 
			
		||||
            isGameMaster = json.isGameMaster ?: default.isGameMaster,
 | 
			
		||||
        )
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,30 +1,16 @@
 | 
			
		|||
package com.pixelized.desktop.lwa.repository.settings
 | 
			
		||||
 | 
			
		||||
import com.pixelized.desktop.lwa.usecase.SettingsUseCase
 | 
			
		||||
import com.pixelized.desktop.lwa.repository.settings.model.Settings
 | 
			
		||||
import kotlinx.coroutines.CoroutineScope
 | 
			
		||||
import kotlinx.coroutines.Dispatchers
 | 
			
		||||
import kotlinx.coroutines.Job
 | 
			
		||||
import kotlinx.coroutines.flow.SharingStarted
 | 
			
		||||
import com.pixelized.desktop.lwa.usecase.SettingsUseCase
 | 
			
		||||
import kotlinx.coroutines.flow.StateFlow
 | 
			
		||||
import kotlinx.coroutines.flow.stateIn
 | 
			
		||||
 | 
			
		||||
class SettingsRepository(
 | 
			
		||||
    private val store: SettingsStore,
 | 
			
		||||
    private val useCase: SettingsUseCase,
 | 
			
		||||
) {
 | 
			
		||||
    private val scope = CoroutineScope(Dispatchers.IO + Job())
 | 
			
		||||
    fun settingsFlow(): StateFlow<Settings> = store.settingsFlow
 | 
			
		||||
 | 
			
		||||
    private val settings = store.settingsFlow()
 | 
			
		||||
        .stateIn(
 | 
			
		||||
            scope = scope,
 | 
			
		||||
            started = SharingStarted.Eagerly,
 | 
			
		||||
            initialValue = useCase.defaultSettings()
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
    fun settingsFlow(): StateFlow<Settings> = settings
 | 
			
		||||
 | 
			
		||||
    fun settings(): Settings = settings.value
 | 
			
		||||
    fun settings(): Settings = store.settingsFlow.value
 | 
			
		||||
 | 
			
		||||
    fun update(settings: Settings) {
 | 
			
		||||
        store.save(settings = settings)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -4,12 +4,9 @@ import com.pixelized.desktop.lwa.repository.settings.model.Settings
 | 
			
		|||
import com.pixelized.desktop.lwa.repository.settings.model.SettingsJson
 | 
			
		||||
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
 | 
			
		||||
import kotlinx.coroutines.flow.MutableStateFlow
 | 
			
		||||
import kotlinx.coroutines.flow.StateFlow
 | 
			
		||||
import kotlinx.coroutines.launch
 | 
			
		||||
import kotlinx.coroutines.runBlocking
 | 
			
		||||
import kotlinx.serialization.json.Json
 | 
			
		||||
import java.io.File
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -19,17 +16,19 @@ class SettingsStore(
 | 
			
		|||
    private val useCase: SettingsUseCase,
 | 
			
		||||
    private val jsonFormatter: Json,
 | 
			
		||||
) {
 | 
			
		||||
    private val flow = MutableStateFlow(value = useCase.defaultSettings())
 | 
			
		||||
 | 
			
		||||
    fun settingsFlow(): StateFlow<Settings> = flow
 | 
			
		||||
    private val _settingsFlow = MutableStateFlow(value = useCase.defaultSettings())
 | 
			
		||||
    val settingsFlow: StateFlow<Settings> = _settingsFlow
 | 
			
		||||
 | 
			
		||||
    init {
 | 
			
		||||
        // create the directory
 | 
			
		||||
        File(pathProvider.storePath()).also { it.mkdirs() }
 | 
			
		||||
        // load the data.
 | 
			
		||||
        val scope = CoroutineScope(Dispatchers.IO + Job())
 | 
			
		||||
        scope.launch {
 | 
			
		||||
            flow.value = load()
 | 
			
		||||
        runBlocking {
 | 
			
		||||
            try {
 | 
			
		||||
                _settingsFlow.value = load()
 | 
			
		||||
            } catch (exception: Exception) {
 | 
			
		||||
                println(exception) // TODO
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -55,7 +54,7 @@ class SettingsStore(
 | 
			
		|||
                root = exception
 | 
			
		||||
            )
 | 
			
		||||
        }
 | 
			
		||||
        flow.value = settings
 | 
			
		||||
        _settingsFlow.value = settings
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private fun load(): Settings {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -9,8 +9,8 @@ data class Settings(
 | 
			
		|||
    val autoHideDelay: Int,
 | 
			
		||||
    val autoShowChat: Boolean,
 | 
			
		||||
    val autoScrollChat: Boolean,
 | 
			
		||||
    val isAdmin: Boolean,
 | 
			
		||||
    val isGM: Boolean,
 | 
			
		||||
    val isAdmin: Boolean? = null,
 | 
			
		||||
    val isGameMaster: Boolean? = null,
 | 
			
		||||
) {
 | 
			
		||||
    val root: String get() = "http://${"${host}:${port}".removePrefix("http://")}"
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -12,6 +12,6 @@ data class SettingsJsonV1(
 | 
			
		|||
    val autoHideDelay: Int?,
 | 
			
		||||
    val autoShowChat: Boolean?,
 | 
			
		||||
    val autoScrollChat: Boolean?,
 | 
			
		||||
    val isGM: Boolean?,
 | 
			
		||||
    val isGameMaster: Boolean?,
 | 
			
		||||
    val isAdmin: Boolean?,
 | 
			
		||||
) : SettingsJson
 | 
			
		||||
| 
						 | 
				
			
			@ -68,9 +68,9 @@ abstract class CharacterRibbonViewModel(
 | 
			
		|||
                                alterations = alterations,
 | 
			
		||||
                                characterInstanceId = entry.key,
 | 
			
		||||
                                characterInstance = entry.value,
 | 
			
		||||
                                enableCharacterId = settings.isGM,
 | 
			
		||||
                                enableCharacterSheet = enableCharacterSheet || settings.isGM,
 | 
			
		||||
                                enableCharacterStats = enableCharacterStats || settings.isGM,
 | 
			
		||||
                                enableCharacterId = settings.isGameMaster ?: false,
 | 
			
		||||
                                enableCharacterSheet = enableCharacterSheet || settings.isGameMaster ?: false,
 | 
			
		||||
                                enableCharacterStats = enableCharacterStats || settings.isGameMaster ?: false,
 | 
			
		||||
                            )
 | 
			
		||||
                        }
 | 
			
		||||
                    },
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -26,7 +26,7 @@ class CampaignToolbarViewModel(
 | 
			
		|||
        )
 | 
			
		||||
 | 
			
		||||
    val isAdmin = settingsRepository.settingsFlow()
 | 
			
		||||
        .map { it.isAdmin }
 | 
			
		||||
        .map { it.isAdmin ?: false }
 | 
			
		||||
        .stateIn(
 | 
			
		||||
            scope = viewModelScope,
 | 
			
		||||
            started = SharingStarted.Lazily,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,6 +1,6 @@
 | 
			
		|||
package com.pixelized.desktop.lwa.ui.screen.gamemaster
 | 
			
		||||
 | 
			
		||||
import com.pixelized.desktop.lwa.repository.campaign.model.CharacterSheetPreview
 | 
			
		||||
import com.pixelized.shared.lwa.model.characterSheet.CharacterSheetPreview
 | 
			
		||||
import com.pixelized.desktop.lwa.ui.screen.gamemaster.items.GMCharacterUio
 | 
			
		||||
import com.pixelized.desktop.lwa.ui.screen.gamemaster.items.GMCharacterUio.Action
 | 
			
		||||
import com.pixelized.desktop.lwa.ui.screen.gamemaster.items.GMTagUio
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -76,7 +76,7 @@ class GameMasterViewModel(
 | 
			
		|||
        val settings = settingsRepository.settings()
 | 
			
		||||
        settingsRepository.update(
 | 
			
		||||
            settings = settings.copy(
 | 
			
		||||
                isGM = settings.isGM.not(),
 | 
			
		||||
                isGameMaster = (settings.isGameMaster ?: false).not(),
 | 
			
		||||
            )
 | 
			
		||||
        )
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -13,8 +13,8 @@ class SettingsUseCase {
 | 
			
		|||
        autoHideDelay = 8,
 | 
			
		||||
        autoShowChat = true,
 | 
			
		||||
        autoScrollChat = true,
 | 
			
		||||
        isAdmin = false,
 | 
			
		||||
        isGM = false,
 | 
			
		||||
        isAdmin = null,
 | 
			
		||||
        isGameMaster = null,
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
    companion object {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -15,6 +15,16 @@ class CharacterSheetJsonFactory(
 | 
			
		|||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    suspend fun convertFromJson(
 | 
			
		||||
        json: CharacterPreviewJson,
 | 
			
		||||
    ): CharacterSheetPreview {
 | 
			
		||||
        return CharacterSheetPreview(
 | 
			
		||||
            characterSheetId = json.id,
 | 
			
		||||
            name = json.name,
 | 
			
		||||
            level = json.level,
 | 
			
		||||
        )
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private suspend fun convertFromV1(
 | 
			
		||||
        json: CharacterSheetJsonV1,
 | 
			
		||||
    ): CharacterSheet = characterSheetUseCase.run {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,4 +1,4 @@
 | 
			
		|||
package com.pixelized.desktop.lwa.repository.campaign.model
 | 
			
		||||
package com.pixelized.shared.lwa.model.characterSheet
 | 
			
		||||
 | 
			
		||||
data class CharacterSheetPreview(
 | 
			
		||||
    val characterSheetId: String,
 | 
			
		||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue