diff --git a/shared-ui/src/commonMain/kotlin/co.touchlab.droidcon/ui/BottomNavigationView.kt b/shared-ui/src/commonMain/kotlin/co.touchlab.droidcon/ui/BottomNavigationView.kt index 018763d6..62873f5e 100644 --- a/shared-ui/src/commonMain/kotlin/co.touchlab.droidcon/ui/BottomNavigationView.kt +++ b/shared-ui/src/commonMain/kotlin/co.touchlab.droidcon/ui/BottomNavigationView.kt @@ -64,7 +64,7 @@ internal fun BottomNavigationView(viewModel: ApplicationViewModel, currentConfer when (selectedTab) { ApplicationViewModel.Tab.Schedule -> SessionListView( viewModel = viewModel.schedule, - title = currentConference?.name ?: "Schedule", + title = currentConference.name, emptyText = "Sessions could not be loaded.", ) @@ -74,7 +74,7 @@ internal fun BottomNavigationView(viewModel: ApplicationViewModel, currentConfer emptyText = "Add sessions to your agenda from session detail in schedule.", ) - ApplicationViewModel.Tab.Venue -> VenueView() + ApplicationViewModel.Tab.Venue -> VenueView(currentConference) ApplicationViewModel.Tab.Sponsors -> SponsorsView(viewModel.sponsors) ApplicationViewModel.Tab.Settings -> SettingsView(viewModel.settings) } diff --git a/shared-ui/src/commonMain/kotlin/co.touchlab.droidcon/ui/venue/VenueView.kt b/shared-ui/src/commonMain/kotlin/co.touchlab.droidcon/ui/venue/VenueView.kt index 475b0026..bbda3f35 100644 --- a/shared-ui/src/commonMain/kotlin/co.touchlab.droidcon/ui/venue/VenueView.kt +++ b/shared-ui/src/commonMain/kotlin/co.touchlab.droidcon/ui/venue/VenueView.kt @@ -1,28 +1,57 @@ package co.touchlab.droidcon.ui.venue +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.padding +import androidx.compose.material3.CircularProgressIndicator import androidx.compose.material3.Scaffold +import androidx.compose.material3.Text import androidx.compose.runtime.Composable +import androidx.compose.runtime.collectAsState +import androidx.compose.runtime.getValue +import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import co.touchlab.droidcon.domain.entity.Conference +import coil3.compose.AsyncImagePainter +import coil3.compose.rememberAsyncImagePainter import com.github.panpf.zoomimage.ZoomImage -import droidcon.shared_ui.generated.resources.venue_map_1 -import org.jetbrains.compose.resources.painterResource @Composable -fun VenueView() { +fun VenueView(currentConference: Conference) { Scaffold { paddingValues -> VenueBodyView( modifier = Modifier.padding(paddingValues), + currentConference, ) } } @Composable -fun VenueBodyView(modifier: Modifier = Modifier) { - ZoomImage( - painter = painterResource(droidcon.shared_ui.generated.resources.Res.drawable.venue_map_1), - contentDescription = null, - modifier = modifier.fillMaxSize(), - ) +fun VenueBodyView(modifier: Modifier = Modifier, currentConference: Conference) { + val painter = rememberAsyncImagePainter(currentConference.venueMap) + val state by painter.state.collectAsState() + + Column( + modifier = Modifier.fillMaxSize(), + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.Center, + ) { + when (state) { + is AsyncImagePainter.State.Empty, + is AsyncImagePainter.State.Loading -> { + CircularProgressIndicator() + } + is AsyncImagePainter.State.Error -> { + Text("Error loading venue map.") + } + is AsyncImagePainter.State.Success -> { + ZoomImage( + painter = painter, + contentDescription = null, + modifier = modifier.fillMaxSize(), + ) + } + } + } } diff --git a/shared/build.gradle.kts b/shared/build.gradle.kts index bdaf0388..4dad6cc1 100644 --- a/shared/build.gradle.kts +++ b/shared/build.gradle.kts @@ -108,5 +108,6 @@ kotlin { sqldelight { databases.create("DroidconDatabase") { packageName.set("co.touchlab.droidcon.db") + schemaOutputDirectory.set(file("src/commonMain/sqldelight/databases")) } } diff --git a/shared/src/commonMain/kotlin/co/touchlab/droidcon/domain/entity/Conference.kt b/shared/src/commonMain/kotlin/co/touchlab/droidcon/domain/entity/Conference.kt index e15cf9af..4e333b3c 100644 --- a/shared/src/commonMain/kotlin/co/touchlab/droidcon/domain/entity/Conference.kt +++ b/shared/src/commonMain/kotlin/co/touchlab/droidcon/domain/entity/Conference.kt @@ -12,8 +12,9 @@ data class Conference( val scheduleId: String, val selected: Boolean = false, val active: Boolean = true, + val venueMap: String?, ) : DomainEntity() { - val showVenueMap: Boolean = false // We'll need to add this to the table + val showVenueMap: Boolean = venueMap != null override val id: Long get() = requireNotNull(_id) { "Conference id cannot be null" } } diff --git a/shared/src/commonMain/kotlin/co/touchlab/droidcon/domain/repository/impl/SqlDelightConferenceRepository.kt b/shared/src/commonMain/kotlin/co/touchlab/droidcon/domain/repository/impl/SqlDelightConferenceRepository.kt index c33205c0..de9913bc 100644 --- a/shared/src/commonMain/kotlin/co/touchlab/droidcon/domain/repository/impl/SqlDelightConferenceRepository.kt +++ b/shared/src/commonMain/kotlin/co/touchlab/droidcon/domain/repository/impl/SqlDelightConferenceRepository.kt @@ -43,6 +43,7 @@ class SqlDelightConferenceRepository( scheduleId = conference.scheduleId, selected = conference.selected, active = conference.active, + venueMap = conference.venueMap, ) // Return the last inserted ID return conferenceQueries.lastInsertRowId().executeAsOne() @@ -60,6 +61,7 @@ class SqlDelightConferenceRepository( selected = conference.selected, active = conference.active, id = conference.id, + venueMap = conference.venueMap, ) return true } catch (e: Exception) { @@ -83,6 +85,7 @@ class SqlDelightConferenceRepository( scheduleId: String, selected: Boolean, active: Boolean, + venueMap: String?, ): Conference = Conference( _id = id, name = conferenceName, @@ -93,5 +96,6 @@ class SqlDelightConferenceRepository( scheduleId = scheduleId, selected = selected, active = active, + venueMap = venueMap, ) } diff --git a/shared/src/commonMain/kotlin/co/touchlab/droidcon/domain/service/impl/DefaultSyncService.kt b/shared/src/commonMain/kotlin/co/touchlab/droidcon/domain/service/impl/DefaultSyncService.kt index 94a20564..582ed241 100644 --- a/shared/src/commonMain/kotlin/co/touchlab/droidcon/domain/service/impl/DefaultSyncService.kt +++ b/shared/src/commonMain/kotlin/co/touchlab/droidcon/domain/service/impl/DefaultSyncService.kt @@ -240,13 +240,15 @@ class DefaultSyncService( val collectionName = conferenceFields.collectionName.stringValue val apiKey = conferenceFields.apiKey.stringValue val scheduleId = conferenceFields.scheduleId.stringValue + val venueMap = conferenceFields.venueMap?.stringValue // Only update if any field has changed val needsUpdate = existingConference.timeZone != timeZone || existingConference.projectId != projectId || existingConference.collectionName != collectionName || existingConference.apiKey != apiKey || - existingConference.scheduleId != scheduleId + existingConference.scheduleId != scheduleId || + existingConference.venueMap != venueMap if (needsUpdate) { val updatedConference = Conference( @@ -259,6 +261,7 @@ class DefaultSyncService( scheduleId = scheduleId, selected = existingConference.selected, active = existingConference.active, + venueMap = venueMap, ) conferenceRepository.update(updatedConference) log.d { "Updated conference: $conferenceName (fields changed)" } @@ -276,6 +279,7 @@ class DefaultSyncService( scheduleId = conferenceFields.scheduleId.stringValue, selected = false, active = true, + venueMap = conferenceFields.venueMap?.stringValue ) conferenceRepository.add(newConference) log.d { "Added new conference: $conferenceName" } @@ -296,6 +300,7 @@ class DefaultSyncService( scheduleId = conference.scheduleId, selected = conference.selected, active = false, + venueMap = conference.venueMap, ) conferenceRepository.update(deactivatedConference) log.d { "Marked conference as inactive: $name" } diff --git a/shared/src/commonMain/kotlin/co/touchlab/droidcon/domain/service/impl/dto/ConferencesDto.kt b/shared/src/commonMain/kotlin/co/touchlab/droidcon/domain/service/impl/dto/ConferencesDto.kt index f4a86156..5d05f38a 100644 --- a/shared/src/commonMain/kotlin/co/touchlab/droidcon/domain/service/impl/dto/ConferencesDto.kt +++ b/shared/src/commonMain/kotlin/co/touchlab/droidcon/domain/service/impl/dto/ConferencesDto.kt @@ -22,7 +22,7 @@ object ConferencesDto { val collectionName: StringValue, val apiKey: StringValue, val scheduleId: StringValue, - val venueMap: StringValue, + val venueMap: StringValue? = null, ) @Serializable diff --git a/shared/src/commonMain/sqldelight/co/touchlab/droidcon/db/Conference.sq b/shared/src/commonMain/sqldelight/co/touchlab/droidcon/db/Conference.sq index 59f3aacd..422786de 100644 --- a/shared/src/commonMain/sqldelight/co/touchlab/droidcon/db/Conference.sq +++ b/shared/src/commonMain/sqldelight/co/touchlab/droidcon/db/Conference.sq @@ -10,16 +10,17 @@ CREATE TABLE conferenceTable( apiKey TEXT NOT NULL, scheduleId TEXT NOT NULL, selected INTEGER AS Boolean NOT NULL DEFAULT 0, - active INTEGER AS Boolean NOT NULL DEFAULT 1 + active INTEGER AS Boolean NOT NULL DEFAULT 1, + venueMap TEXT ); insert: -INSERT INTO conferenceTable(conferenceName, conferenceTimeZone, projectId, collectionName, apiKey, scheduleId, selected, active) -VALUES (?, ?, ?, ?, ?, ?, ?, ?); +INSERT INTO conferenceTable(conferenceName, conferenceTimeZone, projectId, collectionName, apiKey, scheduleId, selected, active, venueMap) +VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?); updateConference: UPDATE conferenceTable -SET conferenceName = ?, conferenceTimeZone = ?, projectId = ?, collectionName = ?, apiKey = ?, scheduleId = ?, selected = ?, active = ? +SET conferenceName = ?, conferenceTimeZone = ?, projectId = ?, collectionName = ?, apiKey = ?, scheduleId = ?, selected = ?, active = ?, venueMap = ? WHERE id = ?; selectAll: @@ -52,8 +53,8 @@ changeSelectedConference { UPDATE conferenceTable SET selected = 1 WHERE id = :conferenceId; } -INSERT INTO conferenceTable(conferenceName, conferenceTimeZone, projectId, collectionName, apiKey, scheduleId, selected, active) -VALUES ("Droidcon NYC 2025", "America/New_York", "droidcon-148cc", "sponsors-nyc-2025", "AIzaSyCkD5DH2rUJ8aZuJzANpIFj0AVuCNik1l0", "4lffd9w7", 1, 1); +INSERT INTO conferenceTable(conferenceName, conferenceTimeZone, projectId, collectionName, apiKey, scheduleId, selected, active, venueMap) +VALUES ("Droidcon NYC 2025", "America/New_York", "droidcon-148cc", "sponsors-nyc-2025", "AIzaSyCkD5DH2rUJ8aZuJzANpIFj0AVuCNik1l0", "4lffd9w7", 1, 1, "https://www.google.com"); lastInsertRowId: SELECT last_insert_rowid(); \ No newline at end of file diff --git a/shared/src/commonMain/sqldelight/databases/2.db b/shared/src/commonMain/sqldelight/databases/2.db new file mode 100644 index 00000000..42d825ed Binary files /dev/null and b/shared/src/commonMain/sqldelight/databases/2.db differ diff --git a/shared/src/commonMain/sqldelight/migrations/1.sqm b/shared/src/commonMain/sqldelight/migrations/1.sqm new file mode 100644 index 00000000..da7898f4 --- /dev/null +++ b/shared/src/commonMain/sqldelight/migrations/1.sqm @@ -0,0 +1 @@ +ALTER TABLE conferenceTable ADD COLUMN venueMap TEXT; \ No newline at end of file