Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

현재 연결된 계정 표시 구현, 로그아웃/회원탈퇴 로직 구현, 캘린더 뷰 구현 #45

Merged
merged 3 commits into from
Nov 28, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ buildscript {
kotlinxCoroutinesVersion = "1.6.4"
paging3Version = "3.1.1"
navVersion = "2.5.3"
playServicesAuthVersion = "20.3.0"
playServicesAuthVersion = "20.4.0"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

혹시 버전을 올리신 이유가 있나요??

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

버전이 업그레이드 됐다고 표시되더라고요! 며칠 전에 릴리즈 된 것 같습니다

hiltVersion = "2.44"
lottieVersion = "5.2.0"
activityKtxVersion = "1.6.1"
Expand Down
2 changes: 2 additions & 0 deletions data/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +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"
implementation "com.google.firebase:firebase-auth-ktx"
implementation "com.google.android.gms:play-services-auth:$playServicesAuthVersion"

// Hilt
implementation "com.google.dagger:hilt-android:$hiltVersion"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,8 @@ interface AccountDataSource {
fun getUserNickName(): Flow<String>
fun getUserProfileImgUri(): Flow<String>
fun getUserUid(): Flow<String>
fun getEmail(): Flow<Result<String>>
suspend fun updateUserNickName(uid: String, newNickName: String): Result<String>
suspend fun signOut(): Result<Boolean>
suspend fun withDrawal(): Result<Boolean>
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,13 @@ import androidx.datastore.core.DataStore
import androidx.datastore.preferences.core.Preferences
import androidx.datastore.preferences.core.edit
import androidx.datastore.preferences.core.stringPreferencesKey
import com.google.firebase.auth.FirebaseAuth
import com.google.firebase.firestore.FirebaseFirestore
import com.whyranoid.data.account.AccountDataSourceImpl.PreferenceKeys.email
import com.whyranoid.data.account.AccountDataSourceImpl.PreferenceKeys.nickName
import com.whyranoid.data.account.AccountDataSourceImpl.PreferenceKeys.profileImgUri
import com.whyranoid.data.account.AccountDataSourceImpl.PreferenceKeys.uid
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map
import javax.inject.Inject

Expand All @@ -16,6 +19,9 @@ class AccountDataSourceImpl @Inject constructor(
private val fireBaseDb: FirebaseFirestore
) : AccountDataSource {

private val auth = FirebaseAuth.getInstance()
private val currentUser = auth.currentUser

Comment on lines 19 to +24
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

파이어 베이스를 모듈안에서 만들어주기 보다는 di를 통해 주입해보는건 어떻게 생각하시나요?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

넵 동의합니다!

private object PreferenceKeys {
val uid = stringPreferencesKey(UID_KEY)
val email = stringPreferencesKey(EMAIL_KEY)
Expand All @@ -38,6 +44,15 @@ class AccountDataSourceImpl @Inject constructor(
preferences[uid] ?: EMPTY_STRING
}

override fun getEmail(): Flow<Result<String>> {
return dataStoreDb.data
.map { preferences ->
runCatching {
preferences[email] ?: EMPTY_STRING
}
}
}

override suspend fun updateUserNickName(uid: String, newNickName: String) = runCatching {
// 로컬에 업데이트
dataStoreDb.edit { preferences ->
Expand All @@ -51,6 +66,15 @@ class AccountDataSourceImpl @Inject constructor(
newNickName
}

override suspend fun signOut(): Result<Boolean> = runCatching {
signOut()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

헉.. 다른 코드가 안보여서 그런건지... 무한 재귀가 되는 것으로 보이는데 혹시 어떻게 동작하나요?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

오.. 그렇네요?

true
}

override suspend fun withDrawal(): Result<Boolean> {
TODO("Not yet implemented")
}

companion object {
private const val UID_KEY = "uid"
private const val EMAIL_KEY = "email"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ class AccountRepositoryImpl @Inject constructor(
return accountDataSource.getUserNickName()
}

override fun getEmail(): Flow<Result<String>> {
return accountDataSource.getEmail()
}

override suspend fun updateNickname(uid: String, newNickName: String): Result<String> {
return accountDataSource.updateUserNickName(uid, newNickName)
}
Expand All @@ -36,4 +40,12 @@ class AccountRepositoryImpl @Inject constructor(
override suspend fun updateProfileUrl(newProfileUrl: String): Boolean {
return true
}

override suspend fun signOut(): Result<Boolean> {
TODO("Not yet implemented")
}

override suspend fun withDrawal(): Result<Boolean> {
TODO("Not yet implemented")
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,6 @@ interface RunningHistoryDao {
@Insert(onConflict = OnConflictStrategy.ABORT)
suspend fun addRunningHistory(runningHistory: RunningHistoryEntity)

@Query("SELECT * FROM running_history ORDER BY startedAt ASC")
@Query("SELECT * FROM running_history ORDER BY started_at ASC")
fun getRunningHistory(): Flow<List<RunningHistoryEntity>>
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.whyranoid.data.account

import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.PrimaryKey
import com.whyranoid.domain.model.RunningHistory
Expand All @@ -8,11 +9,11 @@ import com.whyranoid.domain.model.RunningHistory
data class RunningHistoryEntity(
@PrimaryKey
val historyId: String,
val startedAt: Long,
val finishedAt: Long,
val totalRunningTime: Int,
val pace: Double,
val totalDistance: Double
@ColumnInfo(name = "started_at") val startedAt: Long,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이건 스타일이겠지만 저는 PrimaryKey 어노테이션처럼 ColumnInfo 어노테이션도 변수 위에 붙여줬어요!

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이거는 kt lint를 돌렸을 때 위 코드처럼 됐던 것 같아요!

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

네 저도 ktlint 돌렸습니다!

@ColumnInfo(name = "finished_at") val finishedAt: Long,
@ColumnInfo(name = "total_running_time") val totalRunningTime: Int,
@ColumnInfo(name = "pace") val pace: Double,
@ColumnInfo(name = "total_distance") val totalDistance: Double
)
Comment on lines +13 to 17
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

컬럼 네임 작성해주신거 좋았습니다!


fun RunningHistoryEntity.toRunningHistory(): RunningHistory {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@ import kotlinx.coroutines.flow.map
import javax.inject.Inject

class RunningHistoryLocalDataSourceImpl @Inject constructor(
private val roomDb: RunningHistoryLocalDataBase
private val runningHistoryDao: RunningHistoryDao
Comment on lines 8 to +9
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

피드백 적용해주신거 좋았습니다!

) : RunningHistoryLocalDataSource {

override fun getRunningHistory(): Flow<List<RunningHistory>> {
return roomDb.runningHistoryDao().getRunningHistory().map { runningHistoryList ->
return runningHistoryDao.getRunningHistory().map { runningHistoryList ->
runningHistoryList.map { runningHistoryEntity ->
runningHistoryEntity.toRunningHistory()
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package com.whyranoid.data.di

import android.content.Context
import androidx.room.Room
import com.whyranoid.data.account.RunningHistoryDao
import com.whyranoid.data.account.RunningHistoryLocalDataBase
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.android.qualifiers.ApplicationContext
import dagger.hilt.components.SingletonComponent
import javax.inject.Singleton

@Module
@InstallIn(SingletonComponent::class)
object RunningHistoryDataBaseModule {
@Singleton
@Provides
fun provideRoomDataBase(
@ApplicationContext appContext: Context
): RunningHistoryLocalDataBase = Room.databaseBuilder(
appContext,
RunningHistoryLocalDataBase::class.java,
"mogakrun_running_history.db"
)
.build()

@Singleton
@Provides
fun provideRunningHistoryDao(runningHistoryLocalDataBase: RunningHistoryLocalDataBase): RunningHistoryDao =
runningHistoryLocalDataBase.runningHistoryDao()
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@ import androidx.datastore.core.DataStore
import androidx.datastore.preferences.core.PreferenceDataStoreFactory
import androidx.datastore.preferences.core.Preferences
import androidx.datastore.preferences.preferencesDataStoreFile
import androidx.room.Room
import com.whyranoid.data.account.RunningHistoryLocalDataBase
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
Expand All @@ -16,22 +14,7 @@ import javax.inject.Singleton

@Module
@InstallIn(SingletonComponent::class)
object DataBaseModule {
@Singleton
@Provides
fun provideRoomDataBase(
@ApplicationContext appContext: Context
): RunningHistoryLocalDataBase = Room.databaseBuilder(
appContext,
RunningHistoryLocalDataBase::class.java,
"mogakrun_running_history.db"
)
.build()
}

@Module
@InstallIn(SingletonComponent::class)
object DataStoreModule {
object UserDataBaseModule {

private const val USER_PREFERENCES = "user_preferences"

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ interface AccountRepository {
// 데이터스토어에서 닉네임 가져오기
fun getNickname(): Flow<String>

// 데이터스토어에서 이메일 가져오기
fun getEmail(): Flow<Result<String>>

// 닉네임 수정, 서버에 먼저 보내고 성공하면 로컬에 반영
// 실패하면 실패 사용자에게 알리기
suspend fun updateNickname(uid: String, newNickName: String): Result<String>
Expand All @@ -26,4 +29,10 @@ interface AccountRepository {

// 프로필 사진 서버에 업데이트
suspend fun updateProfileUrl(newProfileUrl: String): Boolean
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이친구만 Result가 아닌 게 궁금합니다!! updateNickname은 반환값이 있고 얘는 반환값이 없나요?!

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

엇 지금 프로필 사진 업데이트 기능은 나중에 구현하기로 해서 지금 안쓰는 함수입니다! 예전에 다같이 작성했던 코드에요


// 로그아웃
suspend fun signOut(): Result<Boolean>

// 회원탈퇴
suspend fun withDrawal(): Result<Boolean>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.whyranoid.domain.usecase

import com.whyranoid.domain.repository.AccountRepository
import kotlinx.coroutines.flow.Flow
import javax.inject.Inject

class GetEmailUseCase @Inject constructor(private val accountRepository: AccountRepository) {
operator fun invoke(): Flow<Result<String>> = accountRepository.getEmail()
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import kotlinx.coroutines.flow.Flow
import javax.inject.Inject

class GetNicknameUseCase @Inject constructor(private val accountRepository: AccountRepository) {
suspend operator fun invoke(): Flow<String> {
operator fun invoke(): Flow<String> {
return accountRepository.getNickname()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.whyranoid.domain.usecase

import com.whyranoid.domain.repository.AccountRepository
import javax.inject.Inject

class SignOutUseCase @Inject constructor(private val accountRepository: AccountRepository) {
suspend operator fun invoke(): Result<Boolean> {
return accountRepository.signOut()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.whyranoid.domain.usecase

import com.whyranoid.domain.repository.AccountRepository
import javax.inject.Inject

class WithDrawalUseCase @Inject constructor(private val accountRepository: AccountRepository) {
suspend operator fun invoke(): Result<Boolean> {
return accountRepository.withDrawal()
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.whyranoid.presentation.myrun
package com.whyranoid.presentation.model

import com.whyranoid.domain.model.RunningHistory

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
package com.whyranoid.presentation.myrun

import android.view.View
import androidx.core.content.ContextCompat
import com.kizitonwose.calendarview.CalendarView
import com.kizitonwose.calendarview.model.CalendarDay
import com.kizitonwose.calendarview.model.DayOwner
import com.kizitonwose.calendarview.ui.DayBinder
import com.kizitonwose.calendarview.ui.ViewContainer
import com.whyranoid.presentation.R
import com.whyranoid.presentation.databinding.ItemCalendarDayBinding
import java.time.LocalDate

class CalendarDayBinder(
private val calendarView: CalendarView
) : DayBinder<CalendarDayBinder.DayContainer> {
private var calendar: Pair<LocalDate?, LocalDate?> = null to null
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pair 대신 간단한 데이터 클래스를 만드는 것은 어떨까요??

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

동의합니다!

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

정확히 무슨 뜻인지 파악하고 데이터 클래스로 만들어 보겠습니다!


class DayContainer(
val binding: ItemCalendarDayBinding
) : ViewContainer(binding.root)

override fun create(view: View): DayContainer =
DayContainer(ItemCalendarDayBinding.bind(view))

override fun bind(container: DayContainer, day: CalendarDay) {
val (startDate, endDate) = this.calendar

container.binding.tvCalendarDay.text = day.date.dayOfMonth.toString()

if (day.owner != DayOwner.THIS_MONTH) {
container.binding.tvCalendarDay.setTextColor(
ContextCompat.getColor(
calendarView.context,
R.color.gray
)
)
// day.day와 day.date.monthValue를 지정해서 특정 월, 일에 달렸다는 콩 표시 가능
} else if (day.day == 10 && day.date.monthValue == 11) {
container.binding.root.background = (
ContextCompat.getDrawable(
calendarView.context,
R.drawable.calendar_kong
)
)
} else {
container.binding.tvCalendarDay.setTextColor(
ContextCompat.getColor(
calendarView.context,
R.color.black
)
)
}

if (isInRange(day.date)) {
container.binding.root.setBackgroundColor(
ContextCompat.getColor(
calendarView.context,
R.color.gray
)
)
}

if (startDate == day.date) {
container.binding.root.background = (
ContextCompat.getDrawable(
calendarView.context,
R.drawable.thumbnail_src_small
)
)
} else if (endDate == day.date) {
container.binding.root.background = (
ContextCompat.getDrawable(
calendarView.context,
R.drawable.thumbnail_src_small
)
)
}
}

private fun isInRange(date: LocalDate): Boolean {
val (startDate, endDate) = this.calendar
return startDate == date || endDate == date || (startDate != null && endDate != null && startDate < date && date < endDate)
}
}
Loading