From 6f12feccc2f51bc101ea7e748d25e07c235c1b43 Mon Sep 17 00:00:00 2001 From: maxime Date: Tue, 2 Apr 2024 21:58:31 +0200 Subject: [PATCH] add navigation --- .../main/java/com/iqball/app/MainActivity.kt | 24 +++++----- .../main/java/com/iqball/app/page/HomePage.kt | 44 +++++++++++-------- .../com/iqball/app/page/VisualizerPage.kt | 36 +++++++-------- .../com/iqball/app/session/Authentication.kt | 2 +- .../com/iqball/app/vm/SessionViewModel.kt | 11 +++++ 5 files changed, 67 insertions(+), 50 deletions(-) create mode 100644 app/src/main/java/com/iqball/app/vm/SessionViewModel.kt diff --git a/app/src/main/java/com/iqball/app/MainActivity.kt b/app/src/main/java/com/iqball/app/MainActivity.kt index 201ec44..9f17386 100644 --- a/app/src/main/java/com/iqball/app/MainActivity.kt +++ b/app/src/main/java/com/iqball/app/MainActivity.kt @@ -7,13 +7,13 @@ import androidx.activity.compose.setContent import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Surface -import androidx.compose.material3.Text import androidx.compose.runtime.Composable -import androidx.compose.runtime.MutableState +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.lifecycle.viewmodel.compose.viewModel import androidx.navigation.compose.NavHost import androidx.navigation.compose.composable import androidx.navigation.compose.rememberNavController @@ -33,11 +33,13 @@ import com.iqball.app.net.service.IQBallService import com.iqball.app.page.HomePage import com.iqball.app.page.LoginPage import com.iqball.app.page.RegisterPage +import com.iqball.app.page.VisualizerPage import com.iqball.app.serialization.EitherTypeAdapterFactory import com.iqball.app.serialization.EnumTypeAdapterFactory import com.iqball.app.session.DataSession import com.iqball.app.session.Session import com.iqball.app.ui.theme.IQBallTheme +import com.iqball.app.vm.SessionViewModel import com.squareup.moshi.Moshi import com.squareup.moshi.adapters.PolymorphicJsonAdapterFactory import com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterFactory @@ -94,8 +96,7 @@ class MainActivity : ComponentActivity() { modifier = Modifier.fillMaxSize(), color = MaterialTheme.colorScheme.background ) { - val sessionState = remember { mutableStateOf(DataSession()) } - App(service, sessionState) + App(service) } } } @@ -103,16 +104,16 @@ class MainActivity : ComponentActivity() { } @Composable -fun App(service: IQBallService, sessionState: MutableState) { +fun App(service: IQBallService) { val navController = rememberNavController() + var session by viewModel().session NavHost(navController = navController, startDestination = "login") { composable("login") { LoginPage( service = service, onLoginSuccess = { auth -> - Log.i("ZIZI", "auth : ${auth}") - sessionState.value = DataSession(auth) + session = DataSession(auth) navController.navigate("home") Log.i("ZIZI", "auth : ${auth}") }, @@ -125,7 +126,7 @@ fun App(service: IQBallService, sessionState: MutableState) { RegisterPage( service = service, onRegisterSuccess = { auth -> - sessionState.value = DataSession(auth) + session = DataSession(auth) navController.navigate("home") }, onNavigateToLogin = { @@ -134,7 +135,10 @@ fun App(service: IQBallService, sessionState: MutableState) { ) } composable("home") { - HomePage(service = service, sessionState.value.auth!!) + HomePage(service = service, auth = session.auth!!, navController = navController) + } + composable("view/{id}") { + VisualizerPage(service = service, auth = session.auth!!, tacticId = it.arguments!!.getString("id")!!.toInt()) } } } \ No newline at end of file diff --git a/app/src/main/java/com/iqball/app/page/HomePage.kt b/app/src/main/java/com/iqball/app/page/HomePage.kt index b440db5..a8d7067 100644 --- a/app/src/main/java/com/iqball/app/page/HomePage.kt +++ b/app/src/main/java/com/iqball/app/page/HomePage.kt @@ -1,14 +1,12 @@ package com.iqball.app.page -import com.iqball.app.model.Tactic -import com.iqball.app.model.Team import androidx.compose.foundation.BorderStroke import androidx.compose.foundation.Canvas import androidx.compose.foundation.background import androidx.compose.foundation.border +import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box -import androidx.compose.runtime.Composable import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.Row @@ -22,7 +20,6 @@ import androidx.compose.foundation.lazy.staggeredgrid.items import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material3.Button import androidx.compose.material3.ButtonDefaults -import androidx.core.graphics.toColorInt import androidx.compose.material3.CenterAlignedTopAppBar import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.MaterialTheme @@ -31,24 +28,28 @@ import androidx.compose.material3.Text import androidx.compose.material3.TopAppBarDefaults import androidx.compose.material3.TopAppBarDefaults.pinnedScrollBehavior import androidx.compose.material3.rememberTopAppBarState +import androidx.compose.runtime.Composable import androidx.compose.runtime.MutableState import androidx.compose.runtime.mutableIntStateOf -import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.text.style.TextOverflow -import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp import androidx.compose.runtime.remember import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier import androidx.compose.ui.draw.shadow +import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.RectangleShape import androidx.compose.ui.input.nestedscroll.nestedScroll import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.TextUnit +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import androidx.core.graphics.toColorInt +import androidx.navigation.NavController import arrow.core.Either import coil.compose.AsyncImage -import com.iqball.app.net.service.AuthService +import com.iqball.app.model.Tactic +import com.iqball.app.model.Team import com.iqball.app.net.service.IQBallService import com.iqball.app.net.service.UserService import com.iqball.app.session.Authentication @@ -60,15 +61,17 @@ import java.time.format.DateTimeFormatter @OptIn(ExperimentalMaterial3Api::class) @Composable -fun HomePage(service: IQBallService, auth: Authentication) { +fun HomePage(service: IQBallService, + auth: Authentication, + navController: NavController) { val tactics: List val teams: List var invalid = false val data = getDataFromApi(service, auth) if (data == null) { - tactics = listOf() - teams = listOf() + tactics = listOf() + teams = listOf() invalid = true } else { @@ -96,7 +99,7 @@ fun HomePage(service: IQBallService, auth: Authentication) { ) }, ) { innerPadding -> - Body(innerPadding, tactics, teams, invalid) + Body(innerPadding, tactics, teams, invalid, navController) } } @@ -105,7 +108,8 @@ private fun Body( padding: PaddingValues, tactics: List, teams: List, - invalid: Boolean + invalid: Boolean, + navController: NavController ) { Column( modifier = Modifier @@ -115,7 +119,9 @@ private fun Body( val tabs = listOf Unit>>( Pair("Espace personnel") { ListComponentCard(tactics) { tactic -> - TacticCard(tactic = tactic) + TacticCard(tactic = tactic, onClick = { + navController.navigate("view/${tactic.id}") + }) } }, Pair("Mes équipes") { @@ -130,7 +136,6 @@ private fun Body( return } - TextCentered( text = "Erreur : Aucune connexion internet. Veillez activer votre connexion internet puis relancer l'application", fontSize = 20.sp @@ -197,7 +202,7 @@ private fun ListComponentCard(items: List, componentCard: @Composable (C) } @Composable -private fun TacticCard(tactic: Tactic) { +private fun TacticCard(tactic: Tactic, onClick: () -> Unit) { Column( modifier = Modifier .padding(5.dp) @@ -210,6 +215,7 @@ private fun TacticCard(tactic: Tactic) { color = Color.White ) .padding(15.dp) + .clickable { onClick() } ) { Row { TextCentered(text = tactic.name, fontSize = 16.sp) @@ -404,4 +410,4 @@ fun ListComponentCard(componentCard: LazyStaggeredGridScope.() -> Unit) { ) } - */ \ No newline at end of file + */ diff --git a/app/src/main/java/com/iqball/app/page/VisualizerPage.kt b/app/src/main/java/com/iqball/app/page/VisualizerPage.kt index f85787a..f94b9e2 100644 --- a/app/src/main/java/com/iqball/app/page/VisualizerPage.kt +++ b/app/src/main/java/com/iqball/app/page/VisualizerPage.kt @@ -4,6 +4,7 @@ import android.content.res.Configuration import android.util.Log import androidx.compose.foundation.background import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.IntrinsicSize import androidx.compose.foundation.layout.Row @@ -43,6 +44,7 @@ import com.iqball.app.model.tactic.StepContent import com.iqball.app.model.tactic.StepNodeInfo import com.iqball.app.model.tactic.getParent import com.iqball.app.net.service.TacticService +import com.iqball.app.session.Authentication import com.iqball.app.session.Token import kotlinx.coroutines.runBlocking import net.engawapg.lib.zoomable.ZoomState @@ -59,10 +61,10 @@ private data class VisualizerInitialData( @Composable fun VisualizerPage( service: TacticService, - auth: Token, + auth: Authentication, tacticId: Int, ) { - val dataEither = remember { initializeVisualizer(service, auth, tacticId) } + val dataEither = remember { initializeVisualizer(service, auth.token, tacticId) } val showTree = remember { mutableStateOf(true) } val (info, stepsTree) = when (dataEither) { @@ -72,7 +74,7 @@ fun VisualizerPage( } fun getStepContent(step: Int): StepContent = runBlocking { - val result = service.getTacticStepContent(auth, tacticId, step).onLeft { + val result = service.getTacticStepContent(auth.token, tacticId, step).onLeft { Log.e( "received error response from server when retrieving step content: {}", it.toString() @@ -112,8 +114,7 @@ fun VisualizerPage( val courtModifier = if (showTree.value) Modifier.width(IntrinsicSize.Min) else Modifier.fillMaxWidth() - - + val courtZoomState = remember { ZoomState() } Row(modifier = Modifier.background(Color.LightGray)) { @@ -142,32 +143,27 @@ fun VisualizerPage( else -> throw Exception("Could not determine device's orientation.") } } - } @Composable private fun VisualizerHeader(title: String, showTree: MutableState) { - - - Row( + Box( modifier = Modifier .fillMaxWidth() .zIndex(10000F) .background(Color.White), - horizontalArrangement = Arrangement.SpaceBetween, - verticalAlignment = Alignment.CenterVertically ) { - IconButton(onClick = { /*TODO*/ }) { - Icon( - imageVector = Icons.Filled.ArrowBack, - contentDescription = "Back", - tint = Color.Black - ) - } - Text(text = title, color = Color.Black) + Text( + text = title, + color = Color.Black, + modifier = Modifier.align(Alignment.Center) + ) - IconButton(onClick = { showTree.value = !showTree.value }) { + IconButton( + onClick = { showTree.value = !showTree.value }, + modifier = Modifier.align(Alignment.CenterEnd) + ) { Icon( painter = painterResource(id = R.drawable.tree_icon), contentDescription = "toggle show tree" diff --git a/app/src/main/java/com/iqball/app/session/Authentication.kt b/app/src/main/java/com/iqball/app/session/Authentication.kt index ff2855f..2b43798 100644 --- a/app/src/main/java/com/iqball/app/session/Authentication.kt +++ b/app/src/main/java/com/iqball/app/session/Authentication.kt @@ -1,4 +1,4 @@ package com.iqball.app.session typealias Token = String -data class Authentication(val token: String, val expirationDate: Long) +data class Authentication(val token: Token, val expirationDate: Long) diff --git a/app/src/main/java/com/iqball/app/vm/SessionViewModel.kt b/app/src/main/java/com/iqball/app/vm/SessionViewModel.kt new file mode 100644 index 0000000..382b67d --- /dev/null +++ b/app/src/main/java/com/iqball/app/vm/SessionViewModel.kt @@ -0,0 +1,11 @@ +package com.iqball.app.vm + +import androidx.compose.runtime.MutableState +import androidx.compose.runtime.mutableStateOf +import androidx.lifecycle.ViewModel +import com.iqball.app.session.DataSession +import com.iqball.app.session.Session + +class SessionViewModel : ViewModel() { + val session: MutableState = mutableStateOf(DataSession()) +} \ No newline at end of file