Skip to content

Commit 4abe7b0

Browse files
committed
✨ 로그아웃, 회원탈퇴 로직 구현 및 캘린더 수정 및 달린 날짜에 아이콘 뜨도록 구현
1 parent 24db28c commit 4abe7b0

File tree

14 files changed

+191
-32
lines changed

14 files changed

+191
-32
lines changed

build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ buildscript {
1414
kotlinxCoroutinesVersion = "1.6.4"
1515
paging3Version = "3.1.1"
1616
navVersion = "2.5.3"
17-
playServicesAuthVersion = "20.3.0"
17+
playServicesAuthVersion = "20.4.0"
1818
hiltVersion = "2.44"
1919
lottieVersion = "5.2.0"
2020
activityKtxVersion = "1.6.1"

data/build.gradle

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@ dependencies {
4444
implementation platform("com.google.firebase:firebase-bom:$firebaseVersion")
4545
implementation "com.google.firebase:firebase-analytics-ktx"
4646
implementation "com.google.firebase:firebase-firestore-ktx"
47+
implementation "com.google.firebase:firebase-auth-ktx"
48+
implementation "com.google.android.gms:play-services-auth:$playServicesAuthVersion"
4749

4850
// Hilt
4951
implementation "com.google.dagger:hilt-android:$hiltVersion"

data/src/main/java/com/whyranoid/data/account/AccountDataSource.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,6 @@ interface AccountDataSource {
88
fun getUserUid(): Flow<String>
99
fun getEmail(): Flow<Result<String>>
1010
suspend fun updateUserNickName(uid: String, newNickName: String): Result<String>
11+
suspend fun signOut(): Result<Boolean>
12+
suspend fun withDrawal(): Result<Boolean>
1113
}

data/src/main/java/com/whyranoid/data/account/AccountDataSourceImpl.kt

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import androidx.datastore.core.DataStore
44
import androidx.datastore.preferences.core.Preferences
55
import androidx.datastore.preferences.core.edit
66
import androidx.datastore.preferences.core.stringPreferencesKey
7+
import com.google.firebase.auth.FirebaseAuth
78
import com.google.firebase.firestore.FirebaseFirestore
89
import com.whyranoid.data.account.AccountDataSourceImpl.PreferenceKeys.email
910
import com.whyranoid.data.account.AccountDataSourceImpl.PreferenceKeys.nickName
@@ -18,6 +19,9 @@ class AccountDataSourceImpl @Inject constructor(
1819
private val fireBaseDb: FirebaseFirestore
1920
) : AccountDataSource {
2021

22+
private val auth = FirebaseAuth.getInstance()
23+
private val currentUser = auth.currentUser
24+
2125
private object PreferenceKeys {
2226
val uid = stringPreferencesKey(UID_KEY)
2327
val email = stringPreferencesKey(EMAIL_KEY)
@@ -62,6 +66,15 @@ class AccountDataSourceImpl @Inject constructor(
6266
newNickName
6367
}
6468

69+
override suspend fun signOut(): Result<Boolean> = runCatching {
70+
signOut()
71+
true
72+
}
73+
74+
override suspend fun withDrawal(): Result<Boolean> {
75+
TODO("Not yet implemented")
76+
}
77+
6578
companion object {
6679
private const val UID_KEY = "uid"
6780
private const val EMAIL_KEY = "email"

data/src/main/java/com/whyranoid/data/account/AccountRepositoryImpl.kt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,4 +40,12 @@ class AccountRepositoryImpl @Inject constructor(
4040
override suspend fun updateProfileUrl(newProfileUrl: String): Boolean {
4141
return true
4242
}
43+
44+
override suspend fun signOut(): Result<Boolean> {
45+
TODO("Not yet implemented")
46+
}
47+
48+
override suspend fun withDrawal(): Result<Boolean> {
49+
TODO("Not yet implemented")
50+
}
4351
}

domain/src/main/java/com/whyranoid/domain/repository/AccountRepository.kt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,4 +29,10 @@ interface AccountRepository {
2929

3030
// 프로필 사진 서버에 업데이트
3131
suspend fun updateProfileUrl(newProfileUrl: String): Boolean
32+
33+
// 로그아웃
34+
suspend fun signOut(): Result<Boolean>
35+
36+
// 회원탈퇴
37+
suspend fun withDrawal(): Result<Boolean>
3238
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package com.whyranoid.domain.usecase
2+
3+
import com.whyranoid.domain.repository.AccountRepository
4+
import javax.inject.Inject
5+
6+
class SignOutUseCase @Inject constructor(private val accountRepository: AccountRepository) {
7+
suspend operator fun invoke(): Result<Boolean> {
8+
return accountRepository.signOut()
9+
}
10+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package com.whyranoid.domain.usecase
2+
3+
import com.whyranoid.domain.repository.AccountRepository
4+
import javax.inject.Inject
5+
6+
class WithDrawalUseCase @Inject constructor(private val accountRepository: AccountRepository) {
7+
suspend operator fun invoke(): Result<Boolean> {
8+
return accountRepository.withDrawal()
9+
}
10+
}
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
package com.whyranoid.presentation.myrun
2+
3+
import android.view.View
4+
import androidx.core.content.ContextCompat
5+
import com.kizitonwose.calendarview.CalendarView
6+
import com.kizitonwose.calendarview.model.CalendarDay
7+
import com.kizitonwose.calendarview.model.DayOwner
8+
import com.kizitonwose.calendarview.ui.DayBinder
9+
import com.kizitonwose.calendarview.ui.ViewContainer
10+
import com.whyranoid.presentation.R
11+
import com.whyranoid.presentation.databinding.ItemCalendarDayBinding
12+
import java.time.LocalDate
13+
14+
class CalendarDayBinder(
15+
private val calendarView: CalendarView
16+
) : DayBinder<CalendarDayBinder.DayContainer> {
17+
private var calendar: Pair<LocalDate?, LocalDate?> = null to null
18+
19+
class DayContainer(
20+
val binding: ItemCalendarDayBinding
21+
) : ViewContainer(binding.root)
22+
23+
override fun create(view: View): DayContainer =
24+
DayContainer(ItemCalendarDayBinding.bind(view))
25+
26+
override fun bind(container: DayContainer, day: CalendarDay) {
27+
val (startDate, endDate) = this.calendar
28+
29+
container.binding.tvCalendarDay.text = day.date.dayOfMonth.toString()
30+
31+
if (day.owner != DayOwner.THIS_MONTH) {
32+
container.binding.tvCalendarDay.setTextColor(
33+
ContextCompat.getColor(
34+
calendarView.context,
35+
R.color.gray
36+
)
37+
)
38+
// day.day와 day.date.monthValue를 지정해서 특정 월, 일에 달렸다는 콩 표시 가능
39+
} else if (day.day == 10 && day.date.monthValue == 11) {
40+
container.binding.root.background = (
41+
ContextCompat.getDrawable(
42+
calendarView.context,
43+
R.drawable.calendar_kong
44+
)
45+
)
46+
} else {
47+
container.binding.tvCalendarDay.setTextColor(
48+
ContextCompat.getColor(
49+
calendarView.context,
50+
R.color.black
51+
)
52+
)
53+
}
54+
55+
if (isInRange(day.date)) {
56+
container.binding.root.setBackgroundColor(
57+
ContextCompat.getColor(
58+
calendarView.context,
59+
R.color.gray
60+
)
61+
)
62+
}
63+
64+
if (startDate == day.date) {
65+
container.binding.root.background = (
66+
ContextCompat.getDrawable(
67+
calendarView.context,
68+
R.drawable.thumbnail_src_small
69+
)
70+
)
71+
} else if (endDate == day.date) {
72+
container.binding.root.background = (
73+
ContextCompat.getDrawable(
74+
calendarView.context,
75+
R.drawable.thumbnail_src_small
76+
)
77+
)
78+
}
79+
}
80+
81+
private fun isInRange(date: LocalDate): Boolean {
82+
val (startDate, endDate) = this.calendar
83+
return startDate == date || endDate == date || (startDate != null && endDate != null && startDate < date && date < endDate)
84+
}
85+
}

presentation/src/main/java/com/whyranoid/presentation/myrun/MyRunFragment.kt

Lines changed: 21 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,9 @@ import android.widget.EditText
66
import androidx.appcompat.app.AlertDialog
77
import androidx.fragment.app.viewModels
88
import androidx.navigation.fragment.findNavController
9-
import com.kizitonwose.calendarview.model.CalendarDay
10-
import com.kizitonwose.calendarview.ui.DayBinder
11-
import com.kizitonwose.calendarview.ui.ViewContainer
129
import com.whyranoid.presentation.R
1310
import com.whyranoid.presentation.base.BaseFragment
1411
import com.whyranoid.presentation.databinding.FragmentMyRunBinding
15-
import com.whyranoid.presentation.databinding.ItemCalendarDayBinding
1612
import com.whyranoid.presentation.util.loadImage
1713
import com.whyranoid.presentation.util.repeatWhenUiStarted
1814
import dagger.hilt.android.AndroidEntryPoint
@@ -31,6 +27,11 @@ internal class MyRunFragment : BaseFragment<FragmentMyRunBinding>(R.layout.fragm
3127

3228
private val runningHistoryAdapter = MyRunningHistoryAdapter()
3329

30+
private val currentMonth = YearMonth.now()
31+
private val firstMonth = currentMonth.minusMonths(5)
32+
private val lastMonth = currentMonth.plusMonths(5)
33+
private val firstDayOfWeek = WeekFields.of(Locale.getDefault()).firstDayOfWeek
34+
3435
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
3536
super.onViewCreated(view, savedInstanceState)
3637

@@ -55,43 +56,33 @@ internal class MyRunFragment : BaseFragment<FragmentMyRunBinding>(R.layout.fragm
5556
true
5657
}
5758

58-
calendarView.dayBinder = object : DayBinder<DayViewContainer> {
59-
60-
override fun create(view: View) = DayViewContainer(view)
61-
62-
override fun bind(container: DayViewContainer, day: CalendarDay) {
63-
container.day = day
64-
val textView = container.binding.tvCalendarDay
65-
66-
textView.text = day.date.dayOfMonth.toString()
67-
}
68-
}
69-
70-
val currentMonth = YearMonth.now()
71-
val firstMonth = currentMonth.minusMonths(240)
72-
val lastMonth = currentMonth.plusMonths(240)
73-
val firstDayOfWeek = WeekFields.of(Locale.getDefault()).firstDayOfWeek
74-
7559
calendarView.apply {
60+
itemAnimator = null
61+
dayBinder = CalendarDayBinder(this)
62+
monthScrollListener = { calendarMonth ->
63+
onMonthScrolled(calendarMonth.yearMonth)
64+
}
65+
// 모든 달력 범위 설정
7666
setup(firstMonth, lastMonth, firstDayOfWeek)
67+
// 첫 화면에서 보일 달 설정
7768
scrollToMonth(currentMonth)
7869
}
7970
}
8071

8172
private fun observeInfo() {
82-
repeatWhenUiStarted {
73+
viewLifecycleOwner.repeatWhenUiStarted {
8374
viewModel.nickName.collect { nickName ->
8475
binding.tvNickName.text = nickName
8576
}
8677
}
8778

88-
repeatWhenUiStarted {
79+
viewLifecycleOwner.repeatWhenUiStarted {
8980
viewModel.profileImgUri.collect { profileImgUri ->
9081
binding.ivProfileImage.loadImage(profileImgUri)
9182
}
9283
}
9384

94-
repeatWhenUiStarted {
85+
viewLifecycleOwner.repeatWhenUiStarted {
9586
viewModel.runningHistoryList.collect { runningHistoryList ->
9687
runningHistoryAdapter.submitList(runningHistoryList)
9788
}
@@ -122,8 +113,11 @@ internal class MyRunFragment : BaseFragment<FragmentMyRunBinding>(R.layout.fragm
122113
}
123114
}
124115

125-
class DayViewContainer(view: View) : ViewContainer(view) {
126-
lateinit var day: CalendarDay
127-
val binding = ItemCalendarDayBinding.bind(view)
116+
private fun onMonthScrolled(currentMonth: YearMonth) {
117+
val visibleMonth = binding.calendarView.findFirstVisibleMonth() ?: return
118+
binding.tvMonthIndicator.text = visibleMonth.yearMonth.month.toString()
119+
if (currentMonth != visibleMonth.yearMonth) {
120+
binding.calendarView.smoothScrollToMonth(currentMonth)
121+
}
128122
}
129123
}

0 commit comments

Comments
 (0)