Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import xyz.sevive.arcaeaoffline.R
import xyz.sevive.arcaeaoffline.core.constants.ArcaeaRatingClass
import xyz.sevive.arcaeaoffline.core.constants.ArcaeaRatingClassDisplay
import xyz.sevive.arcaeaoffline.core.database.entities.Chart
import xyz.sevive.arcaeaoffline.ui.helpers.ArcaeaFormatters
import xyz.sevive.arcaeaoffline.ui.theme.ArcaeaOfflineTheme
Expand Down Expand Up @@ -92,7 +93,10 @@ fun ArcaeaChartCard(
Text(
text = ArcaeaFormatters.ratingText(it),
modifier = Modifier.fillMaxWidth(),
color = ratingClassColor(it.ratingClass),
color =
ratingClassColor(
ArcaeaRatingClassDisplay.of(it.ratingClass, it.ratingClassAlias),
),
)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import kotlinx.coroutines.flow.firstOrNull
import org.koin.compose.koinInject
import xyz.sevive.arcaeaoffline.R
import xyz.sevive.arcaeaoffline.core.database.entities.Chart
import xyz.sevive.arcaeaoffline.core.database.entities.Difficulty
import xyz.sevive.arcaeaoffline.core.database.entities.Song
import xyz.sevive.arcaeaoffline.core.database.helpers.ChartFactory
import xyz.sevive.arcaeaoffline.core.database.repositories.ChartRepository
Expand All @@ -40,25 +41,30 @@ private fun rememberArcaeaSong(
}

@Composable
private fun rememberArcaeaCharts(
private fun rememberArcaeaDifficulties(
difficultyRepo: DifficultyRepository,
song: Song?,
): State<List<Difficulty>> =
produceState(initialValue = emptyList(), song?.id) {
song?.let {
difficultyRepo.findAllBySongId(it.id).collect { value = it }
}
}

@Composable
private fun rememberArcaeaCharts(
chartRepo: ChartRepository,
song: Song?,
difficulties: List<Difficulty>,
allowFakeChart: Boolean = false,
): State<List<Chart>> =
produceState(initialValue = emptyList(), song?.id, allowFakeChart) {
produceState(initialValue = emptyList(), song?.id, difficulties, allowFakeChart) {
song?.let {
val availableRatingClasses =
difficultyRepo.findAllBySongId(song.id).firstOrNull()?.map { it.ratingClass }
?: emptyList()

value =
availableRatingClasses.mapNotNull { ratingClass ->
var chart = chartRepo.find(song.id, ratingClass).firstOrNull()
difficulties.mapNotNull { difficulty ->
var chart = chartRepo.find(difficulty.songId, difficulty.ratingClass).firstOrNull()
if (chart == null && allowFakeChart) {
difficultyRepo.find(song.id, ratingClass).firstOrNull()?.let { difficulty ->
chart = ChartFactory.fakeChart(song, difficulty)
}
chart = ChartFactory.fakeChart(song, difficulty)
}
chart
}
Expand All @@ -80,16 +86,17 @@ fun ArcaeaChartSelector(
mutableStateOf(chart?.ratingClass)
}
val song by rememberArcaeaSong(songRepo = songRepo, songId = selectedSongId)
val difficulties by rememberArcaeaDifficulties(difficultyRepo = difficultyRepo, song = song)
val charts by rememberArcaeaCharts(
difficultyRepo = difficultyRepo,
chartRepo = chartRepo,
song = song,
difficulties = difficulties,
allowFakeChart = allowFakeChart,
)

val selectorItems =
remember(charts) {
charts.toRatingClassSelectorItems()
remember(difficulties) {
difficulties.toRatingClassSelectorItems()
}

// Emit the change when either [selectedSongId] or [selectedRatingClass] changes.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ import androidx.compose.ui.unit.em
import com.materialkolor.hct.Hct
import xyz.sevive.arcaeaoffline.core.constants.ArcaeaRatingClass
import xyz.sevive.arcaeaoffline.core.constants.ArcaeaRatingClassDisplay
import xyz.sevive.arcaeaoffline.core.database.entities.Chart
import xyz.sevive.arcaeaoffline.core.database.entities.Difficulty
import xyz.sevive.arcaeaoffline.ui.theme.ArcaeaOfflineTheme
import xyz.sevive.arcaeaoffline.ui.theme.ratingClassColor

Expand All @@ -58,10 +58,10 @@ data class RatingClassSelectorItem(
val ratingPlus: Boolean = false,
)

fun List<Chart>.toRatingClassSelectorItems(): List<RatingClassSelectorItem> =
fun List<Difficulty>.toRatingClassSelectorItems(): List<RatingClassSelectorItem> =
map {
RatingClassSelectorItem(
display = ArcaeaRatingClassDisplay.of(it.ratingClass),
display = ArcaeaRatingClassDisplay.of(it.ratingClass, it.ratingClassAlias),
rating = it.rating,
ratingPlus = it.ratingPlus,
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import com.ionspin.kotlin.bignum.decimal.DecimalMode
import com.ionspin.kotlin.bignum.decimal.RoundingMode
import com.ionspin.kotlin.bignum.decimal.toBigDecimal
import xyz.sevive.arcaeaoffline.core.constants.ArcaeaRatingClass
import xyz.sevive.arcaeaoffline.core.constants.ArcaeaRatingClassDisplay
import xyz.sevive.arcaeaoffline.core.database.entities.Chart
import xyz.sevive.arcaeaoffline.core.database.entities.Difficulty

Expand Down Expand Up @@ -96,12 +97,12 @@ object ArcaeaFormatters {
}

internal fun ratingText(
ratingClass: ArcaeaRatingClass,
ratingClassDisplay: ArcaeaRatingClassDisplay,
rating: Int,
ratingPlus: Boolean,
constant: Int = 0,
) = buildString {
append(ratingClass.toString())
append(ratingClassDisplay.name)
append(' ')

if (constant > 0) {
Expand All @@ -114,18 +115,31 @@ object ArcaeaFormatters {
}
}

internal fun ratingText(
ratingClass: ArcaeaRatingClass,
rating: Int,
ratingPlus: Boolean,
constant: Int = 0,
) = ratingText(
ArcaeaRatingClassDisplay.of(ratingClass),
rating,
ratingPlus,
constant,
)

/**
* Returns the readable rating text for the given difficulty.
*
* For example:
* * `Difficulty(ratingClass=2, rating=2, ratingPlus=false)` > "FUTURE 2"
* * `Difficulty(ratingClass=2, rating=10, ratingPlus=true)` > "FUTURE 10+"
* * `Difficulty(ratingClass=3, rating=11, ratingPlus=true, ratingClassAlias=1)` > "INSCRIBED 11+"
*/
fun ratingText(difficulty: Difficulty): String =
ratingText(
ratingClass = difficulty.ratingClass,
rating = difficulty.rating,
ratingPlus = difficulty.ratingPlus,
ArcaeaRatingClassDisplay.of(difficulty.ratingClass, difficulty.ratingClassAlias),
difficulty.rating,
difficulty.ratingPlus,
)

/**
Expand All @@ -139,12 +153,13 @@ object ArcaeaFormatters {
* * `Chart(ratingClass=2, rating=10, ratingPlus=true)` > "FUTURE 10+"
* * `Chart(ratingClass=2, rating=10, ratingPlus=true, constant=108)` > "FUTURE 10.8"
* * `Chart(ratingClass=2, rating=10, ratingPlus=true, constant=0)` > "FUTURE 10+"
* * `Chart(ratingClass=3, rating=11, ratingPlus=true, ratingClassAlias=1)` > "INSCRIBED 11+"
*/
fun ratingText(chart: Chart): String =
ratingText(
ratingClass = chart.ratingClass,
rating = chart.rating,
ratingPlus = chart.ratingPlus,
ArcaeaRatingClassDisplay.of(chart.ratingClass, chart.ratingClassAlias),
chart.rating,
chart.ratingPlus,
constant = chart.constant,
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import org.koin.compose.koinInject
import xyz.sevive.arcaeaoffline.R
import xyz.sevive.arcaeaoffline.core.constants.ArcaeaRatingClass
import xyz.sevive.arcaeaoffline.core.database.repositories.ChartRepository
import xyz.sevive.arcaeaoffline.core.database.repositories.DifficultyRepository
import xyz.sevive.arcaeaoffline.ui.SubScreenContainer
import xyz.sevive.arcaeaoffline.ui.components.ArcaeaPackAndSongQuickSearch
import xyz.sevive.arcaeaoffline.ui.components.ArcaeaRatingClassSelector
Expand All @@ -39,6 +40,7 @@ import xyz.sevive.arcaeaoffline.ui.navigation.UtilitiesSubScreen
fun UtilitiesCalculatorScreen(
modifier: Modifier = Modifier,
chartRepo: ChartRepository = koinInject(),
difficultyRepo: DifficultyRepository = koinInject(),
) {
var constant by remember { mutableIntStateOf(0) }
var selectedSongId by remember { mutableStateOf<String?>(null) }
Expand All @@ -48,9 +50,14 @@ fun UtilitiesCalculatorScreen(
value = chartRepo.findAllBySongId(it).firstOrNull() ?: emptyList()
}
}
val difficulties by produceState(initialValue = listOf(), selectedSongId) {
selectedSongId?.let {
value = difficultyRepo.findAllBySongId(it).firstOrNull() ?: emptyList()
}
}
val selectorItems =
remember(charts) {
charts.toRatingClassSelectorItems()
remember(difficulties) {
difficulties.toRatingClassSelectorItems()
}

LaunchedEffect(selectedRatingClass, charts) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package xyz.sevive.arcaeaoffline.ui.helpers
import org.junit.Assert.assertEquals
import org.junit.Test
import xyz.sevive.arcaeaoffline.core.constants.ArcaeaRatingClass
import xyz.sevive.arcaeaoffline.core.constants.ArcaeaRatingClassDisplay

class ArcaeaFormattersTest {
@Test
Expand Down Expand Up @@ -124,4 +125,28 @@ class ArcaeaFormattersTest {
ArcaeaFormatters.ratingText(ArcaeaRatingClass.BEYOND, 11, true, 118),
)
}

@Test
fun ratingTextAliasTest() {
assertEquals(
"INSCRIBED 11",
ArcaeaFormatters.ratingText(ArcaeaRatingClassDisplay.INSCRIBED, 11, false),
)

assertEquals(
"INSCRIBED 11.5",
ArcaeaFormatters.ratingText(ArcaeaRatingClassDisplay.INSCRIBED, 11, false, 115),
)

// Unknown (ratingClass, alias) combos must fall back to the default
// display form of the rating class, not throw.
assertEquals(
"BEYOND 12",
ArcaeaFormatters.ratingText(
ArcaeaRatingClassDisplay.of(ArcaeaRatingClass.BEYOND, alias = 2),
12,
false,
),
)
}
}
Loading
Loading