1+ package io.github.kimmandoo.screen.home
2+
3+ import androidx.compose.foundation.Image
4+ import androidx.compose.foundation.layout.*
5+ import androidx.compose.material3.*
6+ import androidx.compose.runtime.Composable
7+ import androidx.compose.ui.Alignment
8+ import androidx.compose.ui.Modifier
9+ import androidx.compose.ui.layout.ContentScale
10+ import androidx.compose.ui.platform.LocalUriHandler
11+ import androidx.compose.ui.text.AnnotatedString
12+ import androidx.compose.ui.text.SpanStyle
13+ import androidx.compose.ui.text.buildAnnotatedString
14+ import androidx.compose.ui.text.font.FontWeight
15+ import androidx.compose.ui.text.style.TextAlign
16+ import androidx.compose.ui.text.withStyle
17+ import androidx.compose.ui.unit.dp
18+ import androidx.compose.ui.unit.sp
19+ import io.github.kimmandoo.*
20+ import io.github.kimmandoo.component.Loading
21+ import io.github.kimmandoo.model.Section
22+ import io.github.kimmandoo.screen.main.component.GreetingAnimation
23+ import io.github.kimmandoo.ui.adaptive.*
24+ import kimmandoo_porfolio.composeapp.generated.resources.*
25+ import kimmandoo_porfolio.composeapp.generated.resources.Res
26+ import kimmandoo_porfolio.composeapp.generated.resources.blue_chip
27+ import kimmandoo_porfolio.composeapp.generated.resources.ic_android
28+ import kimmandoo_porfolio.composeapp.generated.resources.kimmingyu
29+ import org.jetbrains.compose.resources.painterResource
30+ import org.jetbrains.compose.resources.stringResource
31+
32+ @Composable
33+ fun HomeScreen (
34+ modifier : Modifier = Modifier ,
35+ onSectionClicked : (Section ) -> Unit ,
36+ ) {
37+ val deviceState = rememberDeviceState()
38+ val nicknameString = buildNicknameString(deviceState = deviceState)
39+
40+ when (deviceState.value) {
41+ Device .UNKNOWN -> {
42+ Box (modifier = modifier.fillMaxSize()) {
43+ Loading ()
44+ }
45+ }
46+
47+ Device .DESKTOP ->
48+ HomeDesktopSection (
49+ nicknameString = nicknameString,
50+ modifier = modifier,
51+ onSectionClicked = onSectionClicked,
52+ )
53+
54+ Device .TABLET ->
55+ HomeTabletSection (
56+ nicknameString = nicknameString,
57+ modifier = modifier,
58+ )
59+
60+ Device .MOBILE ->
61+ HomeMobileSection (
62+ nicknameString = nicknameString,
63+ modifier = modifier,
64+ )
65+ }
66+ }
67+
68+ @Composable
69+ private fun buildNicknameString (deviceState : DeviceState ): AnnotatedString =
70+ buildAnnotatedString {
71+ withStyle(
72+ SpanStyle (
73+ fontSize = deviceState.titleFontSize(),
74+ fontWeight = FontWeight .Black ,
75+ ),
76+ ) {
77+ withStyle(SpanStyle (color = MaterialTheme .colorScheme.primary)) {
78+ append(stringResource(Res .string.blue_chip))
79+ }
80+
81+ withStyle(SpanStyle (color = MaterialTheme .colorScheme.onPrimaryContainer)) {
82+ append(stringResource(Res .string.kimmingyu))
83+ }
84+ }
85+ }
86+
87+ @Composable
88+ private fun HomeMobileSection (
89+ nicknameString : AnnotatedString ,
90+ modifier : Modifier = Modifier ,
91+ ) {
92+ val screenSize = LocalScreenSize .current.asDp()
93+
94+ Box (
95+ modifier =
96+ modifier
97+ .fillMaxSize()
98+ .padding(
99+ vertical = MOBILE_CONTENT_VERTICAL_PADDING .dp,
100+ horizontal = MOBILE_CONTENT_HORIZONTAL_PADDING .dp,
101+ ),
102+ ) {
103+ Column (
104+ modifier = Modifier .fillMaxSize(),
105+ horizontalAlignment = Alignment .CenterHorizontally ,
106+ verticalArrangement = Arrangement .Center ,
107+ ) {
108+ Row (modifier = Modifier .height(maxOf(MOBILE_CONTENT_MIN_HEIGHT , screenSize.height).dp / 3f ,),
109+ horizontalArrangement = Arrangement .Center ,
110+ verticalAlignment = Alignment .CenterVertically
111+ ) {
112+ GreetingAnimation ()
113+ Spacer (modifier = Modifier .size(16 .dp))
114+ Box (modifier = Modifier .size(80 .dp)){
115+ Image (
116+ modifier = Modifier .fillMaxHeight(),
117+ painter = painterResource(
118+ resource = Res .drawable.ic_android,
119+ ),
120+ contentDescription = " 버그로이드"
121+ )
122+ }
123+ }
124+
125+ Text (
126+ text = nicknameString,
127+ lineHeight = 76 .sp,
128+ textAlign = TextAlign .Center ,
129+ )
130+
131+ Spacer (modifier = Modifier .height(12 .dp))
132+ Text (
133+ text = stringResource(Res .string.intro),
134+ color = MaterialTheme .colorScheme.onPrimaryContainer.copy(alpha = 0.5f ),
135+ fontSize = 16 .sp,
136+ lineHeight = 24 .sp,
137+ textAlign = TextAlign .Center ,
138+ )
139+
140+ Spacer (modifier = Modifier .height(36 .dp))
141+
142+ Column (
143+ modifier =
144+ Modifier .padding(
145+ horizontal = MOBILE_CONTENT_HORIZONTAL_PADDING .dp,
146+ ),
147+ verticalArrangement = Arrangement .spacedBy(8 .dp),
148+ ) {
149+ GithubButton (modifier = Modifier .fillMaxWidth())
150+ BlogButton (modifier = Modifier .fillMaxWidth())
151+ }
152+ }
153+ }
154+ }
155+
156+ @Composable
157+ private fun HomeTabletSection (
158+ nicknameString : AnnotatedString ,
159+ modifier : Modifier = Modifier ,
160+ ) {
161+ val screenSize = LocalScreenSize .current.asDp()
162+
163+ Box (
164+ modifier =
165+ modifier
166+ .fillMaxSize()
167+ .padding(
168+ vertical = MOBILE_CONTENT_VERTICAL_PADDING .dp,
169+ horizontal = MOBILE_CONTENT_HORIZONTAL_PADDING .dp,
170+ ),
171+ ) {
172+ Column (
173+ modifier = Modifier .fillMaxSize(),
174+ horizontalAlignment = Alignment .CenterHorizontally ,
175+ verticalArrangement = Arrangement .Center ,
176+ ) {
177+ Row (modifier = Modifier .height(maxOf(MOBILE_CONTENT_MIN_HEIGHT , screenSize.height).dp / 3f ,),
178+ horizontalArrangement = Arrangement .Center ,
179+ verticalAlignment = Alignment .CenterVertically
180+ ) {
181+ GreetingAnimation ()
182+ Spacer (modifier = Modifier .size(16 .dp))
183+ Box (modifier = Modifier .size(80 .dp)){
184+ Image (
185+ modifier = Modifier .fillMaxHeight(),
186+ painter = painterResource(
187+ resource = Res .drawable.ic_android,
188+ ),
189+ contentDescription = " 버그로이드"
190+ )
191+ }
192+ }
193+
194+ Text (
195+ text = nicknameString,
196+ lineHeight = 76 .sp,
197+ textAlign = TextAlign .Center ,
198+ )
199+
200+ Spacer (modifier = Modifier .height(12 .dp))
201+ Text (
202+ text = stringResource(Res .string.intro),
203+ color = MaterialTheme .colorScheme.onPrimaryContainer.copy(alpha = 0.5f ),
204+ fontSize = 16 .sp,
205+ lineHeight = 24 .sp,
206+ textAlign = TextAlign .Center ,
207+ )
208+
209+ Spacer (modifier = Modifier .height(36 .dp))
210+
211+ Row (
212+ verticalAlignment = Alignment .CenterVertically ,
213+ horizontalArrangement = Arrangement .spacedBy(8 .dp),
214+ ) {
215+ GithubButton ()
216+ BlogButton ()
217+ }
218+ }
219+ }
220+ }
221+
222+ @Composable
223+ private fun HomeDesktopSection (
224+ nicknameString : AnnotatedString ,
225+ modifier : Modifier = Modifier ,
226+ onSectionClicked : (Section ) -> Unit ,
227+ ) {
228+ val screenSize = LocalScreenSize .current.asDp()
229+
230+ Box (
231+ modifier =
232+ modifier.then(
233+ Modifier
234+ .width(screenSize.width.dp)
235+ .height((maxOf(TABLET_CONTENT_MIN_HEIGHT , screenSize.height) - HEADER_HEIGHT ).dp)
236+ .padding(horizontal = 120 .dp),
237+ ),
238+ ) {
239+ Row (modifier = Modifier
240+ .width(DESKTOP_CONTENT_WIDTH .dp / 2 )
241+ .align(Alignment .CenterStart ),
242+ horizontalArrangement = Arrangement .End ,
243+ verticalAlignment = Alignment .CenterVertically
244+ ) {
245+ GreetingAnimation ()
246+ Spacer (modifier = Modifier .size(16 .dp))
247+ Box (modifier = Modifier .size(200 .dp)){
248+ Image (
249+ modifier = Modifier .fillMaxHeight(),
250+ painter = painterResource(
251+ resource = Res .drawable.ic_android,
252+ ),
253+ contentDescription = " 버그로이드"
254+ )
255+ }
256+ }
257+
258+ Column (
259+ modifier =
260+ Modifier
261+ .width((DESKTOP_CONTENT_WIDTH .dp / 1.5f ))
262+ .align(Alignment .CenterEnd ),
263+ horizontalAlignment = Alignment .Start ,
264+ verticalArrangement = Arrangement .Center ,
265+ ) {
266+ Text (text = nicknameString, lineHeight = 92 .sp)
267+
268+ Spacer (modifier = Modifier .height(12 .dp))
269+
270+ Text (
271+ text = stringResource(Res .string.intro),
272+ color = MaterialTheme .colorScheme.onPrimaryContainer.copy(alpha = 0.5f ),
273+ fontSize = 16 .sp,
274+ lineHeight = 24 .sp,
275+ textAlign = TextAlign .Start ,
276+ )
277+
278+ Spacer (modifier = Modifier .height(36 .dp))
279+
280+ Row (
281+ verticalAlignment = Alignment .CenterVertically ,
282+ horizontalArrangement = Arrangement .spacedBy(8 .dp),
283+ ) {
284+ GithubButton ()
285+ BlogButton ()
286+ }
287+ }
288+ }
289+ }
290+
291+ @Composable
292+ private fun GithubButton (modifier : Modifier = Modifier ) {
293+ val uriHandler = LocalUriHandler .current
294+ val githubUri = " https://github.com/kimmandoo"
295+
296+ Button (
297+ onClick = { uriHandler.openUri(githubUri) },
298+ modifier = modifier.then(Modifier .height(56 .dp)),
299+ contentPadding = PaddingValues (vertical = 12 .dp, horizontal = 24 .dp),
300+ ) {
301+ Icon (
302+ painterResource(Res .drawable.ic_github),
303+ contentDescription = null ,
304+ modifier = Modifier .size(24 .dp),
305+ )
306+ Spacer (Modifier .width(8 .dp))
307+ Text (
308+ text = stringResource(Res .string.follow_github),
309+ fontWeight = FontWeight .SemiBold ,
310+ fontSize = 16 .sp,
311+ )
312+ }
313+ }
314+
315+ @Composable
316+ private fun BlogButton (modifier : Modifier = Modifier ) {
317+ val uriHandler = LocalUriHandler .current
318+ val blogUri = " https://kimmandoo.medium.com"
319+
320+ OutlinedButton (
321+ onClick = { uriHandler.openUri(blogUri) },
322+ modifier = modifier.then(Modifier .height(56 .dp)),
323+ colors =
324+ ButtonDefaults .outlinedButtonColors(
325+ containerColor = MaterialTheme .colorScheme.primaryContainer,
326+ contentColor = MaterialTheme .colorScheme.onPrimaryContainer,
327+ ),
328+ contentPadding = PaddingValues (vertical = 12 .dp, horizontal = 24 .dp),
329+ ) {
330+ Icon (
331+ painter = painterResource(Res .drawable.ic_open_in_new),
332+ contentDescription = null ,
333+ modifier = Modifier .size(24 .dp),
334+ )
335+ Spacer (Modifier .width(8 .dp))
336+ Text (
337+ text = stringResource(Res .string.visit_blog),
338+ fontWeight = FontWeight .SemiBold ,
339+ fontSize = 16 .sp,
340+ )
341+ }
342+ }
0 commit comments