Skip to content
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
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package com.into.websoso.ui.accountInfo
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.into.websoso.data.account.AccountRepository
import com.into.websoso.data.feed.repository.UpdatedFeedRepository
import com.into.websoso.data.filter.repository.MyLibraryFilterRepository
import com.into.websoso.data.library.repository.MyLibraryRepository
import com.into.websoso.data.repository.PushMessageRepository
Expand All @@ -28,6 +29,7 @@ class AccountInfoViewModel
private val accountRepository: AccountRepository,
private val libraryRepository: MyLibraryRepository,
private val filterRepository: MyLibraryFilterRepository,
private val feedRepository: UpdatedFeedRepository,
) : ViewModel() {
private val _userEmail: MutableStateFlow<String> = MutableStateFlow("")
val userEmail: StateFlow<String> get() = _userEmail.asStateFlow()
Expand Down Expand Up @@ -55,6 +57,8 @@ class AccountInfoViewModel

accountRepository
.deleteTokens(userDeviceIdentifier)
// 서버 로그아웃 성공·실패와 관계없이 로그인 화면으로 가므로, 보내지 못한 좋아요 기록을 함께 버린다.
.also { feedRepository.discardPendingLikes() }
.onSuccess {
userRepository.removeTermsAgreementChecked()
pushMessageRepository.clearFCMToken()
Expand Down
5 changes: 5 additions & 0 deletions app/src/main/java/com/into/websoso/ui/main/MainViewModel.kt
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import androidx.lifecycle.SavedStateHandle
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.into.websoso.data.account.AccountRepository
import com.into.websoso.data.feed.repository.UpdatedFeedRepository
import com.into.websoso.data.repository.PushMessageRepository
import com.into.websoso.data.repository.UserRepository
import com.into.websoso.ui.main.model.MainUiState
Expand All @@ -21,6 +22,7 @@ class MainViewModel
private val userRepository: UserRepository,
private val accountRepository: AccountRepository,
private val pushMessageRepository: PushMessageRepository,
private val feedRepository: UpdatedFeedRepository,
savedStateHandle: SavedStateHandle,
) : ViewModel() {
private var userId: Long = DEFAULT_USER_ID
Expand All @@ -34,6 +36,8 @@ class MainViewModel
val isMyPageTooltipPending: LiveData<Boolean> get() = _isMyPageTooltipPending

init {
// 새로 로그인해 메인에 들어왔을 수 있다. 사용자 정보로 계정을 확인할 때까지 이전 좋아요 기록을 보류한다.
feedRepository.beginAccountCheck()
viewModelScope.launch {
_isMyPageTooltipPending.value = !userRepository.fetchMyPageTooltipConfirmed()
}
Expand All @@ -59,6 +63,7 @@ class MainViewModel
}.onSuccess { userInfo ->
userId = userInfo.userId
accountRepository.updateUserId(userId)
feedRepository.confirmAccount(userId)
_mainUiState.value = mainUiState.value?.copy(
nickname = userInfo.nickname,
loading = false,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.into.websoso.data.account.AccountRepository
import com.into.websoso.data.feed.repository.UpdatedFeedRepository
import com.into.websoso.data.filter.repository.MyLibraryFilterRepository
import com.into.websoso.data.library.repository.MyLibraryRepository
import com.into.websoso.data.repository.PushMessageRepository
Expand All @@ -23,6 +24,7 @@ class WithdrawSecondViewModel
private val userRepository: UserRepository,
private val libraryRepository: MyLibraryRepository,
private val filterRepository: MyLibraryFilterRepository,
private val feedRepository: UpdatedFeedRepository,
) : ViewModel() {
private val _withdrawReason: MutableLiveData<String> = MutableLiveData("")
val withdrawReason: LiveData<String> get() = _withdrawReason
Expand Down Expand Up @@ -85,6 +87,8 @@ class WithdrawSecondViewModel
accountRepository
.deleteAccount(reason.orEmpty())
.onSuccess {
// 탈퇴한 계정의 보내지 못한 좋아요 기록은 로그아웃과 같이 버린다.
feedRepository.discardPendingLikes()
_isWithDrawSuccess.value = true
userRepository.removeTermsAgreementChecked()
pushMessageRepository.clearFCMToken()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import androidx.datastore.preferences.core.MutablePreferences
import androidx.datastore.preferences.core.Preferences
import androidx.datastore.preferences.core.booleanPreferencesKey
import androidx.datastore.preferences.core.edit
import androidx.datastore.preferences.core.longPreferencesKey
import androidx.datastore.preferences.core.preferencesOf
import androidx.datastore.preferences.core.stringPreferencesKey
import androidx.datastore.preferences.core.stringSetPreferencesKey
Expand Down Expand Up @@ -94,6 +95,22 @@ internal class DefaultPendingFeedLikeStore
return deleted
}

override suspend fun claimPendingLikes(accountId: Long) {
pendingFeedLikeDataStore.edit { preferences ->
preferences.setAsideUnreadableLikes()
if (preferences[PENDING_FEED_LIKES_ACCOUNT_ID_KEY] == accountId) return@edit
preferences.remove(PENDING_FEED_LIKES_KEY)
preferences[PENDING_FEED_LIKES_ACCOUNT_ID_KEY] = accountId
}
}

override suspend fun clearPendingLikes() {
pendingFeedLikeDataStore.edit { preferences ->
preferences.remove(PENDING_FEED_LIKES_KEY)
preferences.remove(PENDING_FEED_LIKES_ACCOUNT_ID_KEY)
}
}

override suspend fun readResetNotice(): Boolean {
var hasNotice = false
pendingFeedLikeDataStore.edit { preferences ->
Expand Down Expand Up @@ -146,6 +163,9 @@ internal class DefaultPendingFeedLikeStore
private val PENDING_FEED_LIKES_KEY = stringPreferencesKey("PENDING_FEED_LIKES_KEY")
private val PENDING_FEED_LIKES_RESET_KEY = booleanPreferencesKey("PENDING_FEED_LIKES_RESET_KEY")

// 기록을 남긴 계정의 서버 사용자 ID입니다. 없으면 계정 정보가 없던 이전 형식의 기록입니다.
private val PENDING_FEED_LIKES_ACCOUNT_ID_KEY = longPreferencesKey("PENDING_FEED_LIKES_ACCOUNT_ID_KEY")

// 형식 변경이나 해석 코드 문제를 고친 뒤 되살릴 수 있도록, 해석하지 못한 원본을 모아 둡니다.
private val PENDING_FEED_LIKES_UNREADABLE_KEY = stringSetPreferencesKey("PENDING_FEED_LIKES_UNREADABLE_KEY")

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,46 @@ class DefaultPendingFeedLikeStoreTest {
assertEquals(setOf(UNREADABLE_JSON), dataStore.data.first()[PENDING_FEED_LIKES_UNREADABLE_KEY])
}

@Test
fun `같은 계정이 기록을 다시 가져오면 유지하고 다른 계정이 가져오면 지운다`() =
runTest {
val store = createStore(createDataStore(temporaryFolder.newFile(FILE_NAME)))
store.claimPendingLikes(accountId = 1L)
store.updatePendingLike(feedId = 1L, isLiked = true)

store.claimPendingLikes(accountId = 1L)
assertEquals(mapOf(1L to true), store.getPendingLikes())

store.claimPendingLikes(accountId = 2L)
assertTrue(store.getPendingLikes().isEmpty())
}

@Test
fun `계정 정보가 없는 이전 형식의 기록은 어느 계정이 가져와도 지운다`() =
runTest {
val dataStore = createDataStore(temporaryFolder.newFile(FILE_NAME))
dataStore.edit { it[PENDING_FEED_LIKES_KEY] = """{"likes":[{"feedId":1,"isLiked":true}]}""" }
val store = createStore(dataStore)
assertEquals(mapOf(1L to true), store.getPendingLikes())

store.claimPendingLikes(accountId = 1L)

assertTrue(store.getPendingLikes().isEmpty())
}

@Test
fun `기록을 모두 지우면 같은 계정이 다시 가져와도 남은 기록이 없다`() =
runTest {
val store = createStore(createDataStore(temporaryFolder.newFile(FILE_NAME)))
store.claimPendingLikes(accountId = 1L)
store.updatePendingLike(feedId = 1L, isLiked = true)

store.clearPendingLikes()
store.claimPendingLikes(accountId = 1L)

assertTrue(store.getPendingLikes().isEmpty())
}

private fun TestScope.createDataStore(file: File): DataStore<Preferences> =
PreferenceDataStoreFactory.create(
corruptionHandler = DefaultPendingFeedLikeStore.corruptionHandler,
Expand Down
Loading
Loading