|
1 | 1 | package org.nsh07.nsh07.ui |
2 | 2 |
|
3 | | -import androidx.compose.foundation.clickable |
4 | | -import androidx.compose.foundation.layout.* |
5 | | -import androidx.compose.foundation.lazy.LazyColumn |
6 | | -import androidx.compose.foundation.lazy.items |
7 | | -import androidx.compose.foundation.lazy.rememberLazyListState |
8 | | -import androidx.compose.foundation.rememberScrollState |
9 | | -import androidx.compose.foundation.verticalScroll |
10 | | -import androidx.compose.material3.Icon |
11 | | -import androidx.compose.material3.IconButton |
12 | | -import androidx.compose.material3.MaterialTheme.colorScheme |
13 | | -import androidx.compose.material3.MaterialTheme.typography |
14 | | -import androidx.compose.material3.Text |
15 | 3 | import androidx.compose.material3.windowsizeclass.ExperimentalMaterial3WindowSizeClassApi |
16 | | -import androidx.compose.runtime.* |
17 | | -import androidx.compose.ui.Alignment |
| 4 | +import androidx.compose.runtime.Composable |
18 | 5 | import androidx.compose.ui.Modifier |
19 | | -import androidx.compose.ui.platform.LocalUriHandler |
20 | | -import androidx.compose.ui.text.* |
21 | | -import androidx.compose.ui.text.font.FontWeight |
22 | | -import androidx.compose.ui.unit.dp |
23 | | -import androidx.compose.ui.unit.sp |
24 | | -import kotlinx.coroutines.launch |
25 | | -import nsh07.composeapp.generated.resources.* |
26 | | -import org.jetbrains.compose.resources.painterResource |
| 6 | +import org.nsh07.nsh07.ui.homeScreen.AppHomeScreen |
27 | 7 |
|
28 | 8 | @OptIn(ExperimentalMaterial3WindowSizeClassApi::class) |
29 | 9 | @Composable |
30 | | -fun AppScreen(modifier: Modifier = Modifier) { |
31 | | - val uriHandler = LocalUriHandler.current |
32 | | - val scope = rememberCoroutineScope() |
33 | | - |
34 | | - val listState = rememberLazyListState() |
35 | | - val firstVisibleItem by derivedStateOf { listState.firstVisibleItemIndex } |
36 | | - |
37 | | - val paragraphs = remember { |
38 | | - listOf( |
39 | | - "Hi, I'm Nishant. I'm currently a hobbyist open-source software developer and a computer science student at the Indian Institute of Information Technology Bhagalpur.", |
40 | | - "I've written a variety of programs in multiple languages over my years as a hobbyist developer since back when I was in middle and high school (~2019) in Python and C++, spanning multiple areas like games, CLI tools, GUI tools and automation scripts. I'm continuing to work towards persuing my passion of software development as my career, now as a CS student." |
41 | | - ) |
42 | | - } |
43 | | - val paragraphCount = remember { paragraphs.size } |
44 | | - |
45 | | - val experiences = remember { |
46 | | - listOf( |
47 | | - Experience( |
48 | | - start = "Aug 2025", |
49 | | - end = "Present", |
50 | | - position = "Open Source Lead", |
51 | | - description = "Perform the role of Open Source Lead of the Development Club. Helped successfully organise OPCODE (Open Source Fest) 2025.", |
52 | | - company = "DevC, IIIT Bhagalpur", |
53 | | - companyUrl = "https://gymkhana.iiitbh.ac.in/technical/", |
54 | | - skills = listOf() |
55 | | - ), |
56 | | - Experience( |
57 | | - start = "May", |
58 | | - end = "June 2025", |
59 | | - position = "Research Asst. (Android Dev)", |
60 | | - description = "Created an Android app for collecting and compiling a validation dataset for a binary image classification model from scratch. Generated output from the model on-device for a fast, offline experience. Designed an intuitive UI, with options for viewing and editing entries in the dataset. Optimized the UX: the validation dataset can be exported to the device with the click of a button.", |
61 | | - company = "AIIMS Guwahati", |
62 | | - companyUrl = "https://aiimsguwahati.ac.in/", |
63 | | - skills = listOf("Kotlin", "Jetpack Compose", "PyTorch Android", "Android SDK") |
64 | | - ) |
65 | | - ) |
66 | | - } |
67 | | - val experienceCount = remember { experiences.size } |
68 | | - |
69 | | - val cardPadding = remember { 16.dp } |
70 | | - |
71 | | - Row( |
72 | | - modifier = Modifier |
73 | | - .padding(horizontal = 48.dp) |
74 | | - .widthIn(max = 1200.dp) |
75 | | - .then(modifier) |
76 | | - ) { |
77 | | - Column(Modifier.padding(vertical = 96.dp).weight(1f).verticalScroll(rememberScrollState())) { |
78 | | - Text( |
79 | | - "Nishant Mishra", |
80 | | - style = typography.displayLarge.copy(fontSize = 48.sp), |
81 | | - color = colorScheme.onSurface |
82 | | - ) |
83 | | - Spacer(Modifier.height(4.dp)) |
84 | | - Text( |
85 | | - "App developer", |
86 | | - style = typography.titleLarge, |
87 | | - color = colorScheme.onSurface |
88 | | - ) |
89 | | - Spacer(Modifier.height(20.dp)) |
90 | | - Text( |
91 | | - "I build performant, beautiful apps for mobile and desktop.", |
92 | | - style = typography.bodyLarge, |
93 | | - color = colorScheme.onSurfaceVariant, |
94 | | - modifier = Modifier.widthIn(max = 320.dp) |
95 | | - ) |
96 | | - |
97 | | - Spacer(Modifier.height(72.dp)) |
98 | | - |
99 | | - NavigationItem( |
100 | | - selected = firstVisibleItem < paragraphCount + 1, |
101 | | - onClick = { |
102 | | - scope.launch { listState.animateScrollToItem(0) } |
103 | | - }, |
104 | | - label = { Text("About", style = typography.bodyMedium) }, |
105 | | - modifier = Modifier.offset(x = (-20).dp) |
106 | | - ) |
107 | | - NavigationItem( |
108 | | - selected = firstVisibleItem in paragraphCount + 1..<paragraphCount + experienceCount + 2, |
109 | | - onClick = { |
110 | | - scope.launch { listState.animateScrollToItem(paragraphCount + 1) } |
111 | | - }, |
112 | | - label = { Text("Experience", style = typography.bodyMedium) }, |
113 | | - modifier = Modifier.offset(x = (-20).dp) |
114 | | - ) |
115 | | - NavigationItem( |
116 | | - selected = firstVisibleItem >= paragraphCount + experienceCount + 2, |
117 | | - onClick = { |
118 | | - scope.launch { listState.animateScrollToItem(paragraphCount + experienceCount + 2) } |
119 | | - }, |
120 | | - label = { Text("Projects", style = typography.bodyMedium) }, |
121 | | - modifier = Modifier.offset(x = (-20).dp) |
122 | | - ) |
123 | | - |
124 | | - Spacer(Modifier.weight(1f)) |
125 | | - |
126 | | - Spacer(Modifier.padding(top = 32.dp)) |
127 | | - |
128 | | - Row( |
129 | | - horizontalArrangement = Arrangement.spacedBy(4.dp), |
130 | | - verticalAlignment = Alignment.CenterVertically |
131 | | - ) { |
132 | | - IconButton(onClick = { uriHandler.openUri("https://github.com/nsh07") }) { |
133 | | - Icon( |
134 | | - painterResource(Res.drawable.github), |
135 | | - contentDescription = null, |
136 | | - modifier = Modifier.size(24.dp) |
137 | | - ) |
138 | | - } |
139 | | - IconButton(onClick = { uriHandler.openUri("https://gitlab.com/nsh07") }) { |
140 | | - Icon( |
141 | | - painterResource(Res.drawable.gitlab), |
142 | | - contentDescription = null, |
143 | | - modifier = Modifier.size(24.dp) |
144 | | - ) |
145 | | - } |
146 | | - IconButton(onClick = { uriHandler.openUri("https://www.linkedin.com/in/nsh07/") }) { |
147 | | - Icon( |
148 | | - painterResource(Res.drawable.linkedin), |
149 | | - contentDescription = null, |
150 | | - modifier = Modifier.size(24.dp) |
151 | | - ) |
152 | | - } |
153 | | - IconButton(onClick = { uriHandler.openUri( "mailto:[email protected]") }) { |
154 | | - Icon( |
155 | | - painterResource(Res.drawable.email), |
156 | | - contentDescription = null, |
157 | | - modifier = Modifier.size(24.dp) |
158 | | - ) |
159 | | - } |
160 | | - } |
161 | | - } |
162 | | - |
163 | | - LazyColumn( |
164 | | - state = listState, |
165 | | - contentPadding = PaddingValues(vertical = 96.dp), |
166 | | - modifier = Modifier.fillMaxHeight().weight(1.1f) |
167 | | - ) { |
168 | | - items(paragraphs, key = { it.substring(0, 16) }) { |
169 | | - Text( |
170 | | - it, |
171 | | - style = typography.bodyLarge, |
172 | | - color = colorScheme.onSurfaceVariant, |
173 | | - modifier = Modifier.padding(start = cardPadding, bottom = 16.dp, end = cardPadding) |
174 | | - ) |
175 | | - } |
176 | | - item("experience spacer") { Spacer(Modifier.height(112.dp)) } |
177 | | - items(experiences, key = { it.start }) { |
178 | | - ExperienceCard(experience = it, cardPadding = cardPadding, modifier = Modifier.padding(bottom = 32.dp)) |
179 | | - } |
180 | | - item("linkedin link text") { |
181 | | - Row( |
182 | | - verticalAlignment = Alignment.CenterVertically, |
183 | | - modifier = Modifier |
184 | | - .padding(start = cardPadding) |
185 | | - .clickable { uriHandler.openUri("https://www.linkedin.com/in/nsh07/") } |
186 | | - ) { |
187 | | - Text("View LinkedIn Profile ", style = typography.bodyLarge, fontWeight = FontWeight.SemiBold) |
188 | | - Icon(painterResource(Res.drawable.open_in_browser), null, Modifier.size(16.dp)) |
189 | | - } |
190 | | - Spacer(Modifier.height(112.dp)) |
191 | | - } |
192 | | - item("work in progress") { |
193 | | - Column( |
194 | | - horizontalAlignment = Alignment.CenterHorizontally, |
195 | | - verticalArrangement = Arrangement.Center, |
196 | | - modifier = Modifier.fillMaxWidth().padding(vertical = 56.dp) |
197 | | - ) { |
198 | | - Icon( |
199 | | - painterResource(Res.drawable.forklift), |
200 | | - null, |
201 | | - modifier = Modifier.size(64.dp) |
202 | | - ) |
203 | | - Spacer(Modifier.height(16.dp)) |
204 | | - Text("Work in progress", style = typography.headlineSmall) |
205 | | - } |
206 | | - } |
207 | | - item("tech stack spacer") { Spacer(Modifier.height(112.dp)) } |
208 | | - item("tech stack") { |
209 | | - Row( |
210 | | - verticalAlignment = Alignment.CenterVertically, |
211 | | - modifier = Modifier.padding(horizontal = cardPadding) |
212 | | - ) { |
213 | | - Text( |
214 | | - buildAnnotatedString { |
215 | | - append("Built with ") |
216 | | - withLink( |
217 | | - LinkAnnotation.Url( |
218 | | - url = "https://www.jetbrains.com/compose-multiplatform/", |
219 | | - styles = TextLinkStyles(SpanStyle(color = colorScheme.onSurface)) |
220 | | - ) |
221 | | - ) { |
222 | | - append("Compose Multiplatform ") |
223 | | - } |
224 | | - }, |
225 | | - style = typography.bodyMedium, |
226 | | - color = colorScheme.outline |
227 | | - ) |
228 | | - Icon( |
229 | | - painterResource(Res.drawable.compose), |
230 | | - null, |
231 | | - modifier = Modifier.clickable { uriHandler.openUri("https://www.jetbrains.com/compose-multiplatform/") } |
232 | | - ) |
233 | | - Text(" in Kotlin. Deployed with ", style = typography.bodyMedium, color = colorScheme.outline) |
234 | | - Icon( |
235 | | - painterResource(Res.drawable.githubpages), |
236 | | - null, |
237 | | - modifier = Modifier |
238 | | - .height(20.dp) |
239 | | - .clickable { uriHandler.openUri("https://pages.github.com/") } |
240 | | - ) |
241 | | - Text(".", style = typography.bodyMedium, color = colorScheme.outline) |
242 | | - } |
243 | | - Text( |
244 | | - buildAnnotatedString { |
245 | | - append("Text is set in ") |
246 | | - withLink( |
247 | | - LinkAnnotation.Url( |
248 | | - url = "https://fonts.google.com/specimen/DM+Serif+Text", |
249 | | - styles = TextLinkStyles( |
250 | | - SpanStyle( |
251 | | - color = colorScheme.onSurface, |
252 | | - fontFamily = typography.displayLarge.fontFamily |
253 | | - ) |
254 | | - ) |
255 | | - ) |
256 | | - ) { |
257 | | - append("DM Serif Text") |
258 | | - } |
259 | | - append(" and ") |
260 | | - withLink( |
261 | | - LinkAnnotation.Url( |
262 | | - url = "https://rsms.me/inter/", |
263 | | - styles = TextLinkStyles(SpanStyle(color = colorScheme.onSurface)) |
264 | | - ) |
265 | | - ) { |
266 | | - append("Inter") |
267 | | - } |
268 | | - append('.') |
269 | | - }, |
270 | | - color = colorScheme.outline, |
271 | | - style = typography.bodyMedium, |
272 | | - modifier = Modifier.padding(horizontal = cardPadding) |
273 | | - ) |
274 | | - Text( |
275 | | - buildAnnotatedString { |
276 | | - append("Layout inspired by ") |
277 | | - withLink( |
278 | | - LinkAnnotation.Url( |
279 | | - url = "https://brittanychiang.com/", |
280 | | - styles = TextLinkStyles(SpanStyle(color = colorScheme.onSurface)) |
281 | | - ) |
282 | | - ) { |
283 | | - append("Brittany Chiang") |
284 | | - } |
285 | | - append("'s website.") |
286 | | - }, |
287 | | - color = colorScheme.outline, |
288 | | - style = typography.bodyMedium, |
289 | | - modifier = Modifier.padding(horizontal = cardPadding) |
290 | | - ) |
291 | | - } |
292 | | - } |
293 | | - } |
| 10 | +fun AppScreen( |
| 11 | + modifier: Modifier = Modifier |
| 12 | +) { |
| 13 | + AppHomeScreen(modifier) |
294 | 14 | } |
0 commit comments