diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 56fa43a..fc40225 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -1,6 +1,9 @@ plugins { alias(libs.plugins.androidApplication) alias(libs.plugins.jetbrainsKotlinAndroid) + alias(libs.plugins.kotlin.kapt) + alias(libs.plugins.kotlin.ksp) + alias(libs.plugins.dagger.hilt) } android { @@ -69,7 +72,19 @@ dependencies { // navigation implementation(libs.navigation.compose) + implementation(libs.hilt.navigation.compose) // pager implementation(libs.pager) + + // hilt + implementation(libs.hilt) + kapt(libs.hilt.compiler) + + // network + implementation(libs.bundles.network) + ksp(libs.moshi.code.gen) + + // coroutine + implementation(libs.bundles.coroutine) } diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index c1c2975..2d33741 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -2,7 +2,10 @@ + + > +} diff --git a/app/src/main/java/io/seoj17/android_14th_compose_zzik/data/BitRepositoryImpl.kt b/app/src/main/java/io/seoj17/android_14th_compose_zzik/data/BitRepositoryImpl.kt new file mode 100644 index 0000000..390d3fe --- /dev/null +++ b/app/src/main/java/io/seoj17/android_14th_compose_zzik/data/BitRepositoryImpl.kt @@ -0,0 +1,15 @@ +package io.seoj17.android_14th_compose_zzik.data + +import io.seoj17.android_14th_compose_zzik.data.dto.MarketCodeResponse +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.flow +import javax.inject.Inject + +class BitRepositoryImpl @Inject constructor( + private val bitService: BitService +) : BitRepository { + override suspend fun getMarketCodeList(): Flow> = flow { + val marketCodeList = bitService.getMarketCodeList() + emit(marketCodeList) + } +} diff --git a/app/src/main/java/io/seoj17/android_14th_compose_zzik/data/BitService.kt b/app/src/main/java/io/seoj17/android_14th_compose_zzik/data/BitService.kt new file mode 100644 index 0000000..8509c21 --- /dev/null +++ b/app/src/main/java/io/seoj17/android_14th_compose_zzik/data/BitService.kt @@ -0,0 +1,13 @@ +package io.seoj17.android_14th_compose_zzik.data + +import io.seoj17.android_14th_compose_zzik.data.dto.MarketCodeResponse +import retrofit2.http.GET +import retrofit2.http.Query + +interface BitService { + + @GET("/market/all") + suspend fun getMarketCodeList( + @Query("isDetails") isDetails: Boolean = false + ): List +} diff --git a/app/src/main/java/io/seoj17/android_14th_compose_zzik/data/BitWebSocketListener.kt b/app/src/main/java/io/seoj17/android_14th_compose_zzik/data/BitWebSocketListener.kt new file mode 100644 index 0000000..06147e4 --- /dev/null +++ b/app/src/main/java/io/seoj17/android_14th_compose_zzik/data/BitWebSocketListener.kt @@ -0,0 +1,40 @@ +package io.seoj17.android_14th_compose_zzik.data + +import okhttp3.Response +import okhttp3.WebSocket +import okhttp3.WebSocketListener +import okio.ByteString + +class BitWebSocketListener : WebSocketListener() { + override fun onClosed(webSocket: WebSocket, code: Int, reason: String) { + super.onClosed(webSocket, code, reason) + } + + override fun onClosing(webSocket: WebSocket, code: Int, reason: String) { + super.onClosing(webSocket, code, reason) + webSocket.close(NORMAL_CLOSURE_STATUS, null) + webSocket.cancel() + } + + override fun onFailure(webSocket: WebSocket, t: Throwable, response: Response?) { + super.onFailure(webSocket, t, response) + } + + override fun onMessage(webSocket: WebSocket, text: String) { + super.onMessage(webSocket, text) + } + + override fun onMessage(webSocket: WebSocket, bytes: ByteString) { + super.onMessage(webSocket, bytes) + } + + override fun onOpen(webSocket: WebSocket, response: Response) { + super.onOpen(webSocket, response) + webSocket.send("{\"type\":\"ticker\", \"symbols\": [\"BTC_KRW\"], \"tickTypes\": [\"30M\"]}") + webSocket.close(NORMAL_CLOSURE_STATUS, null) //없을 경우 끊임없이 서버와 통신함 + } + + companion object { + private const val NORMAL_CLOSURE_STATUS = 1000 + } +} diff --git a/app/src/main/java/io/seoj17/android_14th_compose_zzik/data/dto/MarketCodeResponse.kt b/app/src/main/java/io/seoj17/android_14th_compose_zzik/data/dto/MarketCodeResponse.kt new file mode 100644 index 0000000..cc62c8e --- /dev/null +++ b/app/src/main/java/io/seoj17/android_14th_compose_zzik/data/dto/MarketCodeResponse.kt @@ -0,0 +1,12 @@ +package io.seoj17.android_14th_compose_zzik.data.dto + +import com.squareup.moshi.Json +import com.squareup.moshi.JsonClass + +@JsonClass(generateAdapter = true) +data class MarketCodeResponse( + @Json(name = "market") + val market: String, + @Json(name = "korean_name") + val korName: String +) diff --git a/app/src/main/java/io/seoj17/android_14th_compose_zzik/di/NetworkModule.kt b/app/src/main/java/io/seoj17/android_14th_compose_zzik/di/NetworkModule.kt new file mode 100644 index 0000000..08c5d33 --- /dev/null +++ b/app/src/main/java/io/seoj17/android_14th_compose_zzik/di/NetworkModule.kt @@ -0,0 +1,54 @@ +package io.seoj17.android_14th_compose_zzik.di + +import dagger.Module +import dagger.Provides +import dagger.hilt.InstallIn +import dagger.hilt.components.SingletonComponent +import io.seoj17.android_14th_compose_zzik.data.BitService +import okhttp3.OkHttpClient +import okhttp3.Request +import okhttp3.logging.HttpLoggingInterceptor +import retrofit2.Retrofit +import retrofit2.converter.moshi.MoshiConverterFactory +import javax.inject.Singleton + +@Module +@InstallIn(SingletonComponent::class) +class NetworkModule { + + @Provides + @Singleton + fun providesOkHttpClient(): OkHttpClient { + val httpLoggingInterceptor = HttpLoggingInterceptor().apply { + level = HttpLoggingInterceptor.Level.BODY + } + return OkHttpClient.Builder() + .addInterceptor(httpLoggingInterceptor) + .build() + } + + @Provides + @Singleton + fun providesRetrofit(okHttpClient: OkHttpClient): Retrofit = + Retrofit.Builder() + .baseUrl(BASE_URL) + .client(okHttpClient) + .addConverterFactory(MoshiConverterFactory.create()) + .build() + + @Provides + @Singleton + fun providesBitService(retrofit: Retrofit): BitService = retrofit.create(BitService::class.java) + + @Provides + @Singleton + fun providesRequest(): Request = + Request.Builder() + .url(WEBSOCKET_URL) + .build() + + companion object { + private const val BASE_URL = "https://api.upbit.com/v1" + private const val WEBSOCKET_URL = "wss://api.upbit.com/websocket/v1" + } +} diff --git a/app/src/main/java/io/seoj17/android_14th_compose_zzik/di/RepositoryModule.kt b/app/src/main/java/io/seoj17/android_14th_compose_zzik/di/RepositoryModule.kt new file mode 100644 index 0000000..1089c85 --- /dev/null +++ b/app/src/main/java/io/seoj17/android_14th_compose_zzik/di/RepositoryModule.kt @@ -0,0 +1,18 @@ +package io.seoj17.android_14th_compose_zzik.di + +import dagger.Binds +import dagger.Module +import dagger.hilt.InstallIn +import dagger.hilt.components.SingletonComponent +import io.seoj17.android_14th_compose_zzik.data.BitRepository +import io.seoj17.android_14th_compose_zzik.data.BitRepositoryImpl +import javax.inject.Singleton + +@Module +@InstallIn(SingletonComponent::class) +interface RepositoryModule { + + @Binds + @Singleton + fun bindsBitRepository(bitRepository: BitRepositoryImpl): BitRepository +} diff --git a/app/src/main/java/io/seoj17/android_14th_compose_zzik/navigation/BitNavHost.kt b/app/src/main/java/io/seoj17/android_14th_compose_zzik/navigation/BitNavHost.kt index 22449e8..231e18a 100644 --- a/app/src/main/java/io/seoj17/android_14th_compose_zzik/navigation/BitNavHost.kt +++ b/app/src/main/java/io/seoj17/android_14th_compose_zzik/navigation/BitNavHost.kt @@ -9,8 +9,6 @@ import io.seoj17.android_14th_compose_zzik.ui.excepthome.compose.CoinInfoRoute import io.seoj17.android_14th_compose_zzik.ui.excepthome.compose.DepositWithdrawalRoute import io.seoj17.android_14th_compose_zzik.ui.excepthome.compose.InvestmentDetailsRoute import io.seoj17.android_14th_compose_zzik.ui.excepthome.compose.MoreDetailsRoute -import io.seoj17.android_14th_compose_zzik.ui.home.compose.DetailRoute -import io.seoj17.android_14th_compose_zzik.ui.home.compose.HomeRoute import io.seoj17.android_14th_compose_zzik.ui.home.navigation.homeGraph @Composable diff --git a/app/src/main/java/io/seoj17/android_14th_compose_zzik/ui/excepthome/compose/CoinInfoScreen.kt b/app/src/main/java/io/seoj17/android_14th_compose_zzik/ui/excepthome/CoinInfoScreen.kt similarity index 81% rename from app/src/main/java/io/seoj17/android_14th_compose_zzik/ui/excepthome/compose/CoinInfoScreen.kt rename to app/src/main/java/io/seoj17/android_14th_compose_zzik/ui/excepthome/CoinInfoScreen.kt index 55655ae..b64c574 100644 --- a/app/src/main/java/io/seoj17/android_14th_compose_zzik/ui/excepthome/compose/CoinInfoScreen.kt +++ b/app/src/main/java/io/seoj17/android_14th_compose_zzik/ui/excepthome/CoinInfoScreen.kt @@ -1,4 +1,4 @@ -package io.seoj17.android_14th_compose_zzik.ui.excepthome.compose +package io.seoj17.android_14th_compose_zzik.ui.excepthome import androidx.compose.material3.Text import androidx.compose.runtime.Composable diff --git a/app/src/main/java/io/seoj17/android_14th_compose_zzik/ui/excepthome/compose/DepositWithdrawalScreen.kt b/app/src/main/java/io/seoj17/android_14th_compose_zzik/ui/excepthome/DepositWithdrawalScreen.kt similarity index 82% rename from app/src/main/java/io/seoj17/android_14th_compose_zzik/ui/excepthome/compose/DepositWithdrawalScreen.kt rename to app/src/main/java/io/seoj17/android_14th_compose_zzik/ui/excepthome/DepositWithdrawalScreen.kt index aa06b30..f1bb062 100644 --- a/app/src/main/java/io/seoj17/android_14th_compose_zzik/ui/excepthome/compose/DepositWithdrawalScreen.kt +++ b/app/src/main/java/io/seoj17/android_14th_compose_zzik/ui/excepthome/DepositWithdrawalScreen.kt @@ -1,4 +1,4 @@ -package io.seoj17.android_14th_compose_zzik.ui.excepthome.compose +package io.seoj17.android_14th_compose_zzik.ui.excepthome import androidx.compose.material3.Text import androidx.compose.runtime.Composable diff --git a/app/src/main/java/io/seoj17/android_14th_compose_zzik/ui/excepthome/compose/InvestmentDetailsScreen.kt b/app/src/main/java/io/seoj17/android_14th_compose_zzik/ui/excepthome/InvestmentDetailsScreen.kt similarity index 83% rename from app/src/main/java/io/seoj17/android_14th_compose_zzik/ui/excepthome/compose/InvestmentDetailsScreen.kt rename to app/src/main/java/io/seoj17/android_14th_compose_zzik/ui/excepthome/InvestmentDetailsScreen.kt index b24dbd5..6c78272 100644 --- a/app/src/main/java/io/seoj17/android_14th_compose_zzik/ui/excepthome/compose/InvestmentDetailsScreen.kt +++ b/app/src/main/java/io/seoj17/android_14th_compose_zzik/ui/excepthome/InvestmentDetailsScreen.kt @@ -1,4 +1,4 @@ -package io.seoj17.android_14th_compose_zzik.ui.excepthome.compose +package io.seoj17.android_14th_compose_zzik.ui.excepthome import androidx.compose.material3.Text import androidx.compose.runtime.Composable diff --git a/app/src/main/java/io/seoj17/android_14th_compose_zzik/ui/excepthome/compose/MoreDetailsScreen.kt b/app/src/main/java/io/seoj17/android_14th_compose_zzik/ui/excepthome/MoreDetailsScreen.kt similarity index 81% rename from app/src/main/java/io/seoj17/android_14th_compose_zzik/ui/excepthome/compose/MoreDetailsScreen.kt rename to app/src/main/java/io/seoj17/android_14th_compose_zzik/ui/excepthome/MoreDetailsScreen.kt index 1683ad0..6215ae6 100644 --- a/app/src/main/java/io/seoj17/android_14th_compose_zzik/ui/excepthome/compose/MoreDetailsScreen.kt +++ b/app/src/main/java/io/seoj17/android_14th_compose_zzik/ui/excepthome/MoreDetailsScreen.kt @@ -1,4 +1,4 @@ -package io.seoj17.android_14th_compose_zzik.ui.excepthome.compose +package io.seoj17.android_14th_compose_zzik.ui.excepthome import androidx.compose.material3.Text import androidx.compose.runtime.Composable diff --git a/app/src/main/java/io/seoj17/android_14th_compose_zzik/ui/home/compose/DetailScreen.kt b/app/src/main/java/io/seoj17/android_14th_compose_zzik/ui/home/DetailScreen.kt similarity index 97% rename from app/src/main/java/io/seoj17/android_14th_compose_zzik/ui/home/compose/DetailScreen.kt rename to app/src/main/java/io/seoj17/android_14th_compose_zzik/ui/home/DetailScreen.kt index 7d7e977..6f0c18e 100644 --- a/app/src/main/java/io/seoj17/android_14th_compose_zzik/ui/home/compose/DetailScreen.kt +++ b/app/src/main/java/io/seoj17/android_14th_compose_zzik/ui/home/DetailScreen.kt @@ -1,4 +1,4 @@ -package io.seoj17.android_14th_compose_zzik.ui.home.compose +package io.seoj17.android_14th_compose_zzik.ui.home import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column diff --git a/app/src/main/java/io/seoj17/android_14th_compose_zzik/ui/home/compose/HomeScreen.kt b/app/src/main/java/io/seoj17/android_14th_compose_zzik/ui/home/HomeScreen.kt similarity index 92% rename from app/src/main/java/io/seoj17/android_14th_compose_zzik/ui/home/compose/HomeScreen.kt rename to app/src/main/java/io/seoj17/android_14th_compose_zzik/ui/home/HomeScreen.kt index 1cee65d..323466e 100644 --- a/app/src/main/java/io/seoj17/android_14th_compose_zzik/ui/home/compose/HomeScreen.kt +++ b/app/src/main/java/io/seoj17/android_14th_compose_zzik/ui/home/HomeScreen.kt @@ -1,4 +1,4 @@ -package io.seoj17.android_14th_compose_zzik.ui.home.compose +package io.seoj17.android_14th_compose_zzik.ui.home import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxWidth @@ -13,6 +13,7 @@ import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp +import androidx.hilt.navigation.compose.hiltViewModel import io.seoj17.android_14th_compose_zzik.ui.common.BitTextField import io.seoj17.android_14th_compose_zzik.ui.common.BitTopBar import io.seoj17.android_14th_compose_zzik.ui.common.BitUnitTabPager @@ -21,8 +22,9 @@ import io.seoj17.android_14th_compose_zzik.ui.theme.BitWhiteColor @Composable fun HomeRoute( + modifier: Modifier = Modifier, onCoinInfoClicked: (String) -> Unit, - modifier: Modifier = Modifier + viewModel: HomeViewModel = hiltViewModel(), ) { HomeScreen( modifier = modifier, diff --git a/app/src/main/java/io/seoj17/android_14th_compose_zzik/ui/home/HomeViewModel.kt b/app/src/main/java/io/seoj17/android_14th_compose_zzik/ui/home/HomeViewModel.kt new file mode 100644 index 0000000..6263de8 --- /dev/null +++ b/app/src/main/java/io/seoj17/android_14th_compose_zzik/ui/home/HomeViewModel.kt @@ -0,0 +1,29 @@ +package io.seoj17.android_14th_compose_zzik.ui.home + +import android.util.Log +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import dagger.hilt.android.lifecycle.HiltViewModel +import io.seoj17.android_14th_compose_zzik.data.BitRepository +import kotlinx.coroutines.launch +import javax.inject.Inject + +@HiltViewModel +class HomeViewModel @Inject constructor( + private val bitRepository: BitRepository +) : ViewModel() { + + init { + getMarketCodeList() + } + + private fun getMarketCodeList() { + viewModelScope.launch { + bitRepository.getMarketCodeList().collect { marketCodeList -> + marketCodeList.forEach { + Log.d("psj", it.market + ": " + it.korName) + } + } + } + } +} diff --git a/app/src/main/java/io/seoj17/android_14th_compose_zzik/ui/home/navigation/HomeNavigation.kt b/app/src/main/java/io/seoj17/android_14th_compose_zzik/ui/home/navigation/HomeNavigation.kt index 14204a6..144d248 100644 --- a/app/src/main/java/io/seoj17/android_14th_compose_zzik/ui/home/navigation/HomeNavigation.kt +++ b/app/src/main/java/io/seoj17/android_14th_compose_zzik/ui/home/navigation/HomeNavigation.kt @@ -5,8 +5,8 @@ import androidx.navigation.NavGraphBuilder import androidx.navigation.compose.composable import androidx.navigation.navigation import io.seoj17.android_14th_compose_zzik.navigation.BitNavigationRoute -import io.seoj17.android_14th_compose_zzik.ui.home.compose.DetailRoute -import io.seoj17.android_14th_compose_zzik.ui.home.compose.HomeRoute +import io.seoj17.android_14th_compose_zzik.ui.home.DetailRoute +import io.seoj17.android_14th_compose_zzik.ui.home.HomeRoute fun NavGraphBuilder.homeGraph( navController: NavController diff --git a/build.gradle.kts b/build.gradle.kts index a0985ef..949ca97 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -2,4 +2,7 @@ plugins { alias(libs.plugins.androidApplication) apply false alias(libs.plugins.jetbrainsKotlinAndroid) apply false + alias(libs.plugins.kotlin.kapt) apply false + alias(libs.plugins.kotlin.ksp) apply false + alias(libs.plugins.dagger.hilt) apply false } \ No newline at end of file diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index dd24933..5c72cd4 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,5 +1,5 @@ [versions] -agp = "8.3.0" +agp = "8.3.1" kotlin = "1.9.0" coreKtx = "1.12.0" ksp = "1.9.10-1.0.13" @@ -12,7 +12,7 @@ lifecycleRuntimeKtx = "2.7.0" activityCompose = "1.8.2" composeBom = "2023.08.00" -hilt = "2.48.1" +hilt = "2.49" okhttp = "4.11.0" retrofit = "2.9.0"