Skip to content

Commit 24db28c

Browse files
committed
✨ 환경설정 화면에서 연결된 계정 정보 보여주기 구현
1 parent e459074 commit 24db28c

File tree

12 files changed

+147
-3
lines changed

12 files changed

+147
-3
lines changed

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,6 @@ interface AccountDataSource {
66
fun getUserNickName(): Flow<String>
77
fun getUserProfileImgUri(): Flow<String>
88
fun getUserUid(): Flow<String>
9+
fun getEmail(): Flow<Result<String>>
910
suspend fun updateUserNickName(uid: String, newNickName: String): Result<String>
1011
}

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

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,11 @@ import androidx.datastore.preferences.core.Preferences
55
import androidx.datastore.preferences.core.edit
66
import androidx.datastore.preferences.core.stringPreferencesKey
77
import com.google.firebase.firestore.FirebaseFirestore
8+
import com.whyranoid.data.account.AccountDataSourceImpl.PreferenceKeys.email
89
import com.whyranoid.data.account.AccountDataSourceImpl.PreferenceKeys.nickName
910
import com.whyranoid.data.account.AccountDataSourceImpl.PreferenceKeys.profileImgUri
1011
import com.whyranoid.data.account.AccountDataSourceImpl.PreferenceKeys.uid
12+
import kotlinx.coroutines.flow.Flow
1113
import kotlinx.coroutines.flow.map
1214
import javax.inject.Inject
1315

@@ -38,6 +40,15 @@ class AccountDataSourceImpl @Inject constructor(
3840
preferences[uid] ?: EMPTY_STRING
3941
}
4042

43+
override fun getEmail(): Flow<Result<String>> {
44+
return dataStoreDb.data
45+
.map { preferences ->
46+
runCatching {
47+
preferences[email] ?: EMPTY_STRING
48+
}
49+
}
50+
}
51+
4152
override suspend fun updateUserNickName(uid: String, newNickName: String) = runCatching {
4253
// 로컬에 업데이트
4354
dataStoreDb.edit { preferences ->

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,10 @@ class AccountRepositoryImpl @Inject constructor(
2525
return accountDataSource.getUserNickName()
2626
}
2727

28+
override fun getEmail(): Flow<Result<String>> {
29+
return accountDataSource.getEmail()
30+
}
31+
2832
override suspend fun updateNickname(uid: String, newNickName: String): Result<String> {
2933
return accountDataSource.updateUserNickName(uid, newNickName)
3034
}

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@ interface AccountRepository {
1717
// 데이터스토어에서 닉네임 가져오기
1818
fun getNickname(): Flow<String>
1919

20+
// 데이터스토어에서 이메일 가져오기
21+
fun getEmail(): Flow<Result<String>>
22+
2023
// 닉네임 수정, 서버에 먼저 보내고 성공하면 로컬에 반영
2124
// 실패하면 실패 사용자에게 알리기
2225
suspend fun updateNickname(uid: String, newNickName: String): Result<String>
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package com.whyranoid.domain.usecase
2+
3+
import com.whyranoid.domain.repository.AccountRepository
4+
import kotlinx.coroutines.flow.Flow
5+
import javax.inject.Inject
6+
7+
class GetEmailUseCase @Inject constructor(private val accountRepository: AccountRepository) {
8+
operator fun invoke(): Flow<Result<String>> = accountRepository.getEmail()
9+
}

domain/src/main/java/com/whyranoid/domain/usecase/GetNicknameUseCase.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import kotlinx.coroutines.flow.Flow
55
import javax.inject.Inject
66

77
class GetNicknameUseCase @Inject constructor(private val accountRepository: AccountRepository) {
8-
suspend operator fun invoke(): Flow<String> {
8+
operator fun invoke(): Flow<String> {
99
return accountRepository.getNickname()
1010
}
1111
}

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

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,19 @@ 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
912
import com.whyranoid.presentation.R
1013
import com.whyranoid.presentation.base.BaseFragment
1114
import com.whyranoid.presentation.databinding.FragmentMyRunBinding
15+
import com.whyranoid.presentation.databinding.ItemCalendarDayBinding
1216
import com.whyranoid.presentation.util.loadImage
1317
import com.whyranoid.presentation.util.repeatWhenUiStarted
1418
import dagger.hilt.android.AndroidEntryPoint
19+
import java.time.YearMonth
20+
import java.time.temporal.WeekFields
21+
import java.util.Locale
1522

1623
@AndroidEntryPoint
1724
internal class MyRunFragment : BaseFragment<FragmentMyRunBinding>(R.layout.fragment_my_run) {
@@ -47,6 +54,28 @@ internal class MyRunFragment : BaseFragment<FragmentMyRunBinding>(R.layout.fragm
4754
}
4855
true
4956
}
57+
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+
75+
calendarView.apply {
76+
setup(firstMonth, lastMonth, firstDayOfWeek)
77+
scrollToMonth(currentMonth)
78+
}
5079
}
5180

5281
private fun observeInfo() {
@@ -92,4 +121,9 @@ internal class MyRunFragment : BaseFragment<FragmentMyRunBinding>(R.layout.fragm
92121
}.show()
93122
}
94123
}
124+
125+
class DayViewContainer(view: View) : ViewContainer(view) {
126+
lateinit var day: CalendarDay
127+
val binding = ItemCalendarDayBinding.bind(view)
128+
}
95129
}
Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,46 @@
11
package com.whyranoid.presentation.myrun
22

3+
import android.os.Bundle
4+
import android.view.View
5+
import androidx.fragment.app.viewModels
36
import com.whyranoid.presentation.R
47
import com.whyranoid.presentation.base.BaseFragment
58
import com.whyranoid.presentation.databinding.FragmentSettingBinding
9+
import com.whyranoid.presentation.model.UiState
10+
import com.whyranoid.presentation.util.repeatWhenUiStarted
11+
import dagger.hilt.android.AndroidEntryPoint
612

7-
internal class SettingFragment : BaseFragment<FragmentSettingBinding>(R.layout.fragment_setting)
13+
@AndroidEntryPoint
14+
internal class SettingFragment : BaseFragment<FragmentSettingBinding>(R.layout.fragment_setting) {
15+
16+
private val viewModel by viewModels<SettingViewModel>()
17+
18+
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
19+
super.onViewCreated(view, savedInstanceState)
20+
21+
observeState()
22+
}
23+
24+
private fun observeState() {
25+
viewLifecycleOwner.repeatWhenUiStarted {
26+
viewModel.emailState.collect { emailState ->
27+
when (emailState) {
28+
is UiState.UnInitialized -> {
29+
// 초기화 안됨
30+
}
31+
is UiState.Loading -> {
32+
// 로딩 중
33+
}
34+
is UiState.Success<String> -> initEmailView(emailState.value)
35+
is UiState.Failure -> {
36+
// 실패
37+
}
38+
}
39+
}
40+
}
41+
}
42+
43+
private fun initEmailView(email: String) {
44+
binding.tvConnectedAccount.text = email
45+
}
46+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
package com.whyranoid.presentation.myrun
2+
3+
import androidx.lifecycle.ViewModel
4+
import androidx.lifecycle.viewModelScope
5+
import com.whyranoid.domain.usecase.GetEmailUseCase
6+
import com.whyranoid.presentation.model.UiState
7+
import dagger.hilt.android.lifecycle.HiltViewModel
8+
import kotlinx.coroutines.flow.MutableStateFlow
9+
import kotlinx.coroutines.flow.StateFlow
10+
import kotlinx.coroutines.flow.asStateFlow
11+
import kotlinx.coroutines.launch
12+
import javax.inject.Inject
13+
14+
@HiltViewModel
15+
class SettingViewModel @Inject constructor(
16+
private val getEmailUseCase: GetEmailUseCase
17+
) : ViewModel() {
18+
19+
init {
20+
getEmail()
21+
}
22+
23+
private val _emailState = MutableStateFlow<UiState<String>>(UiState.UnInitialized)
24+
val emailState: StateFlow<UiState<String>>
25+
get() = _emailState.asStateFlow()
26+
27+
private fun getEmail() {
28+
viewModelScope.launch {
29+
_emailState.value = UiState.Loading
30+
31+
getEmailUseCase().collect { emailResult ->
32+
emailResult.onSuccess { email ->
33+
_emailState.value = UiState.Success(email)
34+
}.onFailure { throwable ->
35+
_emailState.value = UiState.Failure(throwable)
36+
}
37+
}
38+
}
39+
}
40+
}

presentation/src/main/res/layout/fragment_my_run.xml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,9 +86,10 @@
8686
<com.kizitonwose.calendarview.CalendarView
8787
android:id="@+id/calendar_view"
8888
android:layout_width="0dp"
89-
android:layout_height="wrap_content"
89+
android:layout_height="400dp"
9090
android:layout_marginHorizontal="16dp"
9191
android:layout_marginTop="20dp"
92+
app:cv_orientation="horizontal"
9293
app:cv_dayViewResource="@layout/item_calendar_day"
9394
app:cv_hasBoundaries="false"
9495
app:cv_scrollMode="paged"

0 commit comments

Comments
 (0)