11package org.nsh07.nsh07.ui.homeScreen
22
3+ import androidx.compose.animation.*
34import androidx.compose.foundation.layout.*
45import androidx.compose.foundation.lazy.LazyColumn
56import androidx.compose.foundation.lazy.rememberLazyListState
67import androidx.compose.foundation.rememberScrollState
78import androidx.compose.foundation.verticalScroll
8- import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi
9+ import androidx.compose.material3.*
10+ import androidx.compose.material3.MaterialTheme.motionScheme
911import androidx.compose.material3.MaterialTheme.typography
10- import androidx.compose.material3.Text
12+ import androidx.compose.material3.adaptive.currentWindowAdaptiveInfo
1113import androidx.compose.runtime.*
1214import androidx.compose.ui.Modifier
15+ import androidx.compose.ui.platform.LocalLayoutDirection
1316import androidx.compose.ui.platform.LocalUriHandler
1417import androidx.compose.ui.unit.dp
18+ import androidx.window.core.layout.WindowSizeClass
1519import kotlinx.coroutines.launch
1620
17- @OptIn(ExperimentalMaterial3ExpressiveApi ::class )
21+ @OptIn(ExperimentalMaterial3ExpressiveApi ::class , ExperimentalMaterial3Api :: class )
1822@Composable
1923fun AppHomeScreen (
2024 projectState : ProjectsState ,
2125 modifier : Modifier = Modifier
2226) {
2327 val uriHandler = LocalUriHandler .current
2428 val scope = rememberCoroutineScope()
29+ val motionScheme = motionScheme
2530
2631 val listState = rememberLazyListState()
2732 val firstVisibleItem by derivedStateOf { listState.firstVisibleItemIndex }
33+ val scrolledUp by derivedStateOf { listState.lastScrolledForward }
2834
2935 val paragraphs = remember {
3036 listOf (
@@ -40,7 +46,7 @@ fun AppHomeScreen(
4046 start = " Aug 2025" ,
4147 end = " Present" ,
4248 position = " Open Source Lead" ,
43- description = " Perform the role of Open Source Lead of the Development Club. Helped successfully organise OPCODE (Open Source Fest) 2025." ,
49+ description = " Perform the role of Open Source Lead of the Development Club. Successfully organised OPCODE (Open Source Fest) 2025, while also contributing a project ." ,
4450 company = " DevC, IIIT Bhagalpur" ,
4551 companyUrl = " https://gymkhana.iiitbh.ac.in/technical/" ,
4652 skills = listOf ()
@@ -60,63 +66,137 @@ fun AppHomeScreen(
6066
6167 val cardPadding = remember { 16 .dp }
6268
63- Row (
64- modifier = Modifier
65- .padding(horizontal = 48 .dp)
66- .widthIn(max = 1200 .dp)
67- .then(modifier)
68- ) {
69- Column (Modifier .padding(vertical = 96 .dp).weight(1f )) {
70- Column (Modifier .verticalScroll(rememberScrollState())) {
71- NameAndDesc ()
69+ val windowSizeClass = currentWindowAdaptiveInfo().windowSizeClass
7270
73- Spacer (Modifier .height(72 .dp))
71+ if (windowSizeClass.isWidthAtLeastBreakpoint(WindowSizeClass .WIDTH_DP_EXPANDED_LOWER_BOUND )) {
72+ Row (
73+ modifier = Modifier
74+ .padding(horizontal = 48 .dp)
75+ .widthIn(max = 1200 .dp)
76+ .then(modifier)
77+ ) {
78+ Column (Modifier .padding(vertical = 96 .dp).weight(1f )) {
79+ Column (Modifier .verticalScroll(rememberScrollState())) {
80+ NameAndDesc ()
7481
75- NavigationItem (
76- selected = firstVisibleItem < paragraphCount + 1 ,
77- onClick = {
78- scope.launch { listState.animateScrollToItem(0 ) }
79- },
80- label = { Text (" About" , style = typography.bodyMedium) },
81- modifier = Modifier .offset(x = (- 20 ).dp)
82- )
83- NavigationItem (
84- selected = firstVisibleItem in paragraphCount + 1 .. < paragraphCount + experienceCount + 2 ,
85- onClick = {
86- scope.launch { listState.animateScrollToItem(paragraphCount + 1 ) }
87- },
88- label = { Text (" Experience" , style = typography.bodyMedium) },
89- modifier = Modifier .offset(x = (- 20 ).dp)
90- )
91- NavigationItem (
92- selected = firstVisibleItem >= paragraphCount + experienceCount + 2 ,
93- onClick = {
94- scope.launch { listState.animateScrollToItem(paragraphCount + experienceCount + 2 ) }
95- },
96- label = { Text (" Projects" , style = typography.bodyMedium) },
97- modifier = Modifier .offset(x = (- 20 ).dp)
98- )
82+ Spacer (Modifier .height(72 .dp))
9983
100- Spacer (Modifier .height(32 .dp))
101- }
84+ NavigationItem (
85+ selected = firstVisibleItem < paragraphCount + 1 ,
86+ onClick = {
87+ scope.launch { listState.animateScrollToItem(0 ) }
88+ },
89+ label = { Text (" About" , style = typography.bodyMedium) },
90+ modifier = Modifier .offset(x = (- 20 ).dp)
91+ )
92+ NavigationItem (
93+ selected = firstVisibleItem in paragraphCount + 1 .. < paragraphCount + experienceCount + 2 ,
94+ onClick = {
95+ scope.launch { listState.animateScrollToItem(paragraphCount + 1 ) }
96+ },
97+ label = { Text (" Experience" , style = typography.bodyMedium) },
98+ modifier = Modifier .offset(x = (- 20 ).dp)
99+ )
100+ NavigationItem (
101+ selected = firstVisibleItem >= paragraphCount + experienceCount + 2 ,
102+ onClick = {
103+ scope.launch { listState.animateScrollToItem(paragraphCount + experienceCount + 2 ) }
104+ },
105+ label = { Text (" Projects" , style = typography.bodyMedium) },
106+ modifier = Modifier .offset(x = (- 20 ).dp)
107+ )
102108
103- Spacer (Modifier .weight(1f ))
109+ Spacer (Modifier .height(32 .dp))
110+ }
104111
105- SocialIcons ()
106- }
112+ Spacer (Modifier .weight(1f ))
107113
108- LazyColumn (
109- state = listState,
110- contentPadding = PaddingValues (vertical = 96 .dp),
111- modifier = Modifier .fillMaxHeight().weight(1.1f )
112- ) {
113- mainContent(
114- paragraphs,
115- experiences,
116- projectState,
117- cardPadding,
118- uriHandler
119- )
114+ SocialIcons ()
115+ }
116+
117+ LazyColumn (
118+ state = listState,
119+ contentPadding = PaddingValues (vertical = 96 .dp),
120+ modifier = Modifier .fillMaxHeight().weight(1.1f )
121+ ) {
122+ mainContent(
123+ paragraphs,
124+ experiences,
125+ projectState,
126+ cardPadding,
127+ uriHandler
128+ )
129+ }
130+ }
131+ } else {
132+ Scaffold (
133+ topBar = {
134+ AnimatedVisibility (
135+ firstVisibleItem > 1 ,
136+ enter = slideInVertically(motionScheme.defaultSpatialSpec(), initialOffsetY = { - it }),
137+ exit = slideOutVertically(motionScheme.defaultSpatialSpec(), targetOffsetY = { - it })
138+ ) {
139+ val topBarContent = when (firstVisibleItem) {
140+ in paragraphCount + 2 .. < paragraphCount + experienceCount + 3 -> 1
141+ in paragraphCount + experienceCount + 3 .. 1000 -> 2
142+ else -> 0
143+ }
144+ TopAppBar (
145+ title = {
146+ AnimatedContent (
147+ topBarContent,
148+ transitionSpec = {
149+ slideInVertically(
150+ animationSpec = motionScheme.fastSpatialSpec(),
151+ initialOffsetY = {
152+ if (scrolledUp) (it * 1.25 ).toInt() else (- it * 1.25 ).toInt()
153+ }
154+ ).togetherWith(
155+ slideOutVertically(
156+ animationSpec = motionScheme.fastSpatialSpec(),
157+ targetOffsetY = {
158+ if (scrolledUp) (- it * 1.25 ).toInt() else (it * 1.25 ).toInt()
159+ }
160+ )
161+ )
162+ },
163+ modifier = Modifier .width(200 .dp).padding(start = 8 .dp)
164+ ) {
165+ when (it) {
166+ 1 -> Text (" Experience" )
167+ 2 -> Text (" Projects" )
168+ else -> Text (" About" )
169+ }
170+ }
171+ }
172+ )
173+ }
174+ }
175+ ) { innerPadding ->
176+ val layoutDirection = LocalLayoutDirection .current
177+ LazyColumn (
178+ state = listState,
179+ contentPadding = PaddingValues (
180+ top = 48 .dp,
181+ start = innerPadding.calculateStartPadding(layoutDirection),
182+ end = innerPadding.calculateEndPadding(layoutDirection),
183+ bottom = 48 .dp
184+ ),
185+ modifier = Modifier .fillMaxWidth().padding(horizontal = 8 .dp)
186+ ) {
187+ item { NameAndDesc (horizontalPadding = 16 .dp) }
188+ item {
189+ SocialIcons (Modifier .padding(top = 32 .dp, start = 12 .dp, end = 12 .dp))
190+ Spacer (Modifier .height(96 .dp))
191+ }
192+ mainContent(
193+ paragraphs,
194+ experiences,
195+ projectState,
196+ cardPadding,
197+ uriHandler
198+ )
199+ }
120200 }
121201 }
122202}
0 commit comments