mirror of
https://github.com/cmclark00/TetriStats.git
synced 2025-05-17 22:55:21 +01:00
Fix auto-refresh issue and add missing games: Modretro Tetris and Tetris Mobile
This commit is contained in:
parent
b7d0382ecc
commit
aeb463fa88
3 changed files with 120 additions and 52 deletions
|
@ -16,7 +16,9 @@ object ScalingFactors {
|
|||
"Tetris DS" to RangeScalingFactor(3.0, 3.3, 4.5),
|
||||
"Tetris Effect" to RangeScalingFactor(2.5, 3.8, 4.5),
|
||||
"Rosy Retrospection DX" to RangeScalingFactor(4.0, 1.5, 1.8),
|
||||
"Apotris" to RangeScalingFactor(1.8, 3.8, 4.4)
|
||||
"Apotris" to RangeScalingFactor(1.8, 3.8, 4.4),
|
||||
"Modretro Tetris" to RangeScalingFactor(2.0, 2.5, 3.0),
|
||||
"Tetris Mobile" to RangeScalingFactor(2.2, 2.8, 3.5)
|
||||
),
|
||||
"Game Boy Tetris" to mapOf(
|
||||
"NES Tetris" to 1.33,
|
||||
|
@ -24,7 +26,9 @@ object ScalingFactors {
|
|||
"Tetris DS" to RangeScalingFactor(4.0, 2.0, 2.0),
|
||||
"Tetris Effect" to RangeScalingFactor(4.0, 2.3, 2.3),
|
||||
"Rosy Retrospection DX" to 1.1,
|
||||
"Apotris" to RangeScalingFactor(1.33, 1.33, 2.33)
|
||||
"Apotris" to RangeScalingFactor(1.33, 1.33, 2.33),
|
||||
"Modretro Tetris" to RangeScalingFactor(1.5, 1.8, 2.0),
|
||||
"Tetris Mobile" to RangeScalingFactor(1.6, 1.9, 2.1)
|
||||
),
|
||||
"Tetris DX" to mapOf(
|
||||
"NES Tetris" to 1.33,
|
||||
|
@ -32,7 +36,9 @@ object ScalingFactors {
|
|||
"Tetris DS" to RangeScalingFactor(4.0, 2.0, 2.0),
|
||||
"Tetris Effect" to RangeScalingFactor(4.0, 2.3, 2.3),
|
||||
"Rosy Retrospection DX" to 1.1,
|
||||
"Apotris" to RangeScalingFactor(1.33, 1.33, 2.33)
|
||||
"Apotris" to RangeScalingFactor(1.33, 1.33, 2.33),
|
||||
"Modretro Tetris" to RangeScalingFactor(1.5, 1.8, 2.0),
|
||||
"Tetris Mobile" to RangeScalingFactor(1.6, 1.9, 2.1)
|
||||
),
|
||||
"Tetris DS" to mapOf(
|
||||
"NES Tetris" to RangeScalingFactor(0.33, 0.3, 0.22),
|
||||
|
@ -40,7 +46,9 @@ object ScalingFactors {
|
|||
"Tetris DX" to RangeScalingFactor(0.25, 0.5, 0.5),
|
||||
"Tetris Effect" to RangeScalingFactor(0.83, 0.91, 1.0),
|
||||
"Rosy Retrospection DX" to RangeScalingFactor(0.25, 0.91, 0.67),
|
||||
"Apotris" to RangeScalingFactor(0.33, 0.67, 0.9)
|
||||
"Apotris" to RangeScalingFactor(0.33, 0.67, 0.9),
|
||||
"Modretro Tetris" to RangeScalingFactor(0.4, 0.5, 0.6),
|
||||
"Tetris Mobile" to RangeScalingFactor(0.45, 0.55, 0.65)
|
||||
),
|
||||
"Tetris Effect" to mapOf(
|
||||
"NES Tetris" to RangeScalingFactor(0.4, 0.26, 0.22),
|
||||
|
@ -48,7 +56,9 @@ object ScalingFactors {
|
|||
"Tetris DX" to RangeScalingFactor(0.25, 0.43, 0.43),
|
||||
"Tetris DS" to RangeScalingFactor(1.2, 1.1, 1.0),
|
||||
"Rosy Retrospection DX" to RangeScalingFactor(0.25, 0.43, 0.57),
|
||||
"Apotris" to RangeScalingFactor(0.33, 0.67, 0.85)
|
||||
"Apotris" to RangeScalingFactor(0.33, 0.67, 0.85),
|
||||
"Modretro Tetris" to RangeScalingFactor(0.45, 0.55, 0.65),
|
||||
"Tetris Mobile" to RangeScalingFactor(0.5, 0.6, 0.7)
|
||||
),
|
||||
"Rosy Retrospection DX" to mapOf(
|
||||
"NES Tetris" to RangeScalingFactor(0.25, 0.67, 0.57),
|
||||
|
@ -56,7 +66,9 @@ object ScalingFactors {
|
|||
"Tetris DX" to 0.91,
|
||||
"Tetris DS" to RangeScalingFactor(4.0, 1.5, 1.8),
|
||||
"Tetris Effect" to RangeScalingFactor(4.0, 2.3, 1.8),
|
||||
"Apotris" to RangeScalingFactor(1.1, 0.67, 0.5)
|
||||
"Apotris" to RangeScalingFactor(1.1, 0.67, 0.5),
|
||||
"Modretro Tetris" to RangeScalingFactor(1.3, 1.5, 1.7),
|
||||
"Tetris Mobile" to RangeScalingFactor(1.4, 1.6, 1.8)
|
||||
),
|
||||
"Apotris" to mapOf(
|
||||
"NES Tetris" to RangeScalingFactor(0.56, 0.26, 0.23),
|
||||
|
@ -64,7 +76,29 @@ object ScalingFactors {
|
|||
"Tetris DX" to RangeScalingFactor(0.75, 0.75, 0.5),
|
||||
"Tetris DS" to RangeScalingFactor(3.0, 1.5, 1.0),
|
||||
"Tetris Effect" to RangeScalingFactor(3.0, 1.7, 1.2),
|
||||
"Rosy Retrospection DX" to RangeScalingFactor(1.1, 0.67, 0.5)
|
||||
"Rosy Retrospection DX" to RangeScalingFactor(1.1, 0.67, 0.5),
|
||||
"Modretro Tetris" to RangeScalingFactor(1.2, 0.9, 0.7),
|
||||
"Tetris Mobile" to RangeScalingFactor(1.3, 1.0, 0.8)
|
||||
),
|
||||
"Modretro Tetris" to mapOf(
|
||||
"NES Tetris" to RangeScalingFactor(0.5, 0.4, 0.33),
|
||||
"Game Boy Tetris" to RangeScalingFactor(0.67, 0.56, 0.5),
|
||||
"Tetris DX" to RangeScalingFactor(0.67, 0.56, 0.5),
|
||||
"Tetris DS" to RangeScalingFactor(2.5, 2.0, 1.67),
|
||||
"Tetris Effect" to RangeScalingFactor(2.22, 1.82, 1.54),
|
||||
"Rosy Retrospection DX" to RangeScalingFactor(0.77, 0.67, 0.59),
|
||||
"Apotris" to RangeScalingFactor(0.83, 1.11, 1.43),
|
||||
"Tetris Mobile" to RangeScalingFactor(1.1, 1.1, 1.1)
|
||||
),
|
||||
"Tetris Mobile" to mapOf(
|
||||
"NES Tetris" to RangeScalingFactor(0.45, 0.36, 0.29),
|
||||
"Game Boy Tetris" to RangeScalingFactor(0.63, 0.53, 0.48),
|
||||
"Tetris DX" to RangeScalingFactor(0.63, 0.53, 0.48),
|
||||
"Tetris DS" to RangeScalingFactor(2.22, 1.82, 1.54),
|
||||
"Tetris Effect" to RangeScalingFactor(2.0, 1.67, 1.43),
|
||||
"Rosy Retrospection DX" to RangeScalingFactor(0.71, 0.63, 0.56),
|
||||
"Apotris" to RangeScalingFactor(0.77, 1.0, 1.25),
|
||||
"Modretro Tetris" to RangeScalingFactor(0.91, 0.91, 0.91)
|
||||
)
|
||||
)
|
||||
|
||||
|
|
|
@ -56,6 +56,50 @@ class EntryFragment : Fragment() {
|
|||
|
||||
if (game != null && score != null) {
|
||||
viewModel.refreshEquivalentScores(game, score)
|
||||
|
||||
// Make sure UI updates immediately by forcing an adapter refresh
|
||||
viewModel.equivalentScores.value?.let { scores ->
|
||||
equivalentScoreAdapter.submitList(null) // Clear first
|
||||
equivalentScoreAdapter.submitList(scores) // Then add new list
|
||||
}
|
||||
|
||||
// Ensure card is visible
|
||||
updateAnalysisCard()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the analysis card visibility and contents based on current state
|
||||
*/
|
||||
private fun updateAnalysisCard() {
|
||||
if (viewModel.showConversion.value != true) {
|
||||
binding.cardAnalysisResults.visibility = View.GONE
|
||||
return
|
||||
}
|
||||
|
||||
val game = viewModel.lastSubmittedGame.value
|
||||
val score = viewModel.lastSubmittedScore.value
|
||||
|
||||
if (game != null && score != null) {
|
||||
// Get the list of games with scores
|
||||
val playedGames = viewModel.gamesWithScores.value ?: listOf()
|
||||
|
||||
// Make sure we don't show the source game in the equivalent dropdown
|
||||
val filteredGames = playedGames.filter { it != game }
|
||||
if (filteredGames.isNotEmpty()) {
|
||||
binding.textViewOriginalScore.text = "Your $game score of ${"%,d".format(score)} is equivalent to:"
|
||||
binding.cardAnalysisResults.visibility = View.VISIBLE
|
||||
|
||||
val filteredAdapter = ArrayAdapter(requireContext(), android.R.layout.simple_dropdown_item_1line, filteredGames)
|
||||
binding.autoCompleteEquivalentGame.setAdapter(filteredAdapter)
|
||||
|
||||
// Select first game by default
|
||||
binding.autoCompleteEquivalentGame.setText(filteredGames[0], false)
|
||||
viewModel.setSelectedEquivalentGame(filteredGames[0])
|
||||
} else {
|
||||
// If no other games to convert to, hide the card
|
||||
binding.cardAnalysisResults.visibility = View.GONE
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -68,7 +112,9 @@ class EntryFragment : Fragment() {
|
|||
"Tetris DS",
|
||||
"Tetris Effect",
|
||||
"Rosy Retrospection DX",
|
||||
"Apotris"
|
||||
"Apotris",
|
||||
"Modretro Tetris",
|
||||
"Tetris Mobile"
|
||||
)
|
||||
val adapter = ArrayAdapter(requireContext(), android.R.layout.simple_dropdown_item_1line, games)
|
||||
binding.autoCompleteGameVersion.setAdapter(adapter)
|
||||
|
@ -90,8 +136,10 @@ class EntryFragment : Fragment() {
|
|||
viewModel.showConversion.observe(viewLifecycleOwner) { shouldShow ->
|
||||
// No need to show toast here - we'll do it only after score submission
|
||||
if (shouldShow) {
|
||||
// Refresh conversions whenever showConversion becomes true
|
||||
refreshConversions()
|
||||
// Update card when showConversion changes
|
||||
updateAnalysisCard()
|
||||
} else {
|
||||
binding.cardAnalysisResults.visibility = View.GONE
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -99,11 +147,8 @@ class EntryFragment : Fragment() {
|
|||
viewModel.gamesWithScores.observe(viewLifecycleOwner) { games ->
|
||||
// Setup the game dropdown for adding equivalents - only with played games
|
||||
if (games.isNotEmpty()) {
|
||||
val adapter = ArrayAdapter(requireContext(), android.R.layout.simple_dropdown_item_1line, games)
|
||||
binding.autoCompleteEquivalentGame.setAdapter(adapter)
|
||||
|
||||
// Also refresh conversions when game list changes
|
||||
refreshConversions()
|
||||
// Update card when games list changes
|
||||
updateAnalysisCard()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -126,39 +171,22 @@ class EntryFragment : Fragment() {
|
|||
}
|
||||
|
||||
// Observe last submitted score details
|
||||
viewModel.lastSubmittedGame.observe(viewLifecycleOwner) { game ->
|
||||
// Only continue if showConversion is true
|
||||
if (viewModel.showConversion.value != true) {
|
||||
binding.cardAnalysisResults.visibility = View.GONE
|
||||
return@observe
|
||||
}
|
||||
|
||||
viewModel.lastSubmittedScore.value?.let { score ->
|
||||
binding.textViewOriginalScore.text = "Your $game score of ${"%,d".format(score)} is equivalent to:"
|
||||
|
||||
// Get the list of games with scores
|
||||
val playedGames = viewModel.gamesWithScores.value ?: listOf()
|
||||
|
||||
// Make sure we don't show the source game in the equivalent dropdown
|
||||
val filteredGames = playedGames.filter { it != game }
|
||||
if (filteredGames.isNotEmpty()) {
|
||||
binding.cardAnalysisResults.visibility = View.VISIBLE
|
||||
val filteredAdapter = ArrayAdapter(requireContext(), android.R.layout.simple_dropdown_item_1line, filteredGames)
|
||||
binding.autoCompleteEquivalentGame.setAdapter(filteredAdapter)
|
||||
|
||||
// Select first game by default
|
||||
binding.autoCompleteEquivalentGame.setText(filteredGames[0], false)
|
||||
viewModel.setSelectedEquivalentGame(filteredGames[0])
|
||||
} else {
|
||||
// If no other games to convert to, hide the card
|
||||
binding.cardAnalysisResults.visibility = View.GONE
|
||||
}
|
||||
}
|
||||
viewModel.lastSubmittedGame.observe(viewLifecycleOwner) { _ ->
|
||||
// Update the analysis card when last submitted game changes
|
||||
updateAnalysisCard()
|
||||
}
|
||||
|
||||
// Observe last submitted score value
|
||||
viewModel.lastSubmittedScore.observe(viewLifecycleOwner) { _ ->
|
||||
// Update the analysis card when score changes
|
||||
updateAnalysisCard()
|
||||
}
|
||||
|
||||
// Observe equivalent scores
|
||||
viewModel.equivalentScores.observe(viewLifecycleOwner) { scores ->
|
||||
if (scores.isNotEmpty()) {
|
||||
// Force a clean update by clearing first
|
||||
equivalentScoreAdapter.submitList(null)
|
||||
equivalentScoreAdapter.submitList(scores)
|
||||
} else if (viewModel.showConversion.value == true) {
|
||||
// If we should be showing conversions but have no scores, probably no other games
|
||||
|
@ -185,7 +213,7 @@ class EntryFragment : Fragment() {
|
|||
)
|
||||
clearInputs()
|
||||
|
||||
// Check after submission if we should show requirements toast
|
||||
// Force immediate refresh of conversions
|
||||
if (viewModel.showConversion.value == false) {
|
||||
Toast.makeText(
|
||||
context,
|
||||
|
@ -193,7 +221,9 @@ class EntryFragment : Fragment() {
|
|||
Toast.LENGTH_LONG
|
||||
).show()
|
||||
} else {
|
||||
// Only scroll down if we're going to show conversions
|
||||
refreshConversions()
|
||||
|
||||
// Scroll down to show the analysis results
|
||||
binding.root.post {
|
||||
binding.root.fullScroll(View.FOCUS_DOWN)
|
||||
}
|
||||
|
|
|
@ -23,7 +23,9 @@ class EntryViewModel(application: Application) : AndroidViewModel(application) {
|
|||
"Tetris DS",
|
||||
"Tetris Effect",
|
||||
"Rosy Retrospection DX",
|
||||
"Apotris"
|
||||
"Apotris",
|
||||
"Modretro Tetris",
|
||||
"Tetris Mobile"
|
||||
)
|
||||
|
||||
// Track user played games and score counts
|
||||
|
@ -108,13 +110,14 @@ class EntryViewModel(application: Application) : AndroidViewModel(application) {
|
|||
scoreDao.insert(newScore)
|
||||
|
||||
// After inserting, update the last submitted values
|
||||
_lastSubmittedGame.postValue(gameVersion)
|
||||
_lastSubmittedScore.postValue(score)
|
||||
_lastSubmittedGame.value = gameVersion // Use immediate value change instead of postValue
|
||||
_lastSubmittedScore.value = score // Use immediate value change instead of postValue
|
||||
|
||||
// The criteria check will happen automatically through the observers in init
|
||||
// Immediately check conversion criteria with current values
|
||||
checkConversionCriteria()
|
||||
|
||||
// Only generate equivalent scores if we meet the criteria
|
||||
if (_showConversion.value == true) {
|
||||
// Immediate refresh regardless if we just reached the criteria threshold
|
||||
if (totalScoreCount.value ?: 0 >= 3 && (gamesWithScores.value?.size ?: 0) >= 2) {
|
||||
generateEquivalentScores(gameVersion, score)
|
||||
}
|
||||
}
|
||||
|
@ -146,7 +149,8 @@ class EntryViewModel(application: Application) : AndroidViewModel(application) {
|
|||
}
|
||||
}
|
||||
|
||||
_equivalentScores.postValue(equivalents)
|
||||
// Use setValue for immediate update on main thread rather than postValue
|
||||
_equivalentScores.value = equivalents
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue