Add description update feature, reduce update frequence.
This commit is contained in:
parent
c95360d9f1
commit
4ac1dedfb3
3 changed files with 40 additions and 4 deletions
|
|
@ -5,6 +5,9 @@ package com.pixelized.rplexicon.ui.screens.character
|
||||||
import android.content.res.Configuration
|
import android.content.res.Configuration
|
||||||
import androidx.activity.compose.BackHandler
|
import androidx.activity.compose.BackHandler
|
||||||
import androidx.compose.foundation.ExperimentalFoundationApi
|
import androidx.compose.foundation.ExperimentalFoundationApi
|
||||||
|
import androidx.compose.foundation.clickable
|
||||||
|
import androidx.compose.foundation.combinedClickable
|
||||||
|
import androidx.compose.foundation.interaction.MutableInteractionSource
|
||||||
import androidx.compose.foundation.layout.Box
|
import androidx.compose.foundation.layout.Box
|
||||||
import androidx.compose.foundation.layout.BoxScope
|
import androidx.compose.foundation.layout.BoxScope
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
|
|
@ -26,6 +29,7 @@ import androidx.compose.material.pullrefresh.PullRefreshState
|
||||||
import androidx.compose.material.pullrefresh.pullRefresh
|
import androidx.compose.material.pullrefresh.pullRefresh
|
||||||
import androidx.compose.material.pullrefresh.rememberPullRefreshState
|
import androidx.compose.material.pullrefresh.rememberPullRefreshState
|
||||||
import androidx.compose.material.rememberModalBottomSheetState
|
import androidx.compose.material.rememberModalBottomSheetState
|
||||||
|
import androidx.compose.material.ripple.rememberRipple
|
||||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||||
import androidx.compose.material3.Icon
|
import androidx.compose.material3.Icon
|
||||||
import androidx.compose.material3.IconButton
|
import androidx.compose.material3.IconButton
|
||||||
|
|
@ -33,14 +37,17 @@ import androidx.compose.material3.Scaffold
|
||||||
import androidx.compose.material3.Surface
|
import androidx.compose.material3.Surface
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.material3.TopAppBar
|
import androidx.compose.material3.TopAppBar
|
||||||
|
import androidx.compose.material3.minimumInteractiveComponentSize
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.runtime.rememberCoroutineScope
|
import androidx.compose.runtime.rememberCoroutineScope
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.draw.shadow
|
import androidx.compose.ui.draw.shadow
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.res.painterResource
|
import androidx.compose.ui.res.painterResource
|
||||||
|
import androidx.compose.ui.semantics.Role
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
import androidx.compose.ui.tooling.preview.PreviewParameter
|
import androidx.compose.ui.tooling.preview.PreviewParameter
|
||||||
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
|
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
|
||||||
|
|
@ -113,6 +120,9 @@ fun CharacterSheetScreen(
|
||||||
onRefresh = {
|
onRefresh = {
|
||||||
scope.launch { viewModel.update(force = true) }
|
scope.launch { viewModel.update(force = true) }
|
||||||
},
|
},
|
||||||
|
onFullRefresh = {
|
||||||
|
scope.launch { viewModel.update(force = true, full = true) }
|
||||||
|
},
|
||||||
onBack = {
|
onBack = {
|
||||||
screen.popBackStack()
|
screen.popBackStack()
|
||||||
},
|
},
|
||||||
|
|
@ -192,6 +202,7 @@ private fun CharacterSheetContent(
|
||||||
sheetState: ModalBottomSheetState,
|
sheetState: ModalBottomSheetState,
|
||||||
refreshState: PullRefreshState,
|
refreshState: PullRefreshState,
|
||||||
onRefresh: () -> Unit,
|
onRefresh: () -> Unit,
|
||||||
|
onFullRefresh: () -> Unit,
|
||||||
name: String,
|
name: String,
|
||||||
onBack: () -> Unit,
|
onBack: () -> Unit,
|
||||||
loader: @Composable BoxScope.() -> Unit,
|
loader: @Composable BoxScope.() -> Unit,
|
||||||
|
|
@ -217,7 +228,18 @@ private fun CharacterSheetContent(
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
actions = {
|
actions = {
|
||||||
IconButton(onClick = onRefresh) {
|
Box(
|
||||||
|
modifier = Modifier
|
||||||
|
.minimumInteractiveComponentSize()
|
||||||
|
.combinedClickable(
|
||||||
|
onClick = onRefresh,
|
||||||
|
onLongClick = onFullRefresh,
|
||||||
|
role = Role.Button,
|
||||||
|
interactionSource = remember { MutableInteractionSource() },
|
||||||
|
indication = rememberRipple(bounded = false)
|
||||||
|
),
|
||||||
|
contentAlignment = Alignment.Center
|
||||||
|
) {
|
||||||
Icon(
|
Icon(
|
||||||
imageVector = Icons.Default.Refresh,
|
imageVector = Icons.Default.Refresh,
|
||||||
contentDescription = null,
|
contentDescription = null,
|
||||||
|
|
@ -299,6 +321,7 @@ private fun CharacterScreenPreview(
|
||||||
name = "Brulkhai",
|
name = "Brulkhai",
|
||||||
onBack = { },
|
onBack = { },
|
||||||
onRefresh = { },
|
onRefresh = { },
|
||||||
|
onFullRefresh = { },
|
||||||
loader = { },
|
loader = { },
|
||||||
proficiencies = { ProficiencyPreview() },
|
proficiencies = { ProficiencyPreview() },
|
||||||
actions = { ActionPagePreview() },
|
actions = { ActionPagePreview() },
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ import com.pixelized.rplexicon.repository.authentication.FirebaseRepository
|
||||||
import com.pixelized.rplexicon.repository.data.ActionRepository
|
import com.pixelized.rplexicon.repository.data.ActionRepository
|
||||||
import com.pixelized.rplexicon.repository.data.AlterationRepository
|
import com.pixelized.rplexicon.repository.data.AlterationRepository
|
||||||
import com.pixelized.rplexicon.repository.data.CharacterSheetRepository
|
import com.pixelized.rplexicon.repository.data.CharacterSheetRepository
|
||||||
|
import com.pixelized.rplexicon.repository.data.DescriptionRepository
|
||||||
import com.pixelized.rplexicon.repository.data.SkillRepository
|
import com.pixelized.rplexicon.repository.data.SkillRepository
|
||||||
import com.pixelized.rplexicon.repository.data.SpellRepository
|
import com.pixelized.rplexicon.repository.data.SpellRepository
|
||||||
import com.pixelized.rplexicon.ui.composable.error.FetchErrorUio
|
import com.pixelized.rplexicon.ui.composable.error.FetchErrorUio
|
||||||
|
|
@ -26,6 +27,7 @@ import javax.inject.Inject
|
||||||
@HiltViewModel
|
@HiltViewModel
|
||||||
class CharacterSheetViewModel @Inject constructor(
|
class CharacterSheetViewModel @Inject constructor(
|
||||||
private val characterRepository: CharacterSheetRepository,
|
private val characterRepository: CharacterSheetRepository,
|
||||||
|
private val descriptionRepository: DescriptionRepository,
|
||||||
private val alterationRepository: AlterationRepository,
|
private val alterationRepository: AlterationRepository,
|
||||||
private val actionRepository: ActionRepository,
|
private val actionRepository: ActionRepository,
|
||||||
private val spellRepository: SpellRepository,
|
private val spellRepository: SpellRepository,
|
||||||
|
|
@ -54,7 +56,7 @@ class CharacterSheetViewModel @Inject constructor(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun update(force: Boolean) = coroutineScope {
|
suspend fun update(force: Boolean, full: Boolean = false) = coroutineScope {
|
||||||
_isLoading.value = true
|
_isLoading.value = true
|
||||||
val characters = async {
|
val characters = async {
|
||||||
try {
|
try {
|
||||||
|
|
@ -67,7 +69,18 @@ class CharacterSheetViewModel @Inject constructor(
|
||||||
Log.e(TAG, exception.message, exception)
|
Log.e(TAG, exception.message, exception)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
awaitAll(characters)
|
val description = async {
|
||||||
|
try {
|
||||||
|
if (full && (force || characterRepository.lastSuccessFullUpdate.shouldUpdate())) {
|
||||||
|
descriptionRepository.fetchDescription()
|
||||||
|
} else {
|
||||||
|
Unit
|
||||||
|
}
|
||||||
|
} catch (exception: Exception) {
|
||||||
|
Log.e(TAG, exception.message, exception)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
awaitAll(characters, description)
|
||||||
val alterations = async {
|
val alterations = async {
|
||||||
try {
|
try {
|
||||||
if (force || alterationRepository.lastSuccessFullUpdate.shouldUpdate()) {
|
if (force || alterationRepository.lastSuccessFullUpdate.shouldUpdate()) {
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ value class Update(private val value: Long) {
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private const val DELTA = 5 * 60 * 1000
|
private const val DELTA = 24 * 60 * 60 * 1000 // 1 jour
|
||||||
|
|
||||||
val INITIAL = Update(0)
|
val INITIAL = Update(0)
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue