Add illustration to the maps.
This commit is contained in:
		
							parent
							
								
									8410d11799
								
							
						
					
					
						commit
						30b3de2681
					
				
					 11 changed files with 100 additions and 24 deletions
				
			
		| 
						 | 
				
			
			@ -9,5 +9,6 @@ data class Location(
 | 
			
		|||
    val category: String?,
 | 
			
		||||
    val uri: Uri?,
 | 
			
		||||
    val description: String?,
 | 
			
		||||
    val illustrations: List<Uri>,
 | 
			
		||||
    val child: List<Pair<Offset, Location>> = emptyList(),
 | 
			
		||||
)
 | 
			
		||||
| 
						 | 
				
			
			@ -4,7 +4,7 @@ import android.net.Uri
 | 
			
		|||
import com.pixelized.rplexicon.utilitary.extentions.toUriOrNull
 | 
			
		||||
import javax.inject.Inject
 | 
			
		||||
 | 
			
		||||
class PortraitParser @Inject constructor() {
 | 
			
		||||
class IllustrationParser @Inject constructor() {
 | 
			
		||||
 | 
			
		||||
    fun parse(value: String?): List<Uri> {
 | 
			
		||||
        return value?.split(SEPARATOR)?.mapNotNull { it.toUriOrNull() } ?: emptyList()
 | 
			
		||||
| 
						 | 
				
			
			@ -6,7 +6,7 @@ import com.pixelized.rplexicon.utilitary.exceptions.IncompatibleSheetStructure
 | 
			
		|||
import javax.inject.Inject
 | 
			
		||||
 | 
			
		||||
class LexiconParser @Inject constructor(
 | 
			
		||||
    private val portraitParser: PortraitParser,
 | 
			
		||||
    private val illustrationParser: IllustrationParser,
 | 
			
		||||
) {
 | 
			
		||||
    @Throws(IncompatibleSheetStructure::class)
 | 
			
		||||
    fun parse(sheet: ValueRange): List<Lexicon> = parserScope {
 | 
			
		||||
| 
						 | 
				
			
			@ -30,7 +30,7 @@ class LexiconParser @Inject constructor(
 | 
			
		|||
                            race = row.parse(column = RACE),
 | 
			
		||||
                            status = row.parse(column = STATUS),
 | 
			
		||||
                            location = row.parse(column = LOCATION),
 | 
			
		||||
                            portrait = portraitParser.parse(row.parse(column = PORTRAIT)),
 | 
			
		||||
                            portrait = illustrationParser.parse(row.parse(column = ILLUSTRATIONS)),
 | 
			
		||||
                            description = row.parse(column = DESCRIPTION),
 | 
			
		||||
                            history = row.parse(column = HISTORY),
 | 
			
		||||
                            tags = row.parse(column = TAGS),
 | 
			
		||||
| 
						 | 
				
			
			@ -52,7 +52,7 @@ class LexiconParser @Inject constructor(
 | 
			
		|||
        private val RACE = column("Race")
 | 
			
		||||
        private val STATUS = column("Statut")
 | 
			
		||||
        private val LOCATION = column("Localisation")
 | 
			
		||||
        private val PORTRAIT = column("Portrait")
 | 
			
		||||
        private val ILLUSTRATIONS = column("Portrait", "Illustrations")
 | 
			
		||||
        private val DESCRIPTION = column("Description")
 | 
			
		||||
        private val HISTORY = column("Histoire")
 | 
			
		||||
        private val TAGS = column("Mots clés")
 | 
			
		||||
| 
						 | 
				
			
			@ -66,7 +66,7 @@ class LexiconParser @Inject constructor(
 | 
			
		|||
                RACE,
 | 
			
		||||
                STATUS,
 | 
			
		||||
                LOCATION,
 | 
			
		||||
                PORTRAIT,
 | 
			
		||||
                ILLUSTRATIONS,
 | 
			
		||||
                DESCRIPTION,
 | 
			
		||||
                HISTORY,
 | 
			
		||||
                TAGS,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -7,7 +7,7 @@ import com.pixelized.rplexicon.data.model.QuestEntry
 | 
			
		|||
import javax.inject.Inject
 | 
			
		||||
 | 
			
		||||
class QuestParser @Inject constructor(
 | 
			
		||||
    private val imageParser: PortraitParser
 | 
			
		||||
    private val imageParser: IllustrationParser
 | 
			
		||||
) {
 | 
			
		||||
    fun parse(sheet: ValueRange): List<Quest> = parserScope {
 | 
			
		||||
        val entries = hashMapOf<String, MutableList<QuestEntry>>()
 | 
			
		||||
| 
						 | 
				
			
			@ -30,7 +30,7 @@ class QuestParser @Inject constructor(
 | 
			
		|||
                            groupReward = item.parse(column = GROUP_REWARD),
 | 
			
		||||
                            individualReward = item.parse(column = INDIVIDUAL_REWARD),
 | 
			
		||||
                            description = description,
 | 
			
		||||
                            images = imageParser.parse(item.parse(column = IMAGE)),
 | 
			
		||||
                            images = imageParser.parse(item.parse(column = ILLUSTRATIONS)),
 | 
			
		||||
                            background = item.parseUri(column = BACKGROUND),
 | 
			
		||||
                        )
 | 
			
		||||
                        entries.getOrPut(quest) { mutableListOf() }.add(entry)
 | 
			
		||||
| 
						 | 
				
			
			@ -62,7 +62,7 @@ class QuestParser @Inject constructor(
 | 
			
		|||
        private val GROUP_REWARD = column("Récompense de groupe")
 | 
			
		||||
        private val INDIVIDUAL_REWARD = column("Récompense individuelle")
 | 
			
		||||
        private val DESCRIPTION = column("Description")
 | 
			
		||||
        private val IMAGE = column("Image")
 | 
			
		||||
        private val ILLUSTRATIONS = column("Image", "Illustrations") // TODO remove Image after 0.9.0 release
 | 
			
		||||
        private val BACKGROUND = column("fond", "Fond") // TODO remove "fond" after 0.7.0 release
 | 
			
		||||
 | 
			
		||||
        private val COLUMNS
 | 
			
		||||
| 
						 | 
				
			
			@ -76,7 +76,7 @@ class QuestParser @Inject constructor(
 | 
			
		|||
                GROUP_REWARD,
 | 
			
		||||
                INDIVIDUAL_REWARD,
 | 
			
		||||
                DESCRIPTION,
 | 
			
		||||
                IMAGE,
 | 
			
		||||
                ILLUSTRATIONS,
 | 
			
		||||
                BACKGROUND,
 | 
			
		||||
            )
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -22,6 +22,7 @@ class LocationParser @Inject constructor(
 | 
			
		|||
                    category = localMap.category,
 | 
			
		||||
                    uri = localMap.uri,
 | 
			
		||||
                    description = localMap.description,
 | 
			
		||||
                    illustrations = localMap.illustrations,
 | 
			
		||||
                    child = emptyList(),
 | 
			
		||||
                )
 | 
			
		||||
            }.associateBy { it.name }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2,12 +2,15 @@ package com.pixelized.rplexicon.data.parser.map
 | 
			
		|||
 | 
			
		||||
import android.net.Uri
 | 
			
		||||
import com.google.api.services.sheets.v4.model.ValueRange
 | 
			
		||||
import com.pixelized.rplexicon.data.parser.IllustrationParser
 | 
			
		||||
import com.pixelized.rplexicon.data.parser.column
 | 
			
		||||
import com.pixelized.rplexicon.data.parser.parserScope
 | 
			
		||||
import com.pixelized.rplexicon.utilitary.exceptions.IncompatibleSheetStructure
 | 
			
		||||
import javax.inject.Inject
 | 
			
		||||
 | 
			
		||||
class MapParser @Inject constructor() {
 | 
			
		||||
class MapParser @Inject constructor(
 | 
			
		||||
    private val illustrationParser: IllustrationParser,
 | 
			
		||||
) {
 | 
			
		||||
 | 
			
		||||
    @Throws(IncompatibleSheetStructure::class)
 | 
			
		||||
    fun parse(sheet: ValueRange): List<MapDto> = parserScope {
 | 
			
		||||
| 
						 | 
				
			
			@ -21,6 +24,7 @@ class MapParser @Inject constructor() {
 | 
			
		|||
                    category = it.parse(column = CATEGORY),
 | 
			
		||||
                    uri = it.parseUri(column = URI),
 | 
			
		||||
                    description = it.parse(column = DESCRIPTION),
 | 
			
		||||
                    illustrations = illustrationParser.parse(it.parse(column = ILLUSTRATIONS)),
 | 
			
		||||
                )
 | 
			
		||||
                maps.add(map)
 | 
			
		||||
            }
 | 
			
		||||
| 
						 | 
				
			
			@ -34,6 +38,7 @@ class MapParser @Inject constructor() {
 | 
			
		|||
        val category: String?,
 | 
			
		||||
        val uri: Uri?,
 | 
			
		||||
        val description: String?,
 | 
			
		||||
        val illustrations: List<Uri>,
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
    companion object {
 | 
			
		||||
| 
						 | 
				
			
			@ -41,6 +46,7 @@ class MapParser @Inject constructor() {
 | 
			
		|||
        private val CATEGORY = column("Catégorie")
 | 
			
		||||
        private val URI = column("Carte")
 | 
			
		||||
        private val DESCRIPTION = column("Description")
 | 
			
		||||
        private val COLUMNS get() = listOf(NAME, CATEGORY, URI, DESCRIPTION)
 | 
			
		||||
        private val ILLUSTRATIONS = column("Illustrations")
 | 
			
		||||
        private val COLUMNS get() = listOf(NAME, CATEGORY, URI, DESCRIPTION, ILLUSTRATIONS)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,6 +1,5 @@
 | 
			
		|||
package com.pixelized.rplexicon.ui.screens.lexicon.detail
 | 
			
		||||
 | 
			
		||||
import android.content.res.Configuration
 | 
			
		||||
import android.content.res.Configuration.UI_MODE_NIGHT_NO
 | 
			
		||||
import android.content.res.Configuration.UI_MODE_NIGHT_YES
 | 
			
		||||
import android.net.Uri
 | 
			
		||||
| 
						 | 
				
			
			@ -33,8 +32,6 @@ import androidx.compose.material3.Surface
 | 
			
		|||
import androidx.compose.material3.Text
 | 
			
		||||
import androidx.compose.material3.TopAppBar
 | 
			
		||||
import androidx.compose.runtime.Composable
 | 
			
		||||
import androidx.compose.runtime.CompositionLocal
 | 
			
		||||
import androidx.compose.runtime.ProvidableCompositionLocal
 | 
			
		||||
import androidx.compose.runtime.Stable
 | 
			
		||||
import androidx.compose.runtime.State
 | 
			
		||||
import androidx.compose.runtime.mutableStateOf
 | 
			
		||||
| 
						 | 
				
			
			@ -100,7 +97,7 @@ fun LexiconDetailScreen(
 | 
			
		|||
            haveCharacterSheet = viewModel.haveCharacterSheet,
 | 
			
		||||
            onBack = { screen.popBackStack() },
 | 
			
		||||
            onCharacterSheet = { screen.navigateToCharacterSheet(name = it) },
 | 
			
		||||
            onImage = { imageViewModel.showDetail(it) }
 | 
			
		||||
            onIllustration = { imageViewModel.showDetail(it) }
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
        FullScreenImageHandler(
 | 
			
		||||
| 
						 | 
				
			
			@ -119,7 +116,7 @@ private fun LexiconDetailContent(
 | 
			
		|||
    haveCharacterSheet: State<Boolean>,
 | 
			
		||||
    onBack: () -> Unit,
 | 
			
		||||
    onCharacterSheet: (String) -> Unit,
 | 
			
		||||
    onImage: (Uri) -> Unit,
 | 
			
		||||
    onIllustration: (Uri) -> Unit,
 | 
			
		||||
) {
 | 
			
		||||
    val typography = MaterialTheme.lexicon.typography
 | 
			
		||||
    val highlightRegex = remember(highlight) { highlightRegex(terms = highlight.searchCriterion()) }
 | 
			
		||||
| 
						 | 
				
			
			@ -334,7 +331,7 @@ private fun LexiconDetailContent(
 | 
			
		|||
                        items(items = item.portrait) {
 | 
			
		||||
                            AsyncImage(
 | 
			
		||||
                                modifier = Modifier
 | 
			
		||||
                                    .clickable { onImage(it) }
 | 
			
		||||
                                    .clickable { onIllustration(it) }
 | 
			
		||||
                                    .sizeIn(
 | 
			
		||||
                                        minWidth = maxSize / 2,
 | 
			
		||||
                                        maxWidth = maxSize,
 | 
			
		||||
| 
						 | 
				
			
			@ -408,7 +405,7 @@ private fun LexiconDetailPreview() {
 | 
			
		|||
                haveCharacterSheet = remember { mutableStateOf(true) },
 | 
			
		||||
                onBack = { },
 | 
			
		||||
                onCharacterSheet = { },
 | 
			
		||||
                onImage = { },
 | 
			
		||||
                onIllustration = { },
 | 
			
		||||
            )
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -14,12 +14,16 @@ import androidx.compose.foundation.layout.Arrangement
 | 
			
		|||
import androidx.compose.foundation.layout.Box
 | 
			
		||||
import androidx.compose.foundation.layout.BoxWithConstraints
 | 
			
		||||
import androidx.compose.foundation.layout.Column
 | 
			
		||||
import androidx.compose.foundation.layout.PaddingValues
 | 
			
		||||
import androidx.compose.foundation.layout.Row
 | 
			
		||||
import androidx.compose.foundation.layout.fillMaxSize
 | 
			
		||||
import androidx.compose.foundation.layout.fillMaxWidth
 | 
			
		||||
import androidx.compose.foundation.layout.heightIn
 | 
			
		||||
import androidx.compose.foundation.layout.offset
 | 
			
		||||
import androidx.compose.foundation.layout.padding
 | 
			
		||||
import androidx.compose.foundation.layout.sizeIn
 | 
			
		||||
import androidx.compose.foundation.lazy.LazyRow
 | 
			
		||||
import androidx.compose.foundation.lazy.items
 | 
			
		||||
import androidx.compose.foundation.rememberScrollState
 | 
			
		||||
import androidx.compose.foundation.verticalScroll
 | 
			
		||||
import androidx.compose.material3.ExperimentalMaterial3Api
 | 
			
		||||
| 
						 | 
				
			
			@ -53,18 +57,24 @@ import androidx.compose.ui.graphics.RectangleShape
 | 
			
		|||
import androidx.compose.ui.input.nestedscroll.NestedScrollConnection
 | 
			
		||||
import androidx.compose.ui.input.nestedscroll.nestedScroll
 | 
			
		||||
import androidx.compose.ui.layout.ContentScale
 | 
			
		||||
import androidx.compose.ui.platform.LocalConfiguration
 | 
			
		||||
import androidx.compose.ui.platform.LocalContext
 | 
			
		||||
import androidx.compose.ui.platform.LocalUriHandler
 | 
			
		||||
import androidx.compose.ui.platform.LocalView
 | 
			
		||||
import androidx.compose.ui.res.painterResource
 | 
			
		||||
import androidx.compose.ui.res.stringResource
 | 
			
		||||
import androidx.compose.ui.text.style.TextAlign
 | 
			
		||||
import androidx.compose.ui.tooling.preview.Preview
 | 
			
		||||
import androidx.compose.ui.unit.Dp
 | 
			
		||||
import androidx.compose.ui.unit.IntOffset
 | 
			
		||||
import androidx.compose.ui.unit.Velocity
 | 
			
		||||
import androidx.compose.ui.unit.dp
 | 
			
		||||
import androidx.hilt.navigation.compose.hiltViewModel
 | 
			
		||||
import com.pixelized.rplexicon.LocalSnack
 | 
			
		||||
import com.pixelized.rplexicon.R
 | 
			
		||||
import com.pixelized.rplexicon.ui.composable.AsyncImage
 | 
			
		||||
import com.pixelized.rplexicon.ui.composable.FullScreenImageHandler
 | 
			
		||||
import com.pixelized.rplexicon.ui.composable.FullScreenImageViewModel
 | 
			
		||||
import com.pixelized.rplexicon.ui.composable.rememberBackgroundGradient
 | 
			
		||||
import com.pixelized.rplexicon.ui.navigation.LocalScreenNavHost
 | 
			
		||||
import com.pixelized.rplexicon.ui.navigation.screens.navigateToLocationDetail
 | 
			
		||||
| 
						 | 
				
			
			@ -86,12 +96,14 @@ data class LocationDetailUio(
 | 
			
		|||
    val name: String,
 | 
			
		||||
    val map: Uri?,
 | 
			
		||||
    val description: String?,
 | 
			
		||||
    val illustrations: List<Uri>,
 | 
			
		||||
    val marquees: List<MarqueeUio>,
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
@Composable
 | 
			
		||||
fun LocationDetailScreen(
 | 
			
		||||
    viewModel: LocationDetailViewModel = hiltViewModel()
 | 
			
		||||
    viewModel: LocationDetailViewModel = hiltViewModel(),
 | 
			
		||||
    imageViewModel: FullScreenImageViewModel = hiltViewModel(),
 | 
			
		||||
) {
 | 
			
		||||
    val uriHandler = LocalUriHandler.current
 | 
			
		||||
    val screen = LocalScreenNavHost.current
 | 
			
		||||
| 
						 | 
				
			
			@ -121,6 +133,7 @@ fun LocationDetailScreen(
 | 
			
		|||
            onBack = {
 | 
			
		||||
                screen.popBackStack()
 | 
			
		||||
            },
 | 
			
		||||
            onIllustration = { imageViewModel.showDetail(it) },
 | 
			
		||||
            onMarquee = viewModel::onSelectMarquee,
 | 
			
		||||
            onDestination = {
 | 
			
		||||
                screen.navigateToLocationDetail(id = it.id)
 | 
			
		||||
| 
						 | 
				
			
			@ -189,6 +202,10 @@ fun LocationDetailScreen(
 | 
			
		|||
                }
 | 
			
		||||
            },
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
        FullScreenImageHandler(
 | 
			
		||||
            viewModel = imageViewModel,
 | 
			
		||||
        )
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -203,6 +220,7 @@ private fun LocationContent(
 | 
			
		|||
    selectedIndex: State<Int?>,
 | 
			
		||||
    mapHighlight: State<Offset>,
 | 
			
		||||
    onBack: () -> Unit,
 | 
			
		||||
    onIllustration: (Uri) -> Unit,
 | 
			
		||||
    onMarquee: (MarqueeUio) -> Unit,
 | 
			
		||||
    onDestination: (MarqueeUio) -> Unit,
 | 
			
		||||
    onMapTap: (Offset) -> Unit,
 | 
			
		||||
| 
						 | 
				
			
			@ -398,6 +416,40 @@ private fun LocationContent(
 | 
			
		|||
                            ),
 | 
			
		||||
                        )
 | 
			
		||||
                    }
 | 
			
		||||
                    item.value?.illustrations?.takeIf { it.isNotEmpty() }?.let {
 | 
			
		||||
                        Column {
 | 
			
		||||
                            val maxSize = rememberMaxtWidth()
 | 
			
		||||
                            Text(
 | 
			
		||||
                                modifier = Modifier
 | 
			
		||||
                                    .padding(bottom = 8.dp)
 | 
			
		||||
                                    .padding(horizontal = 16.dp),
 | 
			
		||||
                                style = MaterialTheme.typography.titleMedium,
 | 
			
		||||
                                text = annotateWithDropCap(
 | 
			
		||||
                                    text = stringResource(id = R.string.map_illustrations),
 | 
			
		||||
                                    style = MaterialTheme.lexicon.typography.titleMediumDropCap,
 | 
			
		||||
                                )
 | 
			
		||||
                            )
 | 
			
		||||
                            LazyRow(
 | 
			
		||||
                                contentPadding = PaddingValues(horizontal = 16.dp),
 | 
			
		||||
                                horizontalArrangement = Arrangement.spacedBy(8.dp),
 | 
			
		||||
                            ) {
 | 
			
		||||
                                items(items = it) {
 | 
			
		||||
                                    AsyncImage(
 | 
			
		||||
                                        modifier = Modifier
 | 
			
		||||
                                            .clickable { onIllustration(it) }
 | 
			
		||||
                                            .sizeIn(
 | 
			
		||||
                                                minWidth = maxSize / 2,
 | 
			
		||||
                                                maxWidth = maxSize,
 | 
			
		||||
                                                minHeight = maxSize,
 | 
			
		||||
                                                maxHeight = maxSize,
 | 
			
		||||
                                            ),
 | 
			
		||||
                                        contentScale = ContentScale.FillHeight,
 | 
			
		||||
                                        model = it,
 | 
			
		||||
                                    )
 | 
			
		||||
                                }
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                    if (item.value?.marquees?.isNotEmpty() == true) {
 | 
			
		||||
                        Column {
 | 
			
		||||
                            Text(
 | 
			
		||||
| 
						 | 
				
			
			@ -467,6 +519,19 @@ private fun Modifier.offset(scrollState: ScrollState) = this.offset {
 | 
			
		|||
    IntOffset(x = 0, y = scrollState.value / 2)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@Composable
 | 
			
		||||
private fun rememberMaxtWidth(): Dp {
 | 
			
		||||
    val configuration = LocalConfiguration.current
 | 
			
		||||
    val view = LocalView.current
 | 
			
		||||
    return remember(configuration, view) {
 | 
			
		||||
        if (view.isInEditMode) {
 | 
			
		||||
            300.dp
 | 
			
		||||
        } else {
 | 
			
		||||
            (configuration.screenWidthDp.dp - 16.dp * 2)
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@Composable
 | 
			
		||||
@Preview(uiMode = Configuration.UI_MODE_NIGHT_NO)
 | 
			
		||||
@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES)
 | 
			
		||||
| 
						 | 
				
			
			@ -490,6 +555,7 @@ private fun LocationPreview() {
 | 
			
		|||
                            name = "Barovie",
 | 
			
		||||
                            map = Uri.parse("https://cdn.discordapp.com/attachments/1123326578508714106/1161014438736969759/Map_of_Barovia_-_4k_-_Names_-_No_Special_Locations_-_Without_Hex.jpg?ex=6536c1f4&is=65244cf4&hm=671ddc88d073e5559bd37af14dc731e497b78457dc37a3ea5620a5342004b733&"),
 | 
			
		||||
                            description = "Contrée sombre et maudite soumise au joug de Stradh von Zarovith",
 | 
			
		||||
                            illustrations = emptyList(),
 | 
			
		||||
                            marquees = listOf(
 | 
			
		||||
                                MarqueeUio(
 | 
			
		||||
                                    id = "Barovie (village)",
 | 
			
		||||
| 
						 | 
				
			
			@ -524,6 +590,7 @@ private fun LocationPreview() {
 | 
			
		|||
                selectedIndex = remember { mutableIntStateOf(0) },
 | 
			
		||||
                mapHighlight = remember { mutableStateOf(Offset(0.5f, 0.5f)) },
 | 
			
		||||
                onBack = { },
 | 
			
		||||
                onIllustration = { },
 | 
			
		||||
                onMarquee = { },
 | 
			
		||||
                onDestination = { },
 | 
			
		||||
                onMapTap = { },
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -6,7 +6,6 @@ import android.content.ClipboardManager
 | 
			
		|||
import android.content.Context.CLIPBOARD_SERVICE
 | 
			
		||||
import androidx.compose.runtime.State
 | 
			
		||||
import androidx.compose.runtime.mutableStateOf
 | 
			
		||||
import androidx.compose.runtime.remember
 | 
			
		||||
import androidx.compose.ui.geometry.Offset
 | 
			
		||||
import androidx.lifecycle.AndroidViewModel
 | 
			
		||||
import androidx.lifecycle.SavedStateHandle
 | 
			
		||||
| 
						 | 
				
			
			@ -53,6 +52,7 @@ class LocationDetailViewModel @Inject constructor(
 | 
			
		|||
                    name = it.name,
 | 
			
		||||
                    map = it.uri,
 | 
			
		||||
                    description = it.description,
 | 
			
		||||
                    illustrations = it.illustrations,
 | 
			
		||||
                    marquees = it.child.map { child ->
 | 
			
		||||
                        MarqueeUio(
 | 
			
		||||
                            id = child.second.id,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -58,11 +58,13 @@
 | 
			
		|||
    <string name="search_lexicon_item_description">Description :</string>
 | 
			
		||||
    <string name="search_lexicon_item_history">Histoire :</string>
 | 
			
		||||
    <string name="search_lexicon_item_tags">Mots clés :</string>
 | 
			
		||||
    <string name="search_quest_item_owner">Owner :</string>
 | 
			
		||||
    <string name="search_quest_item_location">Location :</string>
 | 
			
		||||
    <string name="search_quest_item_individualReward">Individual reward :</string>
 | 
			
		||||
    <string name="search_quest_item_groupReward">Group reward :</string>
 | 
			
		||||
    <string name="search_quest_item_owner">Commanditaire :</string>
 | 
			
		||||
    <string name="search_quest_item_location">Lieu :</string>
 | 
			
		||||
    <string name="search_quest_item_individualReward">Récompense individuelle :</string>
 | 
			
		||||
    <string name="search_quest_item_groupReward">Récompense de groupe :</string>
 | 
			
		||||
    <string name="search_quest_item_description">Description :</string>
 | 
			
		||||
    <string name="search_location_item_description">Description :</string>
 | 
			
		||||
    <string name="search_location_item_destination">Destination :</string>
 | 
			
		||||
 | 
			
		||||
    <string name="quest_detail_title">Détails de quête</string>
 | 
			
		||||
    <string name="quest_detail_completed">Complétée</string>
 | 
			
		||||
| 
						 | 
				
			
			@ -74,6 +76,7 @@
 | 
			
		|||
    <string name="map_title">Carte</string>
 | 
			
		||||
    <string name="map_label">Coordonnées</string>
 | 
			
		||||
    <string name="map_destination">Destinations :</string>
 | 
			
		||||
    <string name="map_illustrations">Illustrations :</string>
 | 
			
		||||
 | 
			
		||||
    <string name="character_sheet_tab_proficiency">Talents</string>
 | 
			
		||||
    <string name="character_sheet_tab_inventory">Inventaire</string>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -76,6 +76,7 @@
 | 
			
		|||
    <string name="map_title">Map</string>
 | 
			
		||||
    <string name="map_label">Coordinates</string>
 | 
			
		||||
    <string name="map_destination">Destinations:</string>
 | 
			
		||||
    <string name="map_illustrations">Illustrations:</string>
 | 
			
		||||
 | 
			
		||||
    <string name="character_sheet_tab_proficiency">Proficiencies</string>
 | 
			
		||||
    <string name="character_sheet_tab_inventory">Inventory</string>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue