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