Skip to content

Commit d8908ee

Browse files
fix(iOS): enhance UI with Surface wrappers for screens and update Firebase dependencies (#414)
1 parent 69685e2 commit d8908ee

7 files changed

Lines changed: 140 additions & 72 deletions

File tree

gradle/libs.versions.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ androidx-lifecycle = "2.10.0" # Used by the Wear OS app only
1414
androidx-wear-compose = "1.6.0"
1515
apollo = "4.4.2"
1616
apollo-adapters = "0.7.0"
17-
apollo-cache = "1.0.0"
17+
apollo-cache = "1.0.1"
1818
coil = "3.4.0"
1919
compose = "1.10.6" # Used by the Wear OS app only
2020
compose-material-icons-extended = "1.7.8"
@@ -28,7 +28,7 @@ jetbrains-compose = "1.11.0-alpha04"
2828
jetbrains-lifecycle = "2.10.0"
2929
jetbrains-material3-adaptive-nav3 = "1.3.0-alpha06"
3030
jetbrains-compose-material-icons-extended = "1.7.3"
31-
nav3-ui = "1.1.0-alpha04"
31+
nav3-ui = "1.1.0-beta01"
3232
junit = "4.13.2"
3333
koin = "4.1.1"
3434
kotlin = "2.3.20"

iosApp/Android Makers.xcodeproj/project.pbxproj

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
61C8A7672D8B199B0046C2CC /* FirebaseCore in Frameworks */ = {isa = PBXBuildFile; productRef = 61C8A7662D8B199B0046C2CC /* FirebaseCore */; };
1212
61C8A7692D8B199B0046C2CC /* FirebaseFirestore in Frameworks */ = {isa = PBXBuildFile; productRef = 61C8A7682D8B199B0046C2CC /* FirebaseFirestore */; };
1313
61C8A76B2D8B1C490046C2CC /* FirebaseAuth in Frameworks */ = {isa = PBXBuildFile; productRef = 61C8A76A2D8B1C490046C2CC /* FirebaseAuth */; };
14+
61C8A76D2D8B1C490046C2CC /* FirebaseMessaging in Frameworks */ = {isa = PBXBuildFile; productRef = 61C8A76C2D8B1C490046C2CC /* FirebaseMessaging */; };
1415
B2CD272F234D06530016AA02 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = B2CD272E234D06530016AA02 /* AppDelegate.swift */; };
1516
B2CD2731234D06530016AA02 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = B2CD2730234D06530016AA02 /* SceneDelegate.swift */; };
1617
B2CD2733234D06530016AA02 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B2CD2732234D06530016AA02 /* ContentView.swift */; };
@@ -40,6 +41,7 @@
4041
61C8A7672D8B199B0046C2CC /* FirebaseCore in Frameworks */,
4142
61C8A76B2D8B1C490046C2CC /* FirebaseAuth in Frameworks */,
4243
61C8A7692D8B199B0046C2CC /* FirebaseFirestore in Frameworks */,
44+
61C8A76D2D8B1C490046C2CC /* FirebaseMessaging in Frameworks */,
4345
);
4446
runOnlyForDeploymentPostprocessing = 0;
4547
};
@@ -131,6 +133,7 @@
131133
61C8A7662D8B199B0046C2CC /* FirebaseCore */,
132134
61C8A7682D8B199B0046C2CC /* FirebaseFirestore */,
133135
61C8A76A2D8B1C490046C2CC /* FirebaseAuth */,
136+
61C8A76C2D8B1C490046C2CC /* FirebaseMessaging */,
134137
);
135138
productName = RobotConf;
136139
productReference = B2CD272B234D06530016AA02 /* Android Makers.app */;
@@ -205,7 +208,7 @@
205208
);
206209
runOnlyForDeploymentPostprocessing = 0;
207210
shellPath = /bin/sh;
208-
shellScript = "cd \"$SRCROOT/..\"\n./gradlew :shared:embedAndSignAppleFrameworkForXcode\n";
211+
shellScript = "if [ \"YES\" = \"$OVERRIDE_KOTLIN_BUILD_IDE_SUPPORTED\" ]; then\n echo \"Skipping Gradle build task invocation due to OVERRIDE_KOTLIN_BUILD_IDE_SUPPORTED environment variable set to \\\"YES\\\"\"\n exit 0\nfi\ncd \"$SRCROOT/..\"\n./gradlew :shared:embedAndSignAppleFrameworkForXcode";
209212
};
210213
/* End PBXShellScriptBuildPhase section */
211214

@@ -480,6 +483,11 @@
480483
package = 61C8A7632D8B199B0046C2CC /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */;
481484
productName = FirebaseAuth;
482485
};
486+
61C8A76C2D8B1C490046C2CC /* FirebaseMessaging */ = {
487+
isa = XCSwiftPackageProductDependency;
488+
package = 61C8A7632D8B199B0046C2CC /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */;
489+
productName = FirebaseMessaging;
490+
};
483491
/* End XCSwiftPackageProductDependency section */
484492
};
485493
rootObject = B2CD2723234D06530016AA02 /* Project object */;

shared/ui/src/commonMain/composeResources/values/strings.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@
4949
<string name="expert">Expert</string>
5050

5151
<!--About-->
52-
<string name="about_android_makers">Android Makers by droidcon is a two days event held in Paris on April 9th and 10th 2025. Join us in tackling the present and future of Android with the hottest experts of the domain. There will be technical sessions, workshops and opportunities to meet your favorites speakers. All the Talks will be recorded, and uploaded on the Youtube channel.</string>
52+
<string name="about_android_makers">Android Makers by droidcon is a two days event held in Paris on April 9th and 10th 2026. Join us in tackling the present and future of Android with the hottest experts of the domain. There will be technical sessions, workshops and opportunities to meet your favorites speakers. All the Talks will be recorded, and uploaded on the Youtube channel.</string>
5353

5454
<string name="open_slides">Open the slides</string>
5555

shared/ui/src/commonMain/kotlin/com/androidmakers/ui/MainLayout.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ fun MainLayout(
100100
)
101101
}
102102

103-
} // AndroidMakersTheme
103+
}
104104
}
105105

106106
@Composable

shared/ui/src/commonMain/kotlin/com/androidmakers/ui/common/navigation/AVALayout.kt

Lines changed: 97 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,18 @@
11
package com.androidmakers.ui.common.navigation
22

3+
import androidx.compose.animation.EnterTransition
4+
import androidx.compose.animation.ExitTransition
35
import androidx.compose.animation.SharedTransitionLayout
6+
import androidx.compose.animation.core.tween
7+
import androidx.compose.animation.fadeIn
8+
import androidx.compose.animation.fadeOut
9+
import androidx.compose.animation.togetherWith
410
import androidx.compose.foundation.Image
511
import androidx.compose.foundation.layout.Box
612
import androidx.compose.foundation.layout.Column
713
import androidx.compose.foundation.layout.RowScope
814
import androidx.compose.foundation.layout.consumeWindowInsets
15+
import androidx.compose.foundation.layout.fillMaxSize
916
import androidx.compose.foundation.layout.padding
1017
import androidx.compose.foundation.layout.size
1118
import androidx.compose.material3.ExperimentalMaterial3Api
@@ -16,6 +23,7 @@ import androidx.compose.material3.NavigationBar
1623
import androidx.compose.material3.NavigationBarItem
1724
import androidx.compose.material3.NavigationBarItemDefaults
1825
import androidx.compose.material3.Scaffold
26+
import androidx.compose.material3.Surface
1927
import androidx.compose.material3.Text
2028
import androidx.compose.material3.TopAppBar
2129
import androidx.compose.material3.TopAppBarDefaults
@@ -297,40 +305,70 @@ private fun AVANavDisplay(
297305
val entryProvider = entryProvider {
298306
// Tab entries
299307
entry<FeedKey> {
300-
FeedScreen()
308+
Surface(
309+
modifier = Modifier.fillMaxSize(),
310+
color = MaterialTheme.colorScheme.background,
311+
contentColor = MaterialTheme.colorScheme.onBackground,
312+
) {
313+
FeedScreen()
314+
}
301315
}
302316

303317
entry<AgendaKey>(
304318
metadata = ListDetailSceneStrategy.listPane(
305319
detailPlaceholder = {}
306320
)
307321
) {
308-
AgendaLayout(
309-
showFilterBottomSheet = showAgendaFilterBottomSheet,
310-
onFilterBottomSheetDismiss = onDismissAgendaFilter,
311-
onSessionClick = { sessionId -> navigator.navigateToSessionDetail(sessionId) }
312-
)
322+
Surface(
323+
modifier = Modifier.fillMaxSize(),
324+
color = MaterialTheme.colorScheme.background,
325+
contentColor = MaterialTheme.colorScheme.onBackground,
326+
) {
327+
AgendaLayout(
328+
showFilterBottomSheet = showAgendaFilterBottomSheet,
329+
onFilterBottomSheetDismiss = onDismissAgendaFilter,
330+
onSessionClick = { sessionId -> navigator.navigateToSessionDetail(sessionId) }
331+
)
332+
}
313333
}
314334

315335
entry<SpeakersKey> {
316-
SpeakerScreen(
317-
viewModel = koinViewModel(),
318-
navigateToSpeakerDetails = { speakerId -> navigator.navigate(SpeakerDetailKey(speakerId)) },
319-
sharedTransitionScope = sharedTransitionScope,
320-
animatedVisibilityScope = LocalNavAnimatedContentScope.current,
321-
)
336+
Surface(
337+
modifier = Modifier.fillMaxSize(),
338+
color = MaterialTheme.colorScheme.background,
339+
contentColor = MaterialTheme.colorScheme.onBackground,
340+
) {
341+
SpeakerScreen(
342+
viewModel = koinViewModel(),
343+
navigateToSpeakerDetails = { speakerId -> navigator.navigate(SpeakerDetailKey(speakerId)) },
344+
sharedTransitionScope = sharedTransitionScope,
345+
animatedVisibilityScope = LocalNavAnimatedContentScope.current,
346+
)
347+
}
322348
}
323349

324350
entry<SponsorsKey> {
325-
SponsorsScreen()
351+
Surface(
352+
modifier = Modifier.fillMaxSize(),
353+
color = MaterialTheme.colorScheme.background,
354+
contentColor = MaterialTheme.colorScheme.onBackground,
355+
) {
356+
SponsorsScreen()
357+
}
326358
}
327359

328360
entry<InfoKey> {
329-
InfoScreen(
330-
versionCode = versionCode,
331-
versionName = versionName,
332-
featureFlags = featureFlags,
333-
)
361+
Surface(
362+
modifier = Modifier.fillMaxSize(),
363+
color = MaterialTheme.colorScheme.background,
364+
contentColor = MaterialTheme.colorScheme.onBackground,
365+
) {
366+
InfoScreen(
367+
versionCode = versionCode,
368+
versionName = versionName,
369+
featureFlags = featureFlags,
370+
)
371+
}
334372
}
335373

336374
// Detail entries
@@ -341,41 +379,61 @@ private fun AVANavDisplay(
341379
BottomSheetSceneStrategy.bottomSheet()
342380
}
343381
) { key ->
344-
SessionDetailScreen(
345-
viewModel = koinViewModel(key = key.sessionId) { parametersOf(key.sessionId) },
346-
onBackClick = { navigator.goBack() },
347-
onSpeakerClick = { speakerId -> navigator.navigate(SpeakerDetailKey(speakerId)) },
348-
showBackButton = isWideScreen,
349-
showTopBar = isWideScreen,
350-
sharedTransitionScope = sharedTransitionScope,
351-
// LocalNavAnimatedContentScope is unavailable in OverlayScene (bottom sheet)
352-
animatedVisibilityScope = if (isWideScreen) {
353-
LocalNavAnimatedContentScope.current
354-
} else {
355-
null
356-
},
357-
)
382+
Surface(
383+
modifier = Modifier.fillMaxSize(),
384+
color = MaterialTheme.colorScheme.background,
385+
contentColor = MaterialTheme.colorScheme.onBackground,
386+
) {
387+
SessionDetailScreen(
388+
viewModel = koinViewModel(key = key.sessionId) { parametersOf(key.sessionId) },
389+
onBackClick = { navigator.goBack() },
390+
onSpeakerClick = { speakerId -> navigator.navigate(SpeakerDetailKey(speakerId)) },
391+
showBackButton = isWideScreen,
392+
showTopBar = isWideScreen,
393+
sharedTransitionScope = sharedTransitionScope,
394+
// LocalNavAnimatedContentScope is unavailable in OverlayScene (bottom sheet)
395+
animatedVisibilityScope = if (isWideScreen) {
396+
LocalNavAnimatedContentScope.current
397+
} else {
398+
null
399+
},
400+
)
401+
}
358402
}
359403

360404
entry<SpeakerDetailKey> { key ->
361-
SpeakerDetailsRoute(
362-
speakerDetailsViewModel = koinViewModel(key = key.speakerId) { parametersOf(key.speakerId) },
363-
onBackClick = { navigator.goBack() },
364-
sharedTransitionScope = sharedTransitionScope,
365-
animatedVisibilityScope = LocalNavAnimatedContentScope.current,
366-
)
405+
Surface(
406+
modifier = Modifier.fillMaxSize(),
407+
color = MaterialTheme.colorScheme.background,
408+
contentColor = MaterialTheme.colorScheme.onBackground,
409+
) {
410+
SpeakerDetailsRoute(
411+
speakerDetailsViewModel = koinViewModel(key = key.speakerId) { parametersOf(key.speakerId) },
412+
onBackClick = { navigator.goBack() },
413+
sharedTransitionScope = sharedTransitionScope,
414+
animatedVisibilityScope = LocalNavAnimatedContentScope.current,
415+
)
416+
}
367417
}
368418
}
369419

370420
val bottomSheetStrategy = remember { BottomSheetSceneStrategy<NavKey>() }
371421
val listDetailStrategy = rememberListDetailSceneStrategy<NavKey>()
372422

423+
373424
NavDisplay(
374425
entries = navigationState.toDecoratedEntries(entryProvider),
375426
sceneStrategies = listOf(bottomSheetStrategy, listDetailStrategy),
376-
onBack = { navigator.goBack() }
427+
onBack = navigator::goBack,
428+
transitionSpec = {
429+
fadeIn(tween(200)) togetherWith ExitTransition.None
430+
},
431+
popTransitionSpec = {
432+
EnterTransition.None togetherWith fadeOut(tween(200))
433+
},
377434
)
378435
}
436+
379437
}
380438

381439
@Composable

shared/ui/src/commonMain/kotlin/com/androidmakers/ui/feed/FeedScreen.kt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,10 @@ fun FeedScreen() {
1818
val lce by viewModel.values.collectAsStateWithLifecycle()
1919
val dismissedAlertIds by viewModel.dismissedAlertIds.collectAsStateWithLifecycle()
2020

21-
LceLayout(lce = lce, onRetry = { viewModel.refresh() }) { feedItems ->
21+
LceLayout(
22+
lce = lce,
23+
onRetry = { viewModel.refresh() }
24+
) { feedItems ->
2225
val visibleItems = feedItems.filter { item ->
2326
item !is FeedItem.Alert || item.id !in dismissedAlertIds
2427
}

0 commit comments

Comments
 (0)