-
Notifications
You must be signed in to change notification settings - Fork 1
[Koin Project][refactor] 설정 화면 composing UI 부분 #1044
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
Changes from all commits
e0660d2
99ea7db
7626532
690a8dc
0021122
cf1959b
35190d8
436eb25
50e5a38
a542a82
457ef3d
b447ca7
0e5e516
6fe7a81
bd1d097
71f2bfd
e43fb19
dca7df5
a65ef69
9e3c697
ceedfec
4ca18d9
9333a25
7a9ac83
74e3164
c5ba672
96f1728
2c93626
35cc6d0
265d576
c040fe8
ab4e617
044b8cc
05fb0a3
dd4d1ab
77463c7
655d5c3
6ff26aa
93a12fb
c40e7e0
557d908
38b8af7
a03a38a
6cb39f1
810e445
c18cfc0
f7add57
b1e49eb
ae7541b
e4a8959
f501bb0
54533ab
f96d581
a097ecb
75071b2
73323aa
869382c
b7f0821
2f68241
df8bd10
4dabc23
045bd17
8f04f16
1230a0a
a18eb2f
ef3f95c
9abc59a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| package `in`.koreatech.koin.core.util | ||
|
|
||
| import android.content.Context | ||
| import android.content.Intent | ||
| import androidx.core.net.toUri | ||
|
|
||
| fun Context.goToContactUrl() = startActivity(Intent(Intent.ACTION_VIEW, KOIN_ASK_FORM.toUri())) | ||
|
|
||
| const val KOIN_ASK_FORM = "https://forms.gle/Yo1WNR5mLQdi1pMh6" |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| /build |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,26 @@ | ||
| plugins { | ||
| alias(libs.plugins.koin.feature) | ||
| alias(libs.plugins.koin.hilt) | ||
| alias(libs.plugins.kotlin.android) | ||
| } | ||
|
|
||
| android { | ||
| namespace = "in.koreatech.koin.feature.setting" | ||
| } | ||
|
|
||
| dependencies { | ||
|
|
||
| implementation(projects.core) | ||
| implementation(projects.domain) | ||
| implementation(projects.core.designsystem) | ||
| implementation(projects.core.navigation) | ||
|
|
||
| implementation(libs.androidx.core.ktx) | ||
| implementation(libs.androidx.appcompat) | ||
| implementation(libs.material) | ||
|
|
||
| implementation(libs.kotlinx.collections.immutable) | ||
|
|
||
| implementation(libs.timber) | ||
| implementation(libs.play.services.oss.licenses) | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| # Add project specific ProGuard rules here. | ||
| # You can control the set of applied configuration files using the | ||
| # proguardFiles setting in build.gradle. | ||
| # | ||
| # For more details, see | ||
| # http://developer.android.com/guide/developing/tools/proguard.html | ||
|
|
||
| # If your project uses WebView with JS, uncomment the following | ||
| # and specify the fully qualified class name to the JavaScript interface | ||
| # class: | ||
| #-keepclassmembers class fqcn.of.javascript.interface.for.webview { | ||
| # public *; | ||
| #} | ||
|
|
||
| # Uncomment this to preserve the line number information for | ||
| # debugging stack traces. | ||
| #-keepattributes SourceFile,LineNumberTable | ||
|
|
||
| # If you keep the line number information, uncomment this to | ||
| # hide the original source file name. | ||
| #-renamesourcefileattribute SourceFile |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| <?xml version="1.0" encoding="utf-8"?> | ||
| <manifest xmlns:android="http://schemas.android.com/apk/res/android"> | ||
| <application> | ||
| <activity | ||
| android:name=".ui.SettingActivity" | ||
| android:exported="false"> | ||
| </activity> | ||
| </application> | ||
| </manifest> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,61 @@ | ||
| package `in`.koreatech.koin.feature.setting.component | ||
|
|
||
| import androidx.compose.foundation.background | ||
| import androidx.compose.foundation.clickable | ||
| import androidx.compose.foundation.layout.Arrangement | ||
| import androidx.compose.foundation.layout.Row | ||
| import androidx.compose.foundation.layout.fillMaxWidth | ||
| import androidx.compose.foundation.layout.padding | ||
| import androidx.compose.foundation.text.BasicText | ||
| import androidx.compose.material3.HorizontalDivider | ||
| import androidx.compose.material3.Icon | ||
| import androidx.compose.runtime.Composable | ||
| import androidx.compose.ui.Alignment | ||
| import androidx.compose.ui.Modifier | ||
| import androidx.compose.ui.graphics.Color | ||
| import androidx.compose.ui.res.painterResource | ||
| import androidx.compose.ui.text.TextStyle | ||
| import androidx.compose.ui.tooling.preview.Preview | ||
| import androidx.compose.ui.unit.dp | ||
| import `in`.koreatech.koin.core.designsystem.theme.KoinTheme | ||
| import `in`.koreatech.koin.feature.setting.R | ||
|
|
||
| @Composable | ||
| fun SettingItem( | ||
| text: String, | ||
| modifier: Modifier = Modifier, | ||
| showIcon: Boolean = false, | ||
| textStyle: TextStyle = KoinTheme.typography.regular16, | ||
| backgroundColor: Color = KoinTheme.colors.neutral0, | ||
| onClick: () -> Unit = {} | ||
| ) { | ||
| Row( | ||
| modifier = modifier | ||
| .fillMaxWidth() | ||
| .background(color = backgroundColor) | ||
| .clickable(onClick = onClick) | ||
| .padding(vertical = 13.dp, horizontal = 24.dp), | ||
| horizontalArrangement = Arrangement.SpaceBetween, | ||
| verticalAlignment = Alignment.CenterVertically | ||
| ) { | ||
| BasicText( | ||
| text = text, | ||
| style = textStyle | ||
| ) | ||
| if (showIcon) { | ||
| Icon( | ||
| painter = painterResource(R.drawable.ic_arrow_right), | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ImageVector 사용해주세요
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. https://developer.android.com/develop/ui/compose/graphics/images/compare?hl=ko |
||
| contentDescription = "" | ||
| ) | ||
| } | ||
| } | ||
| HorizontalDivider(color = KoinTheme.colors.neutral100) | ||
| } | ||
|
|
||
| @Preview(showBackground = true) | ||
| @Composable | ||
| private fun SettingItemPreview() { | ||
| SettingItem( | ||
| text = "프로필" | ||
| ) | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,38 @@ | ||
| package `in`.koreatech.koin.feature.setting.component | ||
|
|
||
| import androidx.compose.foundation.background | ||
| import androidx.compose.foundation.layout.fillMaxWidth | ||
| import androidx.compose.foundation.layout.padding | ||
| import androidx.compose.foundation.text.BasicText | ||
| import androidx.compose.runtime.Composable | ||
| import androidx.compose.ui.Modifier | ||
| import androidx.compose.ui.graphics.Color | ||
| import androidx.compose.ui.text.TextStyle | ||
| import androidx.compose.ui.tooling.preview.Preview | ||
| import androidx.compose.ui.unit.dp | ||
| import `in`.koreatech.koin.core.designsystem.theme.KoinTheme | ||
|
|
||
| @Composable | ||
| fun SettingTitle( | ||
| text: String, | ||
| modifier: Modifier = Modifier, | ||
| textStyle: TextStyle = KoinTheme.typography.medium14, | ||
kongwoojin marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| backgroundColor: Color = KoinTheme.colors.neutral50 | ||
| ) { | ||
| BasicText( | ||
| modifier = modifier | ||
| .fillMaxWidth() | ||
| .background(color = backgroundColor) | ||
| .padding(vertical = 8.dp, horizontal = 24.dp), | ||
| text = text, | ||
| style = textStyle | ||
| ) | ||
| } | ||
|
|
||
| @Preview(showBackground = true) | ||
| @Composable | ||
| private fun SettingTitlePreview() { | ||
| SettingTitle( | ||
| text = "일반" | ||
| ) | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,102 @@ | ||
| package `in`.koreatech.koin.feature.setting.component | ||
|
|
||
| import androidx.compose.foundation.background | ||
| import androidx.compose.foundation.layout.Arrangement | ||
| import androidx.compose.foundation.layout.Column | ||
| import androidx.compose.foundation.layout.Row | ||
| import androidx.compose.foundation.layout.fillMaxWidth | ||
| import androidx.compose.foundation.layout.padding | ||
| import androidx.compose.foundation.text.BasicText | ||
| import androidx.compose.material3.HorizontalDivider | ||
| import androidx.compose.runtime.Composable | ||
| import androidx.compose.ui.Alignment | ||
| import androidx.compose.ui.Modifier | ||
| import androidx.compose.ui.graphics.Color | ||
| import androidx.compose.ui.res.stringResource | ||
| import androidx.compose.ui.text.TextStyle | ||
| import androidx.compose.ui.tooling.preview.Preview | ||
| import androidx.compose.ui.unit.dp | ||
| import `in`.koreatech.koin.core.designsystem.theme.KoinTheme | ||
| import `in`.koreatech.koin.feature.setting.R | ||
|
|
||
| @Composable | ||
| fun SettingVersionItem( | ||
| currentVersion: String, | ||
| latestVersion: String, | ||
| showVersionInfo: Boolean, | ||
| modifier: Modifier = Modifier, | ||
| textStyle: TextStyle = KoinTheme.typography.regular16, | ||
| backgroundColor: Color = KoinTheme.colors.neutral0 | ||
| ) { | ||
| Row( | ||
| modifier = modifier | ||
| .fillMaxWidth() | ||
| .background(color = backgroundColor) | ||
| .padding( | ||
| vertical = if (showVersionInfo) 5.dp else 13.dp, | ||
| horizontal = 24.dp | ||
| ), | ||
| horizontalArrangement = Arrangement.SpaceBetween, | ||
| verticalAlignment = Alignment.CenterVertically | ||
| ) { | ||
| BasicText( | ||
| text = stringResource(R.string.setting_item_app_version), | ||
| style = textStyle | ||
| ) | ||
| if (showVersionInfo) { | ||
| Column( | ||
| horizontalAlignment = Alignment.End | ||
| ) { | ||
| BasicText( | ||
| text = currentVersion, | ||
| style = KoinTheme.typography.regular14 | ||
| ) | ||
| BasicText( | ||
| text = if (currentVersion == latestVersion) { | ||
| stringResource(R.string.setting_item_newest_version_info) | ||
| } else { | ||
| stringResource(R.string.setting_item_not_newest_version_info, latestVersion) | ||
| }, | ||
| style = KoinTheme.typography.regular12.copy( | ||
| color = if (currentVersion == latestVersion) { | ||
| KoinTheme.colors.neutral500 | ||
| } else { | ||
| KoinTheme.colors.primary500 | ||
| } | ||
| ) | ||
| ) | ||
| } | ||
| } | ||
| } | ||
| HorizontalDivider(color = KoinTheme.colors.neutral100) | ||
| } | ||
|
|
||
| @Preview(showBackground = true) | ||
| @Composable | ||
| private fun SettingVersionItemPreviewVersion() { | ||
| SettingVersionItem( | ||
| currentVersion = "4.2.3", | ||
| latestVersion = "4.2.4", | ||
| showVersionInfo = true | ||
| ) | ||
| } | ||
|
|
||
| @Preview(showBackground = true) | ||
| @Composable | ||
| private fun SettingVersionItemPreviewLatest() { | ||
| SettingVersionItem( | ||
| currentVersion = "4.2.2", | ||
| latestVersion = "4.2.2", | ||
| showVersionInfo = true | ||
| ) | ||
| } | ||
|
|
||
| @Preview(showBackground = true) | ||
| @Composable | ||
| private fun SettingVersionItemPreviewNotShow() { | ||
| SettingVersionItem( | ||
| currentVersion = "4.2.2", | ||
| latestVersion = "4.2.2", | ||
| showVersionInfo = false | ||
| ) | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,116 @@ | ||
| package `in`.koreatech.koin.feature.setting.component.switch | ||
|
|
||
| import androidx.compose.animation.core.Animatable | ||
| import androidx.compose.animation.core.tween | ||
| import androidx.compose.foundation.Canvas | ||
| import androidx.compose.foundation.background | ||
| import androidx.compose.foundation.clickable | ||
| import androidx.compose.foundation.interaction.MutableInteractionSource | ||
| import androidx.compose.foundation.layout.Box | ||
| import androidx.compose.foundation.layout.aspectRatio | ||
| import androidx.compose.foundation.layout.height | ||
| import androidx.compose.foundation.shape.CircleShape | ||
| import androidx.compose.runtime.Composable | ||
| import androidx.compose.runtime.LaunchedEffect | ||
| 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.geometry.CornerRadius | ||
| import androidx.compose.ui.geometry.Offset | ||
| import androidx.compose.ui.graphics.Color | ||
| import androidx.compose.ui.tooling.preview.Preview | ||
| import androidx.compose.ui.unit.dp | ||
| import `in`.koreatech.koin.core.designsystem.theme.KoinTheme | ||
|
|
||
| @Composable | ||
| fun KoinSwitch( | ||
| checked: Boolean, | ||
| onCheckedChange: (Boolean) -> Unit, | ||
| modifier: Modifier = Modifier, | ||
| switchColors: KoinSwitchColors = KoinSwitchDefaults.koinSwitchColors() | ||
| ) { | ||
| var isChecked by remember(checked) { mutableStateOf(checked) } | ||
| val thumbOffset = remember { Animatable(if (isChecked) 1f else 0f) } | ||
|
|
||
| LaunchedEffect(isChecked) { | ||
| thumbOffset.animateTo(if (isChecked) 1f else 0f, animationSpec = tween(durationMillis = 300)) | ||
| } | ||
|
|
||
| Box( | ||
| modifier = modifier | ||
| .height(24.dp) | ||
| .aspectRatio(2.1f) | ||
| .background(Color.Gray, CircleShape) | ||
| .clickable( | ||
| interactionSource = remember { MutableInteractionSource() }, | ||
| indication = null | ||
| ) { | ||
| isChecked = !isChecked | ||
| onCheckedChange(isChecked) | ||
| } | ||
| ) { | ||
| Canvas(modifier = Modifier.matchParentSize()) { | ||
| val trackWidth = size.width | ||
| val trackHeight = size.height | ||
| val thumbMargin = size.height / 8 | ||
| val thumbRadius = trackHeight / 2 - thumbMargin | ||
|
|
||
| // Draw track | ||
| drawRoundRect( | ||
| color = if (isChecked) switchColors.selectedContainerColor else switchColors.unselectedContainerColor, | ||
| size = size, | ||
| cornerRadius = CornerRadius(trackHeight / 2, trackHeight / 2) | ||
| ) | ||
|
|
||
| // Draw thumb | ||
| val thumbX = (thumbOffset.value * (trackWidth - (thumbRadius + thumbMargin) * 2)) + (thumbRadius + thumbMargin) | ||
| drawCircle( | ||
| color = if (isChecked) switchColors.selectedContentColor else switchColors.unselectedContentColor, | ||
| radius = thumbRadius, | ||
| center = Offset(thumbX, trackHeight / 2) | ||
| ) | ||
| } | ||
| } | ||
| } | ||
|
|
||
| object KoinSwitchDefaults { | ||
| @Composable | ||
| fun koinSwitchColors( | ||
| selectedContainerColor: Color = KoinTheme.colors.primary500, | ||
| selectedContentColor: Color = Color.White, | ||
| unselectedContainerColor: Color = KoinTheme.colors.neutral300, | ||
| unselectedContentColor: Color = KoinTheme.colors.neutral0 | ||
| ) = KoinSwitchColors( | ||
| selectedContainerColor = selectedContainerColor, | ||
| selectedContentColor = selectedContentColor, | ||
| unselectedContainerColor = unselectedContainerColor, | ||
| unselectedContentColor = unselectedContentColor | ||
| ) | ||
| } | ||
|
|
||
| class KoinSwitchColors internal constructor( | ||
| val selectedContainerColor: Color, | ||
| val selectedContentColor: Color, | ||
| val unselectedContainerColor: Color, | ||
| val unselectedContentColor: Color | ||
| ) | ||
|
|
||
| @Preview | ||
| @Composable | ||
| private fun KoinSwitchCheckedPreview() { | ||
| KoinSwitch( | ||
| checked = true, | ||
| onCheckedChange = {} | ||
| ) | ||
| } | ||
|
|
||
| @Preview | ||
| @Composable | ||
| private fun KoinSwitchUnCheckedPreview() { | ||
| KoinSwitch( | ||
| checked = false, | ||
| onCheckedChange = {} | ||
| ) | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| package `in`.koreatech.koin.feature.setting.constant | ||
|
|
||
| val ARTICLE_KEYWORD_URL = "koin://article/activity?fragment=article_keyword" |
Uh oh!
There was an error while loading. Please reload this page.