Skip to content

Commit

Permalink
Add session detail screen
Browse files Browse the repository at this point in the history
  • Loading branch information
BoD committed Mar 31, 2024
1 parent 16493f8 commit d668916
Show file tree
Hide file tree
Showing 11 changed files with 446 additions and 97 deletions.
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
package fr.paug.androidmakers.wear.di

import fr.paug.androidmakers.wear.ui.main.MainViewModel
import fr.paug.androidmakers.wear.ui.session.details.SessionDetailViewModel
import fr.paug.androidmakers.wear.ui.settings.SettingsViewModel
import org.koin.androidx.viewmodel.dsl.viewModel
import org.koin.dsl.module

val androidViewModelModule = module {
viewModel { MainViewModel(get(), get(), get(), get(), get(), get()) }
viewModel { SettingsViewModel(get(), get()) }
viewModel { SessionDetailViewModel(get(), get(), get(), get(), get(), get()) }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package fr.paug.androidmakers.wear.ui.common

import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.wear.compose.material.CircularProgressIndicator

@Composable
fun Loading() {
Box(
modifier = Modifier
.fillMaxSize(),
contentAlignment = Alignment.Center
) {
CircularProgressIndicator()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,34 +7,47 @@ import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.pager.PagerState
import androidx.compose.foundation.pager.rememberPagerState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.core.app.ActivityCompat
import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
import androidx.navigation.NavType
import androidx.navigation.navArgument
import androidx.wear.compose.foundation.SwipeToDismissBoxState
import androidx.wear.compose.foundation.SwipeToDismissValue
import androidx.wear.compose.foundation.edgeSwipeToDismiss
import androidx.wear.compose.foundation.rememberSwipeToDismissBoxState
import androidx.wear.compose.navigation.SwipeDismissableNavHost
import androidx.wear.compose.navigation.composable
import androidx.wear.compose.navigation.currentBackStackEntryAsState
import androidx.wear.compose.navigation.rememberSwipeDismissableNavController
import androidx.wear.compose.navigation.rememberSwipeDismissableNavHostState
import com.google.android.horologist.compose.layout.AppScaffold
import com.google.android.horologist.compose.pager.PagerScreen
import fr.androidmakers.domain.model.User
import fr.paug.androidmakers.wear.R
import fr.paug.androidmakers.wear.ui.session.UISession
import fr.paug.androidmakers.wear.ui.session.details.SessionDetailScreen
import fr.paug.androidmakers.wear.ui.session.details.SessionDetailViewModel
import fr.paug.androidmakers.wear.ui.session.list.SessionListScreen
import fr.paug.androidmakers.wear.ui.settings.SettingsScreen
import fr.paug.androidmakers.wear.ui.signin.SignInScreen
import fr.paug.androidmakers.wear.ui.theme.AndroidMakersWearTheme
import org.koin.androidx.compose.koinViewModel
import org.koin.core.parameter.parametersOf

class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
installSplashScreen()
WearApp()
WearApp(onSwipeToDismissRootLevel = { ActivityCompat.finishAffinity(this) })
setTheme(android.R.style.Theme_DeviceDefault)
}
}
Expand All @@ -43,39 +56,69 @@ class MainActivity : ComponentActivity() {
@Composable
fun WearApp(
viewModel: MainViewModel = koinViewModel(),
onSwipeToDismissRootLevel: () -> Unit,
) {
val navController = rememberSwipeDismissableNavController()
val swipeToDismissBoxState = rememberSwipeToDismissBoxState()
val swipeDismissableNavHostState = rememberSwipeDismissableNavHostState(swipeToDismissBoxState)

// Workaround so swipe to dismiss works on the root level
// See https://slack-chats.kotlinlang.org/t/16230979/problem-changing-basicswipetodismiss-background-color-gt
var currentRoute by remember { mutableStateOf("") }
LaunchedEffect(swipeToDismissBoxState.currentValue) {
if (swipeToDismissBoxState.currentValue == SwipeToDismissValue.Dismissed) {
if (currentRoute == Navigation.main) {
onSwipeToDismissRootLevel()
}
}
}

val onSignInClick: () -> Unit = {
navController.navigate(Navigation.SIGN_IN)
navController.navigate(Navigation.signIn)
}
val onSignInDismissOrTimeout: () -> Unit = {
navController.popBackStack()
}

navController.currentBackStackEntryAsState().value?.let { backStackEntry ->
currentRoute = backStackEntry.destination.route ?: ""
}

val onSignInSuccess = viewModel::onSignInSuccess
AndroidMakersWearTheme {
AppScaffold {
val swipeToDismissBoxState = rememberSwipeToDismissBoxState()
val swipeDismissableNavHostState =
rememberSwipeDismissableNavHostState(swipeToDismissBoxState)
SwipeDismissableNavHost(
navController = navController,
startDestination = Navigation.MAIN,
startDestination = Navigation.main,
state = swipeDismissableNavHostState,
) {
composable(Navigation.MAIN) {
composable(Navigation.main) {
MainScreen(
viewModel = viewModel,
swipeToDismissBoxState = swipeToDismissBoxState,
onSignInClick = onSignInClick,
onSignOutClick = { viewModel.signOut() },
swipeToDismissBoxState = swipeToDismissBoxState,
viewModel = viewModel,
onSessionClick = { sessionId ->
navController.navigate(Navigation.sessionDetail(sessionId))
}
)
}
composable(Navigation.SIGN_IN) {
composable(Navigation.signIn) {
SignInScreen(
onSignInSuccess = onSignInSuccess,
onDismissOrTimeout = onSignInDismissOrTimeout
)
}
composable(
Navigation.sessionDetail,
arguments = listOf(navArgument(Navigation.id) { type = NavType.StringType })
) {
val sessionId = it.arguments!!.getString(Navigation.id)!!
val sessionDetailViewModel: SessionDetailViewModel =
koinViewModel { parametersOf(sessionId) }

SessionDetailScreen(sessionDetailViewModel)
}
}
}
}
Expand All @@ -87,6 +130,7 @@ fun MainScreen(
swipeToDismissBoxState: SwipeToDismissBoxState,
onSignInClick: () -> Unit,
onSignOutClick: () -> Unit,
onSessionClick: (String) -> Unit,
) {
val pagerState: PagerState =
rememberPagerState(initialPage = viewModel.getConferenceDay() + 1, pageCount = { 3 })
Expand All @@ -110,11 +154,19 @@ fun MainScreen(
}

1 -> {
SessionListScreen(sessions = sessionsDay1, title = stringResource(id = R.string.main_day1))
SessionListScreen(
sessions = sessionsDay1,
title = stringResource(id = R.string.main_day1),
onSessionClick = onSessionClick
)
}

2 -> {
SessionListScreen(sessions = sessionsDay2, title = stringResource(id = R.string.main_day2))
SessionListScreen(
sessions = sessionsDay2,
title = stringResource(id = R.string.main_day2),
onSessionClick = onSessionClick
)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import fr.androidmakers.domain.repo.UserRepository
import fr.paug.androidmakers.wear.R
import fr.paug.androidmakers.wear.applicationContext
import fr.paug.androidmakers.wear.data.LocalPreferencesRepository
import fr.paug.androidmakers.wear.ui.session.UISession
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharingStarted
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
package fr.paug.androidmakers.wear.ui.main

object Navigation {
const val MAIN = "MAIN"
const val SIGN_IN = "SIGN_IN"
const val main = "main"

const val signIn = "signIn"

const val id = "id"
const val sessionDetail = "sessionDetail/{$id}"
fun sessionDetail(id: String): String {
return "sessionDetail/$id"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package fr.paug.androidmakers.wear.ui.session

import fr.androidmakers.domain.model.Room
import fr.androidmakers.domain.model.Session
import fr.androidmakers.domain.model.Speaker
import kotlinx.datetime.LocalDateTime
import kotlinx.datetime.Month

val uiSession1 = UISession(
session = Session(
id = "1",
title = "Android Graphics: the Path to [UI] Riches",
description = "Android's graphics APIs are extensive and powerful... but maybe a little complicated. This session will show ways to use the graphics APIs to achieve cool effects and improve the visual quality and richness of your applications.",
roomId = "",
speakers = emptyList(),
startsAt = LocalDateTime(2023, Month.APRIL, 27, 9, 15),
endsAt = LocalDateTime(2023, Month.APRIL, 27, 10, 0),
isServiceSession = false,
),
speakers = listOf(
Speaker(
id = "1",
name = "Speaker 1",
bio = "Bio 1",
),
Speaker(
id = "2",
name = "Speaker 2",
bio = "Bio 2",
)
),
room = Room(
id = "1",
name = "Room 1"
),
isBookmarked = true,
)

val uiSession2 = UISession(
session = Session(
id = "2",
title = "Using Compose Runtime to create a client library",
description = "Jetpack Compose (UI) is a powerful UI toolkit for Android. Have you ever wondered where this power comes from? The answer is Compose Runtime. \r\n\r\nIn this talk, we will see how we can use Compose Runtime to create client libraries. Firstly, we will talk about Compose nodes, Composition, Recomposer, and how they are orchestrated to create a slot table. Then, we will see how the changes in the slot table are applied with an Applier. Moreover, we will touch upon the Snapshot system and how the changes in the state objects trigger a recomposition. Finally, we will create a basic UI toolkit for PowerPoint using Compose Runtime.",
roomId = "",
speakers = emptyList(),
startsAt = LocalDateTime(2023, Month.APRIL, 27, 10, 15),
endsAt = LocalDateTime(2023, Month.APRIL, 27, 11, 0),
isServiceSession = false,
),
speakers = listOf(
Speaker(
id = "3",
name = "Speaker 3",
bio = "Bio 3",
),
),
room = Room(
id = "2",
name = "Room 2"
),
isBookmarked = false,
)

val uiSessions = listOf(
uiSession1,
uiSession2,
)
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package fr.paug.androidmakers.wear.ui.main
package fr.paug.androidmakers.wear.ui.session

import fr.androidmakers.domain.model.Room
import fr.androidmakers.domain.model.Session
Expand Down
Loading

0 comments on commit d668916

Please sign in to comment.