-
Notifications
You must be signed in to change notification settings - Fork 5
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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 | ||
|
||
|
@@ -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
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 파이어 베이스를 모듈안에서 만들어주기 보다는 di를 통해 주입해보는건 어떻게 생각하시나요? There was a problem hiding this comment. Choose a reason for hiding this commentThe 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) | ||
|
@@ -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 -> | ||
|
@@ -51,6 +66,15 @@ class AccountDataSourceImpl @Inject constructor( | |
newNickName | ||
} | ||
|
||
override suspend fun signOut(): Result<Boolean> = runCatching { | ||
signOut() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 헉.. 다른 코드가 안보여서 그런건지... 무한 재귀가 되는 것으로 보이는데 혹시 어떻게 동작하나요? There was a problem hiding this comment. Choose a reason for hiding this commentThe 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" | ||
|
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 | ||
|
@@ -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, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 이건 스타일이겠지만 저는 PrimaryKey 어노테이션처럼 ColumnInfo 어노테이션도 변수 위에 붙여줬어요! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 이거는 kt lint를 돌렸을 때 위 코드처럼 됐던 것 같아요! There was a problem hiding this comment. Choose a reason for hiding this commentThe 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
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 컬럼 네임 작성해주신거 좋았습니다! |
||
|
||
fun RunningHistoryEntity.toRunningHistory(): RunningHistory { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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() | ||
} | ||
|
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 |
---|---|---|
|
@@ -17,6 +17,9 @@ interface AccountRepository { | |
// 데이터스토어에서 닉네임 가져오기 | ||
fun getNickname(): Flow<String> | ||
|
||
// 데이터스토어에서 이메일 가져오기 | ||
fun getEmail(): Flow<Result<String>> | ||
|
||
// 닉네임 수정, 서버에 먼저 보내고 성공하면 로컬에 반영 | ||
// 실패하면 실패 사용자에게 알리기 | ||
suspend fun updateNickname(uid: String, newNickName: String): Result<String> | ||
|
@@ -26,4 +29,10 @@ interface AccountRepository { | |
|
||
// 프로필 사진 서버에 업데이트 | ||
suspend fun updateProfileUrl(newProfileUrl: String): Boolean | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 이친구만 Result가 아닌 게 궁금합니다!! updateNickname은 반환값이 있고 얘는 반환값이 없나요?! There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 |
---|---|---|
@@ -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 |
---|---|---|
@@ -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 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Pair 대신 간단한 데이터 클래스를 만드는 것은 어떨까요?? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 동의합니다! There was a problem hiding this comment. Choose a reason for hiding this commentThe 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) | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
혹시 버전을 올리신 이유가 있나요??
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
버전이 업그레이드 됐다고 표시되더라고요! 며칠 전에 릴리즈 된 것 같습니다