commit 742d70bb437617758f0f381e26baa51189d4caaf
parent b9362b0f97961c9a97766d2690b6086717819f0e
Author: MTRNord <MTRNord@users.noreply.github.com>
Date: Mon, 28 Jul 2025 21:05:14 +0200
Improve the content of the details page and fix the topbar title
Diffstat:
4 files changed, 100 insertions(+), 45 deletions(-)
diff --git a/app/build.gradle.kts b/app/build.gradle.kts
@@ -46,7 +46,6 @@ android {
}
dependencies {
-
implementation(libs.androidx.core.ktx)
implementation(libs.androidx.lifecycle.runtime.ktx)
implementation(libs.androidx.activity.compose)
@@ -58,6 +57,8 @@ dependencies {
implementation(libs.accompanist.permissions)
implementation(libs.androidx.navigation.compose)
implementation(libs.androidx.foundation.foundation)
+ implementation(libs.autolinktext)
+
testImplementation(libs.junit)
androidTestImplementation(libs.androidx.junit)
androidTestImplementation(libs.androidx.espresso.core)
diff --git a/app/src/main/java/space/midnightthoughts/nordiccalendar/components/AppScaffold.kt b/app/src/main/java/space/midnightthoughts/nordiccalendar/components/AppScaffold.kt
@@ -55,7 +55,13 @@ fun AppScaffold(
Scaffold(
topBar = {
TopAppBar(
- title = { title ?: Text(stringResource(R.string.app_name)) },
+ title = {
+ if (title == null) {
+ Text(stringResource(R.string.app_name))
+ } else {
+ Text(title)
+ }
+ },
navigationIcon = {
if (isBackButtonVisible) {
IconButton(onClick = {
diff --git a/app/src/main/java/space/midnightthoughts/nordiccalendar/screens/EventDetailsView.kt b/app/src/main/java/space/midnightthoughts/nordiccalendar/screens/EventDetailsView.kt
@@ -1,22 +1,32 @@
package space.midnightthoughts.nordiccalendar.screens
-import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.rememberScrollState
+import androidx.compose.foundation.text.selection.SelectionContainer
+import androidx.compose.foundation.verticalScroll
+import androidx.compose.material3.DividerDefaults
+import androidx.compose.material3.HorizontalDivider
+import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
-import androidx.compose.ui.Alignment
+import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.unit.dp
+import androidx.lifecycle.SavedStateHandle
+import androidx.lifecycle.ViewModel
+import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.viewmodel.compose.LocalViewModelStoreOwner
import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.navigation.NavBackStackEntry
import androidx.navigation.NavHostController
+import sh.calvin.autolinktext.rememberAutoLinkText
import space.midnightthoughts.nordiccalendar.R
import space.midnightthoughts.nordiccalendar.components.AppScaffold
import space.midnightthoughts.nordiccalendar.viewmodels.EventDetailsViewModel
@@ -36,12 +46,12 @@ fun EventDetailsView(
viewModel(
viewModelStoreOwner = owner,
key = "eventDetails_$eventId",
- factory = object : androidx.lifecycle.ViewModelProvider.Factory {
- override fun <T : androidx.lifecycle.ViewModel> create(modelClass: Class<T>): T {
+ factory = object : ViewModelProvider.Factory {
+ override fun <T : ViewModel> create(modelClass: Class<T>): T {
@Suppress("UNCHECKED_CAST")
return EventDetailsViewModel(
app = context,
- savedStateHandle = androidx.lifecycle.SavedStateHandle(mapOf("eventId" to eventId))
+ savedStateHandle = SavedStateHandle(mapOf("eventId" to eventId))
) as T
}
}
@@ -49,50 +59,86 @@ fun EventDetailsView(
} else {
throw IllegalStateException("ViewModelStoreOwner or eventId is null")
}
- val event = viewModel.event.collectAsState().value
+ val event = remember(viewModel) {
+ viewModel.event
+ }.collectAsState(initial = null)
val dateTimeFormat = SimpleDateFormat("dd.MM.yyyy HH:mm", Locale.getDefault())
+
+ val scrollState = rememberScrollState()
+
AppScaffold(
- title = stringResource(R.string.event_details_title),
+ title = event.value?.title
+ ?: stringResource(
+ R.string.event_details,
+ backStackEntry.arguments?.getString("eventId") ?: ""
+ ),
selectedDestination = "eventDetails",
navController = navController,
) { innerPadding ->
- Column(
- modifier = innerPadding
- .fillMaxSize()
- .padding(16.dp),
- verticalArrangement = Arrangement.Center,
- horizontalAlignment = Alignment.CenterHorizontally
- ) {
- if (event != null) {
- Text(event.title)
- Spacer(modifier = Modifier.height(8.dp))
- if (!event.description.isNullOrBlank()) {
- Text(event.description)
- Spacer(modifier = Modifier.height(8.dp))
- }
- Text(
- "Start: " + dateTimeFormat.format(java.util.Date(event.startTime))
- )
- Text(
- "Ende: " + dateTimeFormat.format(java.util.Date(event.endTime))
- )
- if (!event.location.isNullOrBlank()) {
- Spacer(modifier = Modifier.height(8.dp))
- Text("Ort: ${event.location}")
- }
- if (!event.organizer.isNullOrBlank()) {
- Spacer(modifier = Modifier.height(8.dp))
- Text("Organisator: ${event.organizer}")
- }
- } else {
- Text(
- stringResource(
- R.string.event_details,
- backStackEntry.arguments?.getString("eventId") ?: ""
+ SelectionContainer(modifier = innerPadding) {
+ Column(
+ modifier = Modifier
+ .verticalScroll(scrollState)
+ .padding(24.dp)
+ .fillMaxSize(),
+ ) {
+ if (event.value != null) {
+ Text(
+ dateTimeFormat.format(
+ java.util.Date(
+ event.value?.startTime ?: 0L
+ )
+ ) + " - " + dateTimeFormat.format(
+ java.util.Date(event.value?.endTime ?: 0L)
+ ),
+ style = MaterialTheme.typography.bodyLarge,
+ color = MaterialTheme.colorScheme.primary,
)
- )
- Spacer(modifier = Modifier.height(24.dp))
- Text("Event nicht gefunden oder wird geladen...")
+ if (!event.value?.location.isNullOrBlank()) {
+ Spacer(modifier = Modifier.height(16.dp))
+ Text(
+ text = AnnotatedString.rememberAutoLinkText(
+ event.value?.location ?: ""
+ ),
+ style = MaterialTheme.typography.labelLarge.copy(color = MaterialTheme.colorScheme.onSurface),
+ modifier = Modifier.padding(bottom = 4.dp)
+ )
+ }
+ if (!event.value?.organizer.isNullOrBlank()) {
+ Spacer(modifier = Modifier.height(16.dp))
+ Text(
+ event.value?.organizer ?: "",
+ style = MaterialTheme.typography.labelLarge,
+ color = MaterialTheme.colorScheme.onSurface,
+ )
+ }
+ Spacer(modifier = Modifier.height(24.dp))
+ HorizontalDivider(
+ Modifier,
+ DividerDefaults.Thickness,
+ color = MaterialTheme.colorScheme.outlineVariant
+ )
+ if (!event.value?.description.isNullOrBlank()) {
+ Spacer(modifier = Modifier.height(24.dp))
+
+ Text(
+ text = AnnotatedString.rememberAutoLinkText(
+ event.value?.description ?: ""
+ ),
+ style = MaterialTheme.typography.bodyMedium.copy(color = MaterialTheme.colorScheme.onSurface),
+ )
+ }
+
+ } else {
+ Text(
+ stringResource(
+ R.string.event_details,
+ backStackEntry.arguments?.getString("eventId") ?: ""
+ )
+ )
+ Spacer(modifier = Modifier.height(24.dp))
+ Text("Event nicht gefunden oder wird geladen...")
+ }
}
}
}
diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml
@@ -11,6 +11,7 @@ composeBom = "2025.07.00"
accompanistPermissions = "0.37.3"
navigationCompose = "2.9.2"
foundation = "1.8.3"
+autolinktext = "2.0.2"
[libraries]
androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }
@@ -30,6 +31,7 @@ androidx-material3 = { group = "androidx.compose.material3", name = "material3"
accompanist-permissions = { group = "com.google.accompanist", name = "accompanist-permissions", version.ref = "accompanistPermissions" }
androidx-navigation-compose = { group = "androidx.navigation", name = "navigation-compose", version.ref = "navigationCompose" }
androidx-foundation-foundation = { group = "androidx.compose.foundation", name = "foundation", version.ref = "foundation" }
+autolinktext = { module = "sh.calvin.autolinktext:autolinktext", version.ref = "autolinktext" }
[plugins]
android-application = { id = "com.android.application", version.ref = "agp" }