diff --git a/.claude/settings.local.json b/.claude/settings.local.json new file mode 100644 index 00000000..09608855 --- /dev/null +++ b/.claude/settings.local.json @@ -0,0 +1,9 @@ +{ + "permissions": { + "allow": [ + "Bash(git add:*)", + "Bash(git rebase:*)", + "Bash(git fetch:*)" + ] + } +} diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 00000000..46889840 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,14 @@ +root = true + +[*] +charset = utf-8 +indent_size = 4 +indent_style = space +max_line_length = 150 +insert_final_newline = true +trim_trailing_whitespace = true + +[*.{kt,kts}] +ij_kotlin_allow_trailing_comma = true +ij_kotlin_allow_trailing_comma_on_call_site = true +ktlint_function_naming_ignore_when_annotated_with = Composable \ No newline at end of file diff --git a/.github/workflows/android_ci.yml b/.github/workflows/android_ci.yml new file mode 100644 index 00000000..bb59fb2d --- /dev/null +++ b/.github/workflows/android_ci.yml @@ -0,0 +1,37 @@ +name: Android CI + +on: + push: + branches: [ "develop" ] + pull_request: + branches: [ "develop" ] + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + + - name: Setup Gradle + uses: gradle/actions/setup-gradle@v4 + with: + gradle-home-cache-cleanup: true + + - name: Set up JDK 21 + uses: actions/setup-java@v4 + with: + java-version: '21' + distribution: 'temurin' + + - name: Grant execute permission for gradlew + run: chmod +x gradlew + + - name: Set up local.properties + run: echo "${{ secrets.LOCAL_PROPERTIES }}" > local.properties + + - name: Code style checks + run: ./gradlew ktlintCheck detekt + + - name: Run build + run: ./gradlew assembleDebug --stacktrace diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 12dc3df8..90ab0433 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -4,6 +4,12 @@ plugins { android { namespace = Configuration.APPLICATION_ID + + buildTypes { + release { + isMinifyEnabled = true + } + } } dependencies { diff --git a/app/src/main/java/com/yapp/ndgl/MainActivity.kt b/app/src/main/java/com/yapp/ndgl/MainActivity.kt index 1db40f36..f97fffde 100644 --- a/app/src/main/java/com/yapp/ndgl/MainActivity.kt +++ b/app/src/main/java/com/yapp/ndgl/MainActivity.kt @@ -20,4 +20,3 @@ class MainActivity : ComponentActivity() { } } } - diff --git a/app/src/main/java/com/yapp/ndgl/navigation/BottomNavTab.kt b/app/src/main/java/com/yapp/ndgl/navigation/BottomNavTab.kt index 99181c0a..35f6b634 100644 --- a/app/src/main/java/com/yapp/ndgl/navigation/BottomNavTab.kt +++ b/app/src/main/java/com/yapp/ndgl/navigation/BottomNavTab.kt @@ -1,7 +1,6 @@ package com.yapp.ndgl.navigation import androidx.annotation.DrawableRes -import com.yapp.ndgl.navigation.Route import com.yapp.ndgl.core.ui.R enum class BottomNavTab( @@ -24,5 +23,4 @@ enum class BottomNavTab( label = "여행", route = Route.Travel, ), - ; } diff --git a/app/src/main/java/com/yapp/ndgl/ui/BottomNavigationBar.kt b/app/src/main/java/com/yapp/ndgl/ui/BottomNavigationBar.kt index a8dde05e..7219ffac 100644 --- a/app/src/main/java/com/yapp/ndgl/ui/BottomNavigationBar.kt +++ b/app/src/main/java/com/yapp/ndgl/ui/BottomNavigationBar.kt @@ -12,8 +12,8 @@ import com.yapp.ndgl.navigation.Route @Composable internal fun BottomNavigationBar( - currentTab : Route, - onTabSelected : (Route) -> Unit, + currentTab: Route, + onTabSelected: (Route) -> Unit, ) { // FIXME 네비게이션 바 디자인 수정 및 추상화 NavigationBar { @@ -24,10 +24,10 @@ internal fun BottomNavigationBar( icon = { Icon( imageVector = ImageVector.vectorResource(id = topLevelRoute.icon), - contentDescription = topLevelRoute.label + contentDescription = topLevelRoute.label, ) }, - label = { Text(text = topLevelRoute.label) } + label = { Text(text = topLevelRoute.label) }, ) } } diff --git a/app/src/main/java/com/yapp/ndgl/ui/NDGLApp.kt b/app/src/main/java/com/yapp/ndgl/ui/NDGLApp.kt index 161617cb..be247498 100644 --- a/app/src/main/java/com/yapp/ndgl/ui/NDGLApp.kt +++ b/app/src/main/java/com/yapp/ndgl/ui/NDGLApp.kt @@ -9,19 +9,20 @@ import androidx.compose.runtime.remember import androidx.compose.ui.Modifier import androidx.navigation3.runtime.entryProvider import androidx.navigation3.ui.NavDisplay -import com.yapp.ndgl.feature.travelhelper.navigation.travelHelperEntry import com.yapp.ndgl.feature.home.navigation.homeEntry +import com.yapp.ndgl.feature.travel.navigation.travelEntry +import com.yapp.ndgl.feature.travelhelper.navigation.travelHelperEntry import com.yapp.ndgl.navigation.BottomNavTab import com.yapp.ndgl.navigation.Navigator import com.yapp.ndgl.navigation.Route import com.yapp.ndgl.navigation.rememberNavigationState import com.yapp.ndgl.navigation.toEntries -import com.yapp.ndgl.feature.travel.navigation.travelEntry @Composable fun NDGLApp() { val navigationState = rememberNavigationState( - startRoute = Route.Home, topLevelKeys = BottomNavTab.entries.map { it.route }.toSet(), + startRoute = Route.Home, + topLevelKeys = BottomNavTab.entries.map { it.route }.toSet(), ) val navigator = remember { Navigator(navigationState) } @@ -31,7 +32,8 @@ fun NDGLApp() { travelHelperEntry(navigator) } - val shouldShowBottomBar = remember(navigationState.currentKey) { navigationState.currentKey in navigationState.topLevelKeys } + val shouldShowBottomBar = + remember(navigationState.currentKey) { navigationState.currentKey in navigationState.topLevelKeys } Scaffold( modifier = Modifier.fillMaxSize(), @@ -55,4 +57,3 @@ fun NDGLApp() { ) } } - diff --git a/build-logic/src/main/kotlin/NDGLAndroidLibraryPlugin.kt b/build-logic/src/main/kotlin/NDGLAndroidLibraryPlugin.kt index cf348d87..6b5d82f5 100644 --- a/build-logic/src/main/kotlin/NDGLAndroidLibraryPlugin.kt +++ b/build-logic/src/main/kotlin/NDGLAndroidLibraryPlugin.kt @@ -1,6 +1,6 @@ import convention.configureComposeAndroid import convention.configureFirebase -import extensions.configureAndroidLibrary +import convention.configureKotlinAndroid import org.gradle.api.Plugin import org.gradle.api.Project import org.gradle.kotlin.dsl.dependencies @@ -13,7 +13,7 @@ class NDGLAndroidLibraryPlugin : Plugin { apply("org.jetbrains.kotlin.android") } - configureAndroidLibrary() + configureKotlinAndroid() configureFirebase() configureComposeAndroid() diff --git a/build-logic/src/main/kotlin/NDGLApplicationPlugin.kt b/build-logic/src/main/kotlin/NDGLApplicationPlugin.kt index 3552d83a..cb818833 100644 --- a/build-logic/src/main/kotlin/NDGLApplicationPlugin.kt +++ b/build-logic/src/main/kotlin/NDGLApplicationPlugin.kt @@ -2,7 +2,6 @@ import convention.configureComposeAndroid import convention.configureHiltAndroid import convention.configureKotlinAndroid import convention.configureTimber -import extensions.configureAndroidApplication import org.gradle.api.Plugin import org.gradle.api.Project @@ -13,7 +12,6 @@ class NDGLApplicationPlugin : Plugin { } configureKotlinAndroid() - configureAndroidApplication() configureHiltAndroid() configureTimber() configureComposeAndroid() diff --git a/build-logic/src/main/kotlin/NDGLDataPlugin.kt b/build-logic/src/main/kotlin/NDGLDataPlugin.kt index cd607287..71affa75 100644 --- a/build-logic/src/main/kotlin/NDGLDataPlugin.kt +++ b/build-logic/src/main/kotlin/NDGLDataPlugin.kt @@ -1,7 +1,6 @@ import convention.configureCoroutineAndroid import convention.configureHiltAndroid import convention.configureKotlinAndroid -import extensions.configureAndroidLibrary import org.gradle.api.Plugin import org.gradle.api.Project @@ -12,7 +11,6 @@ class NDGLDataPlugin : Plugin { } configureKotlinAndroid() - configureAndroidLibrary() configureHiltAndroid() configureCoroutineAndroid() } diff --git a/build-logic/src/main/kotlin/NDGLFeaturePlugin.kt b/build-logic/src/main/kotlin/NDGLFeaturePlugin.kt index ab4107ce..da84f274 100644 --- a/build-logic/src/main/kotlin/NDGLFeaturePlugin.kt +++ b/build-logic/src/main/kotlin/NDGLFeaturePlugin.kt @@ -2,7 +2,6 @@ import convention.configureComposeAndroid import convention.configureCoroutineAndroid import convention.configureFirebase import convention.configureHiltAndroid -import extensions.configureAndroidLibrary import org.gradle.api.Plugin import org.gradle.api.Project import org.gradle.kotlin.dsl.dependencies @@ -11,14 +10,10 @@ import util.libs class NDGLFeaturePlugin : Plugin { override fun apply(target: Project): Unit = with(target) { with(pluginManager) { - apply("com.android.library") - apply("org.jetbrains.kotlin.android") + apply("ndgl.android.library") } - configureAndroidLibrary() configureHiltAndroid() - configureFirebase() - configureComposeAndroid() configureCoroutineAndroid() dependencies { diff --git a/build-logic/src/main/kotlin/NDGLKotlinLibraryPlugin.kt b/build-logic/src/main/kotlin/NDGLKotlinLibraryPlugin.kt index e542b7fc..b48db923 100644 --- a/build-logic/src/main/kotlin/NDGLKotlinLibraryPlugin.kt +++ b/build-logic/src/main/kotlin/NDGLKotlinLibraryPlugin.kt @@ -1,13 +1,35 @@ - -import extensions.configureKotlinJvm import org.gradle.api.Plugin import org.gradle.api.Project +import org.gradle.api.plugins.JavaPluginExtension +import org.gradle.kotlin.dsl.configure +import org.gradle.kotlin.dsl.dependencies +import org.jetbrains.kotlin.gradle.dsl.JvmTarget +import org.jetbrains.kotlin.gradle.dsl.KotlinJvmProjectExtension +import util.libs class NDGLKotlinLibraryPlugin : Plugin { override fun apply(target: Project): Unit = with(target) { with(pluginManager) { apply("org.jetbrains.kotlin.jvm") } + configureKotlinJvm() + + dependencies { + "detektPlugins"(libs.findLibrary("detekt.formatting").get()) + } + } +} + +internal fun Project.configureKotlinJvm() { + extensions.configure { + sourceCompatibility = Configuration.JAVA_VERSION + targetCompatibility = Configuration.JAVA_VERSION + } + + extensions.configure { + compilerOptions { + jvmTarget.set(JvmTarget.fromTarget(Configuration.JVM_TARGET)) + } } } diff --git a/build-logic/src/main/kotlin/convention/KotlinAndroid.kt b/build-logic/src/main/kotlin/convention/KotlinAndroid.kt index 2d59c9d5..2c064653 100644 --- a/build-logic/src/main/kotlin/convention/KotlinAndroid.kt +++ b/build-logic/src/main/kotlin/convention/KotlinAndroid.kt @@ -20,6 +20,15 @@ internal fun Project.configureKotlinAndroid() { defaultConfig { minSdk = Configuration.MIN_SDK } + buildTypes { + getByName("release") { + isMinifyEnabled = false + proguardFiles( + getDefaultProguardFile("proguard-android-optimize.txt"), + "proguard-rules.pro", + ) + } + } compileOptions { sourceCompatibility = Configuration.JAVA_VERSION targetCompatibility = Configuration.JAVA_VERSION @@ -39,6 +48,7 @@ internal fun Project.configureKotlinAndroid() { dependencies { "coreLibraryDesugaring"(libs.findLibrary("android.desugarJdkLibs").get()) + "detektPlugins"(libs.findLibrary("detekt.formatting").get()) } } @@ -51,7 +61,7 @@ internal fun Project.configureKotlin() { freeCompilerArgs.set( freeCompilerArgs.get() + listOf( "-opt-in=kotlin.RequiresOptIn", - ) + ), ) } } diff --git a/build-logic/src/main/kotlin/extensions/ProjectExtensions.kt b/build-logic/src/main/kotlin/extensions/ProjectExtensions.kt deleted file mode 100644 index ee29f8e5..00000000 --- a/build-logic/src/main/kotlin/extensions/ProjectExtensions.kt +++ /dev/null @@ -1,88 +0,0 @@ -package extensions - -import Configuration -import org.gradle.api.Project -import org.gradle.api.plugins.JavaPluginExtension -import org.gradle.kotlin.dsl.configure -import org.gradle.kotlin.dsl.dependencies -import org.jetbrains.kotlin.gradle.dsl.JvmTarget -import org.jetbrains.kotlin.gradle.dsl.KotlinAndroidProjectExtension -import org.jetbrains.kotlin.gradle.dsl.KotlinJvmProjectExtension -import util.applicationExtension -import util.libraryExtension -import util.libs - -internal fun Project.configureAndroidApplication() { - applicationExtension.apply { - compileSdk = Configuration.COMPILE_SDK - - defaultConfig { - minSdk = Configuration.MIN_SDK - } - - buildTypes { - release { - isMinifyEnabled = true - proguardFiles( - getDefaultProguardFile("proguard-android-optimize.txt"), - "proguard-rules.pro" - ) - } - } - - compileOptions { - sourceCompatibility = Configuration.JAVA_VERSION - targetCompatibility = Configuration.JAVA_VERSION - } - } - - extensions.configure { - compilerOptions { - jvmTarget.set(JvmTarget.fromTarget(Configuration.JVM_TARGET)) - } - } -} - -internal fun Project.configureAndroidLibrary() { - libraryExtension.apply { - compileSdk = Configuration.COMPILE_SDK - - defaultConfig { - minSdk = Configuration.MIN_SDK - } - - buildTypes { - release { - isMinifyEnabled = false - proguardFiles( - getDefaultProguardFile("proguard-android-optimize.txt"), - "proguard-rules.pro" - ) - } - } - - compileOptions { - sourceCompatibility = Configuration.JAVA_VERSION - targetCompatibility = Configuration.JAVA_VERSION - } - } - - extensions.configure { - compilerOptions { - jvmTarget.set(JvmTarget.fromTarget(Configuration.JVM_TARGET)) - } - } -} - -internal fun Project.configureKotlinJvm() { - extensions.configure { - sourceCompatibility = Configuration.JAVA_VERSION - targetCompatibility = Configuration.JAVA_VERSION - } - - extensions.configure { - compilerOptions { - jvmTarget.set(JvmTarget.fromTarget(Configuration.JVM_TARGET)) - } - } -} diff --git a/build.gradle.kts b/build.gradle.kts index d281a248..ed8b46a3 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,3 +1,6 @@ +import io.gitlab.arturbosch.detekt.extensions.DetektExtension +import org.jlleitschuh.gradle.ktlint.KtlintExtension + plugins { alias(libs.plugins.android.application) apply false alias(libs.plugins.android.library) apply false @@ -7,11 +10,31 @@ plugins { alias(libs.plugins.jetbrains.kotlin.jvm) apply false alias(libs.plugins.ksp) apply false alias(libs.plugins.hilt) apply false + alias(libs.plugins.ktlint) + alias(libs.plugins.detekt) } -// Use Kotlin BOM with enforcedPlatform to strictly enforce Kotlin stdlib versions subprojects { + apply { + plugin(rootProject.libs.plugins.ktlint.get().pluginId) + plugin(rootProject.libs.plugins.detekt.get().pluginId) + } + + configure { + version.set(rootProject.libs.versions.ktlint.source.get()) + android.set(true) + verbose.set(true) + } + + configure { + parallel = true + buildUponDefaultConfig = true + toolVersion = rootProject.libs.versions.detekt.get() + config.setFrom(files("$rootDir/detekt-config.yml")) + } + afterEvaluate { + // Use Kotlin BOM with enforcedPlatform to strictly enforce Kotlin stdlib versions configurations.findByName("implementation")?.let { dependencies { "implementation"(enforcedPlatform("org.jetbrains.kotlin:kotlin-bom:${rootProject.libs.versions.kotlin.get()}")) diff --git a/core/ui/src/main/java/com/yapp/ndgl/core/ui/theme/Theme.kt b/core/ui/src/main/java/com/yapp/ndgl/core/ui/theme/Theme.kt index 96f89327..80c2314a 100644 --- a/core/ui/src/main/java/com/yapp/ndgl/core/ui/theme/Theme.kt +++ b/core/ui/src/main/java/com/yapp/ndgl/core/ui/theme/Theme.kt @@ -13,13 +13,13 @@ import androidx.compose.ui.platform.LocalContext private val DarkColorScheme = darkColorScheme( primary = Purple80, secondary = PurpleGrey80, - tertiary = Pink80 + tertiary = Pink80, ) private val LightColorScheme = lightColorScheme( primary = Purple40, secondary = PurpleGrey40, - tertiary = Pink40 + tertiary = Pink40, /* Other default colors to override background = Color(0xFFFFFBFE), @@ -29,7 +29,7 @@ private val LightColorScheme = lightColorScheme( onTertiary = Color.White, onBackground = Color(0xFF1C1B1F), onSurface = Color(0xFF1C1B1F), - */ + */ ) @Composable @@ -37,7 +37,7 @@ fun NDGLTheme( darkTheme: Boolean = isSystemInDarkTheme(), // Dynamic color is available on Android 12+ dynamicColor: Boolean = true, - content: @Composable () -> Unit + content: @Composable () -> Unit, ) { val colorScheme = when { dynamicColor && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> { @@ -52,6 +52,6 @@ fun NDGLTheme( MaterialTheme( colorScheme = colorScheme, typography = Typography, - content = content + content = content, ) } diff --git a/core/ui/src/main/java/com/yapp/ndgl/core/ui/theme/Type.kt b/core/ui/src/main/java/com/yapp/ndgl/core/ui/theme/Type.kt index 2f172a04..2a13947e 100644 --- a/core/ui/src/main/java/com/yapp/ndgl/core/ui/theme/Type.kt +++ b/core/ui/src/main/java/com/yapp/ndgl/core/ui/theme/Type.kt @@ -13,8 +13,8 @@ val Typography = Typography( fontWeight = FontWeight.Normal, fontSize = 16.sp, lineHeight = 24.sp, - letterSpacing = 0.5.sp - ) + letterSpacing = 0.5.sp, + ), /* Other default text styles to override titleLarge = TextStyle( fontFamily = FontFamily.Default, @@ -30,5 +30,5 @@ val Typography = Typography( lineHeight = 16.sp, letterSpacing = 0.5.sp ) - */ + */ ) diff --git a/core/ui/src/main/java/com/yapp/ui/base/BaseContract.kt b/core/ui/src/main/java/com/yapp/ui/base/BaseContract.kt index 34d87771..4a50b78c 100644 --- a/core/ui/src/main/java/com/yapp/ui/base/BaseContract.kt +++ b/core/ui/src/main/java/com/yapp/ui/base/BaseContract.kt @@ -4,4 +4,4 @@ interface UiState interface UiIntent -interface UiSideEffect \ No newline at end of file +interface UiSideEffect diff --git a/core/ui/src/main/java/com/yapp/ui/base/BaseViewModel.kt b/core/ui/src/main/java/com/yapp/ui/base/BaseViewModel.kt index 9ba32e04..8201ee2a 100644 --- a/core/ui/src/main/java/com/yapp/ui/base/BaseViewModel.kt +++ b/core/ui/src/main/java/com/yapp/ui/base/BaseViewModel.kt @@ -17,8 +17,8 @@ import kotlinx.coroutines.channels.Channel.Factory.BUFFERED import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.receiveAsFlow -import kotlinx.coroutines.launch import kotlinx.coroutines.flow.update +import kotlinx.coroutines.launch import kotlinx.coroutines.withContext abstract class BaseViewModel( diff --git a/core/util/src/main/java/com/yapp/util/Extensions.kt b/core/util/src/main/java/com/yapp/util/Extensions.kt deleted file mode 100644 index bee10f30..00000000 --- a/core/util/src/main/java/com/yapp/util/Extensions.kt +++ /dev/null @@ -1,4 +0,0 @@ -package com.yapp.util - -class Extensions { -} \ No newline at end of file diff --git a/detekt-config.yml b/detekt-config.yml new file mode 100644 index 00000000..5383fffa --- /dev/null +++ b/detekt-config.yml @@ -0,0 +1,88 @@ +complexity: + LongMethod: + threshold: 100 + ignoreAnnotated: [ 'Composable' ] + CyclomaticComplexMethod: + threshold: 40 + ignoreAnnotated: [ 'Composable' ] + LongParameterList: + active: false + TooManyFunctions: + active: false + ComplexCondition: + threshold: 7 + +performance: + SpreadOperator: + active: false + +formatting: + TrailingCommaOnCallSite: + active: true + TrailingCommaOnDeclarationSite: + active: true + ImportOrdering: + active: false + MaximumLineLength: + active: false + MultiLineIfElse: + active: false + Indentation: + active: false + indentSize: 4 + ParameterListWrapping: + active: false + ArgumentListWrapping: + indentSize: 4 + maxLineLength: 150 + KdocWrapping: + active: true + indentSize: 4 + Wrapping: + indentSize: 4 + active: false + CommentWrapping: + active: false + Filename: + active: false + PackageName: + active: false + AnnotationOnSeparateLine: + active: false + +style: + MagicNumber: + active: false + ignoreAnnotated: [ 'AllowMagicNumber' ] + ForbiddenComment: + active: false + UnusedPrivateMember: + ignoreAnnotated: [ 'Preview', 'ComponentPreview', 'DevicePreview' ] + UnusedParameter: + active: false + ThrowsCount: + active: false + ReturnCount: + active: false + LoopWithTooManyJumpStatements: + active: false + DestructuringDeclarationWithTooManyEntries: + active: false + MaxLineLength: + active: false + +exceptions: + TooGenericExceptionCaught: + active: false + +naming: + TopLevelPropertyNaming: + constantPattern: '[A-Z][A-Za-z0-9_]*' + FunctionNaming: + ignoreAnnotated: [ 'Composable' ] + MatchingDeclarationName: + active: false + VariableNaming: + active: false + PackageNaming: + packagePattern: '[a-z]+(\._?[_A-Za-z0-9]*)*' diff --git a/feature/auth/src/main/java/com/yapp/ndgl/feature/auth/AuthScreen.kt b/feature/auth/src/main/java/com/yapp/ndgl/feature/auth/AuthScreen.kt index 595c3753..1dd4f994 100644 --- a/feature/auth/src/main/java/com/yapp/ndgl/feature/auth/AuthScreen.kt +++ b/feature/auth/src/main/java/com/yapp/ndgl/feature/auth/AuthScreen.kt @@ -8,25 +8,21 @@ import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.tooling.preview.Preview -import androidx.compose.ui.unit.dp import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel -import com.yapp.ndgl.feature.auth.AuthViewModel @Composable fun AuthRoute( viewModel: AuthViewModel = hiltViewModel(), ) { - AuthScreen() } @Composable -private fun AuthScreen( -) { +private fun AuthScreen() { LazyColumn( modifier = Modifier.fillMaxSize(), verticalArrangement = Arrangement.Center, - horizontalAlignment = Alignment.CenterHorizontally + horizontalAlignment = Alignment.CenterHorizontally, ) { item { Text(text = "Auth Screen") diff --git a/feature/auth/src/main/java/com/yapp/ndgl/feature/auth/AuthViewModel.kt b/feature/auth/src/main/java/com/yapp/ndgl/feature/auth/AuthViewModel.kt index 77934f9f..06c610f6 100644 --- a/feature/auth/src/main/java/com/yapp/ndgl/feature/auth/AuthViewModel.kt +++ b/feature/auth/src/main/java/com/yapp/ndgl/feature/auth/AuthViewModel.kt @@ -1,18 +1,8 @@ package com.yapp.ndgl.feature.auth import androidx.lifecycle.ViewModel -import androidx.lifecycle.viewModelScope import dagger.hilt.android.lifecycle.HiltViewModel -import kotlinx.coroutines.flow.MutableSharedFlow -import kotlinx.coroutines.flow.MutableStateFlow -import kotlinx.coroutines.flow.StateFlow -import kotlinx.coroutines.flow.asSharedFlow -import kotlinx.coroutines.flow.asStateFlow -import kotlinx.coroutines.launch import javax.inject.Inject @HiltViewModel -class AuthViewModel @Inject constructor() : ViewModel() { - -} - +class AuthViewModel @Inject constructor() : ViewModel() diff --git a/feature/home/src/main/java/com/yapp/ndgl/feature/home/HomeScreen.kt b/feature/home/src/main/java/com/yapp/ndgl/feature/home/HomeScreen.kt index 19bbd1df..3c34f2a7 100644 --- a/feature/home/src/main/java/com/yapp/ndgl/feature/home/HomeScreen.kt +++ b/feature/home/src/main/java/com/yapp/ndgl/feature/home/HomeScreen.kt @@ -8,24 +8,21 @@ import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.tooling.preview.Preview -import androidx.compose.ui.unit.dp import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel @Composable internal fun HomeRoute( viewModel: HomeViewModel = hiltViewModel(), ) { - HomeScreen() } @Composable -private fun HomeScreen( -) { +private fun HomeScreen() { LazyColumn( modifier = Modifier.fillMaxSize(), verticalArrangement = Arrangement.Center, - horizontalAlignment = Alignment.CenterHorizontally + horizontalAlignment = Alignment.CenterHorizontally, ) { item { Text(text = "Home Screen") diff --git a/feature/home/src/main/java/com/yapp/ndgl/feature/home/HomeViewModel.kt b/feature/home/src/main/java/com/yapp/ndgl/feature/home/HomeViewModel.kt index 319dcd32..bffa75c7 100644 --- a/feature/home/src/main/java/com/yapp/ndgl/feature/home/HomeViewModel.kt +++ b/feature/home/src/main/java/com/yapp/ndgl/feature/home/HomeViewModel.kt @@ -5,6 +5,4 @@ import dagger.hilt.android.lifecycle.HiltViewModel import javax.inject.Inject @HiltViewModel -class HomeViewModel @Inject constructor() : ViewModel() { - -} \ No newline at end of file +class HomeViewModel @Inject constructor() : ViewModel() diff --git a/feature/travel-helper/src/main/java/com/yapp/ndgl/feature/travelhelper/TravelHelperScreen.kt b/feature/travel-helper/src/main/java/com/yapp/ndgl/feature/travelhelper/TravelHelperScreen.kt index df19afe9..8d368916 100644 --- a/feature/travel-helper/src/main/java/com/yapp/ndgl/feature/travelhelper/TravelHelperScreen.kt +++ b/feature/travel-helper/src/main/java/com/yapp/ndgl/feature/travelhelper/TravelHelperScreen.kt @@ -14,17 +14,15 @@ import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel internal fun TravelHelperRoute( viewModel: TravelHelperViewModel = hiltViewModel(), ) { - TravelHelperScreen() } @Composable -private fun TravelHelperScreen( -) { +private fun TravelHelperScreen() { LazyColumn( modifier = Modifier.fillMaxSize(), verticalArrangement = Arrangement.Center, - horizontalAlignment = Alignment.CenterHorizontally + horizontalAlignment = Alignment.CenterHorizontally, ) { item { Text(text = "Travel Helper Screen") diff --git a/feature/travel-helper/src/main/java/com/yapp/ndgl/feature/travelhelper/TravelHelperViewModel.kt b/feature/travel-helper/src/main/java/com/yapp/ndgl/feature/travelhelper/TravelHelperViewModel.kt index 8681219a..9c89c5be 100644 --- a/feature/travel-helper/src/main/java/com/yapp/ndgl/feature/travelhelper/TravelHelperViewModel.kt +++ b/feature/travel-helper/src/main/java/com/yapp/ndgl/feature/travelhelper/TravelHelperViewModel.kt @@ -5,6 +5,4 @@ import dagger.hilt.android.lifecycle.HiltViewModel import javax.inject.Inject @HiltViewModel -class TravelHelperViewModel @Inject constructor() : ViewModel() { - -} +class TravelHelperViewModel @Inject constructor() : ViewModel() diff --git a/feature/travel/src/main/java/com/yapp/ndgl/feature/travel/TravelContract.kt b/feature/travel/src/main/java/com/yapp/ndgl/feature/travel/TravelContract.kt index e818c01e..911dbae5 100644 --- a/feature/travel/src/main/java/com/yapp/ndgl/feature/travel/TravelContract.kt +++ b/feature/travel/src/main/java/com/yapp/ndgl/feature/travel/TravelContract.kt @@ -5,10 +5,9 @@ import com.yapp.ui.base.UiSideEffect import com.yapp.ui.base.UiState data class TravelState( - val displayText: String = "초기 상태" + val displayText: String = "초기 상태", ) : UiState - sealed interface TravelIntent : UiIntent { data class ClickTravel(val travelId: Int) : TravelIntent } diff --git a/feature/travel/src/main/java/com/yapp/ndgl/feature/travel/TravelScreen.kt b/feature/travel/src/main/java/com/yapp/ndgl/feature/travel/TravelScreen.kt index bf586cfa..8e5c38fc 100644 --- a/feature/travel/src/main/java/com/yapp/ndgl/feature/travel/TravelScreen.kt +++ b/feature/travel/src/main/java/com/yapp/ndgl/feature/travel/TravelScreen.kt @@ -21,7 +21,8 @@ internal fun TravelRoute( TravelScreen( state = state, - clickTravel = { id -> viewModel.onIntent(TravelIntent.ClickTravel(id)) }) + clickTravel = { id -> viewModel.onIntent(TravelIntent.ClickTravel(id)) }, + ) viewModel.collectSideEffect { sideEffect -> when (sideEffect) { @@ -38,7 +39,7 @@ private fun TravelScreen( LazyColumn( modifier = Modifier.fillMaxSize(), verticalArrangement = Arrangement.Center, - horizontalAlignment = Alignment.CenterHorizontally + horizontalAlignment = Alignment.CenterHorizontally, ) { item { Text(text = "Travel Screen") @@ -47,16 +48,17 @@ private fun TravelScreen( Text(text = state.displayText) } item { - Button(onClick = { - clickTravel(123) - }) { + Button( + onClick = { + clickTravel(123) + }, + ) { Text(text = "Go to Travel Detail") } } } } - @Preview(showBackground = true) @Composable private fun TravelScreenPreview() { diff --git a/feature/travel/src/main/java/com/yapp/ndgl/feature/travel/TravelViewModel.kt b/feature/travel/src/main/java/com/yapp/ndgl/feature/travel/TravelViewModel.kt index cad6253b..2838d247 100644 --- a/feature/travel/src/main/java/com/yapp/ndgl/feature/travel/TravelViewModel.kt +++ b/feature/travel/src/main/java/com/yapp/ndgl/feature/travel/TravelViewModel.kt @@ -6,7 +6,7 @@ import javax.inject.Inject @HiltViewModel class TravelViewModel @Inject constructor() : BaseViewModel( - initialState = TravelState() + initialState = TravelState(), ) { override suspend fun handleIntent(intent: TravelIntent) { when (intent) { @@ -17,8 +17,7 @@ class TravelViewModel @Inject constructor() : BaseViewModel.travelEntry(navigator: Navigator) { entry { TravelRoute( navigateToDetail = { travelId -> navigator.navigate(Route.TravelDetail(travelId)) - }) + }, + ) } entry { route -> val viewModel = diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 2da17932..47615e63 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -44,6 +44,11 @@ appcompat = "1.7.1" material = "1.13.0" +# Static Analysis +detekt = "1.23.8" +ktlint-gradle = "12.1.1" +ktlint-source = "0.50.0" #https://github.com/pinterest/ktlint/releases + [libraries] # AndroidX androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" } @@ -101,6 +106,8 @@ firebase-crashlytics = { group = "com.google.firebase", name = "firebase-crashly # Other timber = { group = "com.jakewharton.timber", name = "timber", version.ref = "timber" } android-desugarJdkLibs = { group = "com.android.tools", name = "desugar_jdk_libs", version.ref = "desugarJdkLibs" } +detekt-formatting = { group = "io.gitlab.arturbosch.detekt", name = "detekt-formatting", version.ref = "detekt" } + # Gradle Plugins (for build-logic) android-gradlePlugin = { group = "com.android.tools.build", name = "gradle", version.ref = "agp" } @@ -119,3 +126,5 @@ kotlin-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", versi jetbrains-kotlin-jvm = { id = "org.jetbrains.kotlin.jvm", version.ref = "jetbrainsKotlinJvm" } ksp = { id = "com.google.devtools.ksp", version.ref = "ksp" } hilt = { id = "com.google.dagger.hilt.android", version.ref = "hilt" } +ktlint = { id = "org.jlleitschuh.gradle.ktlint", version.ref = "ktlint-gradle" } +detekt = { id = "io.gitlab.arturbosch.detekt", version.ref = "detekt" } diff --git a/navigation/src/main/java/com/yapp/ndgl/navigation/NavigationState.kt b/navigation/src/main/java/com/yapp/ndgl/navigation/NavigationState.kt index 49e38619..3ae555b4 100644 --- a/navigation/src/main/java/com/yapp/ndgl/navigation/NavigationState.kt +++ b/navigation/src/main/java/com/yapp/ndgl/navigation/NavigationState.kt @@ -50,17 +50,17 @@ class NavigationState( @Composable fun NavigationState.toEntries( - entryProvider: (NavKey) -> NavEntry + entryProvider: (NavKey) -> NavEntry, ): SnapshotStateList> { val decoratedEntries = subStacks.mapValues { (_, stack) -> val decorators = listOf( rememberSaveableStateHolderNavEntryDecorator(), - rememberViewModelStoreNavEntryDecorator() + rememberViewModelStoreNavEntryDecorator(), ) rememberDecoratedNavEntries( backStack = stack, entryDecorators = decorators, - entryProvider = entryProvider + entryProvider = entryProvider, ) }