From ea4ac65c8a6d99562958d18ed040a075fe891b0b Mon Sep 17 00:00:00 2001 From: bngsh Date: Thu, 17 Nov 2022 20:44:36 +0900 Subject: [PATCH 01/10] =?UTF-8?q?:wrench:=20presentation=20=EB=A0=88?= =?UTF-8?q?=EC=9D=B4=EC=96=B4=EC=97=90=20hilt=20=EC=9D=98=EC=A1=B4?= =?UTF-8?q?=EC=84=B1=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: yonghanJu --- app/build.gradle | 9 ++++++++ .../whyranoid/mogakrun/MogakrunApplication.kt | 2 ++ build.gradle | 6 +++++ data/build.gradle | 6 +++++ presentation/build.gradle | 23 +++++++++++++++++-- .../whyranoid/presentation/MainActivity.kt | 2 ++ 6 files changed, 46 insertions(+), 2 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 0ca9756..973702b 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,6 +1,8 @@ plugins { id "com.android.application" id "org.jetbrains.kotlin.android" + id "kotlin-kapt" + id "dagger.hilt.android.plugin" } android { @@ -30,6 +32,9 @@ android { kotlinOptions { jvmTarget = "11" } + buildFeatures { + dataBinding true + } } dependencies { @@ -51,4 +56,8 @@ dependencies { // leakcanary 메모리 누수 체크 debugImplementation "com.squareup.leakcanary:leakcanary-android:$leakcanaryVersion" + + // Hilt + implementation "com.google.dagger:hilt-android:$hiltVersion" + kapt "com.google.dagger:hilt-android-compiler:$hiltVersion" } \ No newline at end of file diff --git a/app/src/main/java/com/whyranoid/mogakrun/MogakrunApplication.kt b/app/src/main/java/com/whyranoid/mogakrun/MogakrunApplication.kt index 1bc8776..4cc97b6 100644 --- a/app/src/main/java/com/whyranoid/mogakrun/MogakrunApplication.kt +++ b/app/src/main/java/com/whyranoid/mogakrun/MogakrunApplication.kt @@ -2,8 +2,10 @@ package com.whyranoid.mogakrun import android.app.Application import com.whyranoid.mogakrun.util.TimberDebugTree +import dagger.hilt.android.HiltAndroidApp import timber.log.Timber +@HiltAndroidApp class MogakrunApplication : Application() { override fun onCreate() { super.onCreate() diff --git a/build.gradle b/build.gradle index 52db2a0..9961e58 100644 --- a/build.gradle +++ b/build.gradle @@ -13,6 +13,11 @@ buildscript { leakcanaryVersion = "2.10" kotlinxCoroutinesVersion = "1.6.4" paging3Version = "3.1.1" + hiltVersion = "2.44" + lottieVersion = "5.2.0" // 병한이 : 로티 추가했습니당 + activityKtxVersion = "1.6.1" + fragmentKtxVersion = "1.5.4" + lifecycleViewmodelKtxVersion = "2.5.1" } dependencies { classpath "com.google.gms:google-services:$googleServiceVersion" @@ -24,4 +29,5 @@ plugins { id "com.android.library" version "7.3.1" apply false id "org.jetbrains.kotlin.android" version "1.7.20" apply false id 'org.jetbrains.kotlin.jvm' version '1.7.20' apply false + id "com.google.dagger.hilt.android" version "2.44" apply false } diff --git a/data/build.gradle b/data/build.gradle index 5f56e03..3a8db63 100644 --- a/data/build.gradle +++ b/data/build.gradle @@ -2,6 +2,8 @@ plugins { id "com.android.library" id "org.jetbrains.kotlin.android" id "com.google.gms.google-services" + id "kotlin-kapt" + id "dagger.hilt.android.plugin" } android { @@ -42,4 +44,8 @@ dependencies { implementation platform("com.google.firebase:firebase-bom:$firebaseVersion") implementation "com.google.firebase:firebase-analytics-ktx" implementation "com.google.firebase:firebase-firestore-ktx" + + // Hilt + implementation "com.google.dagger:hilt-android:$hiltVersion" + kapt "com.google.dagger:hilt-android-compiler:$hiltVersion" } \ No newline at end of file diff --git a/presentation/build.gradle b/presentation/build.gradle index 0ac35b3..cec0661 100644 --- a/presentation/build.gradle +++ b/presentation/build.gradle @@ -1,6 +1,8 @@ plugins { id "com.android.library" id "org.jetbrains.kotlin.android" + id "kotlin-kapt" + id "dagger.hilt.android.plugin" } android { @@ -28,13 +30,15 @@ android { kotlinOptions { jvmTarget = "11" } - dataBinding { - enable = true + buildFeatures { + dataBinding true } } dependencies { + implementation project(":domain") + implementation "androidx.core:core-ktx:$coreKtxVersion" implementation "androidx.appcompat:appcompat:$appcompatVersion" implementation "com.google.android.material:material:$materialVersion" @@ -45,4 +49,19 @@ dependencies { // timber 로그 implementation "com.jakewharton.timber:timber:$timberVersion" + + // 병한이 : 로티 디펜던시 추가 + // lottie + implementation "com.airbnb.android:lottie:$lottieVersion" + + // Hilt + implementation "com.google.dagger:hilt-android:$hiltVersion" + kapt "com.google.dagger:hilt-android-compiler:$hiltVersion" + + // by viewModels + implementation "androidx.activity:activity-ktx:$activityKtxVersion" + implementation "androidx.fragment:fragment-ktx:$fragmentKtxVersion" + + // ViewModelScope + implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycleViewmodelKtxVersion" } \ No newline at end of file diff --git a/presentation/src/main/java/com/whyranoid/presentation/MainActivity.kt b/presentation/src/main/java/com/whyranoid/presentation/MainActivity.kt index 776b901..2f01272 100644 --- a/presentation/src/main/java/com/whyranoid/presentation/MainActivity.kt +++ b/presentation/src/main/java/com/whyranoid/presentation/MainActivity.kt @@ -2,7 +2,9 @@ package com.whyranoid.presentation import android.os.Bundle import androidx.appcompat.app.AppCompatActivity +import dagger.hilt.android.AndroidEntryPoint +@AndroidEntryPoint class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) From a1bd129cf5c2f69933ddf60af5ed9b3bbb49692c Mon Sep 17 00:00:00 2001 From: bngsh Date: Thu, 17 Nov 2022 20:50:36 +0900 Subject: [PATCH 02/10] =?UTF-8?q?:lipstick:=20=EB=9F=AC=EB=8B=9D=20?= =?UTF-8?q?=ED=83=AD=20=EB=A6=AC=EC=86=8C=EC=8A=A4=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: yonghanJu --- .../main/res/drawable/thumbnail_src_small.png | Bin 0 -> 22543 bytes .../src/main/res/raw/runing_tab_animation.json | 1 + presentation/src/main/res/values/colors.xml | 4 ++-- presentation/src/main/res/values/strings.xml | 5 +++++ 4 files changed, 8 insertions(+), 2 deletions(-) create mode 100644 presentation/src/main/res/drawable/thumbnail_src_small.png create mode 100644 presentation/src/main/res/raw/runing_tab_animation.json diff --git a/presentation/src/main/res/drawable/thumbnail_src_small.png b/presentation/src/main/res/drawable/thumbnail_src_small.png new file mode 100644 index 0000000000000000000000000000000000000000..5bdd0b4951633f607c1738ab42cd33c1617bdc55 GIT binary patch literal 22543 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 #FF03DAC5 #FF018786 - #FF000000 + #FF010101 #FFFFFFFF #F5FFD9 - #ffffff + #F3F8E9 #c2cca7 #6d8f5a diff --git a/presentation/src/main/res/values/strings.xml b/presentation/src/main/res/values/strings.xml index e4a3c7c..2edfc84 100644 --- a/presentation/src/main/res/values/strings.xml +++ b/presentation/src/main/res/values/strings.xml @@ -1,3 +1,8 @@ MoGakRun + + 지금, + 함께 달리고 있습니다 + 달리기 + 모각런 썸네일 \ No newline at end of file From eb682740cbfaace7e8d5a3ec378fc8e2d195d450 Mon Sep 17 00:00:00 2001 From: bngsh Date: Thu, 17 Nov 2022 20:54:09 +0900 Subject: [PATCH 03/10] =?UTF-8?q?:lipstick:=20=EB=9F=AC=EB=8B=9D=20?= =?UTF-8?q?=ED=83=AD=20=EB=A0=88=EC=9D=B4=EC=95=84=EC=9B=83=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: yonghanJu --- .../res/layout/fragment_running_start.xml | 147 ++++++++++++++++++ 1 file changed, 147 insertions(+) create mode 100644 presentation/src/main/res/layout/fragment_running_start.xml diff --git a/presentation/src/main/res/layout/fragment_running_start.xml b/presentation/src/main/res/layout/fragment_running_start.xml new file mode 100644 index 0000000..c481f25 --- /dev/null +++ b/presentation/src/main/res/layout/fragment_running_start.xml @@ -0,0 +1,147 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file From ebd502b3b9dc46f13508eb1c9eecebdc1a2fc04b Mon Sep 17 00:00:00 2001 From: bngsh Date: Thu, 17 Nov 2022 20:58:00 +0900 Subject: [PATCH 04/10] =?UTF-8?q?:sparkles:=20=ED=8C=8C=EC=9D=B4=EC=96=B4?= =?UTF-8?q?=EB=B2=A0=EC=9D=B4=EC=8A=A4=20=EB=AA=A8=EB=93=88=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: soopeach --- .../com/whyranoid/data/di/NetworkModule.kt | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 data/src/main/java/com/whyranoid/data/di/NetworkModule.kt diff --git a/data/src/main/java/com/whyranoid/data/di/NetworkModule.kt b/data/src/main/java/com/whyranoid/data/di/NetworkModule.kt new file mode 100644 index 0000000..cb9b6ae --- /dev/null +++ b/data/src/main/java/com/whyranoid/data/di/NetworkModule.kt @@ -0,0 +1,20 @@ +package com.whyranoid.data.di + +import com.google.firebase.firestore.FirebaseFirestore +import com.google.firebase.firestore.ktx.firestore +import com.google.firebase.ktx.Firebase +import dagger.Module +import dagger.Provides +import dagger.hilt.InstallIn +import dagger.hilt.components.SingletonComponent +import javax.inject.Singleton + +@Module +@InstallIn(SingletonComponent::class) +class NetworkModule { + + @Provides + @Singleton + fun provideFireStoreDatabase(): FirebaseFirestore = + Firebase.firestore +} From 3f011ba79820083637b0f1becf1a40a04d14183d Mon Sep 17 00:00:00 2001 From: bngsh Date: Thu, 17 Nov 2022 21:00:39 +0900 Subject: [PATCH 05/10] =?UTF-8?q?:sparkles:=20=EB=9F=AC=EB=8B=9D=20?= =?UTF-8?q?=EB=8D=B0=EC=9D=B4=ED=84=B0=20=EC=86=8C=EC=8A=A4=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84=20(getCurrentRunnerCount)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: yonghanJu --- .../data/di/running/RunningDataSource.kt | 12 +++++ .../data/di/running/RunningDataSourceImpl.kt | 53 +++++++++++++++++++ 2 files changed, 65 insertions(+) create mode 100644 data/src/main/java/com/whyranoid/data/di/running/RunningDataSource.kt create mode 100644 data/src/main/java/com/whyranoid/data/di/running/RunningDataSourceImpl.kt diff --git a/data/src/main/java/com/whyranoid/data/di/running/RunningDataSource.kt b/data/src/main/java/com/whyranoid/data/di/running/RunningDataSource.kt new file mode 100644 index 0000000..61ae0da --- /dev/null +++ b/data/src/main/java/com/whyranoid/data/di/running/RunningDataSource.kt @@ -0,0 +1,12 @@ +package com.whyranoid.data.di.running + +import kotlinx.coroutines.flow.Flow + +interface RunningDataSource { + + fun getCurrentRunnerCount(): Flow + + suspend fun startRunning(uid: String): Boolean + + suspend fun finishRunning(uid: String): Boolean +} diff --git a/data/src/main/java/com/whyranoid/data/di/running/RunningDataSourceImpl.kt b/data/src/main/java/com/whyranoid/data/di/running/RunningDataSourceImpl.kt new file mode 100644 index 0000000..ce0783a --- /dev/null +++ b/data/src/main/java/com/whyranoid/data/di/running/RunningDataSourceImpl.kt @@ -0,0 +1,53 @@ +package com.whyranoid.data.di.running + +import com.google.firebase.firestore.FieldValue +import com.google.firebase.firestore.FirebaseFirestore +import kotlinx.coroutines.channels.awaitClose +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.callbackFlow +import kotlin.coroutines.resume +import kotlin.coroutines.suspendCoroutine + +class RunningDataSourceImpl(private val db: FirebaseFirestore) : RunningDataSource { + + override fun getCurrentRunnerCount(): Flow = callbackFlow { + db.collection("Runners") + .document("runnersId") + .addSnapshotListener { snapshot, _ -> + snapshot?.let { + val count = it.data?.size ?: -1 + trySend(count) + } + } + + awaitClose() + } + + override suspend fun startRunning(uid: String): Boolean { + return suspendCoroutine { continuation -> + db.collection("Runners") + .document("runnersId") + .update(uid, uid) + .addOnSuccessListener { + continuation.resume(true) + } + .addOnFailureListener { + continuation.resume(false) + } + } + } + + override suspend fun finishRunning(uid: String): Boolean { + return suspendCoroutine { continuation -> + db.collection("Runners") + .document("runnersId") + .update(uid, FieldValue.delete()) + .addOnSuccessListener { + continuation.resume(true) + } + .addOnFailureListener { + continuation.resume(false) + } + } + } +} From ff992150058eff31bb0f036b10670c45ff2ec8b7 Mon Sep 17 00:00:00 2001 From: bngsh Date: Thu, 17 Nov 2022 21:01:47 +0900 Subject: [PATCH 06/10] =?UTF-8?q?:sparkles:=20=EB=9F=AC=EB=8B=9D=20?= =?UTF-8?q?=EB=A0=88=ED=8F=AC=EC=A7=80=ED=86=A0=EB=A6=AC=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84=20(getCurrentRunnerCount)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: yonghanJu --- .../data/running/RunningRepositoryImpl.kt | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 data/src/main/java/com/whyranoid/data/running/RunningRepositoryImpl.kt diff --git a/data/src/main/java/com/whyranoid/data/running/RunningRepositoryImpl.kt b/data/src/main/java/com/whyranoid/data/running/RunningRepositoryImpl.kt new file mode 100644 index 0000000..23be8e7 --- /dev/null +++ b/data/src/main/java/com/whyranoid/data/running/RunningRepositoryImpl.kt @@ -0,0 +1,19 @@ +package com.whyranoid.data.running + +import com.whyranoid.data.di.running.RunningDataSource +import com.whyranoid.domain.repository.RunningRepository +import kotlinx.coroutines.flow.Flow + +class RunningRepositoryImpl(private val runningDataSource: RunningDataSource) : RunningRepository { + override fun getCurrentRunnerCount(): Flow { + return runningDataSource.getCurrentRunnerCount() + } + + override suspend fun startRunning(uid: String): Boolean { + return true + } + + override suspend fun finishRunning(uid: String): Boolean { + return true + } +} From 22c5806166f0abc69e72838f5d9bf234cca2b83d Mon Sep 17 00:00:00 2001 From: bngsh Date: Thu, 17 Nov 2022 21:02:20 +0900 Subject: [PATCH 07/10] =?UTF-8?q?:sparkles:=20=EB=9F=AC=EB=8B=9D=20di=20?= =?UTF-8?q?=EB=AA=A8=EB=93=88=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: yonghanJu --- .../data/di/running/RunningModule.kt | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 data/src/main/java/com/whyranoid/data/di/running/RunningModule.kt diff --git a/data/src/main/java/com/whyranoid/data/di/running/RunningModule.kt b/data/src/main/java/com/whyranoid/data/di/running/RunningModule.kt new file mode 100644 index 0000000..b343c7c --- /dev/null +++ b/data/src/main/java/com/whyranoid/data/di/running/RunningModule.kt @@ -0,0 +1,27 @@ +package com.whyranoid.data.di.running + +import com.google.firebase.firestore.FirebaseFirestore +import com.whyranoid.data.running.RunningRepositoryImpl +import com.whyranoid.domain.repository.RunningRepository +import dagger.Module +import dagger.Provides +import dagger.hilt.InstallIn +import dagger.hilt.components.SingletonComponent +import javax.inject.Singleton + +@Module +@InstallIn(SingletonComponent::class) +class RunningModule { + + @Provides + @Singleton + fun provideRunningDataSource(db: FirebaseFirestore): RunningDataSource { + return RunningDataSourceImpl(db) + } + + @Provides + @Singleton + fun provideRunningRepository(runningDataSource: RunningDataSource): RunningRepository { + return RunningRepositoryImpl(runningDataSource) + } +} From 92a1b6196af6a29ec42b1b0d374911cef3fb2750 Mon Sep 17 00:00:00 2001 From: bngsh Date: Thu, 17 Nov 2022 21:04:11 +0900 Subject: [PATCH 08/10] =?UTF-8?q?:truck:=20GetCurrentRunnerCountUseCase=20?= =?UTF-8?q?->=20GetRunnerCountUseCase=20=EC=9C=A0=EC=A6=88=EC=BC=80?= =?UTF-8?q?=EC=9D=B4=EC=8A=A4=20=EC=9D=B4=EB=A6=84=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: yonghanJu --- ...GetCurrentRunnerCountUseCase.kt => GetRunnerCountUseCase.kt} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename domain/src/main/java/com/whyranoid/domain/usecase/{GetCurrentRunnerCountUseCase.kt => GetRunnerCountUseCase.kt} (71%) diff --git a/domain/src/main/java/com/whyranoid/domain/usecase/GetCurrentRunnerCountUseCase.kt b/domain/src/main/java/com/whyranoid/domain/usecase/GetRunnerCountUseCase.kt similarity index 71% rename from domain/src/main/java/com/whyranoid/domain/usecase/GetCurrentRunnerCountUseCase.kt rename to domain/src/main/java/com/whyranoid/domain/usecase/GetRunnerCountUseCase.kt index 59af753..353ff34 100644 --- a/domain/src/main/java/com/whyranoid/domain/usecase/GetCurrentRunnerCountUseCase.kt +++ b/domain/src/main/java/com/whyranoid/domain/usecase/GetRunnerCountUseCase.kt @@ -4,7 +4,7 @@ import com.whyranoid.domain.repository.RunningRepository import kotlinx.coroutines.flow.Flow import javax.inject.Inject -class GetCurrentRunnerCountUseCase @Inject constructor(private val runningRepository: RunningRepository) { +class GetRunnerCountUseCase @Inject constructor(private val runningRepository: RunningRepository) { operator fun invoke(): Flow { return runningRepository.getCurrentRunnerCount() } From 5b1e6879b2997d530f47a13506f6f5992a1c4365 Mon Sep 17 00:00:00 2001 From: bngsh Date: Thu, 17 Nov 2022 21:05:39 +0900 Subject: [PATCH 09/10] =?UTF-8?q?:bug:=20BaseFragment=EC=9D=98=20=EB=9D=BC?= =?UTF-8?q?=EC=9D=B4=ED=94=84=EC=82=AC=EC=9D=B4=ED=81=B4=20=EC=98=A4?= =?UTF-8?q?=EB=84=88=20=EC=84=A4=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: yonghanJu --- .../main/java/com/whyranoid/presentation/base/BaseFragment.kt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/presentation/src/main/java/com/whyranoid/presentation/base/BaseFragment.kt b/presentation/src/main/java/com/whyranoid/presentation/base/BaseFragment.kt index 006fe36..df689a5 100644 --- a/presentation/src/main/java/com/whyranoid/presentation/base/BaseFragment.kt +++ b/presentation/src/main/java/com/whyranoid/presentation/base/BaseFragment.kt @@ -21,7 +21,9 @@ internal abstract class BaseFragment( container: ViewGroup?, savedInstanceState: Bundle? ): View? { + super.onCreateView(inflater, container, savedInstanceState) _binding = DataBindingUtil.inflate(inflater, layoutRes, container, false) + binding.lifecycleOwner = viewLifecycleOwner return binding.root } From 5811202f48db1cc911b7d7313233487ff65aa767 Mon Sep 17 00:00:00 2001 From: bngsh Date: Thu, 17 Nov 2022 21:07:15 +0900 Subject: [PATCH 10/10] =?UTF-8?q?:sparkles:=20RunningStart=20=EB=B7=B0=20?= =?UTF-8?q?=EB=AA=A8=EB=8D=B8=20=EA=B5=AC=ED=98=84=20(=ED=98=84=EC=9E=AC?= =?UTF-8?q?=20=EB=9F=AC=EB=84=88=20=EC=B9=B4=EC=9A=B4=ED=8A=B8=20=EB=B0=9B?= =?UTF-8?q?=EC=95=84=EC=98=A4=EA=B8=B0)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: yonghanJu --- .../runningstart/RunningStartFragment.kt | 33 +++++++++++++++++++ .../runningstart/RunningStartViewModel.kt | 14 ++++++++ 2 files changed, 47 insertions(+) create mode 100644 presentation/src/main/java/com/whyranoid/presentation/runningstart/RunningStartFragment.kt create mode 100644 presentation/src/main/java/com/whyranoid/presentation/runningstart/RunningStartViewModel.kt diff --git a/presentation/src/main/java/com/whyranoid/presentation/runningstart/RunningStartFragment.kt b/presentation/src/main/java/com/whyranoid/presentation/runningstart/RunningStartFragment.kt new file mode 100644 index 0000000..e833d5d --- /dev/null +++ b/presentation/src/main/java/com/whyranoid/presentation/runningstart/RunningStartFragment.kt @@ -0,0 +1,33 @@ +package com.whyranoid.presentation.runningstart + +import android.os.Bundle +import android.view.View +import androidx.fragment.app.viewModels +import androidx.lifecycle.Lifecycle +import androidx.lifecycle.lifecycleScope +import androidx.lifecycle.repeatOnLifecycle +import com.whyranoid.presentation.R +import com.whyranoid.presentation.base.BaseFragment +import com.whyranoid.presentation.databinding.FragmentRunningStartBinding +import dagger.hilt.android.AndroidEntryPoint +import kotlinx.coroutines.launch + +@AndroidEntryPoint +internal class RunningStartFragment : + BaseFragment(R.layout.fragment_running_start) { + + private val viewModel by viewModels() + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + binding.vm = viewModel + + lifecycleScope.launch { + viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) { + viewModel.runnerCount.collect { runnerCount -> + binding.tvRunnerCountNumber.text = runnerCount.toString() + } + } + } + } +} diff --git a/presentation/src/main/java/com/whyranoid/presentation/runningstart/RunningStartViewModel.kt b/presentation/src/main/java/com/whyranoid/presentation/runningstart/RunningStartViewModel.kt new file mode 100644 index 0000000..1e1c354 --- /dev/null +++ b/presentation/src/main/java/com/whyranoid/presentation/runningstart/RunningStartViewModel.kt @@ -0,0 +1,14 @@ +package com.whyranoid.presentation.runningstart + +import androidx.lifecycle.ViewModel +import com.whyranoid.domain.usecase.GetRunnerCountUseCase +import dagger.hilt.android.lifecycle.HiltViewModel +import javax.inject.Inject + +@HiltViewModel +class RunningStartViewModel @Inject constructor( + getRunnerCountUseCase: GetRunnerCountUseCase +) : ViewModel() { + + val runnerCount = getRunnerCountUseCase() +}