diff --git a/app/build.gradle.kts b/app/build.gradle.kts index e086e1e0..0681f262 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -6,6 +6,7 @@ plugins { alias(libs.plugins.hilt) alias(libs.plugins.ksp) alias(libs.plugins.google.services) + alias(libs.plugins.firebase.crashlytics) } val localProperties = @@ -21,8 +22,8 @@ android { defaultConfig { applicationId = "com.sseotdabwa.buyornot" - versionCode = 1 - versionName = "1.0.0" + versionCode = 2 + versionName = "0.0.1" buildConfigField("String", "KAKAO_NATIVE_APP_KEY", "\"${localProperties.getProperty("kakao.nativeAppKey", "")}\"") manifestPlaceholders["NATIVE_APP_KEY"] = localProperties.getProperty("kakao.nativeAppKey", "") @@ -59,7 +60,8 @@ android { signingConfig = signingConfigs.getByName("release") } release { - isMinifyEnabled = false + isMinifyEnabled = true + isShrinkResources = true proguardFiles( getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro", @@ -104,6 +106,7 @@ dependencies { implementation(platform(libs.firebase.bom)) implementation(libs.firebase.messaging) + implementation(libs.firebase.crashlytics) ksp(libs.hilt.compiler) diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro index 481bb434..b44e8339 100644 --- a/app/proguard-rules.pro +++ b/app/proguard-rules.pro @@ -1,21 +1,60 @@ -# 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 \ No newline at end of file +# [Common] Android +-keepattributes SourceFile,LineNumberTable +-keepattributes *Annotation* +-keepattributes Signature +-keepattributes InnerClasses +-dontwarn sun.misc.** +-dontwarn javax.annotation.** + +# [Kotlin] +-keep class kotlin.Metadata { *; } + +# [Hilt / Dagger] +-keep class dagger.hilt.** { *; } +-keep class com.google.dagger.** { *; } +-keep @dagger.hilt.android.lifecycle.HiltViewModel class * +-keep interface * extends javax.inject.Provider + +# [Retrofit / OkHttp] +-keep class retrofit2.** { *; } +-dontwarn retrofit2.** +-keepattributes *Annotation* +-keepclassmembers class * { + @retrofit2.http.* ; +} +-keep class okhttp3.** { *; } +-dontwarn okhttp3.** +-dontwarn okio.** + +# [Kotlinx Serialization] +-keepattributes *Annotation*, InnerClasses +-keepclassmembers class * { + @kotlinx.serialization.Serializable *; +} +-keepclassmembers class * { + kotlinx.serialization.KSerializer serializer(...); +} + +# [Domain/Data Models] - API 통신 데이터 클래스 보존 +# 모든 모듈의 domain.model, network.model 하위의 클래스들을 보존합니다. +-keep class com.sseotdabwa.buyornot.domain.model.** { *; } +-keep class com.sseotdabwa.buyornot.core.network.model.** { *; } + +# [Coil] +-keep class coil.** { *; } +-dontwarn coil.** + +# [Firebase] +-keep class com.google.firebase.** { *; } +-dontwarn com.google.firebase.** + +# [Lottie] +-keep class com.airbnb.lottie.** { *; } + +# [Kakao SDK] +-keep class com.kakao.sdk.** { *; } +-dontwarn com.kakao.sdk.** + +# [Jetpack Compose] +-keep class androidx.compose.runtime.RecomposeScopeImpl { *; } +-keep class * implements androidx.compose.runtime.Parcelable { *; } diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 2afd70c0..cf13dc03 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -3,6 +3,7 @@ + -> diff --git a/feature/upload/src/main/java/com/sseotdabwa/buyornot/feature/upload/ui/UploadContract.kt b/feature/upload/src/main/java/com/sseotdabwa/buyornot/feature/upload/ui/UploadContract.kt index c04db261..51b2d2d4 100644 --- a/feature/upload/src/main/java/com/sseotdabwa/buyornot/feature/upload/ui/UploadContract.kt +++ b/feature/upload/src/main/java/com/sseotdabwa/buyornot/feature/upload/ui/UploadContract.kt @@ -15,7 +15,10 @@ data class UploadUiState( val showCategorySheet: Boolean = false, val showExitDialog: Boolean = false, val categories: List = FeedCategory.entries, -) +) { + val hasInput: Boolean + get() = selectedImageUri != null || category != null || price.isNotEmpty() || content.isNotEmpty() +} sealed interface UploadIntent { data class UpdateCategory( diff --git a/feature/upload/src/main/java/com/sseotdabwa/buyornot/feature/upload/ui/UploadScreen.kt b/feature/upload/src/main/java/com/sseotdabwa/buyornot/feature/upload/ui/UploadScreen.kt index 783e7692..665ae09b 100644 --- a/feature/upload/src/main/java/com/sseotdabwa/buyornot/feature/upload/ui/UploadScreen.kt +++ b/feature/upload/src/main/java/com/sseotdabwa/buyornot/feature/upload/ui/UploadScreen.kt @@ -119,7 +119,11 @@ fun UploadScreen( } BackHandler { - if (!uiState.showExitDialog) viewModel.handleIntent(UploadIntent.UpdateExitDialogVisibility(true)) + if (uiState.hasInput) { + if (!uiState.showExitDialog) viewModel.handleIntent(UploadIntent.UpdateExitDialogVisibility(true)) + } else { + onNavigateBack() + } } Column( @@ -131,7 +135,11 @@ fun UploadScreen( .windowInsetsPadding(WindowInsets.safeDrawing), ) { BackTopBar { - viewModel.handleIntent(UploadIntent.UpdateExitDialogVisibility(true)) + if (uiState.hasInput) { + viewModel.handleIntent(UploadIntent.UpdateExitDialogVisibility(true)) + } else { + onNavigateBack() + } } Column( diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index cf28deaa..ad3dea6b 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -41,8 +41,9 @@ googleid = "1.2.0" lottie = "6.7.1" # Firebase -firebaseBom = "33.9.0" +firebaseBom = "34.9.0" googleServices = "4.4.2" +firebaseCrashlytics = "3.0.3" # Code Quality ktlint = "14.0.1" @@ -120,6 +121,7 @@ androidx-compose-runtime = { group = "androidx.compose.runtime", name = "runtime # Firebase firebase-bom = { group = "com.google.firebase", name = "firebase-bom", version.ref = "firebaseBom" } firebase-messaging = { group = "com.google.firebase", name = "firebase-messaging" } +firebase-crashlytics = { group = "com.google.firebase", name = "firebase-crashlytics" } lottie-compose = { group = "com.airbnb.android", name = "lottie-compose", version.ref = "lottie" } @@ -134,3 +136,4 @@ hilt = { id = "com.google.dagger.hilt.android", version.ref = "hilt" } ksp = { id = "com.google.devtools.ksp", version.ref = "ksp" } ktlint = { id = "org.jlleitschuh.gradle.ktlint", version.ref = "ktlint" } google-services = { id = "com.google.gms.google-services", version.ref = "googleServices" } +firebase-crashlytics = { id = "com.google.firebase.crashlytics", version.ref = "firebaseCrashlytics" }