Fix Mannschaften
This commit is contained in:
@@ -10,8 +10,12 @@ sealed class Destinations(val route: String) {
|
||||
object Links : Destinations("verein/links")
|
||||
object Impressum : Destinations("impressum")
|
||||
object Mannschaften : Destinations("mannschaften")
|
||||
object MannschaftDetail : Destinations("mannschaften/{slug}") {
|
||||
fun create(slug: String): String = "mannschaften/$slug"
|
||||
object MannschaftDetail : Destinations("mannschaften/{slug}?season={season}") {
|
||||
fun create(slug: String, season: String? = null): String {
|
||||
val encodedSlug = android.net.Uri.encode(slug)
|
||||
val selectedSeason = season?.takeIf { it.isNotBlank() } ?: return "mannschaften/$encodedSlug"
|
||||
return "mannschaften/$encodedSlug?season=${android.net.Uri.encode(selectedSeason)}"
|
||||
}
|
||||
}
|
||||
object MannschaftLegacyDetail : Destinations("mannschaft/{slug}") {
|
||||
fun create(slug: String): String = "mannschaft/$slug"
|
||||
|
||||
@@ -17,6 +17,7 @@ import androidx.navigation.NavHostController
|
||||
import androidx.navigation.compose.currentBackStackEntryAsState
|
||||
import androidx.navigation.compose.NavHost
|
||||
import androidx.navigation.compose.composable
|
||||
import androidx.navigation.navArgument
|
||||
import androidx.hilt.navigation.compose.hiltViewModel
|
||||
import androidx.compose.runtime.collectAsState
|
||||
import androidx.compose.runtime.getValue
|
||||
@@ -32,7 +33,9 @@ fun NavGraph(
|
||||
val backStackEntry = navController.currentBackStackEntryAsState().value
|
||||
val route = backStackEntry?.destination?.route
|
||||
val currentRoute = if (route == Destinations.MannschaftDetail.route) {
|
||||
backStackEntry.arguments?.getString("slug")?.let(Destinations.MannschaftDetail::create)
|
||||
backStackEntry.arguments?.getString("slug")?.let { slug ->
|
||||
Destinations.MannschaftDetail.create(slug, backStackEntry.arguments?.getString("season"))
|
||||
}
|
||||
} else route
|
||||
val navigationState by navigationViewModel.state.collectAsState()
|
||||
LaunchedEffect(currentRoute) {
|
||||
@@ -136,9 +139,13 @@ fun NavGraph(
|
||||
composable("mannschaften/jugend") {
|
||||
de.harheimertc.ui.screens.mannschaften.MannschaftenScreen(navController, !persistentNavigation)
|
||||
}
|
||||
composable(Destinations.MannschaftDetail.route) { entry ->
|
||||
composable(
|
||||
route = Destinations.MannschaftDetail.route,
|
||||
arguments = listOf(navArgument("season") { nullable = true; defaultValue = null }),
|
||||
) { entry ->
|
||||
de.harheimertc.ui.screens.mannschaften.MannschaftDetailScreen(
|
||||
slug = entry.arguments?.getString("slug").orEmpty(),
|
||||
season = entry.arguments?.getString("season"),
|
||||
navController = navController,
|
||||
showBackNavigation = !persistentNavigation,
|
||||
)
|
||||
@@ -146,6 +153,7 @@ fun NavGraph(
|
||||
composable(Destinations.MannschaftLegacyDetail.route) { entry ->
|
||||
de.harheimertc.ui.screens.mannschaften.MannschaftDetailScreen(
|
||||
slug = entry.arguments?.getString("slug").orEmpty(),
|
||||
season = null,
|
||||
navController = navController,
|
||||
showBackNavigation = !persistentNavigation,
|
||||
)
|
||||
|
||||
@@ -85,7 +85,7 @@ fun MannschaftenScreen(
|
||||
state.error != null -> item { ErrorPanel(state.error.orEmpty(), viewModel::load) }
|
||||
state.teams.isEmpty() -> item { Text("Keine Mannschaftsdaten geladen", color = Accent500) }
|
||||
else -> items(state.teams) { team ->
|
||||
TeamCard(team) { navController.navigate(Destinations.MannschaftDetail.create(team.slug)) }
|
||||
TeamCard(team) { navController.navigate(Destinations.MannschaftDetail.create(team.slug, state.selectedSeason)) }
|
||||
}
|
||||
}
|
||||
item {
|
||||
@@ -161,13 +161,14 @@ private fun TeamCard(team: Mannschaft, onOpen: () -> Unit) {
|
||||
@Composable
|
||||
fun MannschaftDetailScreen(
|
||||
slug: String,
|
||||
season: String?,
|
||||
navController: NavController,
|
||||
showBackNavigation: Boolean,
|
||||
viewModel: MannschaftDetailViewModel = hiltViewModel(),
|
||||
) {
|
||||
val state by viewModel.state.collectAsState()
|
||||
var selectedTab by rememberSaveable(slug) { mutableStateOf(DetailTab.Matches) }
|
||||
LaunchedEffect(slug) { viewModel.load(slug) }
|
||||
var selectedTab by rememberSaveable(slug, season) { mutableStateOf(DetailTab.Matches) }
|
||||
LaunchedEffect(slug, season) { viewModel.load(slug, season) }
|
||||
LazyColumn(
|
||||
modifier = Modifier.fillMaxSize().background(Color(0xFFFAFAFA)),
|
||||
contentPadding = PaddingValues(horizontal = 18.dp, vertical = 22.dp),
|
||||
@@ -229,7 +230,7 @@ fun MannschaftDetailScreen(
|
||||
}
|
||||
}
|
||||
}
|
||||
} ?: item { ErrorPanel(state.matchesError ?: "Mannschaft nicht gefunden.") { viewModel.load(slug) } }
|
||||
} ?: item { ErrorPanel(state.matchesError ?: "Mannschaft nicht gefunden.") { viewModel.load(slug, season) } }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -121,35 +121,38 @@ class MannschaftDetailViewModel @Inject constructor(
|
||||
) : ViewModel() {
|
||||
private val _state = MutableStateFlow(MannschaftDetailUiState())
|
||||
val state: StateFlow<MannschaftDetailUiState> = _state
|
||||
private var loadedSlug: String? = null
|
||||
private var loadedKey: String? = null
|
||||
|
||||
fun load(slug: String) {
|
||||
if (loadedSlug == slug) return
|
||||
loadedSlug = slug
|
||||
fun load(slug: String, season: String? = null) {
|
||||
val selectedSeason = season?.takeIf { it.isNotBlank() }
|
||||
val key = "$slug|${selectedSeason.orEmpty()}"
|
||||
if (loadedKey == key) return
|
||||
loadedKey = key
|
||||
viewModelScope.launch {
|
||||
_state.value = MannschaftDetailUiState(loading = true)
|
||||
val team = mannschaftenRepository.fetchMannschaften().getOrDefault(emptyList()).find { it.slug == slug }
|
||||
_state.value = MannschaftDetailUiState(loading = true, season = selectedSeason)
|
||||
val team = mannschaftenRepository.fetchMannschaften(selectedSeason).getOrDefault(emptyList()).find { it.slug == slug }
|
||||
if (team == null) {
|
||||
_state.value = MannschaftDetailUiState(loading = false, matchesError = "Mannschaft nicht gefunden.")
|
||||
return@launch
|
||||
}
|
||||
spielplanRepository.fetchSpielplan()
|
||||
spielplanRepository.fetchSpielplan(selectedSeason)
|
||||
.onSuccess { plan ->
|
||||
_state.value = MannschaftDetailUiState(
|
||||
loading = false,
|
||||
team = team,
|
||||
matches = plan.data.filter { matchesTeam(it, team.mannschaft) },
|
||||
season = plan.season,
|
||||
season = plan.season ?: selectedSeason,
|
||||
)
|
||||
if (team.informationenLink.isNotBlank()) {
|
||||
loadTable(team, plan.season)
|
||||
loadTable(team, plan.season ?: selectedSeason)
|
||||
}
|
||||
}
|
||||
.onFailure {
|
||||
_state.value = MannschaftDetailUiState(
|
||||
loading = false,
|
||||
team = team,
|
||||
matchesError = "Der aktuelle Spielplan konnte nicht geladen werden.",
|
||||
season = selectedSeason,
|
||||
matchesError = "Der Spielplan konnte nicht geladen werden.",
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,8 +8,8 @@ LOCAL_API_BASE_URL=https://harheimertc.tsschulz.de/
|
||||
PRODUCTION_API_BASE_URL=https://harheimertc.de/
|
||||
|
||||
# Android app versioning for Play Store uploads
|
||||
ANDROID_VERSION_CODE=24
|
||||
ANDROID_VERSION_NAME=0.9.19
|
||||
ANDROID_VERSION_CODE=25
|
||||
ANDROID_VERSION_NAME=0.9.20
|
||||
|
||||
# Temporary hotfix: disable R8 minification for release to avoid Retrofit generic signature stripping.
|
||||
RELEASE_MINIFY_ENABLED=false
|
||||
|
||||
Reference in New Issue
Block a user