From 6969a2121199140db85d834839cef829d90e1ad3 Mon Sep 17 00:00:00 2001 From: fredLeeJH Date: Fri, 20 Jun 2025 16:37:48 +0900 Subject: [PATCH 1/9] =?UTF-8?q?#1=20[init]=20:=20=ED=94=84=EB=A1=9C?= =?UTF-8?q?=EC=A0=9D=ED=8A=B8=20=EA=B8=B0=EC=B4=88=20=EC=84=B8=ED=8C=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/ktlint.yml | 26 +++ app/build.gradle.kts | 86 ++++++++-- .../android/heartz/ExampleInstrumentedTest.kt | 14 +- app/src/main/AndroidManifest.xml | 17 +- app/src/main/java/com/heartz/app/Heartz.kt | 24 +++ .../app/core/designsystem/ui/theme/Color.kt | 13 ++ .../app/core/designsystem/ui/theme/Theme.kt | 13 ++ .../core/designsystem/ui/theme/TypoGraphy.kt | 18 +++ .../app/core/navigation/MainTabRoute.kt | 3 + .../com/heartz/app/core/navigation/Route.kt | 3 + .../java/com/heartz/app/core/state/UiState.kt | 15 ++ .../com/heartz/app/core/util/ModifierExt.kt | 17 ++ .../datasource/local/DummyLocalDataSource.kt | 12 ++ .../remote/DummyRemoteDataSource.kt | 9 ++ .../local/DummyLocalDataSourceImpl.kt | 37 +++++ .../remote/DummyRemoteDataSourceImpl.kt | 16 ++ .../java/com/heartz/app/data/di/ApiModule.kt | 17 ++ .../heartz/app/data/di/DataSourceModule.kt | 23 +++ .../com/heartz/app/data/di/NetworkModule.kt | 51 ++++++ .../heartz/app/data/di/RepositoryModule.kt | 17 ++ .../app/data/dto/base/DummyBaseResponse.kt | 16 ++ .../dto/base/DummyNullableBaseResponse.kt | 16 ++ .../app/data/dto/request/RequestDummyDto.kt | 12 ++ .../app/data/dto/response/ResponseDummyDto.kt | 10 ++ .../app/data/mapper/todata/DummyMapper.kt | 10 ++ .../mapper/todomain/ResponseDummyDtoMapper.kt | 9 ++ .../repositoryimpl/DummyRepositoryImpl.kt | 24 +++ .../heartz/app/data/service/DummyService.kt | 14 ++ .../java/com/heartz/app/domain/model/Dummy.kt | 6 + .../app/domain/model/DummyResultModel.kt | 5 + .../app/domain/repository/DummyRepository.kt | 8 + .../heartz/app/domain/usecase/DummyUseCase.kt | 5 + .../app/presentation/graph/FigureScreen.kt | 28 ++++ .../graph/navigation/FigureNavigation.kt | 22 +++ .../app/presentation/home/HomeScreen.kt | 50 ++++++ .../heartz/app/presentation/home/HomeState.kt | 8 + .../app/presentation/home/HomeViewModel.kt | 41 +++++ .../home/navigation/HomeNavigation.kt | 22 +++ .../app/presentation/main/MainActivity.kt | 21 +++ .../app/presentation/main/MainNavHost.kt | 31 ++++ .../app/presentation/main/MainNavTab.kt | 59 +++++++ .../app/presentation/main/MainNavigator.kt | 68 ++++++++ .../app/presentation/main/MainScreen.kt | 36 +++++ .../main/component/MainBottomBar.kt | 114 ++++++++++++++ .../app/presentation/mypage/MypageScreen.kt | 28 ++++ .../mypage/navigation/MypageNavigation.kt | 22 +++ .../app/presentation/quest/QuestScreen.kt | 28 ++++ .../quest/navigation/QuestNavigation.kt | 22 +++ app/src/main/res/drawable/ic_folder_open.xml | 10 ++ app/src/main/res/drawable/ic_graph.xml | 18 +++ app/src/main/res/drawable/ic_home.xml | 10 ++ app/src/main/res/drawable/ic_user.xml | 16 ++ app/src/main/res/values/strings.xml | 7 + .../com/android/heartz/ExampleUnitTest.kt | 10 +- build.gradle.kts | 9 +- gradle/libs.versions.toml | 148 +++++++++++++++++- settings.gradle.kts | 1 + 57 files changed, 1354 insertions(+), 41 deletions(-) create mode 100644 .github/workflows/ktlint.yml create mode 100644 app/src/main/java/com/heartz/app/Heartz.kt create mode 100644 app/src/main/java/com/heartz/app/core/designsystem/ui/theme/Color.kt create mode 100644 app/src/main/java/com/heartz/app/core/designsystem/ui/theme/Theme.kt create mode 100644 app/src/main/java/com/heartz/app/core/designsystem/ui/theme/TypoGraphy.kt create mode 100644 app/src/main/java/com/heartz/app/core/navigation/MainTabRoute.kt create mode 100644 app/src/main/java/com/heartz/app/core/navigation/Route.kt create mode 100644 app/src/main/java/com/heartz/app/core/state/UiState.kt create mode 100644 app/src/main/java/com/heartz/app/core/util/ModifierExt.kt create mode 100644 app/src/main/java/com/heartz/app/data/datasource/local/DummyLocalDataSource.kt create mode 100644 app/src/main/java/com/heartz/app/data/datasource/remote/DummyRemoteDataSource.kt create mode 100644 app/src/main/java/com/heartz/app/data/datasourceimpl/local/DummyLocalDataSourceImpl.kt create mode 100644 app/src/main/java/com/heartz/app/data/datasourceimpl/remote/DummyRemoteDataSourceImpl.kt create mode 100644 app/src/main/java/com/heartz/app/data/di/ApiModule.kt create mode 100644 app/src/main/java/com/heartz/app/data/di/DataSourceModule.kt create mode 100644 app/src/main/java/com/heartz/app/data/di/NetworkModule.kt create mode 100644 app/src/main/java/com/heartz/app/data/di/RepositoryModule.kt create mode 100644 app/src/main/java/com/heartz/app/data/dto/base/DummyBaseResponse.kt create mode 100644 app/src/main/java/com/heartz/app/data/dto/base/DummyNullableBaseResponse.kt create mode 100644 app/src/main/java/com/heartz/app/data/dto/request/RequestDummyDto.kt create mode 100644 app/src/main/java/com/heartz/app/data/dto/response/ResponseDummyDto.kt create mode 100644 app/src/main/java/com/heartz/app/data/mapper/todata/DummyMapper.kt create mode 100644 app/src/main/java/com/heartz/app/data/mapper/todomain/ResponseDummyDtoMapper.kt create mode 100644 app/src/main/java/com/heartz/app/data/repositoryimpl/DummyRepositoryImpl.kt create mode 100644 app/src/main/java/com/heartz/app/data/service/DummyService.kt create mode 100644 app/src/main/java/com/heartz/app/domain/model/Dummy.kt create mode 100644 app/src/main/java/com/heartz/app/domain/model/DummyResultModel.kt create mode 100644 app/src/main/java/com/heartz/app/domain/repository/DummyRepository.kt create mode 100644 app/src/main/java/com/heartz/app/domain/usecase/DummyUseCase.kt create mode 100644 app/src/main/java/com/heartz/app/presentation/graph/FigureScreen.kt create mode 100644 app/src/main/java/com/heartz/app/presentation/graph/navigation/FigureNavigation.kt create mode 100644 app/src/main/java/com/heartz/app/presentation/home/HomeScreen.kt create mode 100644 app/src/main/java/com/heartz/app/presentation/home/HomeState.kt create mode 100644 app/src/main/java/com/heartz/app/presentation/home/HomeViewModel.kt create mode 100644 app/src/main/java/com/heartz/app/presentation/home/navigation/HomeNavigation.kt create mode 100644 app/src/main/java/com/heartz/app/presentation/main/MainActivity.kt create mode 100644 app/src/main/java/com/heartz/app/presentation/main/MainNavHost.kt create mode 100644 app/src/main/java/com/heartz/app/presentation/main/MainNavTab.kt create mode 100644 app/src/main/java/com/heartz/app/presentation/main/MainNavigator.kt create mode 100644 app/src/main/java/com/heartz/app/presentation/main/MainScreen.kt create mode 100644 app/src/main/java/com/heartz/app/presentation/main/component/MainBottomBar.kt create mode 100644 app/src/main/java/com/heartz/app/presentation/mypage/MypageScreen.kt create mode 100644 app/src/main/java/com/heartz/app/presentation/mypage/navigation/MypageNavigation.kt create mode 100644 app/src/main/java/com/heartz/app/presentation/quest/QuestScreen.kt create mode 100644 app/src/main/java/com/heartz/app/presentation/quest/navigation/QuestNavigation.kt create mode 100644 app/src/main/res/drawable/ic_folder_open.xml create mode 100644 app/src/main/res/drawable/ic_graph.xml create mode 100644 app/src/main/res/drawable/ic_home.xml create mode 100644 app/src/main/res/drawable/ic_user.xml diff --git a/.github/workflows/ktlint.yml b/.github/workflows/ktlint.yml new file mode 100644 index 00000000..0ab21ba7 --- /dev/null +++ b/.github/workflows/ktlint.yml @@ -0,0 +1,26 @@ +name: ktlint Check + +on: + pull_request: + branches: [ develop ] + +jobs: + ktlint: + name: Run ktlint + runs-on: ubuntu-latest + + steps: + - name: Checkout Code + uses: actions/checkout@v4 + + - name: Set up JDK 17 + uses: actions/setup-java@v4 + with: + distribution: 'temurin' + java-version: 17 + + - name: Grant execute permission for gradlew + run: chmod +x ./gradlew + + - name: Run ktlint check + run: ./gradlew ktlintCheck diff --git a/app/build.gradle.kts b/app/build.gradle.kts index c480de3d..1af23e4d 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -1,20 +1,36 @@ +import java.util.Properties + plugins { alias(libs.plugins.android.application) alias(libs.plugins.kotlin.android) + alias(libs.plugins.kotlin.compose) + alias(libs.plugins.kotlin.serialization) + alias(libs.plugins.hilt) + alias(libs.plugins.ksp) + alias(libs.plugins.kotlin.parcelize) + alias(libs.plugins.ktlint) } +val properties = + Properties().apply { + load(project.rootProject.file("local.properties").inputStream()) + } android { - namespace = "com.android.heartz" + namespace = "com.heartz.app" compileSdk = 35 defaultConfig { - applicationId = "com.android.heartz" + applicationId = "com.heartz.app" minSdk = 28 targetSdk = 35 versionCode = 1 versionName = "1.0" testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" + + buildConfigField("String", "BASE_URL", properties["base.url"].toString()) + // TODO: kakao social login + buildConfigField("String", "KAKAO_NATIVE_APP_KEY", properties["kakao.native.app.key"].toString()) } buildTypes { @@ -22,25 +38,71 @@ android { isMinifyEnabled = false proguardFiles( getDefaultProguardFile("proguard-android-optimize.txt"), - "proguard-rules.pro" + "proguard-rules.pro", ) } } compileOptions { - sourceCompatibility = JavaVersion.VERSION_11 - targetCompatibility = JavaVersion.VERSION_11 + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 } kotlinOptions { - jvmTarget = "11" + jvmTarget = "17" + } + buildFeatures { + compose = true + buildConfig = true } } dependencies { - implementation(libs.androidx.core.ktx) - implementation(libs.androidx.appcompat) - implementation(libs.material) + // Test testImplementation(libs.junit) - androidTestImplementation(libs.androidx.junit) - androidTestImplementation(libs.androidx.espresso.core) -} \ No newline at end of file + androidTestImplementation(platform(libs.androidx.compose.bom)) + androidTestImplementation(libs.bundles.test) + + // Debug + debugImplementation(libs.bundles.debug) + + // AndroidX + implementation(libs.bundles.androidx) + implementation(platform(libs.androidx.compose.bom)) + implementation(libs.kotlinx.collections.immutable) + + // Google + implementation(platform(libs.google.firebase.bom)) + implementation(libs.google.firebase.crashlytics) + + // Network + implementation(platform(libs.okhttp.bom)) + implementation(libs.bundles.okhttp) + implementation(libs.bundles.retrofit) + implementation(libs.kotlinx.serialization.json) + + // Hilt + implementation(libs.bundles.hilt) + ksp(libs.hilt.compiler) + + // Coil + implementation(libs.coil.compose) + + // Timber + implementation(libs.timber) + + // Kakao Login + implementation(libs.bundles.kakao) + + // Ui + implementation(libs.androidx.ui) + implementation(libs.androidx.ui.graphics) + debugImplementation(libs.androidx.ui.tooling) +} + +ktlint { + android = true + debug = true + coloredOutput = true + verbose = true + outputToConsole = true +} diff --git a/app/src/androidTest/java/com/android/heartz/ExampleInstrumentedTest.kt b/app/src/androidTest/java/com/android/heartz/ExampleInstrumentedTest.kt index f6e485f6..56eb3020 100644 --- a/app/src/androidTest/java/com/android/heartz/ExampleInstrumentedTest.kt +++ b/app/src/androidTest/java/com/android/heartz/ExampleInstrumentedTest.kt @@ -1,24 +1,16 @@ package com.android.heartz -import androidx.test.platform.app.InstrumentationRegistry import androidx.test.ext.junit.runners.AndroidJUnit4 - +import androidx.test.platform.app.InstrumentationRegistry +import org.junit.Assert.assertEquals import org.junit.Test import org.junit.runner.RunWith -import org.junit.Assert.* - -/** - * Instrumented test, which will execute on an Android device. - * - * See [testing documentation](http://d.android.com/tools/testing). - */ @RunWith(AndroidJUnit4::class) class ExampleInstrumentedTest { @Test fun useAppContext() { - // Context of the app under test. val appContext = InstrumentationRegistry.getInstrumentation().targetContext assertEquals("com.android.heartz", appContext.packageName) } -} \ No newline at end of file +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 1a49ba31..e8eaf110 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -2,7 +2,10 @@ + + + tools:targetApi="31"> + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/heartz/app/Heartz.kt b/app/src/main/java/com/heartz/app/Heartz.kt new file mode 100644 index 00000000..4817d0e0 --- /dev/null +++ b/app/src/main/java/com/heartz/app/Heartz.kt @@ -0,0 +1,24 @@ +package com.heartz.app + +import android.app.Application +import androidx.appcompat.app.AppCompatDelegate +import dagger.hilt.android.HiltAndroidApp +import timber.log.Timber + +@HiltAndroidApp +class Heartz : Application() { + override fun onCreate() { + super.onCreate() + + initTimber() + setDayMode() + } + + private fun initTimber() { + if (BuildConfig.DEBUG) Timber.plant(Timber.DebugTree()) + } + + private fun setDayMode() { + AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO) + } +} diff --git a/app/src/main/java/com/heartz/app/core/designsystem/ui/theme/Color.kt b/app/src/main/java/com/heartz/app/core/designsystem/ui/theme/Color.kt new file mode 100644 index 00000000..31e94702 --- /dev/null +++ b/app/src/main/java/com/heartz/app/core/designsystem/ui/theme/Color.kt @@ -0,0 +1,13 @@ +package com.heartz.app.core.designsystem.ui.theme + +import androidx.compose.material3.darkColorScheme +import androidx.compose.ui.graphics.Color + +val Red80 = Color(0xFFFF5656) +val Pink80 = Color(0xFFFFB0B0) + +val HeartzColorScheme = + darkColorScheme( + primary = Red80, + secondary = Pink80, + ) diff --git a/app/src/main/java/com/heartz/app/core/designsystem/ui/theme/Theme.kt b/app/src/main/java/com/heartz/app/core/designsystem/ui/theme/Theme.kt new file mode 100644 index 00000000..ac161080 --- /dev/null +++ b/app/src/main/java/com/heartz/app/core/designsystem/ui/theme/Theme.kt @@ -0,0 +1,13 @@ +package com.heartz.app.core.designsystem.ui.theme + +import androidx.compose.material3.MaterialTheme +import androidx.compose.runtime.Composable + +@Composable +fun HeartzTheme(content: @Composable () -> Unit) { + MaterialTheme( + colorScheme = HeartzColorScheme, + typography = Typography, + content = content, + ) +} diff --git a/app/src/main/java/com/heartz/app/core/designsystem/ui/theme/TypoGraphy.kt b/app/src/main/java/com/heartz/app/core/designsystem/ui/theme/TypoGraphy.kt new file mode 100644 index 00000000..f3385656 --- /dev/null +++ b/app/src/main/java/com/heartz/app/core/designsystem/ui/theme/TypoGraphy.kt @@ -0,0 +1,18 @@ +package com.heartz.app.core.designsystem.ui.theme + +import androidx.compose.material3.Typography +import androidx.compose.ui.text.TextStyle +import androidx.compose.ui.text.font.FontFamily +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.unit.sp + +val Typography = + Typography( + bodyLarge = + TextStyle( + fontFamily = FontFamily.Default, + fontWeight = FontWeight.SemiBold, + fontSize = 16.sp, + lineHeight = 24.sp, + ), + ) diff --git a/app/src/main/java/com/heartz/app/core/navigation/MainTabRoute.kt b/app/src/main/java/com/heartz/app/core/navigation/MainTabRoute.kt new file mode 100644 index 00000000..03140d06 --- /dev/null +++ b/app/src/main/java/com/heartz/app/core/navigation/MainTabRoute.kt @@ -0,0 +1,3 @@ +package com.heartz.app.core.navigation + +interface MainTabRoute : Route diff --git a/app/src/main/java/com/heartz/app/core/navigation/Route.kt b/app/src/main/java/com/heartz/app/core/navigation/Route.kt new file mode 100644 index 00000000..7a9eeecc --- /dev/null +++ b/app/src/main/java/com/heartz/app/core/navigation/Route.kt @@ -0,0 +1,3 @@ +package com.heartz.app.core.navigation + +interface Route diff --git a/app/src/main/java/com/heartz/app/core/state/UiState.kt b/app/src/main/java/com/heartz/app/core/state/UiState.kt new file mode 100644 index 00000000..b7198a2f --- /dev/null +++ b/app/src/main/java/com/heartz/app/core/state/UiState.kt @@ -0,0 +1,15 @@ +package com.heartz.app.core.state + +sealed interface UiState { + data object Empty : UiState + + data object Loading : UiState + + data class Success( + val data: T, + ) : UiState + + data class Failure( + val msg: String, + ) : UiState +} diff --git a/app/src/main/java/com/heartz/app/core/util/ModifierExt.kt b/app/src/main/java/com/heartz/app/core/util/ModifierExt.kt new file mode 100644 index 00000000..0b8d8389 --- /dev/null +++ b/app/src/main/java/com/heartz/app/core/util/ModifierExt.kt @@ -0,0 +1,17 @@ +package com.heartz.app.core.util + +import androidx.compose.foundation.clickable +import androidx.compose.foundation.interaction.MutableInteractionSource +import androidx.compose.runtime.remember +import androidx.compose.ui.Modifier +import androidx.compose.ui.composed + +inline fun Modifier.noRippleClickable(crossinline onClick: () -> Unit = {}): Modifier = + composed { + this.clickable( + indication = null, + interactionSource = remember { MutableInteractionSource() }, + ) { + onClick() + } + } diff --git a/app/src/main/java/com/heartz/app/data/datasource/local/DummyLocalDataSource.kt b/app/src/main/java/com/heartz/app/data/datasource/local/DummyLocalDataSource.kt new file mode 100644 index 00000000..32aa0808 --- /dev/null +++ b/app/src/main/java/com/heartz/app/data/datasource/local/DummyLocalDataSource.kt @@ -0,0 +1,12 @@ +package org.sopt.dateroad.data.datalocal.datasourceimpl + +import kotlinx.coroutines.flow.Flow + +// TODO: 임시 +interface DummyLocalDataSource { + val isLogin: Flow + + suspend fun setIsLogin(value: Boolean) + + suspend fun clear() +} diff --git a/app/src/main/java/com/heartz/app/data/datasource/remote/DummyRemoteDataSource.kt b/app/src/main/java/com/heartz/app/data/datasource/remote/DummyRemoteDataSource.kt new file mode 100644 index 00000000..d7f2b509 --- /dev/null +++ b/app/src/main/java/com/heartz/app/data/datasource/remote/DummyRemoteDataSource.kt @@ -0,0 +1,9 @@ +package com.heartz.app.data.datasource.remote + +import com.heartz.app.data.dto.base.DummyBaseResponse +import com.heartz.app.data.dto.request.RequestDummyDto +import com.heartz.app.data.dto.response.ResponseDummyDto + +interface DummyRemoteDataSource { + suspend fun getDummies(request: RequestDummyDto): DummyBaseResponse +} diff --git a/app/src/main/java/com/heartz/app/data/datasourceimpl/local/DummyLocalDataSourceImpl.kt b/app/src/main/java/com/heartz/app/data/datasourceimpl/local/DummyLocalDataSourceImpl.kt new file mode 100644 index 00000000..1888d106 --- /dev/null +++ b/app/src/main/java/com/heartz/app/data/datasourceimpl/local/DummyLocalDataSourceImpl.kt @@ -0,0 +1,37 @@ +package org.sopt.dateroad.data.datalocal.datasourceimpl + +import android.content.Context +import androidx.datastore.preferences.core.booleanPreferencesKey +import androidx.datastore.preferences.core.edit +import androidx.datastore.preferences.preferencesDataStore +import dagger.hilt.android.qualifiers.ApplicationContext +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.map +import javax.inject.Inject + +private const val FILE_NAME = "date_road_datastore" + +private val Context.dataStore by preferencesDataStore(name = FILE_NAME) + +class DummyLocalDataSourceImpl + @Inject + constructor( + @ApplicationContext private val context: Context, + ) : DummyLocalDataSource { + companion object { + val IS_LOGIN = booleanPreferencesKey("is_login") + } + + override val isLogin: Flow = + context.dataStore.data.map { preferences -> + preferences[IS_LOGIN] ?: false + } + + override suspend fun setIsLogin(value: Boolean) { + context.dataStore.edit { it[IS_LOGIN] = value } + } + + override suspend fun clear() { + context.dataStore.edit { it.clear() } + } + } diff --git a/app/src/main/java/com/heartz/app/data/datasourceimpl/remote/DummyRemoteDataSourceImpl.kt b/app/src/main/java/com/heartz/app/data/datasourceimpl/remote/DummyRemoteDataSourceImpl.kt new file mode 100644 index 00000000..80669819 --- /dev/null +++ b/app/src/main/java/com/heartz/app/data/datasourceimpl/remote/DummyRemoteDataSourceImpl.kt @@ -0,0 +1,16 @@ +package com.heartz.app.data.datasourceimpl.remote + +import com.heartz.app.data.datasource.remote.DummyRemoteDataSource +import com.heartz.app.data.dto.base.DummyBaseResponse +import com.heartz.app.data.dto.request.RequestDummyDto +import com.heartz.app.data.dto.response.ResponseDummyDto +import com.heartz.app.data.service.DummyService +import javax.inject.Inject + +class DummyRemoteDataSourceImpl + @Inject + constructor( + private val dummyService: DummyService, + ) : DummyRemoteDataSource { + override suspend fun getDummies(request: RequestDummyDto): DummyBaseResponse = dummyService.getDummies(request) + } diff --git a/app/src/main/java/com/heartz/app/data/di/ApiModule.kt b/app/src/main/java/com/heartz/app/data/di/ApiModule.kt new file mode 100644 index 00000000..6de86a6e --- /dev/null +++ b/app/src/main/java/com/heartz/app/data/di/ApiModule.kt @@ -0,0 +1,17 @@ +package com.heartz.app.data.di + +import com.heartz.app.data.service.DummyService +import dagger.Module +import dagger.Provides +import dagger.hilt.InstallIn +import dagger.hilt.components.SingletonComponent +import retrofit2.Retrofit +import javax.inject.Singleton + +@Module +@InstallIn(SingletonComponent::class) +object ApiModule { + @Provides + @Singleton + fun providesDummyService(retrofit: Retrofit): DummyService = retrofit.create(DummyService::class.java) +} diff --git a/app/src/main/java/com/heartz/app/data/di/DataSourceModule.kt b/app/src/main/java/com/heartz/app/data/di/DataSourceModule.kt new file mode 100644 index 00000000..9bf03bb7 --- /dev/null +++ b/app/src/main/java/com/heartz/app/data/di/DataSourceModule.kt @@ -0,0 +1,23 @@ +package com.heartz.app.data.di + +import com.heartz.app.data.datasource.remote.DummyRemoteDataSource +import com.heartz.app.data.datasourceimpl.remote.DummyRemoteDataSourceImpl +import dagger.Binds +import dagger.Module +import dagger.hilt.InstallIn +import dagger.hilt.components.SingletonComponent +import org.sopt.dateroad.data.datalocal.datasourceimpl.DummyLocalDataSource +import org.sopt.dateroad.data.datalocal.datasourceimpl.DummyLocalDataSourceImpl +import javax.inject.Singleton + +@Module +@InstallIn(SingletonComponent::class) +abstract class DataSourceModule { + @Binds + @Singleton + abstract fun bindDummyRemoteDataSource(impl: DummyRemoteDataSourceImpl): DummyRemoteDataSource + + @Binds + @Singleton + abstract fun bindDummyLocalDataSource(impl: DummyLocalDataSourceImpl): DummyLocalDataSource +} diff --git a/app/src/main/java/com/heartz/app/data/di/NetworkModule.kt b/app/src/main/java/com/heartz/app/data/di/NetworkModule.kt new file mode 100644 index 00000000..4055cc60 --- /dev/null +++ b/app/src/main/java/com/heartz/app/data/di/NetworkModule.kt @@ -0,0 +1,51 @@ +package com.heartz.app.data.di + +import com.heartz.app.BuildConfig +import com.jakewharton.retrofit2.converter.kotlinx.serialization.asConverterFactory +import dagger.Module +import dagger.Provides +import dagger.hilt.InstallIn +import dagger.hilt.components.SingletonComponent +import kotlinx.serialization.ExperimentalSerializationApi +import kotlinx.serialization.json.Json +import okhttp3.MediaType.Companion.toMediaType +import okhttp3.OkHttpClient +import okhttp3.logging.HttpLoggingInterceptor +import retrofit2.Converter +import retrofit2.Retrofit +import javax.inject.Singleton + +@Module +@InstallIn(SingletonComponent::class) +object NetworkModule { + @Provides + @Singleton + fun providesLoggingInterceptor() = + HttpLoggingInterceptor().apply { + level = HttpLoggingInterceptor.Level.BODY + } + + @Provides + @Singleton + fun providesOkHttpClient(loggingInterceptor: HttpLoggingInterceptor): OkHttpClient = + OkHttpClient.Builder() + .addInterceptor(loggingInterceptor) + .build() + + @OptIn(ExperimentalSerializationApi::class) + @Provides + @Singleton + fun providesConverterFactory(): Converter.Factory = Json.asConverterFactory("application/json".toMediaType()) + + @Provides + @Singleton + fun providesRetrofit( + client: OkHttpClient, + converterFactory: Converter.Factory, + ): Retrofit = + Retrofit.Builder() + .baseUrl(BuildConfig.BASE_URL) + .client(client) + .addConverterFactory(converterFactory) + .build() +} diff --git a/app/src/main/java/com/heartz/app/data/di/RepositoryModule.kt b/app/src/main/java/com/heartz/app/data/di/RepositoryModule.kt new file mode 100644 index 00000000..b04fd17f --- /dev/null +++ b/app/src/main/java/com/heartz/app/data/di/RepositoryModule.kt @@ -0,0 +1,17 @@ +package com.heartz.app.data.di + +import com.heartz.app.data.repositoryimpl.DummyRepositoryImpl +import com.heartz.app.domain.repository.DummyRepository +import dagger.Binds +import dagger.Module +import dagger.hilt.InstallIn +import dagger.hilt.components.SingletonComponent +import javax.inject.Singleton + +@Module +@InstallIn(SingletonComponent::class) +abstract class RepositoryModule { + @Binds + @Singleton + abstract fun bindsDummyRepository(dummyRepositoryImpl: DummyRepositoryImpl): DummyRepository +} diff --git a/app/src/main/java/com/heartz/app/data/dto/base/DummyBaseResponse.kt b/app/src/main/java/com/heartz/app/data/dto/base/DummyBaseResponse.kt new file mode 100644 index 00000000..5fe032ac --- /dev/null +++ b/app/src/main/java/com/heartz/app/data/dto/base/DummyBaseResponse.kt @@ -0,0 +1,16 @@ +package com.heartz.app.data.dto.base + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +@Serializable +data class DummyBaseResponse( + @SerialName("success") + val success: Boolean, + @SerialName("code") + val code: String, + @SerialName("message") + val message: String, + @SerialName("data") + val data: T, +) diff --git a/app/src/main/java/com/heartz/app/data/dto/base/DummyNullableBaseResponse.kt b/app/src/main/java/com/heartz/app/data/dto/base/DummyNullableBaseResponse.kt new file mode 100644 index 00000000..b820de8d --- /dev/null +++ b/app/src/main/java/com/heartz/app/data/dto/base/DummyNullableBaseResponse.kt @@ -0,0 +1,16 @@ +package com.heartz.app.data.dto.base + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +@Serializable +data class DummyNullableBaseResponse( + @SerialName("success") + val success: Boolean, + @SerialName("code") + val code: String, + @SerialName("message") + val message: String, + @SerialName("data") + val data: T? = null, +) diff --git a/app/src/main/java/com/heartz/app/data/dto/request/RequestDummyDto.kt b/app/src/main/java/com/heartz/app/data/dto/request/RequestDummyDto.kt new file mode 100644 index 00000000..b1dffade --- /dev/null +++ b/app/src/main/java/com/heartz/app/data/dto/request/RequestDummyDto.kt @@ -0,0 +1,12 @@ +package com.heartz.app.data.dto.request + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +@Serializable +data class RequestDummyDto( + @SerialName("id") + val id: Int, + @SerialName("email") + val email: String, +) diff --git a/app/src/main/java/com/heartz/app/data/dto/response/ResponseDummyDto.kt b/app/src/main/java/com/heartz/app/data/dto/response/ResponseDummyDto.kt new file mode 100644 index 00000000..c3edb4a2 --- /dev/null +++ b/app/src/main/java/com/heartz/app/data/dto/response/ResponseDummyDto.kt @@ -0,0 +1,10 @@ +package com.heartz.app.data.dto.response + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +@Serializable +data class ResponseDummyDto( + @SerialName("info") + val info: List, +) diff --git a/app/src/main/java/com/heartz/app/data/mapper/todata/DummyMapper.kt b/app/src/main/java/com/heartz/app/data/mapper/todata/DummyMapper.kt new file mode 100644 index 00000000..85f20600 --- /dev/null +++ b/app/src/main/java/com/heartz/app/data/mapper/todata/DummyMapper.kt @@ -0,0 +1,10 @@ +package com.heartz.app.data.mapper.todata + +import com.heartz.app.data.dto.request.RequestDummyDto +import com.heartz.app.domain.model.Dummy + +fun Dummy.toData(): RequestDummyDto = + RequestDummyDto( + id = this.id, + email = this.email, + ) diff --git a/app/src/main/java/com/heartz/app/data/mapper/todomain/ResponseDummyDtoMapper.kt b/app/src/main/java/com/heartz/app/data/mapper/todomain/ResponseDummyDtoMapper.kt new file mode 100644 index 00000000..9296a50f --- /dev/null +++ b/app/src/main/java/com/heartz/app/data/mapper/todomain/ResponseDummyDtoMapper.kt @@ -0,0 +1,9 @@ +package com.heartz.app.data.mapper.todomain + +import com.heartz.app.data.dto.response.ResponseDummyDto +import com.heartz.app.domain.model.DummyResultModel + +fun ResponseDummyDto.toDomain(): DummyResultModel = + DummyResultModel( + info = info, + ) diff --git a/app/src/main/java/com/heartz/app/data/repositoryimpl/DummyRepositoryImpl.kt b/app/src/main/java/com/heartz/app/data/repositoryimpl/DummyRepositoryImpl.kt new file mode 100644 index 00000000..49d18725 --- /dev/null +++ b/app/src/main/java/com/heartz/app/data/repositoryimpl/DummyRepositoryImpl.kt @@ -0,0 +1,24 @@ +package com.heartz.app.data.repositoryimpl + +import com.heartz.app.data.mapper.todata.toData +import com.heartz.app.data.mapper.todomain.toDomain +import com.heartz.app.data.service.DummyService +import com.heartz.app.domain.model.Dummy +import com.heartz.app.domain.model.DummyResultModel +import com.heartz.app.domain.repository.DummyRepository +import javax.inject.Inject + +class DummyRepositoryImpl + @Inject + constructor( + private val dummyService: DummyService, + ) : DummyRepository { + override suspend fun getDummies(request: Dummy): Result = + runCatching { + val response = + dummyService.getDummies( + request = request.toData(), + ) + response.data.toDomain() + } + } diff --git a/app/src/main/java/com/heartz/app/data/service/DummyService.kt b/app/src/main/java/com/heartz/app/data/service/DummyService.kt new file mode 100644 index 00000000..33bb8672 --- /dev/null +++ b/app/src/main/java/com/heartz/app/data/service/DummyService.kt @@ -0,0 +1,14 @@ +package com.heartz.app.data.service + +import com.heartz.app.data.dto.base.DummyBaseResponse +import com.heartz.app.data.dto.request.RequestDummyDto +import com.heartz.app.data.dto.response.ResponseDummyDto +import retrofit2.http.Body +import retrofit2.http.GET + +interface DummyService { + @GET("/api/v1/service") + suspend fun getDummies( + @Body request: RequestDummyDto, + ): DummyBaseResponse +} diff --git a/app/src/main/java/com/heartz/app/domain/model/Dummy.kt b/app/src/main/java/com/heartz/app/domain/model/Dummy.kt new file mode 100644 index 00000000..ebcc13bd --- /dev/null +++ b/app/src/main/java/com/heartz/app/domain/model/Dummy.kt @@ -0,0 +1,6 @@ +package com.heartz.app.domain.model + +data class Dummy( + val id: Int, + val email: String, +) diff --git a/app/src/main/java/com/heartz/app/domain/model/DummyResultModel.kt b/app/src/main/java/com/heartz/app/domain/model/DummyResultModel.kt new file mode 100644 index 00000000..63bd03b0 --- /dev/null +++ b/app/src/main/java/com/heartz/app/domain/model/DummyResultModel.kt @@ -0,0 +1,5 @@ +package com.heartz.app.domain.model + +data class DummyResultModel( + val info: List, +) diff --git a/app/src/main/java/com/heartz/app/domain/repository/DummyRepository.kt b/app/src/main/java/com/heartz/app/domain/repository/DummyRepository.kt new file mode 100644 index 00000000..9c976824 --- /dev/null +++ b/app/src/main/java/com/heartz/app/domain/repository/DummyRepository.kt @@ -0,0 +1,8 @@ +package com.heartz.app.domain.repository + +import com.heartz.app.domain.model.Dummy +import com.heartz.app.domain.model.DummyResultModel + +interface DummyRepository { + suspend fun getDummies(request: Dummy): Result +} diff --git a/app/src/main/java/com/heartz/app/domain/usecase/DummyUseCase.kt b/app/src/main/java/com/heartz/app/domain/usecase/DummyUseCase.kt new file mode 100644 index 00000000..03c76369 --- /dev/null +++ b/app/src/main/java/com/heartz/app/domain/usecase/DummyUseCase.kt @@ -0,0 +1,5 @@ +package com.heartz.app.domain.usecase + +// / TODO: usecase는 생각이 많은데 고민을 조금 해봐야 겠습니다! + +interface DummyUseCase diff --git a/app/src/main/java/com/heartz/app/presentation/graph/FigureScreen.kt b/app/src/main/java/com/heartz/app/presentation/graph/FigureScreen.kt new file mode 100644 index 00000000..b7417000 --- /dev/null +++ b/app/src/main/java/com/heartz/app/presentation/graph/FigureScreen.kt @@ -0,0 +1,28 @@ +package com.heartz.app.presentation.graph + +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color + +@Composable +fun FigureScreen() { + Column( + modifier = + Modifier + .fillMaxSize() + .background(Color.White), + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.Center, + ) { + Text( + text = "figure Screen", + color = Color.Black, + ) + } +} diff --git a/app/src/main/java/com/heartz/app/presentation/graph/navigation/FigureNavigation.kt b/app/src/main/java/com/heartz/app/presentation/graph/navigation/FigureNavigation.kt new file mode 100644 index 00000000..2ea2c523 --- /dev/null +++ b/app/src/main/java/com/heartz/app/presentation/graph/navigation/FigureNavigation.kt @@ -0,0 +1,22 @@ +package com.heartz.app.presentation.graph.navigation + +import androidx.navigation.NavController +import androidx.navigation.NavGraphBuilder +import androidx.navigation.NavOptions +import androidx.navigation.compose.composable +import com.heartz.app.core.navigation.MainTabRoute +import com.heartz.app.presentation.graph.FigureScreen +import kotlinx.serialization.Serializable + +fun NavController.navigateToFigure(navOptions: NavOptions? = null) { + navigate(Figure, navOptions) +} + +fun NavGraphBuilder.figureGraph() { + composable
{ + FigureScreen() + } +} + +@Serializable +data object Figure : MainTabRoute diff --git a/app/src/main/java/com/heartz/app/presentation/home/HomeScreen.kt b/app/src/main/java/com/heartz/app/presentation/home/HomeScreen.kt new file mode 100644 index 00000000..2b9fbdb6 --- /dev/null +++ b/app/src/main/java/com/heartz/app/presentation/home/HomeScreen.kt @@ -0,0 +1,50 @@ +package com.heartz.app.presentation.home + +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.collectAsState +import androidx.compose.runtime.getValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import com.heartz.app.core.state.UiState +import androidx.hilt.navigation.compose.hiltViewModel + +@Composable +fun HomeScreen( + viewModel: HomeViewModel = hiltViewModel() +) { + val uiState by viewModel.uiState.collectAsState() + + Column( + modifier = Modifier + .fillMaxSize() + .background(Color.White), + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.Center + ) { + when (val state = uiState.user) { + is UiState.Loading -> { + Text(text = "로딩 중...", color = Color.Gray) + } + + is UiState.Success -> { + state.data.info.forEachIndexed { index, item -> + Text(text = "Info[$index]: $item") + } + } + + is UiState.Failure -> { + Text(text = "에러: ${state.msg}", color = Color.Red) + } + + UiState.Empty -> { + Text(text = "데이터가 없습니다.") + } + } + } +} diff --git a/app/src/main/java/com/heartz/app/presentation/home/HomeState.kt b/app/src/main/java/com/heartz/app/presentation/home/HomeState.kt new file mode 100644 index 00000000..5f2de3fa --- /dev/null +++ b/app/src/main/java/com/heartz/app/presentation/home/HomeState.kt @@ -0,0 +1,8 @@ +package com.heartz.app.presentation.home + +import com.heartz.app.core.state.UiState +import com.heartz.app.domain.model.DummyResultModel + +data class HomeState( + var user: UiState = UiState.Loading +) \ No newline at end of file diff --git a/app/src/main/java/com/heartz/app/presentation/home/HomeViewModel.kt b/app/src/main/java/com/heartz/app/presentation/home/HomeViewModel.kt new file mode 100644 index 00000000..a11daa56 --- /dev/null +++ b/app/src/main/java/com/heartz/app/presentation/home/HomeViewModel.kt @@ -0,0 +1,41 @@ +package com.heartz.app.presentation.home + +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import com.heartz.app.core.state.UiState +import com.heartz.app.domain.model.Dummy +import com.heartz.app.domain.repository.DummyRepository +import dagger.hilt.android.lifecycle.HiltViewModel +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.update +import kotlinx.coroutines.launch +import javax.inject.Inject + + +@HiltViewModel +class HomeViewModel @Inject constructor( + private val dummyRepository: DummyRepository +) : ViewModel() { + var uiState = MutableStateFlow(HomeState()) + private set + + fun getDummies(id: Int, email: String) { + viewModelScope.launch { + dummyRepository.getDummies( + request = Dummy(id = id, email = email) + ) + .onSuccess { response -> + uiState.update { + it.copy( + user = UiState.Success(response) + ) + } + } + .onFailure { e -> + uiState.update { + it.copy(user = UiState.Failure(e.message ?: "오류 발생")) + } + } + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/heartz/app/presentation/home/navigation/HomeNavigation.kt b/app/src/main/java/com/heartz/app/presentation/home/navigation/HomeNavigation.kt new file mode 100644 index 00000000..7333e77b --- /dev/null +++ b/app/src/main/java/com/heartz/app/presentation/home/navigation/HomeNavigation.kt @@ -0,0 +1,22 @@ +package com.heartz.app.presentation.home.navigation + +import androidx.navigation.NavController +import androidx.navigation.NavGraphBuilder +import androidx.navigation.NavOptions +import androidx.navigation.compose.composable +import com.heartz.app.core.navigation.MainTabRoute +import com.heartz.app.presentation.home.HomeScreen +import kotlinx.serialization.Serializable + +fun NavController.navigateToHome(navOptions: NavOptions? = null) { + navigate(Home, navOptions) +} + +fun NavGraphBuilder.homeGraph() { + composable { + HomeScreen() + } +} + +@Serializable +data object Home : MainTabRoute diff --git a/app/src/main/java/com/heartz/app/presentation/main/MainActivity.kt b/app/src/main/java/com/heartz/app/presentation/main/MainActivity.kt new file mode 100644 index 00000000..f499a8c9 --- /dev/null +++ b/app/src/main/java/com/heartz/app/presentation/main/MainActivity.kt @@ -0,0 +1,21 @@ +package com.heartz.app.presentation.main + +import android.os.Bundle +import androidx.activity.ComponentActivity +import androidx.activity.compose.setContent +import androidx.activity.enableEdgeToEdge +import com.heartz.app.core.designsystem.ui.theme.HeartzTheme +import dagger.hilt.android.AndroidEntryPoint + +@AndroidEntryPoint +class MainActivity : ComponentActivity() { + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + enableEdgeToEdge() + setContent { + HeartzTheme { + MainScreen() + } + } + } +} diff --git a/app/src/main/java/com/heartz/app/presentation/main/MainNavHost.kt b/app/src/main/java/com/heartz/app/presentation/main/MainNavHost.kt new file mode 100644 index 00000000..943f22a5 --- /dev/null +++ b/app/src/main/java/com/heartz/app/presentation/main/MainNavHost.kt @@ -0,0 +1,31 @@ +package com.heartz.app.presentation.main + +import androidx.compose.animation.EnterTransition +import androidx.compose.animation.ExitTransition +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.navigation.compose.NavHost +import com.heartz.app.presentation.graph.navigation.figureGraph +import com.heartz.app.presentation.home.navigation.homeGraph +import com.heartz.app.presentation.mypage.navigation.mypageGraph +import com.heartz.app.presentation.quest.navigation.questGraph + +@Composable +fun MainNavHost( + navigator: MainNavigator, + modifier: Modifier = Modifier, +) { + NavHost( + enterTransition = { EnterTransition.None }, + exitTransition = { ExitTransition.None }, + popEnterTransition = { EnterTransition.None }, + popExitTransition = { ExitTransition.None }, + navController = navigator.navController, + startDestination = navigator.startDestination, + ) { + homeGraph() + questGraph() + figureGraph() + mypageGraph() + } +} diff --git a/app/src/main/java/com/heartz/app/presentation/main/MainNavTab.kt b/app/src/main/java/com/heartz/app/presentation/main/MainNavTab.kt new file mode 100644 index 00000000..7f4fbaa7 --- /dev/null +++ b/app/src/main/java/com/heartz/app/presentation/main/MainNavTab.kt @@ -0,0 +1,59 @@ +package com.heartz.app.presentation.main + +import androidx.annotation.DrawableRes +import androidx.annotation.StringRes +import androidx.compose.runtime.Composable +import com.heartz.app.R.drawable.ic_folder_open +import com.heartz.app.R.drawable.ic_graph +import com.heartz.app.R.drawable.ic_home +import com.heartz.app.R.drawable.ic_user +import com.heartz.app.R.string.ic_figure_desc +import com.heartz.app.R.string.ic_home_desc +import com.heartz.app.R.string.ic_mypage_desc +import com.heartz.app.R.string.ic_quest_desc +import com.heartz.app.core.navigation.MainTabRoute +import com.heartz.app.core.navigation.Route +import com.heartz.app.presentation.graph.navigation.Figure +import com.heartz.app.presentation.home.navigation.Home +import com.heartz.app.presentation.mypage.navigation.Mypage +import com.heartz.app.presentation.quest.navigation.Quest + +enum class MainNavTab( + @DrawableRes val icon: Int, + @StringRes val contentDescription: Int, + val route: MainTabRoute, +) { + QUEST( + icon = ic_folder_open, + contentDescription = ic_quest_desc, + route = Quest, + ), + HOME( + icon = ic_home, + contentDescription = ic_home_desc, + route = Home, + ), + FIGURE( + icon = ic_graph, + contentDescription = ic_figure_desc, + route = Figure, + ), + MYPAGE( + icon = ic_user, + contentDescription = ic_mypage_desc, + route = Mypage, + ), + ; + + companion object { + @Composable + fun find(predicate: @Composable (MainTabRoute) -> Boolean): MainNavTab? { + return entries.find { predicate(it.route) } + } + + @Composable + fun contains(predicate: @Composable (Route) -> Boolean): Boolean { + return entries.map { it.route }.any { predicate(it) } + } + } +} diff --git a/app/src/main/java/com/heartz/app/presentation/main/MainNavigator.kt b/app/src/main/java/com/heartz/app/presentation/main/MainNavigator.kt new file mode 100644 index 00000000..f4f64768 --- /dev/null +++ b/app/src/main/java/com/heartz/app/presentation/main/MainNavigator.kt @@ -0,0 +1,68 @@ +package com.heartz.app.presentation.main + +import androidx.compose.runtime.Composable +import androidx.compose.runtime.remember +import androidx.navigation.NavDestination +import androidx.navigation.NavDestination.Companion.hasRoute +import androidx.navigation.NavHostController +import androidx.navigation.compose.currentBackStackEntryAsState +import androidx.navigation.compose.rememberNavController +import androidx.navigation.navOptions +import com.heartz.app.presentation.graph.navigation.navigateToFigure +import com.heartz.app.presentation.home.navigation.Home +import com.heartz.app.presentation.home.navigation.navigateToHome +import com.heartz.app.presentation.mypage.navigation.navigateToMypage +import com.heartz.app.presentation.quest.navigation.navigateToQuest + +class MainNavigator( + val navController: NavHostController, +) { + private val currentDestination: NavDestination? + @Composable get() = + navController + .currentBackStackEntryAsState().value?.destination + + val startDestination = Home + + val currentTab: MainNavTab? + @Composable get() = + MainNavTab.find { tab -> + currentDestination?.hasRoute(tab::class) == true + } + + fun navigate(tab: MainNavTab) { + val navOptions = + navOptions { + navController.currentDestination?.route?.let { + popUpTo(it) { + inclusive = true + saveState = true + } + } + launchSingleTop = true + restoreState = true + } + when (tab) { + MainNavTab.QUEST -> navController.navigateToQuest(navOptions) + MainNavTab.HOME -> navController.navigateToHome(navOptions) + MainNavTab.FIGURE -> navController.navigateToFigure(navOptions) + MainNavTab.MYPAGE -> navController.navigateToMypage(navOptions) + } + } + + @Composable + fun showBottomBar() = + MainNavTab.contains { + currentDestination?.hasRoute(it::class) == true + } + + fun navigateUp() { + navController.navigateUp() + } +} + +@Composable +fun rememberMainNavigator(navController: NavHostController = rememberNavController()): MainNavigator = + remember(navController) { + MainNavigator(navController) + } diff --git a/app/src/main/java/com/heartz/app/presentation/main/MainScreen.kt b/app/src/main/java/com/heartz/app/presentation/main/MainScreen.kt new file mode 100644 index 00000000..749600ac --- /dev/null +++ b/app/src/main/java/com/heartz/app/presentation/main/MainScreen.kt @@ -0,0 +1,36 @@ +package com.heartz.app.presentation.main + +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.systemBarsPadding +import androidx.compose.material3.Scaffold +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import com.heartz.app.presentation.main.component.MainBottomBar +import kotlinx.collections.immutable.toImmutableList + +@Composable +fun MainScreen(navigator: MainNavigator = rememberMainNavigator()) { + Scaffold( + bottomBar = { + MainBottomBar( + visible = navigator.showBottomBar(), + tabs = MainNavTab.entries.toImmutableList(), + currentTab = navigator.currentTab, + onTabSelected = navigator::navigate, + ) + }, + modifier = + Modifier + .background(Color.White) + .systemBarsPadding() + .fillMaxSize(), + ) { innerPadding -> + MainNavHost( + navigator = navigator, + modifier = Modifier.padding(innerPadding), + ) + } +} diff --git a/app/src/main/java/com/heartz/app/presentation/main/component/MainBottomBar.kt b/app/src/main/java/com/heartz/app/presentation/main/component/MainBottomBar.kt new file mode 100644 index 00000000..f19a8e07 --- /dev/null +++ b/app/src/main/java/com/heartz/app/presentation/main/component/MainBottomBar.kt @@ -0,0 +1,114 @@ +package com.heartz.app.presentation.main.component + +import androidx.compose.animation.AnimatedVisibility +import androidx.compose.animation.EnterTransition +import androidx.compose.animation.ExitTransition +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.RowScope +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.navigationBarsPadding +import androidx.compose.foundation.layout.padding +import androidx.compose.material3.Icon +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.key +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.vector.ImageVector +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.res.vectorResource +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import com.heartz.app.core.designsystem.ui.theme.HeartzTheme +import com.heartz.app.core.designsystem.ui.theme.Pink80 +import com.heartz.app.core.designsystem.ui.theme.Red80 +import com.heartz.app.core.util.noRippleClickable +import com.heartz.app.presentation.main.MainNavTab +import kotlinx.collections.immutable.ImmutableList +import kotlinx.collections.immutable.toImmutableList + +@Composable +fun MainBottomBar( + visible: Boolean, + tabs: ImmutableList, + currentTab: MainNavTab?, + onTabSelected: (MainNavTab) -> Unit, +) { + AnimatedVisibility( + visible = visible, + enter = EnterTransition.None, + exit = ExitTransition.None, + ) { + Column( + modifier = + Modifier + .background(Color.White), + ) { + Row( + modifier = + Modifier + .navigationBarsPadding() + .fillMaxWidth() + .padding(vertical = 21.dp), + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.SpaceEvenly, + ) { + tabs.forEach { tab -> + key(tab.route) { + val selected = currentTab == tab + MainBottomBarItem( + tab = tab, + selected = selected, + onClick = { onTabSelected(tab) }, + ) + } + } + } + } + } +} + +@Composable +fun RowScope.MainBottomBarItem( + modifier: Modifier = Modifier, + tab: MainNavTab, + selected: Boolean, + onClick: () -> Unit, +) { + val bottomItemColor = if (selected) Red80 else Pink80 + Column( + modifier = + modifier + .noRippleClickable(onClick = onClick) + .weight(1f), + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.spacedBy(1.dp), + ) { + Icon( + imageVector = ImageVector.vectorResource(tab.icon), + contentDescription = stringResource(tab.contentDescription), + tint = bottomItemColor, + ) + } +} + +@Preview +@Composable +private fun MainBottomBarPreview() { + HeartzTheme { + var currentTab by remember { mutableStateOf(MainNavTab.HOME) } + MainBottomBar( + visible = true, + tabs = MainNavTab.entries.toImmutableList(), + currentTab = currentTab, + onTabSelected = { currentTab = it }, + ) + } +} diff --git a/app/src/main/java/com/heartz/app/presentation/mypage/MypageScreen.kt b/app/src/main/java/com/heartz/app/presentation/mypage/MypageScreen.kt new file mode 100644 index 00000000..8c065eeb --- /dev/null +++ b/app/src/main/java/com/heartz/app/presentation/mypage/MypageScreen.kt @@ -0,0 +1,28 @@ +package com.heartz.app.presentation.mypage + +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color + +@Composable +fun MypageScreen() { + Column( + modifier = + Modifier + .fillMaxSize() + .background(Color.White), + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.Center, + ) { + Text( + text = "mypage Screen", + color = Color.Black, + ) + } +} diff --git a/app/src/main/java/com/heartz/app/presentation/mypage/navigation/MypageNavigation.kt b/app/src/main/java/com/heartz/app/presentation/mypage/navigation/MypageNavigation.kt new file mode 100644 index 00000000..89f83007 --- /dev/null +++ b/app/src/main/java/com/heartz/app/presentation/mypage/navigation/MypageNavigation.kt @@ -0,0 +1,22 @@ +package com.heartz.app.presentation.mypage.navigation + +import androidx.navigation.NavController +import androidx.navigation.NavGraphBuilder +import androidx.navigation.NavOptions +import androidx.navigation.compose.composable +import com.heartz.app.core.navigation.MainTabRoute +import com.heartz.app.presentation.mypage.MypageScreen +import kotlinx.serialization.Serializable + +fun NavController.navigateToMypage(navOptions: NavOptions? = null) { + navigate(Mypage, navOptions) +} + +fun NavGraphBuilder.mypageGraph() { + composable { + MypageScreen() + } +} + +@Serializable +data object Mypage : MainTabRoute diff --git a/app/src/main/java/com/heartz/app/presentation/quest/QuestScreen.kt b/app/src/main/java/com/heartz/app/presentation/quest/QuestScreen.kt new file mode 100644 index 00000000..9e503e75 --- /dev/null +++ b/app/src/main/java/com/heartz/app/presentation/quest/QuestScreen.kt @@ -0,0 +1,28 @@ +package com.heartz.app.presentation.quest + +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color + +@Composable +fun QuestScreen() { + Column( + modifier = + Modifier + .fillMaxSize() + .background(Color.White), + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.Center, + ) { + Text( + text = "quest Screen", + color = Color.Black, + ) + } +} diff --git a/app/src/main/java/com/heartz/app/presentation/quest/navigation/QuestNavigation.kt b/app/src/main/java/com/heartz/app/presentation/quest/navigation/QuestNavigation.kt new file mode 100644 index 00000000..fabfda56 --- /dev/null +++ b/app/src/main/java/com/heartz/app/presentation/quest/navigation/QuestNavigation.kt @@ -0,0 +1,22 @@ +package com.heartz.app.presentation.quest.navigation + +import androidx.navigation.NavController +import androidx.navigation.NavGraphBuilder +import androidx.navigation.NavOptions +import androidx.navigation.compose.composable +import com.heartz.app.core.navigation.MainTabRoute +import com.heartz.app.presentation.quest.QuestScreen +import kotlinx.serialization.Serializable + +fun NavController.navigateToQuest(navOptions: NavOptions? = null) { + navigate(Quest, navOptions) +} + +fun NavGraphBuilder.questGraph() { + composable { + QuestScreen() + } +} + +@Serializable +data object Quest : MainTabRoute diff --git a/app/src/main/res/drawable/ic_folder_open.xml b/app/src/main/res/drawable/ic_folder_open.xml new file mode 100644 index 00000000..835e8fcc --- /dev/null +++ b/app/src/main/res/drawable/ic_folder_open.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/drawable/ic_graph.xml b/app/src/main/res/drawable/ic_graph.xml new file mode 100644 index 00000000..d8994e7a --- /dev/null +++ b/app/src/main/res/drawable/ic_graph.xml @@ -0,0 +1,18 @@ + + + + + diff --git a/app/src/main/res/drawable/ic_home.xml b/app/src/main/res/drawable/ic_home.xml new file mode 100644 index 00000000..c53ccc3b --- /dev/null +++ b/app/src/main/res/drawable/ic_home.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/drawable/ic_user.xml b/app/src/main/res/drawable/ic_user.xml new file mode 100644 index 00000000..372ba8aa --- /dev/null +++ b/app/src/main/res/drawable/ic_user.xml @@ -0,0 +1,16 @@ + + + + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 1e86fbeb..114d6664 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1,3 +1,10 @@ heartz + + + 퀘스트 + + 그래프 + 마이페이지 + \ No newline at end of file diff --git a/app/src/test/java/com/android/heartz/ExampleUnitTest.kt b/app/src/test/java/com/android/heartz/ExampleUnitTest.kt index bad101c1..a2a4ebf9 100644 --- a/app/src/test/java/com/android/heartz/ExampleUnitTest.kt +++ b/app/src/test/java/com/android/heartz/ExampleUnitTest.kt @@ -1,17 +1,11 @@ package com.android.heartz +import org.junit.Assert.assertEquals import org.junit.Test -import org.junit.Assert.* - -/** - * Example local unit test, which will execute on the development machine (host). - * - * See [testing documentation](http://d.android.com/tools/testing). - */ class ExampleUnitTest { @Test fun addition_isCorrect() { assertEquals(4, 2 + 2) } -} \ No newline at end of file +} diff --git a/build.gradle.kts b/build.gradle.kts index 922f5511..a619be0c 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,5 +1,12 @@ // Top-level build file where you can add configuration options common to all sub-projects/modules. + plugins { alias(libs.plugins.android.application) apply false alias(libs.plugins.kotlin.android) apply false -} \ No newline at end of file + alias(libs.plugins.kotlin.compose) apply false + alias(libs.plugins.kotlin.serialization) apply false + alias(libs.plugins.hilt) apply false + alias(libs.plugins.ksp) apply false + alias(libs.plugins.kotlin.parcelize) apply false + alias(libs.plugins.ktlint) apply false +} diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 6c9cfac2..cb20bd63 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,22 +1,154 @@ [versions] -agp = "8.9.1" + +# Kotlin +agp = "8.9.2" kotlin = "2.0.21" +kotlinParcelize = "1.8.20" +kotlinxCollectionsImmutable = "0.3.5" + +# AndroidX coreKtx = "1.16.0" +appcompat = "1.7.1" +material = "1.12.0" +material3 = "1.2.0" +lifecycle = "2.8.1" +activityCompose = "1.9.0" +composeBom = "2025.04.01" +navigationCompose = "2.8.9" + +# Test junit = "4.13.2" junitVersion = "1.2.1" espressoCore = "3.6.1" -appcompat = "1.7.1" -material = "1.12.0" +uiTest = "1.6.7" + +# Firebase +firebaseBom = "32.7.4" +crashlytics = "18.6.2" + +# Network +okhttpBom = "4.12.0" +retrofit = "2.11.0" +serialization = "1.6.3" + +# Hilt +hilt = "2.51.1" +hiltCompiler = "2.51.1" +hiltNavigationCompose = "1.2.0" + +# Coil +coil = "2.6.0" + +# Timber +timber = "5.0.1" + +# Kakao +kakao = "2.21.4" + +#Third Party +ksp = "2.0.21-1.0.25" +ktlint = "12.3.0" + + +[plugins] +android-application = { id = "com.android.application", version.ref = "agp" } +kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" } +kotlin-compose = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" } +kotlin-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" } +ksp = { id = "com.google.devtools.ksp", version.ref = "ksp" } +kotlin-parcelize = { id = "org.jetbrains.kotlin.plugin.parcelize", version.ref = "kotlinParcelize" } +ktlint = { id = "org.jlleitschuh.gradle.ktlint", version.ref = "ktlint" } +hilt = { id = "com.google.dagger.hilt.android", version.ref = "hilt" } [libraries] +# AndroidX androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" } +androidx-appcompat = { group = "androidx.appcompat", name = "appcompat", version.ref = "appcompat" } +material = { group = "com.google.android.material", name = "material", version.ref = "material" } +material3 = { group = "androidx.compose.material3", name = "material3", version.ref = "material3" } +androidx-lifecycle-runtime = { group = "androidx.lifecycle", name = "lifecycle-runtime-ktx", version.ref = "lifecycle" } +androidx-lifecycle-viewmodel = { group = "androidx.lifecycle", name = "lifecycle-viewmodel-ktx", version.ref = "lifecycle" } +androidx-activity-compose = { group = "androidx.activity", name = "activity-compose", version.ref = "activityCompose" } +androidx-navigation-compose = { group = "androidx.navigation", name = "navigation-compose", version.ref = "navigationCompose" } +androidx-compose-bom = { group = "androidx.compose", name = "compose-bom", version.ref = "composeBom" } +kotlinx-collections-immutable = { module = "org.jetbrains.kotlinx:kotlinx-collections-immutable", version.ref = "kotlinxCollectionsImmutable" } +androidx-ui = { group = "androidx.compose.ui", name = "ui" } +androidx-ui-graphics = { group = "androidx.compose.ui", name = "ui-graphics" } +androidx-ui-tooling = { group = "androidx.compose.ui", name = "ui-tooling" } + +# Test junit = { group = "junit", name = "junit", version.ref = "junit" } androidx-junit = { group = "androidx.test.ext", name = "junit", version.ref = "junitVersion" } androidx-espresso-core = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "espressoCore" } -androidx-appcompat = { group = "androidx.appcompat", name = "appcompat", version.ref = "appcompat" } -material = { group = "com.google.android.material", name = "material", version.ref = "material" } +androidx-ui-test-junit = { group = "androidx.compose.ui", name = "ui-test-junit4", version.ref = "uiTest" } +androidx-ui-test-manifest = { group = "androidx.compose.ui", name = "ui-test-manifest", version.ref = "uiTest" } + +# Firebase +google-firebase-bom = { group = "com.google.firebase", name = "firebase-bom", version.ref = "firebaseBom" } +google-firebase-crashlytics = { group = "com.google.firebase", name = "firebase-crashlytics", version.ref = "crashlytics" } + +# Network +okhttp-bom = { group = "com.squareup.okhttp3", name = "okhttp-bom", version.ref = "okhttpBom" } +okhttp = { group = "com.squareup.okhttp3", name = "okhttp" } +logging-interceptor = { group = "com.squareup.okhttp3", name = "logging-interceptor" } +retrofit = { group = "com.squareup.retrofit2", name = "retrofit", version.ref = "retrofit" } +retrofit-serialization = { group = "com.jakewharton.retrofit", name = "retrofit2-kotlinx-serialization-converter", version = "0.8.0" } +kotlinx-serialization-json = { group = "org.jetbrains.kotlinx", name = "kotlinx-serialization-json", version.ref = "serialization" } + +# Hilt +hilt-android = { group = "com.google.dagger", name = "hilt-android", version.ref = "hilt" } +hilt-compiler = { group = "com.google.dagger", name = "hilt-compiler", version.ref = "hiltCompiler" } +androidx-hilt-navigation-compose = { group = "androidx.hilt", name = "hilt-navigation-compose", version.ref = "hiltNavigationCompose" } + + +# Coil +coil-compose = { group = "io.coil-kt", name = "coil-compose", version.ref = "coil" } + +# Timber +timber = { group = "com.jakewharton.timber", name = "timber", version.ref = "timber" } + +# Kakao +kakao-v2-user = { group = "com.kakao.sdk", name = "v2-user", version.ref = "kakao" } + +[bundles] +androidx = [ + "androidx-core-ktx", + "androidx-appcompat", + "material", + "material3", + "androidx-lifecycle-runtime", + "androidx-lifecycle-viewmodel", + "androidx-activity-compose", + "androidx-navigation-compose" +] + +test = [ + "androidx-ui-test-junit", + "androidx-ui-test-manifest", + "androidx-junit", + "androidx-espresso-core" +] + +debug = [ + "androidx-ui-test-manifest" +] + +okhttp = [ + "okhttp", + "logging-interceptor" +] + +retrofit = [ + "retrofit", + "retrofit-serialization" +] + +hilt = [ + "hilt-android", + "androidx-hilt-navigation-compose" +] -[plugins] -android-application = { id = "com.android.application", version.ref = "agp" } -kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" } +kakao = [ + "kakao-v2-user" +] diff --git a/settings.gradle.kts b/settings.gradle.kts index 2a5a63dd..4350d7b8 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -16,6 +16,7 @@ dependencyResolutionManagement { repositories { google() mavenCentral() + maven { url = uri("https://devrepo.kakao.com/nexus/content/groups/public") } } } From 34e80617920081c9788876ebb5960747a3b50dc3 Mon Sep 17 00:00:00 2001 From: fredLeeJH Date: Fri, 20 Jun 2025 16:39:17 +0900 Subject: [PATCH 2/9] =?UTF-8?q?#1=20[init]=20:=20=ED=94=84=EB=A1=9C?= =?UTF-8?q?=EC=A0=9D=ED=8A=B8=20=EA=B8=B0=EC=B4=88=20=EC=84=B8=ED=8C=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/ktlint.yml | 26 -------------------------- 1 file changed, 26 deletions(-) delete mode 100644 .github/workflows/ktlint.yml diff --git a/.github/workflows/ktlint.yml b/.github/workflows/ktlint.yml deleted file mode 100644 index 0ab21ba7..00000000 --- a/.github/workflows/ktlint.yml +++ /dev/null @@ -1,26 +0,0 @@ -name: ktlint Check - -on: - pull_request: - branches: [ develop ] - -jobs: - ktlint: - name: Run ktlint - runs-on: ubuntu-latest - - steps: - - name: Checkout Code - uses: actions/checkout@v4 - - - name: Set up JDK 17 - uses: actions/setup-java@v4 - with: - distribution: 'temurin' - java-version: 17 - - - name: Grant execute permission for gradlew - run: chmod +x ./gradlew - - - name: Run ktlint check - run: ./gradlew ktlintCheck From ae20ee0e2ad9dfd59061161b752a7d33635bb05f Mon Sep 17 00:00:00 2001 From: fredLeeJH Date: Sat, 21 Jun 2025 16:02:13 +0900 Subject: [PATCH 3/9] =?UTF-8?q?#1=20[chore]=20:=20=ED=94=84=EB=A1=9C?= =?UTF-8?q?=EC=A0=9D=ED=8A=B8=20=EA=B8=B0=EC=B4=88=20=EC=84=B8=ED=8C=85=20?= =?UTF-8?q?=EC=88=98=EC=A0=95=20=EB=B0=8F=20ktlint=20=EB=B2=84=EC=A0=84=20?= =?UTF-8?q?=EB=8B=A4=EC=9A=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/build.gradle.kts | 8 +++-- .../app/core/designsystem/ui/theme/Color.kt | 2 +- .../app/core/designsystem/ui/theme/Theme.kt | 2 +- .../core/designsystem/ui/theme/TypoGraphy.kt | 12 +++---- .../java/com/heartz/app/core/state/UiState.kt | 4 +-- .../com/heartz/app/core/util/ModifierExt.kt | 2 +- .../local/DummyLocalDataSourceImpl.kt | 36 +++++++++---------- .../remote/DummyRemoteDataSourceImpl.kt | 15 ++++---- .../java/com/heartz/app/data/di/ApiModule.kt | 6 ++-- .../heartz/app/data/di/DataSourceModule.kt | 2 +- .../com/heartz/app/data/di/NetworkModule.kt | 8 +++-- .../app/data/dto/base/DummyBaseResponse.kt | 2 +- .../dto/base/DummyNullableBaseResponse.kt | 2 +- .../app/data/dto/request/RequestDummyDto.kt | 2 +- .../app/data/dto/response/ResponseDummyDto.kt | 2 +- .../app/data/mapper/todata/DummyMapper.kt | 2 +- .../mapper/todomain/ResponseDummyDtoMapper.kt | 2 +- .../repositoryimpl/DummyRepositoryImpl.kt | 26 +++++++------- .../heartz/app/data/service/DummyService.kt | 2 +- .../java/com/heartz/app/domain/model/Dummy.kt | 2 +- .../app/domain/model/DummyResultModel.kt | 2 +- .../app/presentation/graph/FigureScreen.kt | 10 +++--- .../app/presentation/home/HomeScreen.kt | 9 +++-- .../heartz/app/presentation/home/HomeState.kt | 2 +- .../app/presentation/home/HomeViewModel.kt | 14 +++++--- .../app/presentation/main/MainNavHost.kt | 4 +-- .../app/presentation/main/MainNavTab.kt | 12 +++---- .../app/presentation/main/MainNavigator.kt | 11 +++--- .../app/presentation/main/MainScreen.kt | 12 +++---- .../main/component/MainBottomBar.kt | 34 +++++++++--------- .../app/presentation/mypage/MypageScreen.kt | 10 +++--- .../app/presentation/quest/QuestScreen.kt | 10 +++--- gradle/libs.versions.toml | 5 ++- 33 files changed, 146 insertions(+), 128 deletions(-) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 1af23e4d..59c7aa8c 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -30,7 +30,11 @@ android { buildConfigField("String", "BASE_URL", properties["base.url"].toString()) // TODO: kakao social login - buildConfigField("String", "KAKAO_NATIVE_APP_KEY", properties["kakao.native.app.key"].toString()) + buildConfigField( + "String", + "KAKAO_NATIVE_APP_KEY", + properties["kakao.native.app.key"].toString() + ) } buildTypes { @@ -38,7 +42,7 @@ android { isMinifyEnabled = false proguardFiles( getDefaultProguardFile("proguard-android-optimize.txt"), - "proguard-rules.pro", + "proguard-rules.pro" ) } } diff --git a/app/src/main/java/com/heartz/app/core/designsystem/ui/theme/Color.kt b/app/src/main/java/com/heartz/app/core/designsystem/ui/theme/Color.kt index 31e94702..97bca443 100644 --- a/app/src/main/java/com/heartz/app/core/designsystem/ui/theme/Color.kt +++ b/app/src/main/java/com/heartz/app/core/designsystem/ui/theme/Color.kt @@ -9,5 +9,5 @@ val Pink80 = Color(0xFFFFB0B0) val HeartzColorScheme = darkColorScheme( primary = Red80, - secondary = Pink80, + secondary = Pink80 ) diff --git a/app/src/main/java/com/heartz/app/core/designsystem/ui/theme/Theme.kt b/app/src/main/java/com/heartz/app/core/designsystem/ui/theme/Theme.kt index ac161080..608d4b9d 100644 --- a/app/src/main/java/com/heartz/app/core/designsystem/ui/theme/Theme.kt +++ b/app/src/main/java/com/heartz/app/core/designsystem/ui/theme/Theme.kt @@ -8,6 +8,6 @@ fun HeartzTheme(content: @Composable () -> Unit) { MaterialTheme( colorScheme = HeartzColorScheme, typography = Typography, - content = content, + content = content ) } diff --git a/app/src/main/java/com/heartz/app/core/designsystem/ui/theme/TypoGraphy.kt b/app/src/main/java/com/heartz/app/core/designsystem/ui/theme/TypoGraphy.kt index f3385656..8d06639d 100644 --- a/app/src/main/java/com/heartz/app/core/designsystem/ui/theme/TypoGraphy.kt +++ b/app/src/main/java/com/heartz/app/core/designsystem/ui/theme/TypoGraphy.kt @@ -9,10 +9,10 @@ import androidx.compose.ui.unit.sp val Typography = Typography( bodyLarge = - TextStyle( - fontFamily = FontFamily.Default, - fontWeight = FontWeight.SemiBold, - fontSize = 16.sp, - lineHeight = 24.sp, - ), + TextStyle( + fontFamily = FontFamily.Default, + fontWeight = FontWeight.SemiBold, + fontSize = 16.sp, + lineHeight = 24.sp + ) ) diff --git a/app/src/main/java/com/heartz/app/core/state/UiState.kt b/app/src/main/java/com/heartz/app/core/state/UiState.kt index b7198a2f..e590e1a8 100644 --- a/app/src/main/java/com/heartz/app/core/state/UiState.kt +++ b/app/src/main/java/com/heartz/app/core/state/UiState.kt @@ -6,10 +6,10 @@ sealed interface UiState { data object Loading : UiState data class Success( - val data: T, + val data: T ) : UiState data class Failure( - val msg: String, + val msg: String ) : UiState } diff --git a/app/src/main/java/com/heartz/app/core/util/ModifierExt.kt b/app/src/main/java/com/heartz/app/core/util/ModifierExt.kt index 0b8d8389..68ac49fa 100644 --- a/app/src/main/java/com/heartz/app/core/util/ModifierExt.kt +++ b/app/src/main/java/com/heartz/app/core/util/ModifierExt.kt @@ -10,7 +10,7 @@ inline fun Modifier.noRippleClickable(crossinline onClick: () -> Unit = {}): Mod composed { this.clickable( indication = null, - interactionSource = remember { MutableInteractionSource() }, + interactionSource = remember { MutableInteractionSource() } ) { onClick() } diff --git a/app/src/main/java/com/heartz/app/data/datasourceimpl/local/DummyLocalDataSourceImpl.kt b/app/src/main/java/com/heartz/app/data/datasourceimpl/local/DummyLocalDataSourceImpl.kt index 1888d106..2a2a7882 100644 --- a/app/src/main/java/com/heartz/app/data/datasourceimpl/local/DummyLocalDataSourceImpl.kt +++ b/app/src/main/java/com/heartz/app/data/datasourceimpl/local/DummyLocalDataSourceImpl.kt @@ -5,33 +5,33 @@ import androidx.datastore.preferences.core.booleanPreferencesKey import androidx.datastore.preferences.core.edit import androidx.datastore.preferences.preferencesDataStore import dagger.hilt.android.qualifiers.ApplicationContext +import javax.inject.Inject import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.map -import javax.inject.Inject private const val FILE_NAME = "date_road_datastore" private val Context.dataStore by preferencesDataStore(name = FILE_NAME) class DummyLocalDataSourceImpl - @Inject - constructor( - @ApplicationContext private val context: Context, - ) : DummyLocalDataSource { - companion object { - val IS_LOGIN = booleanPreferencesKey("is_login") - } - - override val isLogin: Flow = - context.dataStore.data.map { preferences -> - preferences[IS_LOGIN] ?: false - } +@Inject +constructor( + @ApplicationContext private val context: Context +) : DummyLocalDataSource { + companion object { + val IS_LOGIN = booleanPreferencesKey("is_login") + } - override suspend fun setIsLogin(value: Boolean) { - context.dataStore.edit { it[IS_LOGIN] = value } + override val isLogin: Flow = + context.dataStore.data.map { preferences -> + preferences[IS_LOGIN] ?: false } - override suspend fun clear() { - context.dataStore.edit { it.clear() } - } + override suspend fun setIsLogin(value: Boolean) { + context.dataStore.edit { it[IS_LOGIN] = value } + } + + override suspend fun clear() { + context.dataStore.edit { it.clear() } } +} diff --git a/app/src/main/java/com/heartz/app/data/datasourceimpl/remote/DummyRemoteDataSourceImpl.kt b/app/src/main/java/com/heartz/app/data/datasourceimpl/remote/DummyRemoteDataSourceImpl.kt index 80669819..f432b52b 100644 --- a/app/src/main/java/com/heartz/app/data/datasourceimpl/remote/DummyRemoteDataSourceImpl.kt +++ b/app/src/main/java/com/heartz/app/data/datasourceimpl/remote/DummyRemoteDataSourceImpl.kt @@ -8,9 +8,12 @@ import com.heartz.app.data.service.DummyService import javax.inject.Inject class DummyRemoteDataSourceImpl - @Inject - constructor( - private val dummyService: DummyService, - ) : DummyRemoteDataSource { - override suspend fun getDummies(request: RequestDummyDto): DummyBaseResponse = dummyService.getDummies(request) - } +@Inject +constructor( + private val dummyService: DummyService +) : DummyRemoteDataSource { + override suspend fun getDummies( + request: RequestDummyDto + ): DummyBaseResponse = + dummyService.getDummies(request) +} diff --git a/app/src/main/java/com/heartz/app/data/di/ApiModule.kt b/app/src/main/java/com/heartz/app/data/di/ApiModule.kt index 6de86a6e..b6cf59a3 100644 --- a/app/src/main/java/com/heartz/app/data/di/ApiModule.kt +++ b/app/src/main/java/com/heartz/app/data/di/ApiModule.kt @@ -5,13 +5,15 @@ import dagger.Module import dagger.Provides import dagger.hilt.InstallIn import dagger.hilt.components.SingletonComponent -import retrofit2.Retrofit import javax.inject.Singleton +import retrofit2.Retrofit @Module @InstallIn(SingletonComponent::class) object ApiModule { @Provides @Singleton - fun providesDummyService(retrofit: Retrofit): DummyService = retrofit.create(DummyService::class.java) + fun providesDummyService(retrofit: Retrofit): DummyService = retrofit.create( + DummyService::class.java + ) } diff --git a/app/src/main/java/com/heartz/app/data/di/DataSourceModule.kt b/app/src/main/java/com/heartz/app/data/di/DataSourceModule.kt index 9bf03bb7..1adaaebd 100644 --- a/app/src/main/java/com/heartz/app/data/di/DataSourceModule.kt +++ b/app/src/main/java/com/heartz/app/data/di/DataSourceModule.kt @@ -6,9 +6,9 @@ import dagger.Binds import dagger.Module import dagger.hilt.InstallIn import dagger.hilt.components.SingletonComponent +import javax.inject.Singleton import org.sopt.dateroad.data.datalocal.datasourceimpl.DummyLocalDataSource import org.sopt.dateroad.data.datalocal.datasourceimpl.DummyLocalDataSourceImpl -import javax.inject.Singleton @Module @InstallIn(SingletonComponent::class) diff --git a/app/src/main/java/com/heartz/app/data/di/NetworkModule.kt b/app/src/main/java/com/heartz/app/data/di/NetworkModule.kt index 4055cc60..21a17dba 100644 --- a/app/src/main/java/com/heartz/app/data/di/NetworkModule.kt +++ b/app/src/main/java/com/heartz/app/data/di/NetworkModule.kt @@ -6,6 +6,7 @@ import dagger.Module import dagger.Provides import dagger.hilt.InstallIn import dagger.hilt.components.SingletonComponent +import javax.inject.Singleton import kotlinx.serialization.ExperimentalSerializationApi import kotlinx.serialization.json.Json import okhttp3.MediaType.Companion.toMediaType @@ -13,7 +14,6 @@ import okhttp3.OkHttpClient import okhttp3.logging.HttpLoggingInterceptor import retrofit2.Converter import retrofit2.Retrofit -import javax.inject.Singleton @Module @InstallIn(SingletonComponent::class) @@ -35,13 +35,15 @@ object NetworkModule { @OptIn(ExperimentalSerializationApi::class) @Provides @Singleton - fun providesConverterFactory(): Converter.Factory = Json.asConverterFactory("application/json".toMediaType()) + fun providesConverterFactory(): Converter.Factory = Json.asConverterFactory( + "application/json".toMediaType() + ) @Provides @Singleton fun providesRetrofit( client: OkHttpClient, - converterFactory: Converter.Factory, + converterFactory: Converter.Factory ): Retrofit = Retrofit.Builder() .baseUrl(BuildConfig.BASE_URL) diff --git a/app/src/main/java/com/heartz/app/data/dto/base/DummyBaseResponse.kt b/app/src/main/java/com/heartz/app/data/dto/base/DummyBaseResponse.kt index 5fe032ac..efbb0fc3 100644 --- a/app/src/main/java/com/heartz/app/data/dto/base/DummyBaseResponse.kt +++ b/app/src/main/java/com/heartz/app/data/dto/base/DummyBaseResponse.kt @@ -12,5 +12,5 @@ data class DummyBaseResponse( @SerialName("message") val message: String, @SerialName("data") - val data: T, + val data: T ) diff --git a/app/src/main/java/com/heartz/app/data/dto/base/DummyNullableBaseResponse.kt b/app/src/main/java/com/heartz/app/data/dto/base/DummyNullableBaseResponse.kt index b820de8d..d67cc6e5 100644 --- a/app/src/main/java/com/heartz/app/data/dto/base/DummyNullableBaseResponse.kt +++ b/app/src/main/java/com/heartz/app/data/dto/base/DummyNullableBaseResponse.kt @@ -12,5 +12,5 @@ data class DummyNullableBaseResponse( @SerialName("message") val message: String, @SerialName("data") - val data: T? = null, + val data: T? = null ) diff --git a/app/src/main/java/com/heartz/app/data/dto/request/RequestDummyDto.kt b/app/src/main/java/com/heartz/app/data/dto/request/RequestDummyDto.kt index b1dffade..fb15987f 100644 --- a/app/src/main/java/com/heartz/app/data/dto/request/RequestDummyDto.kt +++ b/app/src/main/java/com/heartz/app/data/dto/request/RequestDummyDto.kt @@ -8,5 +8,5 @@ data class RequestDummyDto( @SerialName("id") val id: Int, @SerialName("email") - val email: String, + val email: String ) diff --git a/app/src/main/java/com/heartz/app/data/dto/response/ResponseDummyDto.kt b/app/src/main/java/com/heartz/app/data/dto/response/ResponseDummyDto.kt index c3edb4a2..b3b9adb6 100644 --- a/app/src/main/java/com/heartz/app/data/dto/response/ResponseDummyDto.kt +++ b/app/src/main/java/com/heartz/app/data/dto/response/ResponseDummyDto.kt @@ -6,5 +6,5 @@ import kotlinx.serialization.Serializable @Serializable data class ResponseDummyDto( @SerialName("info") - val info: List, + val info: List ) diff --git a/app/src/main/java/com/heartz/app/data/mapper/todata/DummyMapper.kt b/app/src/main/java/com/heartz/app/data/mapper/todata/DummyMapper.kt index 85f20600..05c1f308 100644 --- a/app/src/main/java/com/heartz/app/data/mapper/todata/DummyMapper.kt +++ b/app/src/main/java/com/heartz/app/data/mapper/todata/DummyMapper.kt @@ -6,5 +6,5 @@ import com.heartz.app.domain.model.Dummy fun Dummy.toData(): RequestDummyDto = RequestDummyDto( id = this.id, - email = this.email, + email = this.email ) diff --git a/app/src/main/java/com/heartz/app/data/mapper/todomain/ResponseDummyDtoMapper.kt b/app/src/main/java/com/heartz/app/data/mapper/todomain/ResponseDummyDtoMapper.kt index 9296a50f..0d39273a 100644 --- a/app/src/main/java/com/heartz/app/data/mapper/todomain/ResponseDummyDtoMapper.kt +++ b/app/src/main/java/com/heartz/app/data/mapper/todomain/ResponseDummyDtoMapper.kt @@ -5,5 +5,5 @@ import com.heartz.app.domain.model.DummyResultModel fun ResponseDummyDto.toDomain(): DummyResultModel = DummyResultModel( - info = info, + info = info ) diff --git a/app/src/main/java/com/heartz/app/data/repositoryimpl/DummyRepositoryImpl.kt b/app/src/main/java/com/heartz/app/data/repositoryimpl/DummyRepositoryImpl.kt index 49d18725..84dafff6 100644 --- a/app/src/main/java/com/heartz/app/data/repositoryimpl/DummyRepositoryImpl.kt +++ b/app/src/main/java/com/heartz/app/data/repositoryimpl/DummyRepositoryImpl.kt @@ -9,16 +9,16 @@ import com.heartz.app.domain.repository.DummyRepository import javax.inject.Inject class DummyRepositoryImpl - @Inject - constructor( - private val dummyService: DummyService, - ) : DummyRepository { - override suspend fun getDummies(request: Dummy): Result = - runCatching { - val response = - dummyService.getDummies( - request = request.toData(), - ) - response.data.toDomain() - } - } +@Inject +constructor( + private val dummyService: DummyService +) : DummyRepository { + override suspend fun getDummies(request: Dummy): Result = + runCatching { + val response = + dummyService.getDummies( + request = request.toData() + ) + response.data.toDomain() + } +} diff --git a/app/src/main/java/com/heartz/app/data/service/DummyService.kt b/app/src/main/java/com/heartz/app/data/service/DummyService.kt index 33bb8672..712fc4dd 100644 --- a/app/src/main/java/com/heartz/app/data/service/DummyService.kt +++ b/app/src/main/java/com/heartz/app/data/service/DummyService.kt @@ -9,6 +9,6 @@ import retrofit2.http.GET interface DummyService { @GET("/api/v1/service") suspend fun getDummies( - @Body request: RequestDummyDto, + @Body request: RequestDummyDto ): DummyBaseResponse } diff --git a/app/src/main/java/com/heartz/app/domain/model/Dummy.kt b/app/src/main/java/com/heartz/app/domain/model/Dummy.kt index ebcc13bd..22cd1d99 100644 --- a/app/src/main/java/com/heartz/app/domain/model/Dummy.kt +++ b/app/src/main/java/com/heartz/app/domain/model/Dummy.kt @@ -2,5 +2,5 @@ package com.heartz.app.domain.model data class Dummy( val id: Int, - val email: String, + val email: String ) diff --git a/app/src/main/java/com/heartz/app/domain/model/DummyResultModel.kt b/app/src/main/java/com/heartz/app/domain/model/DummyResultModel.kt index 63bd03b0..05820764 100644 --- a/app/src/main/java/com/heartz/app/domain/model/DummyResultModel.kt +++ b/app/src/main/java/com/heartz/app/domain/model/DummyResultModel.kt @@ -1,5 +1,5 @@ package com.heartz.app.domain.model data class DummyResultModel( - val info: List, + val info: List ) diff --git a/app/src/main/java/com/heartz/app/presentation/graph/FigureScreen.kt b/app/src/main/java/com/heartz/app/presentation/graph/FigureScreen.kt index b7417000..5b02a709 100644 --- a/app/src/main/java/com/heartz/app/presentation/graph/FigureScreen.kt +++ b/app/src/main/java/com/heartz/app/presentation/graph/FigureScreen.kt @@ -14,15 +14,15 @@ import androidx.compose.ui.graphics.Color fun FigureScreen() { Column( modifier = - Modifier - .fillMaxSize() - .background(Color.White), + Modifier + .fillMaxSize() + .background(Color.White), horizontalAlignment = Alignment.CenterHorizontally, - verticalArrangement = Arrangement.Center, + verticalArrangement = Arrangement.Center ) { Text( text = "figure Screen", - color = Color.Black, + color = Color.Black ) } } diff --git a/app/src/main/java/com/heartz/app/presentation/home/HomeScreen.kt b/app/src/main/java/com/heartz/app/presentation/home/HomeScreen.kt index 2b9fbdb6..ca831025 100644 --- a/app/src/main/java/com/heartz/app/presentation/home/HomeScreen.kt +++ b/app/src/main/java/com/heartz/app/presentation/home/HomeScreen.kt @@ -11,17 +11,16 @@ import androidx.compose.runtime.getValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color -import com.heartz.app.core.state.UiState import androidx.hilt.navigation.compose.hiltViewModel +import com.heartz.app.core.state.UiState @Composable -fun HomeScreen( - viewModel: HomeViewModel = hiltViewModel() -) { +fun HomeScreen(viewModel: HomeViewModel = hiltViewModel()) { val uiState by viewModel.uiState.collectAsState() Column( - modifier = Modifier + modifier = + Modifier .fillMaxSize() .background(Color.White), horizontalAlignment = Alignment.CenterHorizontally, diff --git a/app/src/main/java/com/heartz/app/presentation/home/HomeState.kt b/app/src/main/java/com/heartz/app/presentation/home/HomeState.kt index 5f2de3fa..23454c1c 100644 --- a/app/src/main/java/com/heartz/app/presentation/home/HomeState.kt +++ b/app/src/main/java/com/heartz/app/presentation/home/HomeState.kt @@ -5,4 +5,4 @@ import com.heartz.app.domain.model.DummyResultModel data class HomeState( var user: UiState = UiState.Loading -) \ No newline at end of file +) diff --git a/app/src/main/java/com/heartz/app/presentation/home/HomeViewModel.kt b/app/src/main/java/com/heartz/app/presentation/home/HomeViewModel.kt index a11daa56..7d93191e 100644 --- a/app/src/main/java/com/heartz/app/presentation/home/HomeViewModel.kt +++ b/app/src/main/java/com/heartz/app/presentation/home/HomeViewModel.kt @@ -6,20 +6,24 @@ import com.heartz.app.core.state.UiState import com.heartz.app.domain.model.Dummy import com.heartz.app.domain.repository.DummyRepository import dagger.hilt.android.lifecycle.HiltViewModel +import javax.inject.Inject import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.update import kotlinx.coroutines.launch -import javax.inject.Inject - @HiltViewModel -class HomeViewModel @Inject constructor( +class HomeViewModel +@Inject +constructor( private val dummyRepository: DummyRepository ) : ViewModel() { var uiState = MutableStateFlow(HomeState()) private set - fun getDummies(id: Int, email: String) { + fun getDummies( + id: Int, + email: String + ) { viewModelScope.launch { dummyRepository.getDummies( request = Dummy(id = id, email = email) @@ -38,4 +42,4 @@ class HomeViewModel @Inject constructor( } } } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/heartz/app/presentation/main/MainNavHost.kt b/app/src/main/java/com/heartz/app/presentation/main/MainNavHost.kt index 943f22a5..33c58199 100644 --- a/app/src/main/java/com/heartz/app/presentation/main/MainNavHost.kt +++ b/app/src/main/java/com/heartz/app/presentation/main/MainNavHost.kt @@ -13,7 +13,7 @@ import com.heartz.app.presentation.quest.navigation.questGraph @Composable fun MainNavHost( navigator: MainNavigator, - modifier: Modifier = Modifier, + modifier: Modifier = Modifier ) { NavHost( enterTransition = { EnterTransition.None }, @@ -21,7 +21,7 @@ fun MainNavHost( popEnterTransition = { EnterTransition.None }, popExitTransition = { ExitTransition.None }, navController = navigator.navController, - startDestination = navigator.startDestination, + startDestination = navigator.startDestination ) { homeGraph() questGraph() diff --git a/app/src/main/java/com/heartz/app/presentation/main/MainNavTab.kt b/app/src/main/java/com/heartz/app/presentation/main/MainNavTab.kt index 7f4fbaa7..a5c0bb8c 100644 --- a/app/src/main/java/com/heartz/app/presentation/main/MainNavTab.kt +++ b/app/src/main/java/com/heartz/app/presentation/main/MainNavTab.kt @@ -21,28 +21,28 @@ import com.heartz.app.presentation.quest.navigation.Quest enum class MainNavTab( @DrawableRes val icon: Int, @StringRes val contentDescription: Int, - val route: MainTabRoute, + val route: MainTabRoute ) { QUEST( icon = ic_folder_open, contentDescription = ic_quest_desc, - route = Quest, + route = Quest ), HOME( icon = ic_home, contentDescription = ic_home_desc, - route = Home, + route = Home ), FIGURE( icon = ic_graph, contentDescription = ic_figure_desc, - route = Figure, + route = Figure ), MYPAGE( icon = ic_user, contentDescription = ic_mypage_desc, - route = Mypage, - ), + route = Mypage + ) ; companion object { diff --git a/app/src/main/java/com/heartz/app/presentation/main/MainNavigator.kt b/app/src/main/java/com/heartz/app/presentation/main/MainNavigator.kt index f4f64768..5cc90a56 100644 --- a/app/src/main/java/com/heartz/app/presentation/main/MainNavigator.kt +++ b/app/src/main/java/com/heartz/app/presentation/main/MainNavigator.kt @@ -15,7 +15,7 @@ import com.heartz.app.presentation.mypage.navigation.navigateToMypage import com.heartz.app.presentation.quest.navigation.navigateToQuest class MainNavigator( - val navController: NavHostController, + val navController: NavHostController ) { private val currentDestination: NavDestination? @Composable get() = @@ -62,7 +62,8 @@ class MainNavigator( } @Composable -fun rememberMainNavigator(navController: NavHostController = rememberNavController()): MainNavigator = - remember(navController) { - MainNavigator(navController) - } +fun rememberMainNavigator( + navController: NavHostController = rememberNavController() +): MainNavigator = remember(navController) { + MainNavigator(navController) +} diff --git a/app/src/main/java/com/heartz/app/presentation/main/MainScreen.kt b/app/src/main/java/com/heartz/app/presentation/main/MainScreen.kt index 749600ac..a07bc5cb 100644 --- a/app/src/main/java/com/heartz/app/presentation/main/MainScreen.kt +++ b/app/src/main/java/com/heartz/app/presentation/main/MainScreen.kt @@ -19,18 +19,18 @@ fun MainScreen(navigator: MainNavigator = rememberMainNavigator()) { visible = navigator.showBottomBar(), tabs = MainNavTab.entries.toImmutableList(), currentTab = navigator.currentTab, - onTabSelected = navigator::navigate, + onTabSelected = navigator::navigate ) }, modifier = - Modifier - .background(Color.White) - .systemBarsPadding() - .fillMaxSize(), + Modifier + .background(Color.White) + .systemBarsPadding() + .fillMaxSize() ) { innerPadding -> MainNavHost( navigator = navigator, - modifier = Modifier.padding(innerPadding), + modifier = Modifier.padding(innerPadding) ) } } diff --git a/app/src/main/java/com/heartz/app/presentation/main/component/MainBottomBar.kt b/app/src/main/java/com/heartz/app/presentation/main/component/MainBottomBar.kt index f19a8e07..736d15d4 100644 --- a/app/src/main/java/com/heartz/app/presentation/main/component/MainBottomBar.kt +++ b/app/src/main/java/com/heartz/app/presentation/main/component/MainBottomBar.kt @@ -39,26 +39,26 @@ fun MainBottomBar( visible: Boolean, tabs: ImmutableList, currentTab: MainNavTab?, - onTabSelected: (MainNavTab) -> Unit, + onTabSelected: (MainNavTab) -> Unit ) { AnimatedVisibility( visible = visible, enter = EnterTransition.None, - exit = ExitTransition.None, + exit = ExitTransition.None ) { Column( modifier = - Modifier - .background(Color.White), + Modifier + .background(Color.White) ) { Row( modifier = - Modifier - .navigationBarsPadding() - .fillMaxWidth() - .padding(vertical = 21.dp), + Modifier + .navigationBarsPadding() + .fillMaxWidth() + .padding(vertical = 21.dp), verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.SpaceEvenly, + horizontalArrangement = Arrangement.SpaceEvenly ) { tabs.forEach { tab -> key(tab.route) { @@ -66,7 +66,7 @@ fun MainBottomBar( MainBottomBarItem( tab = tab, selected = selected, - onClick = { onTabSelected(tab) }, + onClick = { onTabSelected(tab) } ) } } @@ -80,21 +80,21 @@ fun RowScope.MainBottomBarItem( modifier: Modifier = Modifier, tab: MainNavTab, selected: Boolean, - onClick: () -> Unit, + onClick: () -> Unit ) { val bottomItemColor = if (selected) Red80 else Pink80 Column( modifier = - modifier - .noRippleClickable(onClick = onClick) - .weight(1f), + modifier + .noRippleClickable(onClick = onClick) + .weight(1f), horizontalAlignment = Alignment.CenterHorizontally, - verticalArrangement = Arrangement.spacedBy(1.dp), + verticalArrangement = Arrangement.spacedBy(1.dp) ) { Icon( imageVector = ImageVector.vectorResource(tab.icon), contentDescription = stringResource(tab.contentDescription), - tint = bottomItemColor, + tint = bottomItemColor ) } } @@ -108,7 +108,7 @@ private fun MainBottomBarPreview() { visible = true, tabs = MainNavTab.entries.toImmutableList(), currentTab = currentTab, - onTabSelected = { currentTab = it }, + onTabSelected = { currentTab = it } ) } } diff --git a/app/src/main/java/com/heartz/app/presentation/mypage/MypageScreen.kt b/app/src/main/java/com/heartz/app/presentation/mypage/MypageScreen.kt index 8c065eeb..74aef03a 100644 --- a/app/src/main/java/com/heartz/app/presentation/mypage/MypageScreen.kt +++ b/app/src/main/java/com/heartz/app/presentation/mypage/MypageScreen.kt @@ -14,15 +14,15 @@ import androidx.compose.ui.graphics.Color fun MypageScreen() { Column( modifier = - Modifier - .fillMaxSize() - .background(Color.White), + Modifier + .fillMaxSize() + .background(Color.White), horizontalAlignment = Alignment.CenterHorizontally, - verticalArrangement = Arrangement.Center, + verticalArrangement = Arrangement.Center ) { Text( text = "mypage Screen", - color = Color.Black, + color = Color.Black ) } } diff --git a/app/src/main/java/com/heartz/app/presentation/quest/QuestScreen.kt b/app/src/main/java/com/heartz/app/presentation/quest/QuestScreen.kt index 9e503e75..c1a14e14 100644 --- a/app/src/main/java/com/heartz/app/presentation/quest/QuestScreen.kt +++ b/app/src/main/java/com/heartz/app/presentation/quest/QuestScreen.kt @@ -14,15 +14,15 @@ import androidx.compose.ui.graphics.Color fun QuestScreen() { Column( modifier = - Modifier - .fillMaxSize() - .background(Color.White), + Modifier + .fillMaxSize() + .background(Color.White), horizontalAlignment = Alignment.CenterHorizontally, - verticalArrangement = Arrangement.Center, + verticalArrangement = Arrangement.Center ) { Text( text = "quest Screen", - color = Color.Black, + color = Color.Black ) } } diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index cb20bd63..241b2609 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -47,7 +47,10 @@ kakao = "2.21.4" #Third Party ksp = "2.0.21-1.0.25" -ktlint = "12.3.0" + + + +ktlint = "11.6.1" [plugins] From 266fcdd2b2dfb3a2d7866453b7cc03a3b3aeff0e Mon Sep 17 00:00:00 2001 From: fredLeeJH Date: Thu, 26 Jun 2025 14:23:09 +0900 Subject: [PATCH 4/9] =?UTF-8?q?#1=20[chore]=20:=20=EB=84=A4=EC=9D=B4?= =?UTF-8?q?=EB=B0=8D=20=EC=88=98=EC=A0=95,=20=EB=B2=84=EC=A0=84=20?= =?UTF-8?q?=EC=B9=B4=ED=83=88=EB=A1=9C=EA=B7=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/build.gradle.kts | 11 +++++------ .../app/data/di/{ApiModule.kt => ServiceModule.kt} | 2 +- .../app/data/repositoryimpl/DummyRepositoryImpl.kt | 5 +---- .../com/heartz/app/presentation/graph/FigureScreen.kt | 3 +-- .../com/heartz/app/presentation/home/HomeScreen.kt | 7 +++---- .../com/heartz/app/presentation/main/MainNavTab.kt | 3 +-- .../heartz/app/presentation/mypage/MypageScreen.kt | 3 +-- .../com/heartz/app/presentation/quest/QuestScreen.kt | 3 +-- gradle/libs.versions.toml | 6 ++++++ 9 files changed, 20 insertions(+), 23 deletions(-) rename app/src/main/java/com/heartz/app/data/di/{ApiModule.kt => ServiceModule.kt} (95%) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 59c7aa8c..10192b42 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -17,19 +17,18 @@ val properties = android { namespace = "com.heartz.app" - compileSdk = 35 + compileSdk = libs.versions.compileSdk.get().toInt() defaultConfig { applicationId = "com.heartz.app" - minSdk = 28 - targetSdk = 35 - versionCode = 1 - versionName = "1.0" + minSdk = libs.versions.minSdk.get().toInt() + targetSdk = libs.versions.targetSdk.get().toInt() + versionCode = libs.versions.versionCode.get().toInt() + versionName = libs.versions.versionName.get() testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" buildConfigField("String", "BASE_URL", properties["base.url"].toString()) - // TODO: kakao social login buildConfigField( "String", "KAKAO_NATIVE_APP_KEY", diff --git a/app/src/main/java/com/heartz/app/data/di/ApiModule.kt b/app/src/main/java/com/heartz/app/data/di/ServiceModule.kt similarity index 95% rename from app/src/main/java/com/heartz/app/data/di/ApiModule.kt rename to app/src/main/java/com/heartz/app/data/di/ServiceModule.kt index b6cf59a3..261e8a56 100644 --- a/app/src/main/java/com/heartz/app/data/di/ApiModule.kt +++ b/app/src/main/java/com/heartz/app/data/di/ServiceModule.kt @@ -10,7 +10,7 @@ import retrofit2.Retrofit @Module @InstallIn(SingletonComponent::class) -object ApiModule { +object ServiceModule { @Provides @Singleton fun providesDummyService(retrofit: Retrofit): DummyService = retrofit.create( diff --git a/app/src/main/java/com/heartz/app/data/repositoryimpl/DummyRepositoryImpl.kt b/app/src/main/java/com/heartz/app/data/repositoryimpl/DummyRepositoryImpl.kt index 84dafff6..c009e141 100644 --- a/app/src/main/java/com/heartz/app/data/repositoryimpl/DummyRepositoryImpl.kt +++ b/app/src/main/java/com/heartz/app/data/repositoryimpl/DummyRepositoryImpl.kt @@ -15,10 +15,7 @@ constructor( ) : DummyRepository { override suspend fun getDummies(request: Dummy): Result = runCatching { - val response = - dummyService.getDummies( - request = request.toData() - ) + val response = dummyService.getDummies(request = request.toData()) response.data.toDomain() } } diff --git a/app/src/main/java/com/heartz/app/presentation/graph/FigureScreen.kt b/app/src/main/java/com/heartz/app/presentation/graph/FigureScreen.kt index 5b02a709..0832af32 100644 --- a/app/src/main/java/com/heartz/app/presentation/graph/FigureScreen.kt +++ b/app/src/main/java/com/heartz/app/presentation/graph/FigureScreen.kt @@ -13,8 +13,7 @@ import androidx.compose.ui.graphics.Color @Composable fun FigureScreen() { Column( - modifier = - Modifier + modifier = Modifier .fillMaxSize() .background(Color.White), horizontalAlignment = Alignment.CenterHorizontally, diff --git a/app/src/main/java/com/heartz/app/presentation/home/HomeScreen.kt b/app/src/main/java/com/heartz/app/presentation/home/HomeScreen.kt index ca831025..bc6d5d4a 100644 --- a/app/src/main/java/com/heartz/app/presentation/home/HomeScreen.kt +++ b/app/src/main/java/com/heartz/app/presentation/home/HomeScreen.kt @@ -6,21 +6,20 @@ import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.material3.Text import androidx.compose.runtime.Composable -import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.hilt.navigation.compose.hiltViewModel +import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.heartz.app.core.state.UiState @Composable fun HomeScreen(viewModel: HomeViewModel = hiltViewModel()) { - val uiState by viewModel.uiState.collectAsState() + val uiState by viewModel.uiState.collectAsStateWithLifecycle() Column( - modifier = - Modifier + modifier = Modifier .fillMaxSize() .background(Color.White), horizontalAlignment = Alignment.CenterHorizontally, diff --git a/app/src/main/java/com/heartz/app/presentation/main/MainNavTab.kt b/app/src/main/java/com/heartz/app/presentation/main/MainNavTab.kt index a5c0bb8c..bae48307 100644 --- a/app/src/main/java/com/heartz/app/presentation/main/MainNavTab.kt +++ b/app/src/main/java/com/heartz/app/presentation/main/MainNavTab.kt @@ -42,8 +42,7 @@ enum class MainNavTab( icon = ic_user, contentDescription = ic_mypage_desc, route = Mypage - ) - ; + ); companion object { @Composable diff --git a/app/src/main/java/com/heartz/app/presentation/mypage/MypageScreen.kt b/app/src/main/java/com/heartz/app/presentation/mypage/MypageScreen.kt index 74aef03a..77d598fa 100644 --- a/app/src/main/java/com/heartz/app/presentation/mypage/MypageScreen.kt +++ b/app/src/main/java/com/heartz/app/presentation/mypage/MypageScreen.kt @@ -13,8 +13,7 @@ import androidx.compose.ui.graphics.Color @Composable fun MypageScreen() { Column( - modifier = - Modifier + modifier = Modifier .fillMaxSize() .background(Color.White), horizontalAlignment = Alignment.CenterHorizontally, diff --git a/app/src/main/java/com/heartz/app/presentation/quest/QuestScreen.kt b/app/src/main/java/com/heartz/app/presentation/quest/QuestScreen.kt index c1a14e14..aaa0d000 100644 --- a/app/src/main/java/com/heartz/app/presentation/quest/QuestScreen.kt +++ b/app/src/main/java/com/heartz/app/presentation/quest/QuestScreen.kt @@ -13,8 +13,7 @@ import androidx.compose.ui.graphics.Color @Composable fun QuestScreen() { Column( - modifier = - Modifier + modifier = Modifier .fillMaxSize() .background(Color.White), horizontalAlignment = Alignment.CenterHorizontally, diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 241b2609..37ebb985 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,5 +1,11 @@ [versions] +compileSdk = "35" +minSdk = "28" +targetSdk = "35" +versionCode = "1" +versionName = "1.0" + # Kotlin agp = "8.9.2" kotlin = "2.0.21" From 367370b47e0a0905e32a7c8f4b18f68ecadd5eb7 Mon Sep 17 00:00:00 2001 From: fredLeeJH Date: Thu, 26 Jun 2025 16:29:26 +0900 Subject: [PATCH 5/9] #1 [chore] : code rabbit test --- gradle/libs.versions.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 37ebb985..f7366827 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,5 +1,6 @@ [versions] +# Version compileSdk = "35" minSdk = "28" targetSdk = "35" From 5ace7f0b1569dbd908f6b3f64e152b8a90b9ff61 Mon Sep 17 00:00:00 2001 From: fredLeeJH Date: Thu, 26 Jun 2025 16:44:44 +0900 Subject: [PATCH 6/9] =?UTF-8?q?#1=20[chore]=20:=20=ED=8C=A8=ED=82=A4?= =?UTF-8?q?=EC=A7=80=20=EC=A3=BC=EC=86=8C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../heartz/app/data/datasource/local/DummyLocalDataSource.kt | 4 ++-- .../data/datasourceimpl/local/DummyLocalDataSourceImpl.kt | 5 ++--- app/src/main/java/com/heartz/app/data/di/DataSourceModule.kt | 4 ++-- .../main/java/com/heartz/app/data/service/DummyService.kt | 4 +++- 4 files changed, 9 insertions(+), 8 deletions(-) diff --git a/app/src/main/java/com/heartz/app/data/datasource/local/DummyLocalDataSource.kt b/app/src/main/java/com/heartz/app/data/datasource/local/DummyLocalDataSource.kt index 32aa0808..ce147398 100644 --- a/app/src/main/java/com/heartz/app/data/datasource/local/DummyLocalDataSource.kt +++ b/app/src/main/java/com/heartz/app/data/datasource/local/DummyLocalDataSource.kt @@ -1,4 +1,4 @@ -package org.sopt.dateroad.data.datalocal.datasourceimpl +package com.heartz.app.data.datasource.local import kotlinx.coroutines.flow.Flow @@ -9,4 +9,4 @@ interface DummyLocalDataSource { suspend fun setIsLogin(value: Boolean) suspend fun clear() -} +} \ No newline at end of file diff --git a/app/src/main/java/com/heartz/app/data/datasourceimpl/local/DummyLocalDataSourceImpl.kt b/app/src/main/java/com/heartz/app/data/datasourceimpl/local/DummyLocalDataSourceImpl.kt index 2a2a7882..262a5fb3 100644 --- a/app/src/main/java/com/heartz/app/data/datasourceimpl/local/DummyLocalDataSourceImpl.kt +++ b/app/src/main/java/com/heartz/app/data/datasourceimpl/local/DummyLocalDataSourceImpl.kt @@ -4,6 +4,7 @@ import android.content.Context import androidx.datastore.preferences.core.booleanPreferencesKey import androidx.datastore.preferences.core.edit import androidx.datastore.preferences.preferencesDataStore +import com.heartz.app.data.datasource.local.DummyLocalDataSource import dagger.hilt.android.qualifiers.ApplicationContext import javax.inject.Inject import kotlinx.coroutines.flow.Flow @@ -13,9 +14,7 @@ private const val FILE_NAME = "date_road_datastore" private val Context.dataStore by preferencesDataStore(name = FILE_NAME) -class DummyLocalDataSourceImpl -@Inject -constructor( +class DummyLocalDataSourceImpl @Inject constructor( @ApplicationContext private val context: Context ) : DummyLocalDataSource { companion object { diff --git a/app/src/main/java/com/heartz/app/data/di/DataSourceModule.kt b/app/src/main/java/com/heartz/app/data/di/DataSourceModule.kt index 1adaaebd..ac973752 100644 --- a/app/src/main/java/com/heartz/app/data/di/DataSourceModule.kt +++ b/app/src/main/java/com/heartz/app/data/di/DataSourceModule.kt @@ -1,14 +1,14 @@ package com.heartz.app.data.di +import com.heartz.app.data.datasource.local.DummyLocalDataSource import com.heartz.app.data.datasource.remote.DummyRemoteDataSource import com.heartz.app.data.datasourceimpl.remote.DummyRemoteDataSourceImpl import dagger.Binds import dagger.Module import dagger.hilt.InstallIn import dagger.hilt.components.SingletonComponent -import javax.inject.Singleton -import org.sopt.dateroad.data.datalocal.datasourceimpl.DummyLocalDataSource import org.sopt.dateroad.data.datalocal.datasourceimpl.DummyLocalDataSourceImpl +import javax.inject.Singleton @Module @InstallIn(SingletonComponent::class) diff --git a/app/src/main/java/com/heartz/app/data/service/DummyService.kt b/app/src/main/java/com/heartz/app/data/service/DummyService.kt index 712fc4dd..17c22171 100644 --- a/app/src/main/java/com/heartz/app/data/service/DummyService.kt +++ b/app/src/main/java/com/heartz/app/data/service/DummyService.kt @@ -5,9 +5,11 @@ import com.heartz.app.data.dto.request.RequestDummyDto import com.heartz.app.data.dto.response.ResponseDummyDto import retrofit2.http.Body import retrofit2.http.GET +import retrofit2.http.POST interface DummyService { - @GET("/api/v1/service") + // TODO: 이름은 getDummies지만 @Body를 사용해버려서 post로 바꿨습니다,, 임시! + @POST("/api/v1/service") suspend fun getDummies( @Body request: RequestDummyDto ): DummyBaseResponse From da22a30cd29ca1576899657d45e843343bd6ee72 Mon Sep 17 00:00:00 2001 From: fredLeeJH Date: Thu, 26 Jun 2025 16:46:30 +0900 Subject: [PATCH 7/9] =?UTF-8?q?#1=20[chore]=20:=20=ED=8C=A8=ED=82=A4?= =?UTF-8?q?=EC=A7=80=20=EC=A3=BC=EC=86=8C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../app/data/datasourceimpl/local/DummyLocalDataSourceImpl.kt | 2 +- app/src/main/java/com/heartz/app/data/di/DataSourceModule.kt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/com/heartz/app/data/datasourceimpl/local/DummyLocalDataSourceImpl.kt b/app/src/main/java/com/heartz/app/data/datasourceimpl/local/DummyLocalDataSourceImpl.kt index 262a5fb3..c22c6227 100644 --- a/app/src/main/java/com/heartz/app/data/datasourceimpl/local/DummyLocalDataSourceImpl.kt +++ b/app/src/main/java/com/heartz/app/data/datasourceimpl/local/DummyLocalDataSourceImpl.kt @@ -1,4 +1,4 @@ -package org.sopt.dateroad.data.datalocal.datasourceimpl +package com.heartz.app.data.datasourceimpl.local import android.content.Context import androidx.datastore.preferences.core.booleanPreferencesKey diff --git a/app/src/main/java/com/heartz/app/data/di/DataSourceModule.kt b/app/src/main/java/com/heartz/app/data/di/DataSourceModule.kt index ac973752..8512122f 100644 --- a/app/src/main/java/com/heartz/app/data/di/DataSourceModule.kt +++ b/app/src/main/java/com/heartz/app/data/di/DataSourceModule.kt @@ -2,12 +2,12 @@ package com.heartz.app.data.di import com.heartz.app.data.datasource.local.DummyLocalDataSource import com.heartz.app.data.datasource.remote.DummyRemoteDataSource +import com.heartz.app.data.datasourceimpl.local.DummyLocalDataSourceImpl import com.heartz.app.data.datasourceimpl.remote.DummyRemoteDataSourceImpl import dagger.Binds import dagger.Module import dagger.hilt.InstallIn import dagger.hilt.components.SingletonComponent -import org.sopt.dateroad.data.datalocal.datasourceimpl.DummyLocalDataSourceImpl import javax.inject.Singleton @Module From 008177f53a4f210a1d3670d5930408095c18f133 Mon Sep 17 00:00:00 2001 From: fredLeeJH Date: Thu, 26 Jun 2025 16:48:45 +0900 Subject: [PATCH 8/9] =?UTF-8?q?#1=20[chore]=20:=20=EB=A1=9C=EC=BB=AC=20?= =?UTF-8?q?=EB=8D=B0=EC=9D=B4=ED=84=B0=EC=86=8C=EC=8A=A4=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../app/data/datasourceimpl/local/DummyLocalDataSourceImpl.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/com/heartz/app/data/datasourceimpl/local/DummyLocalDataSourceImpl.kt b/app/src/main/java/com/heartz/app/data/datasourceimpl/local/DummyLocalDataSourceImpl.kt index c22c6227..d4af76a5 100644 --- a/app/src/main/java/com/heartz/app/data/datasourceimpl/local/DummyLocalDataSourceImpl.kt +++ b/app/src/main/java/com/heartz/app/data/datasourceimpl/local/DummyLocalDataSourceImpl.kt @@ -10,7 +10,7 @@ import javax.inject.Inject import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.map -private const val FILE_NAME = "date_road_datastore" +private const val FILE_NAME = "heartz_datastore" private val Context.dataStore by preferencesDataStore(name = FILE_NAME) From 4994c0cc2715d8bccca658dfdc0bcfccc5a746e9 Mon Sep 17 00:00:00 2001 From: fredLeeJH Date: Thu, 26 Jun 2025 16:54:21 +0900 Subject: [PATCH 9/9] #1 [chore] : kt lint check --- .../heartz/app/data/datasource/local/DummyLocalDataSource.kt | 2 +- app/src/main/java/com/heartz/app/data/service/DummyService.kt | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/com/heartz/app/data/datasource/local/DummyLocalDataSource.kt b/app/src/main/java/com/heartz/app/data/datasource/local/DummyLocalDataSource.kt index ce147398..070aee8b 100644 --- a/app/src/main/java/com/heartz/app/data/datasource/local/DummyLocalDataSource.kt +++ b/app/src/main/java/com/heartz/app/data/datasource/local/DummyLocalDataSource.kt @@ -9,4 +9,4 @@ interface DummyLocalDataSource { suspend fun setIsLogin(value: Boolean) suspend fun clear() -} \ No newline at end of file +} diff --git a/app/src/main/java/com/heartz/app/data/service/DummyService.kt b/app/src/main/java/com/heartz/app/data/service/DummyService.kt index 17c22171..fbb5b1fa 100644 --- a/app/src/main/java/com/heartz/app/data/service/DummyService.kt +++ b/app/src/main/java/com/heartz/app/data/service/DummyService.kt @@ -4,11 +4,10 @@ import com.heartz.app.data.dto.base.DummyBaseResponse import com.heartz.app.data.dto.request.RequestDummyDto import com.heartz.app.data.dto.response.ResponseDummyDto import retrofit2.http.Body -import retrofit2.http.GET import retrofit2.http.POST interface DummyService { - // TODO: 이름은 getDummies지만 @Body를 사용해버려서 post로 바꿨습니다,, 임시! + // TODO: 이름은 getDummies지만 @Body를 사용해버려서 post로 바꿨습니다,, 임시! @POST("/api/v1/service") suspend fun getDummies( @Body request: RequestDummyDto