diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 942ebee8..c323c528 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -83,6 +83,10 @@
android:name=".presentation.main.notification.NotificationActivity"
android:exported="false"
android:screenOrientation="portrait" />
+
(R.layout.activity_main
private val isUploadSuccess by lazy { intent.getBooleanExtra(KEY_FEED_UPLOAD, false) }
private val isDeleteSuccess by lazy { intent.getBooleanExtra(KEY_FEED_DELETE, false) }
- private val prevScreenName by lazy { intent.getStringExtra(KEY_PREV_SCREEN) }
private val notiType by lazy { intent.getStringExtra(KEY_NOTI_TYPE) }
private val feedId by lazy { intent.getStringExtra(KEY_FEED_ID) }
@@ -125,11 +122,7 @@ class MainActivity : BindingActivity(R.layout.activity_main
return
}
- if (prevScreenName == MY_FEED_SCREEN) {
- navigateToMyPageFragment(KEY_TO_MYFEED, true)
- } else {
- navigateTo()
- }
+ navigateTo()
}
private fun showWineyFeedResultSnackBar() {
@@ -204,12 +197,6 @@ class MainActivity : BindingActivity(R.layout.activity_main
}
}
- private inline fun navigateTo() {
- supportFragmentManager.commit {
- replace(R.id.fcv_main, T::class.simpleName)
- }
- }
-
private fun navigateToMyPageFragment(key: String, value: Boolean) {
supportFragmentManager.commit {
val bundle = Bundle()
@@ -232,18 +219,20 @@ class MainActivity : BindingActivity(R.layout.activity_main
startActivity(intent)
}
- companion object {
- const val KEY_FEED_ID = "feedId"
- const val KEY_TO_MY_PAGE = "navigateMyPage"
- const val KEY_FROM_GOAL_PATH = "fromGoalPath"
+ private inline fun navigateTo() {
+ supportFragmentManager.commit {
+ replace(R.id.fcv_main, T::class.simpleName)
+ }
+ }
+ companion object {
private const val KEY_FEED_UPLOAD = "upload"
private const val KEY_FEED_DELETE = "delete"
private const val KEY_NOTI_TYPE = "notiType"
private const val KEY_FROM_NOTI = "fromNoti"
- private const val KEY_TO_MYFEED = "toMyFeed"
- private const val KEY_PREV_SCREEN = "PREV_SCREEN_NAME"
- private const val MY_FEED_SCREEN = "MyFeedFragment"
+ const val KEY_FEED_ID = "feedId"
+ const val KEY_TO_MY_PAGE = "navigateMyPage"
+ const val KEY_FROM_GOAL_PATH = "fromGoalPath"
}
}
diff --git a/app/src/main/java/org/go/sopt/winey/presentation/main/MainViewModel.kt b/app/src/main/java/org/go/sopt/winey/presentation/main/MainViewModel.kt
index ec55fb3e..0877f4e2 100644
--- a/app/src/main/java/org/go/sopt/winey/presentation/main/MainViewModel.kt
+++ b/app/src/main/java/org/go/sopt/winey/presentation/main/MainViewModel.kt
@@ -26,7 +26,7 @@ class MainViewModel @Inject constructor(
private val dataStoreRepository: DataStoreRepository,
private val notificationRepository: NotificationRepository
) : ViewModel() {
- private val _getUserState = MutableStateFlow>(UiState.Loading)
+ private val _getUserState = MutableStateFlow>(UiState.Empty)
val getUserState: StateFlow> = _getUserState.asStateFlow()
private val _logoutState = MutableStateFlow>(UiState.Empty)
@@ -44,7 +44,7 @@ class MainViewModel @Inject constructor(
authRepository.getUser()
.onSuccess { response ->
- Timber.e("SUCCESS GET USER IN MAIN")
+ Timber.d("SUCCESS GET USER IN MAIN")
dataStoreRepository.saveUserInfo(response)
_getUserState.value = UiState.Success(response)
}
@@ -61,7 +61,7 @@ class MainViewModel @Inject constructor(
}
}
- private fun postLogout() {
+ fun postLogout() {
viewModelScope.launch {
_logoutState.value = UiState.Loading
diff --git a/app/src/main/java/org/go/sopt/winey/presentation/main/feed/WineyFeedFragment.kt b/app/src/main/java/org/go/sopt/winey/presentation/main/feed/WineyFeedFragment.kt
index e84e4e49..dd04f690 100644
--- a/app/src/main/java/org/go/sopt/winey/presentation/main/feed/WineyFeedFragment.kt
+++ b/app/src/main/java/org/go/sopt/winey/presentation/main/feed/WineyFeedFragment.kt
@@ -6,7 +6,6 @@ import android.os.Bundle
import android.view.View
import androidx.core.view.isVisible
import androidx.fragment.app.activityViewModels
-import androidx.fragment.app.commit
import androidx.fragment.app.viewModels
import androidx.lifecycle.flowWithLifecycle
import androidx.lifecycle.lifecycleScope
@@ -14,21 +13,19 @@ import androidx.paging.LoadState
import androidx.paging.PagingData
import androidx.recyclerview.widget.ConcatAdapter
import androidx.recyclerview.widget.SimpleItemAnimator
-import com.google.android.material.bottomnavigation.BottomNavigationView
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.flow.first
-import kotlinx.coroutines.flow.firstOrNull
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.launch
import org.go.sopt.winey.R
import org.go.sopt.winey.databinding.FragmentWineyFeedBinding
+import org.go.sopt.winey.domain.entity.UserV2
import org.go.sopt.winey.domain.entity.WineyFeed
import org.go.sopt.winey.domain.repository.DataStoreRepository
import org.go.sopt.winey.presentation.main.MainViewModel
import org.go.sopt.winey.presentation.main.feed.detail.DetailActivity
import org.go.sopt.winey.presentation.main.feed.upload.UploadActivity
-import org.go.sopt.winey.presentation.main.mypage.MyPageFragment
import org.go.sopt.winey.presentation.main.mypage.goal.GoalPathActivity
import org.go.sopt.winey.presentation.main.notification.NotificationActivity
import org.go.sopt.winey.presentation.model.WineyDialogLabel
@@ -60,9 +57,9 @@ class WineyFeedFragment :
private val viewModel by viewModels()
private val mainViewModel by activityViewModels()
private lateinit var wineyFeedAdapter: WineyFeedAdapter
- private lateinit var wineyFeedHeaderAdapter: WineyFeedHeaderAdapter
- private lateinit var wineyFeedGoalAdapter: WineyFeedGoalAdapter
private lateinit var wineyFeedLoadAdapter: WineyFeedLoadAdapter
+ private lateinit var wineyFeedHeaderAdapter: WineyFeedHeaderAdapter
+ private var wineyFeedGoalAdapter: WineyFeedGoalAdapter? = null
private var clickedFeedId = -1
@Inject
@@ -109,7 +106,6 @@ class WineyFeedFragment :
/** Adapter */
private fun initAdapter() {
- initGoalAdapter()
wineyFeedHeaderAdapter = WineyFeedHeaderAdapter(
onBannerClicked = {
navigateToWineyInstagram()
@@ -129,21 +125,16 @@ class WineyFeedFragment :
}
)
wineyFeedLoadAdapter = WineyFeedLoadAdapter()
+ initConcatAdapter()
+ }
+ private fun initConcatAdapter() {
binding.rvWineyfeedPost.adapter = ConcatAdapter(
wineyFeedHeaderAdapter,
- wineyFeedGoalAdapter,
wineyFeedAdapter.withLoadStateFooter(wineyFeedLoadAdapter)
)
}
- private fun initGoalAdapter() {
- viewLifeCycleScope.launch {
- val user = dataStoreRepository.getUserInfo().firstOrNull() ?: return@launch
- wineyFeedGoalAdapter = WineyFeedGoalAdapter(requireContext(), user)
- }
- }
-
private fun navigateToWineyInstagram() {
val url = INSTAGRAM_URL
val intent = Intent(Intent.ACTION_VIEW, Uri.parse(url))
@@ -278,13 +269,25 @@ class WineyFeedFragment :
mainViewModel.getUserState.flowWithLifecycle(viewLifeCycle)
.onEach { state ->
when (state) {
+ is UiState.Loading -> {
+ showLoadingProgressBar()
+ }
+
is UiState.Success -> {
- // 피드 생성, 삭제에 따라 유저 데이터와 프로그레스바 갱신
val userInfo = state.data ?: return@onEach
- wineyFeedGoalAdapter.updateProgressBar(userInfo)
+
+ if (wineyFeedGoalAdapter == null) {
+ updateConcatAdapter(userInfo)
+ } else {
+ // 피드 생성, 삭제에 따라 유저 데이터와 프로그레스바 갱신
+ wineyFeedGoalAdapter?.updateGoalProgressBar(userInfo)
+ }
+
+ dismissLoadingProgressBar()
}
is UiState.Failure -> {
+ dismissLoadingProgressBar()
snackBar(binding.root) { state.msg }
}
@@ -293,6 +296,25 @@ class WineyFeedFragment :
}.launchIn(viewLifeCycleScope)
}
+ private fun updateConcatAdapter(user: UserV2) {
+ wineyFeedGoalAdapter = WineyFeedGoalAdapter(requireContext(), user)
+ binding.rvWineyfeedPost.adapter = ConcatAdapter(
+ wineyFeedHeaderAdapter,
+ wineyFeedGoalAdapter,
+ wineyFeedAdapter.withLoadStateFooter(wineyFeedLoadAdapter)
+ )
+ }
+
+ private fun showLoadingProgressBar() {
+ binding.pbWineyfeedLoading.isVisible = true
+ binding.rvWineyfeedPost.isVisible = false
+ }
+
+ private fun dismissLoadingProgressBar() {
+ binding.pbWineyfeedLoading.isVisible = false
+ binding.rvWineyfeedPost.isVisible = true
+ }
+
private fun initGetWineyFeedListStateObserver() {
viewModel.getWineyFeedListState.flowWithLifecycle(viewLifeCycle)
.onEach { state ->
@@ -450,23 +472,6 @@ class WineyFeedFragment :
}
/** Amplitude Event Tagging */
- private fun sendDialogClickEvent(isNavigate: Boolean) {
- val eventProperties = JSONObject()
-
- try {
- if (isNavigate) {
- eventProperties.put("method", "yes")
- } else {
- eventProperties.put("method", "no")
- }
- } catch (e: JSONException) {
- System.err.println("Invalid JSON")
- e.printStackTrace()
- }
-
- amplitudeUtils.logEvent("click_goalsetting", eventProperties)
- }
-
private fun sendWineyFeedEvent(type: EventType, feed: WineyFeed) {
val eventProperties = JSONObject()
@@ -496,51 +501,11 @@ class WineyFeedFragment :
}
}
- private fun showDefaultGoalSettingDialog() {
- amplitudeUtils.logEvent("view_goalsetting_popup")
-
- val dialog = WineyDialogFragment.newInstance(
- WineyDialogLabel(
- stringOf(R.string.wineyfeed_goal_dialog_title),
- stringOf(R.string.wineyfeed_goal_dialog_subtitle),
- stringOf(R.string.wineyfeed_goal_dialog_negative_button),
- stringOf(R.string.wineyfeed_goal_dialog_positive_button)
- ),
- handleNegativeButton = {
- sendDialogClickEvent(false)
- },
- handlePositiveButton = {
- sendDialogClickEvent(true)
- navigateToMyPageWithBundle()
- }
- )
-
- activity?.supportFragmentManager?.let { dialog.show(it, TAG_DEFAULT_GOAL_SETTING_DIALOG) }
- }
-
- private fun navigateToMyPageWithBundle() {
- val myPageFragment = MyPageFragment().apply {
- arguments = Bundle().apply {
- putBoolean(KEY_FROM_WINEY_FEED, true)
- }
- }
- activity?.supportFragmentManager?.commit {
- replace(R.id.fcv_main, myPageFragment)
- }
- syncBnvSelectedItem()
- }
-
- private fun syncBnvSelectedItem() {
- val bottomNav: BottomNavigationView = requireActivity().findViewById(R.id.bnv_main)
- bottomNav.selectedItemId = R.id.menu_mypage
- }
-
companion object {
private const val INSTAGRAM_URL =
"https://instagram.com/winey__official?igshid=MzRlODBiNWFlZA=="
-
private const val MSG_WINEYFEED_ERROR = "ERROR"
- private const val TAG_DEFAULT_GOAL_SETTING_DIALOG = "DEFAULT_GOAL_SETTING_DIALOG"
+
private const val TAG_FEED_DELETE_DIALOG = "FEED_DELETE_DIALOG"
private const val TAG_FEED_REPORT_DIALOG = "FEED_REPORT_DIALOG"
private const val TAG_UPLOAD_DIALOG = "UPLOAD_DIALOG"
@@ -548,7 +513,6 @@ class WineyFeedFragment :
private const val KEY_PREV_SCREEN_NAME = "PREV_SCREEN_NAME"
private const val WINEY_FEED_SCREEN = "WineyFeedFragment"
- private const val KEY_FROM_WINEY_FEED = "fromWineyFeed"
private const val KEY_FEED_ID = "feedId"
private const val KEY_FEED_WRITER_ID = "feedWriterId"
diff --git a/app/src/main/java/org/go/sopt/winey/presentation/main/feed/WineyFeedGoalAdapter.kt b/app/src/main/java/org/go/sopt/winey/presentation/main/feed/WineyFeedGoalAdapter.kt
index 8c7eb5f3..06369ebe 100644
--- a/app/src/main/java/org/go/sopt/winey/presentation/main/feed/WineyFeedGoalAdapter.kt
+++ b/app/src/main/java/org/go/sopt/winey/presentation/main/feed/WineyFeedGoalAdapter.kt
@@ -15,7 +15,6 @@ class WineyFeedGoalAdapter(
private val initialUser: UserV2
) : RecyclerView.Adapter() {
private lateinit var binding: ItemWineyfeedGoalBinding
- private var isInitialized = false
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): WineyFeedGoalViewHolder {
binding = ItemWineyfeedGoalBinding.inflate(
@@ -33,18 +32,21 @@ class WineyFeedGoalAdapter(
override fun getItemCount(): Int = ITEM_COUNT
inner class WineyFeedGoalViewHolder : RecyclerView.ViewHolder(binding.root) {
+ private var isInitialized = false
+
fun bind() {
if (!isInitialized) {
isInitialized = true
- // 최초 1회만 실행 (아이템 뷰의 재활용에 따라 예전 초기 데이터가 반영되는 문제 해결)
- updateProgressBar(initialUser)
+ // 초기 유저 데이터로 최초 1회만 바인딩
+ updateGoalProgressBar(initialUser)
}
}
}
- fun updateProgressBar(user: UserV2) {
+ fun updateGoalProgressBar(user: UserV2) {
if (::binding.isInitialized) {
+ // 피드 생성, 삭제에 따라 바뀌는 유저 데이터 반영
binding.user = user
updateProgressBarRate(user)
}
diff --git a/app/src/main/java/org/go/sopt/winey/presentation/main/mypage/MyPageFragment.kt b/app/src/main/java/org/go/sopt/winey/presentation/main/mypage/MyPageFragment.kt
index 8961dc8f..db0ee8aa 100644
--- a/app/src/main/java/org/go/sopt/winey/presentation/main/mypage/MyPageFragment.kt
+++ b/app/src/main/java/org/go/sopt/winey/presentation/main/mypage/MyPageFragment.kt
@@ -1,25 +1,15 @@
package org.go.sopt.winey.presentation.main.mypage
-import android.Manifest
-import android.content.ActivityNotFoundException
-import android.content.Context
import android.content.Intent
-import android.content.pm.PackageManager
-import android.os.Build
import android.os.Bundle
-import android.provider.Settings
import android.view.View
import androidx.activity.OnBackPressedCallback
-import androidx.core.content.ContextCompat
-import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels
-import androidx.fragment.app.commit
-import androidx.fragment.app.replace
-import androidx.fragment.app.viewModels
import androidx.lifecycle.flowWithLifecycle
import androidx.lifecycle.lifecycleScope
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.flow.first
+import kotlinx.coroutines.flow.firstOrNull
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.launch
@@ -30,13 +20,12 @@ import org.go.sopt.winey.domain.repository.DataStoreRepository
import org.go.sopt.winey.presentation.main.MainViewModel
import org.go.sopt.winey.presentation.main.mypage.goal.GoalPathActivity
import org.go.sopt.winey.presentation.main.mypage.myfeed.MyFeedActivity
+import org.go.sopt.winey.presentation.main.mypage.setting.SettingActivity
import org.go.sopt.winey.presentation.main.notification.NotificationActivity
import org.go.sopt.winey.presentation.nickname.NicknameActivity
-import org.go.sopt.winey.presentation.onboarding.guide.GuideActivity
import org.go.sopt.winey.util.amplitude.AmplitudeUtils
import org.go.sopt.winey.util.binding.BindingFragment
import org.go.sopt.winey.util.fragment.snackBar
-import org.go.sopt.winey.util.fragment.viewLifeCycle
import org.go.sopt.winey.util.fragment.viewLifeCycleScope
import org.go.sopt.winey.util.view.UiState
import org.go.sopt.winey.util.view.setOnSingleClickListener
@@ -45,7 +34,6 @@ import javax.inject.Inject
@AndroidEntryPoint
class MyPageFragment : BindingFragment(R.layout.fragment_my_page) {
private val mainViewModel by activityViewModels()
- private val myPageViewModel by viewModels()
@Inject
lateinit var dataStoreRepository: DataStoreRepository
@@ -57,19 +45,32 @@ class MyPageFragment : BindingFragment(R.layout.fragment_
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
amplitudeUtils.logEvent("view_mypage")
- initCheckNotificationPermission()
initUserData()
- initNavigation()
-
addListener()
addObserver()
+ }
+
+ // 닉네임 액티비티 갔다가 다시 돌아왔을 때 유저 데이터 갱신하도록
+ override fun onStart() {
+ super.onStart()
+ mainViewModel.getUser()
+ }
+
+ private fun initUserData() {
+ viewLifeCycleScope.launch {
+ val userInfo = dataStoreRepository.getUserInfo().firstOrNull() ?: return@launch
+ updateUserInfo(userInfo)
+ }
+ }
- checkFromWineyFeed()
+ private fun updateUserInfo(data: UserV2) {
+ binding.data = data
}
private fun addListener() {
initEditNicknameButtonClickListener()
+ initSettingButtonClickListener()
initMyFeedButtonClickListener()
initGoalPathButtonClickListener()
registerBackPressedCallback()
@@ -77,71 +78,6 @@ class MyPageFragment : BindingFragment(R.layout.fragment_
private fun addObserver() {
setupGetUserState()
- setupDeleteUserState()
- }
-
- private fun initCheckNotificationPermission() {
- isNotificationPermissionAllowed =
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
- ContextCompat.checkSelfPermission(
- requireContext(),
- Manifest.permission.POST_NOTIFICATIONS
- ) == PackageManager.PERMISSION_GRANTED
- } else {
- true
- }
- }
-
- private fun navigateToNotificationSetting(context: Context) {
- val intent = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
- setNotificationIntentActionOreo(context)
- } else {
- setNorificationIntentActionOreoLess(context)
- }
- try {
- context.startActivity(intent)
- } catch (e: ActivityNotFoundException) {
- e.printStackTrace()
- }
- }
-
- private fun setNotificationIntentActionOreo(context: Context): Intent {
- return Intent().also { intent ->
- intent.action = Settings.ACTION_APP_NOTIFICATION_SETTINGS
- intent.putExtra(Settings.EXTRA_APP_PACKAGE, context.packageName)
- intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
- }
- }
-
- private fun setNorificationIntentActionOreoLess(context: Context): Intent {
- return Intent().also { intent ->
- intent.action = "android.settings.APP_NOTIFICATION_SETTINGS"
- intent.putExtra("app_package", context.packageName)
- intent.putExtra("app_uid", context.applicationInfo?.uid)
- intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
- }
- }
-
- private fun patchUserInfo() {
- lifecycleScope.launch {
- val data = dataStoreRepository.getUserInfo().first()
- val newData = data?.copy(fcmIsAllowed = false)
- dataStoreRepository.saveUserInfo(newData)
- }
- }
-
- // 닉네임 액티비티 갔다가 다시 돌아왔을 때 유저 데이터 갱신하도록
- override fun onStart() {
- super.onStart()
- mainViewModel.getUser()
- initCheckNotificationPermission()
- }
-
- private fun checkFromWineyFeed() {
- val isFromWineyFeed = arguments?.getBoolean(KEY_FROM_WINEY_FEED)
- if (isFromWineyFeed == true) {
- showTargetSettingBottomSheet()
- }
}
private fun initEditNicknameButtonClickListener() {
@@ -150,6 +86,12 @@ class MyPageFragment : BindingFragment(R.layout.fragment_
}
}
+ private fun initSettingButtonClickListener() {
+ binding.ivMypageSetting.setOnClickListener {
+ navigateToSettingScreen()
+ }
+ }
+
private fun initMyFeedButtonClickListener() {
binding.btnMypageMyfeed.setOnSingleClickListener {
navigateToMyFeedScreen()
@@ -158,13 +100,7 @@ class MyPageFragment : BindingFragment(R.layout.fragment_
private fun initGoalPathButtonClickListener() {
binding.btnMypageTrip.setOnClickListener {
- navigateToGoalPath()
- }
- }
-
- private fun navigateToGoalPath() {
- Intent(requireContext(), GoalPathActivity::class.java).apply {
- startActivity(this)
+ navigateToGoalPathScreen()
}
}
@@ -187,61 +123,27 @@ class MyPageFragment : BindingFragment(R.layout.fragment_
requireActivity().onBackPressedDispatcher.addCallback(viewLifecycleOwner, callback)
}
- private fun initUserData() {
- viewLifeCycleScope.launch {
- val data = dataStoreRepository.getUserInfo().first()
- if (data != null) {
- updateUserInfo(data)
- }
- }
- }
-
- private fun initNavigation() {
- val receivedBundle = arguments
- if (receivedBundle != null) {
- val value = receivedBundle.getBoolean(KEY_TO_MYFEED)
- if (value) {
- navigateToMyFeedScreen()
- arguments?.clear()
- }
+ private fun navigateToNicknameScreen() {
+ Intent(requireContext(), NicknameActivity::class.java).apply {
+ putExtra(KEY_PREV_SCREEN_NAME, MY_PAGE_SCREEN)
+ startActivity(this)
}
}
- private fun setupDeleteUserState() {
- myPageViewModel.deleteUserState.flowWithLifecycle(viewLifeCycle)
- .onEach { state ->
- when (state) {
- is UiState.Success -> {
- myPageViewModel.clearDataStore()
- navigateToGuideScreen()
- }
-
- is UiState.Failure -> {
- snackBar(binding.root) { state.msg }
- }
-
- else -> {
- }
- }
- }.launchIn(viewLifeCycleScope)
- }
-
- private fun navigateToGuideScreen() {
- Intent(requireContext(), GuideActivity::class.java).apply {
- addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK)
+ private fun navigateToSettingScreen() {
+ Intent(requireContext(), SettingActivity::class.java).apply {
startActivity(this)
}
}
- private fun navigateToNicknameScreen() {
- Intent(requireContext(), NicknameActivity::class.java).apply {
- putExtra(KEY_PREV_SCREEN_NAME, MY_PAGE_SCREEN)
+ private fun navigateToMyFeedScreen() {
+ Intent(requireContext(), MyFeedActivity::class.java).apply {
startActivity(this)
}
}
- private fun navigateToMyFeedScreen() {
- Intent(requireContext(), MyFeedActivity::class.java).apply {
+ private fun navigateToGoalPathScreen() {
+ Intent(requireContext(), GoalPathActivity::class.java).apply {
startActivity(this)
}
}
@@ -263,33 +165,9 @@ class MyPageFragment : BindingFragment(R.layout.fragment_
}.launchIn(lifecycleScope)
}
- private fun updateUserInfo(data: UserV2) {
- binding.data = data
- }
-
- private fun showTargetSettingBottomSheet() {
- val bottomSheet = TargetAmountBottomSheetFragment()
- bottomSheet.show(parentFragmentManager, bottomSheet.tag)
- amplitudeUtils.logEvent("view_goalsetting")
- }
-
- private fun showTargetNotOverDialog() {
- val dialog = MyPageNotOverDialogFragment()
- dialog.show(parentFragmentManager, dialog.tag)
- }
-
- private inline fun navigateAndBackStack() {
- parentFragmentManager.commit {
- replace(R.id.fcv_main, T::class.simpleName)
- addToBackStack(null)
- }
- }
-
companion object {
private const val KEY_PREV_SCREEN_NAME = "PREV_SCREEN_NAME"
private const val MY_PAGE_SCREEN = "MyPageFragment"
private const val KEY_FROM_NOTI = "fromNoti"
- private const val KEY_FROM_WINEY_FEED = "fromWineyFeed"
- private const val KEY_TO_MYFEED = "toMyFeed"
}
}
diff --git a/app/src/main/java/org/go/sopt/winey/presentation/main/mypage/goal/GoalPathActivity.kt b/app/src/main/java/org/go/sopt/winey/presentation/main/mypage/goal/GoalPathActivity.kt
index 26122b00..ba8545b2 100644
--- a/app/src/main/java/org/go/sopt/winey/presentation/main/mypage/goal/GoalPathActivity.kt
+++ b/app/src/main/java/org/go/sopt/winey/presentation/main/mypage/goal/GoalPathActivity.kt
@@ -13,6 +13,7 @@ import kotlinx.coroutines.flow.firstOrNull
import kotlinx.coroutines.launch
import org.go.sopt.winey.R
import org.go.sopt.winey.databinding.ActivityGoalPathBinding
+import org.go.sopt.winey.domain.entity.UserV2
import org.go.sopt.winey.domain.repository.DataStoreRepository
import org.go.sopt.winey.presentation.main.MainActivity
import org.go.sopt.winey.presentation.main.feed.WineyFeedFragment
@@ -23,6 +24,10 @@ import javax.inject.Inject
@AndroidEntryPoint
class GoalPathActivity : BindingActivity(R.layout.activity_goal_path) {
+ @Inject
+ lateinit var dataStoreRepository: DataStoreRepository
+
+ private var userInfo: UserV2? = null
private val levelUpFromWineyFeed by lazy {
intent.getBooleanExtra(
WineyFeedFragment.KEY_LEVEL_UP,
@@ -30,47 +35,37 @@ class GoalPathActivity : BindingActivity(R.layout.activ
)
}
- @Inject
- lateinit var dataStoreRepository: DataStoreRepository
-
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
- setupFragmentByLevel()
+ initUserData()
initRemainingGoal()
-
+ setupFragmentByLevel()
initBackButtonClickListener()
registerBackPressedCallback()
}
- private fun registerBackPressedCallback() {
- val callback = object : OnBackPressedCallback(true) {
- override fun handleOnBackPressed() {
- if (levelUpFromWineyFeed) {
- navigateToMainScreen()
- } else {
- finish()
- }
- }
+ private fun initUserData() {
+ lifecycleScope.launch {
+ userInfo = dataStoreRepository.getUserInfo().firstOrNull() ?: return@launch
}
- onBackPressedDispatcher.addCallback(this, callback)
}
- private fun initBackButtonClickListener() {
- binding.ivGoalPathBack.setOnClickListener {
- if (levelUpFromWineyFeed) {
- navigateToMainScreen()
- } else {
- finish()
- }
+ private fun initRemainingGoal() {
+ lifecycleScope.launch {
+ binding.tvGoalPathRemainingMoney.text =
+ getString(
+ R.string.goal_path_remaining_money,
+ userInfo?.remainingAmount?.formatAmountNumber()
+ )
+ binding.tvGoalPathRemainingFeed.text =
+ getString(R.string.goal_path_remaining_feed, userInfo?.remainingCount)
}
}
private fun setupFragmentByLevel() {
lifecycleScope.launch {
- val userInfo = dataStoreRepository.getUserInfo().firstOrNull() ?: return@launch
-
- when (userInfo.userLevel) {
+ when (userInfo?.userLevel) {
UserLevel.FIRST.rankName -> {
navigateTo()
}
@@ -105,19 +100,29 @@ class GoalPathActivity : BindingActivity(R.layout.activ
}
}
- private fun initRemainingGoal() {
- lifecycleScope.launch {
- val userInfo = dataStoreRepository.getUserInfo().firstOrNull() ?: return@launch
- binding.tvGoalPathRemainingMoney.text =
- getString(
- R.string.goal_path_remaining_money,
- userInfo.remainingAmount.formatAmountNumber()
- )
- binding.tvGoalPathRemainingFeed.text =
- getString(R.string.goal_path_remaining_feed, userInfo.remainingCount)
+ private fun initBackButtonClickListener() {
+ binding.ivGoalPathBack.setOnClickListener {
+ if (levelUpFromWineyFeed) {
+ navigateToMainScreen()
+ } else {
+ finish()
+ }
}
}
+ private fun registerBackPressedCallback() {
+ val callback = object : OnBackPressedCallback(true) {
+ override fun handleOnBackPressed() {
+ if (levelUpFromWineyFeed) {
+ navigateToMainScreen()
+ } else {
+ finish()
+ }
+ }
+ }
+ onBackPressedDispatcher.addCallback(this, callback)
+ }
+
private fun navigateToMainScreen() {
Intent(this@GoalPathActivity, MainActivity::class.java).apply {
putExtra(MainActivity.KEY_FROM_GOAL_PATH, true)
diff --git a/app/src/main/java/org/go/sopt/winey/presentation/main/mypage/setting/SettingActivity.kt b/app/src/main/java/org/go/sopt/winey/presentation/main/mypage/setting/SettingActivity.kt
new file mode 100644
index 00000000..f6c237ef
--- /dev/null
+++ b/app/src/main/java/org/go/sopt/winey/presentation/main/mypage/setting/SettingActivity.kt
@@ -0,0 +1,349 @@
+package org.go.sopt.winey.presentation.main.mypage.setting
+
+import android.Manifest
+import android.content.Intent
+import android.content.pm.PackageManager
+import android.net.Uri
+import android.os.Build
+import android.os.Bundle
+import android.provider.Settings
+import androidx.activity.viewModels
+import androidx.core.content.ContextCompat
+import androidx.core.view.isGone
+import androidx.core.view.isVisible
+import androidx.lifecycle.flowWithLifecycle
+import androidx.lifecycle.lifecycleScope
+import dagger.hilt.android.AndroidEntryPoint
+import kotlinx.coroutines.flow.first
+import kotlinx.coroutines.flow.launchIn
+import kotlinx.coroutines.flow.onEach
+import kotlinx.coroutines.launch
+import org.go.sopt.winey.R
+import org.go.sopt.winey.databinding.ActivitySettingBinding
+import org.go.sopt.winey.domain.entity.UserV2
+import org.go.sopt.winey.domain.repository.DataStoreRepository
+import org.go.sopt.winey.presentation.main.MainViewModel
+import org.go.sopt.winey.presentation.model.WineyDialogLabel
+import org.go.sopt.winey.presentation.onboarding.guide.GuideActivity
+import org.go.sopt.winey.presentation.onboarding.login.LoginActivity
+import org.go.sopt.winey.util.amplitude.AmplitudeUtils
+import org.go.sopt.winey.util.binding.BindingActivity
+import org.go.sopt.winey.util.context.snackBar
+import org.go.sopt.winey.util.context.stringOf
+import org.go.sopt.winey.util.fragment.WineyDialogFragment
+import org.go.sopt.winey.util.view.UiState
+import org.go.sopt.winey.util.view.setOnSingleClickListener
+import javax.inject.Inject
+
+@AndroidEntryPoint
+class SettingActivity : BindingActivity(R.layout.activity_setting) {
+ private val settingViewModel by viewModels()
+ private val mainViewModel by viewModels()
+
+ @Inject
+ lateinit var dataStoreRepository: DataStoreRepository
+
+ @Inject
+ lateinit var amplitudeUtils: AmplitudeUtils
+ private var isNotificationPermissionAllowed = true
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ addListener()
+ addObserver()
+ initNotificationPermissionState()
+ initUserData()
+ }
+
+ override fun onStart() {
+ super.onStart()
+ initNotificationPermissionState()
+ updateNotificationButtonByPermission()
+ }
+
+ private fun addListener() {
+ init1On1ButtonClickListener()
+ initLogoutButtonClickListener()
+ initTermsButtonClickListener()
+ initWithdrawButtonClickListener()
+ initNotificationPermissionButtonClickListener()
+ initNotiToggleButtonClickListener()
+ initBackButtonClickListener()
+ }
+
+ private fun addObserver() {
+ setupDeleteUserState()
+ setupPatchAllowedNotificationState()
+ setupLogoutState()
+ }
+
+ private fun switchOnNotification() {
+ binding.ivSettingAgree.transitionToState(R.id.end, -1)
+ patchUserInfo()
+ settingViewModel.patchAllowedNotification(isAllowed = false)
+ }
+
+ private fun switchOffNotification() {
+ binding.ivSettingAgree.transitionToState(R.id.start, -1)
+ patchUserInfo()
+ settingViewModel.patchAllowedNotification(isAllowed = true)
+ }
+
+ private fun initNotificationPermissionButtonClickListener() {
+ binding.llSettingAgreePermissionChange.setOnClickListener {
+ showSystemNotificationSetting()
+ }
+ }
+
+ private fun showSystemNotificationSetting() {
+ Intent().apply {
+ action = Settings.ACTION_APP_NOTIFICATION_SETTINGS
+ putExtra(Settings.EXTRA_APP_PACKAGE, packageName)
+ flags = Intent.FLAG_ACTIVITY_NEW_TASK
+ startActivity(this)
+ }
+ }
+
+ private fun showNotificationOffConfirmDialog() {
+ val dialog = WineyDialogFragment.newInstance(
+ WineyDialogLabel(
+ stringOf(R.string.notification_off_dialog_title),
+ stringOf(R.string.notification_off_dialog_subtitle),
+ stringOf(R.string.notification_off_dialog_negative_button),
+ stringOf(R.string.notification_off_dialog_positive_button)
+ ),
+ handleNegativeButton = {},
+ handlePositiveButton = { switchOffNotification() }
+ )
+ dialog.show(
+ supportFragmentManager,
+ TAG_NOTIFICATION_OFF_DIALOG
+ )
+ }
+
+ private fun initUserData() {
+ lifecycleScope.launch {
+ val data = dataStoreRepository.getUserInfo().first()
+ if (data != null) {
+ updateNotificationAllowSwitchState(data)
+ }
+ }
+ }
+
+ private fun updateNotificationAllowSwitchState(data: UserV2) {
+ if (isNotificationPermissionAllowed) {
+ binding.ivSettingAgree.isVisible = true
+ binding.llSettingAgreePermissionChange.isGone = true
+ binding.tvSettingAgreePermission.isGone = true
+ when (data.fcmIsAllowed) {
+ true -> {
+ binding.ivSettingAgree.transitionToState(R.id.end, 1)
+ }
+
+ false -> {
+ binding.ivSettingAgree.transitionToState(R.id.start, 1)
+ }
+ }
+ } else {
+ binding.ivSettingAgree.isGone = true
+ binding.llSettingAgreePermissionChange.isVisible = true
+ binding.tvSettingAgreePermission.isVisible = true
+ }
+ }
+
+ private fun updateNotificationButtonByPermission() {
+ if (isNotificationPermissionAllowed) {
+ binding.ivSettingAgree.isVisible = true
+
+ binding.llSettingAgreePermissionChange.isGone = true
+ binding.tvSettingAgreePermission.isGone = true
+ } else {
+ binding.ivSettingAgree.isGone = true
+
+ binding.llSettingAgreePermissionChange.isVisible = true
+ binding.tvSettingAgreePermission.isVisible = true
+ }
+ }
+
+ private fun patchUserInfo() {
+ lifecycleScope.launch {
+ val data = dataStoreRepository.getUserInfo().first()
+ val newData = data?.copy(fcmIsAllowed = false)
+ dataStoreRepository.saveUserInfo(newData)
+ }
+ }
+
+ private fun initNotiToggleButtonClickListener() {
+ binding.ivSettingSwitch.setOnClickListener {
+ val isAllowed = when (binding.ivSettingAgree.currentState) {
+ R.id.start -> false
+ R.id.end -> true
+ else -> false
+ }
+
+ if (!isAllowed) {
+ switchOnNotification()
+ } else {
+ showNotificationOffConfirmDialog()
+ }
+ }
+ }
+
+ private fun initNotificationPermissionState() {
+ isNotificationPermissionAllowed =
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
+ ContextCompat.checkSelfPermission(
+ this,
+ Manifest.permission.POST_NOTIFICATIONS
+ ) == PackageManager.PERMISSION_GRANTED
+ } else {
+ true
+ }
+ }
+
+ private fun init1On1ButtonClickListener() {
+ binding.clSettingTo1on1.setOnClickListener {
+ val url = ONE_ON_ONE_URL
+ val intent = Intent(Intent.ACTION_VIEW, Uri.parse(url))
+ startActivity(intent)
+ }
+ }
+
+ private fun initTermsButtonClickListener() {
+ binding.clSettingToTerms.setOnClickListener {
+ val url = TERMS_URL
+ val intent = Intent(Intent.ACTION_VIEW, Uri.parse(url))
+ startActivity(intent)
+ }
+ }
+
+ private fun initBackButtonClickListener() {
+ binding.ivSettingBack.setOnSingleClickListener {
+ finish()
+ }
+ }
+
+ private fun initLogoutButtonClickListener() {
+ binding.clSettingLogout.setOnClickListener {
+ amplitudeUtils.logEvent("click_logout")
+ val dialog = WineyDialogFragment.newInstance(
+ WineyDialogLabel(
+ stringOf(R.string.mypage_logout_dialog_title),
+ stringOf(R.string.mypage_logout_dialog_subtitle),
+ stringOf(R.string.mypage_logout_dialog_negative_button),
+ stringOf(R.string.mypage_logout_dialog_positive_button)
+ ),
+ handleNegativeButton = {},
+ handlePositiveButton = { mainViewModel.postLogout() }
+ )
+ dialog.show(supportFragmentManager, TAG_LOGOUT_DIALOG)
+ }
+ }
+
+ private fun initWithdrawButtonClickListener() {
+ binding.clSettingWithdraw.setOnClickListener {
+ val dialog = WineyDialogFragment.newInstance(
+ WineyDialogLabel(
+ stringOf(R.string.mypage_withdraw_dialog_title),
+ stringOf(R.string.mypage_withdraw_dialog_subtitle),
+ stringOf(R.string.mypage_withdraw_dialog_negative_button),
+ stringOf(R.string.mypage_withdraw_dialog_positive_button)
+ ),
+ handleNegativeButton = { settingViewModel.deleteUser() },
+ handlePositiveButton = {}
+ )
+ dialog.show(supportFragmentManager, TAG_WITHDRAW_DIALOG)
+ }
+ }
+
+ private fun setupDeleteUserState() {
+ settingViewModel.deleteUserState.flowWithLifecycle(lifecycle)
+ .onEach { state ->
+ when (state) {
+ is UiState.Success -> {
+ settingViewModel.clearDataStore()
+ navigateToGuideScreen()
+ }
+
+ is UiState.Failure -> {
+ snackBar(binding.root) { state.msg }
+ }
+
+ else -> {
+ }
+ }
+ }.launchIn(lifecycleScope)
+ }
+
+ private fun setupPatchAllowedNotificationState() {
+ settingViewModel.patchAllowedNotificationState.flowWithLifecycle(lifecycle)
+ .onEach { state ->
+ when (state) {
+ is UiState.Success -> {
+ when (state.data) {
+ true -> {
+ binding.ivSettingAgree.transitionToState(R.id.end, -1)
+ }
+
+ false -> {
+ binding.ivSettingAgree.transitionToState(R.id.start, -1)
+ }
+
+ null -> {
+ binding.ivSettingAgree.transitionToState(R.id.start, -1)
+ }
+ }
+ }
+
+ else -> {}
+ }
+ }
+ }
+
+ private fun setupLogoutState() {
+ mainViewModel.logoutState.flowWithLifecycle(lifecycle).onEach { state ->
+ when (state) {
+ is UiState.Loading -> {
+ }
+
+ is UiState.Success -> {
+ navigateToLoginScreen()
+ }
+
+ is UiState.Failure -> {
+ snackBar(binding.root) { state.msg }
+ }
+
+ is UiState.Empty -> {
+ }
+ }
+ }.launchIn(lifecycleScope)
+ }
+
+ private fun navigateToLoginScreen() {
+ Intent(this, LoginActivity::class.java).apply {
+ addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
+ startActivity(this)
+ finish()
+ }
+ }
+
+ private fun navigateToGuideScreen() {
+ Intent(this, GuideActivity::class.java).apply {
+ addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK)
+ startActivity(this)
+ }
+ }
+
+ companion object {
+
+ private const val ONE_ON_ONE_URL = "https://open.kakao.com/o/s751Susf"
+ private const val TERMS_URL =
+ "https://empty-weaver-a9f.notion.site/iney-9dbfe130c7df4fb9a0903481c3e377e6?pvs=4"
+
+ private const val TAG_LOGOUT_DIALOG = "LOGOUT_DIALOG"
+ private const val TAG_WITHDRAW_DIALOG = "WITHDRAW_DIALOG"
+
+ private const val TAG_NOTIFICATION_OFF_DIALOG = "offNotification"
+ }
+}
diff --git a/app/src/main/java/org/go/sopt/winey/presentation/main/mypage/MyPageViewModel.kt b/app/src/main/java/org/go/sopt/winey/presentation/main/mypage/setting/SettingViewModel.kt
similarity index 94%
rename from app/src/main/java/org/go/sopt/winey/presentation/main/mypage/MyPageViewModel.kt
rename to app/src/main/java/org/go/sopt/winey/presentation/main/mypage/setting/SettingViewModel.kt
index 6346e006..f6ae5b5e 100644
--- a/app/src/main/java/org/go/sopt/winey/presentation/main/mypage/MyPageViewModel.kt
+++ b/app/src/main/java/org/go/sopt/winey/presentation/main/mypage/setting/SettingViewModel.kt
@@ -1,4 +1,4 @@
-package org.go.sopt.winey.presentation.main.mypage
+package org.go.sopt.winey.presentation.main.mypage.setting
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
@@ -15,15 +15,17 @@ import timber.log.Timber
import javax.inject.Inject
@HiltViewModel
-class MyPageViewModel @Inject constructor(
+class SettingViewModel @Inject constructor(
private val authRepository: AuthRepository,
private val dataStoreRepository: DataStoreRepository
) : ViewModel() {
+
private val _deleteUserState = MutableStateFlow>(UiState.Empty)
val deleteUserState: StateFlow> = _deleteUserState.asStateFlow()
private val _patchAllowedNotificationState = MutableStateFlow>(UiState.Empty)
- val patchAllowedNotificationState: StateFlow> = _patchAllowedNotificationState.asStateFlow()
+ val patchAllowedNotificationState: StateFlow> =
+ _patchAllowedNotificationState.asStateFlow()
fun deleteUser() {
viewModelScope.launch {
diff --git a/app/src/main/java/org/go/sopt/winey/presentation/onboarding/login/LoginActivity.kt b/app/src/main/java/org/go/sopt/winey/presentation/onboarding/login/LoginActivity.kt
index 9ddc7c4a..19b6a21d 100644
--- a/app/src/main/java/org/go/sopt/winey/presentation/onboarding/login/LoginActivity.kt
+++ b/app/src/main/java/org/go/sopt/winey/presentation/onboarding/login/LoginActivity.kt
@@ -20,7 +20,6 @@ import org.go.sopt.winey.util.context.snackBar
import org.go.sopt.winey.util.view.UiState
import org.json.JSONException
import org.json.JSONObject
-import timber.log.Timber
import javax.inject.Inject
@AndroidEntryPoint
@@ -46,30 +45,6 @@ class LoginActivity :
}
}
- private fun sendEventToAmplitude(type: EventType) {
- val eventProperties = JSONObject()
-
- try {
- when (type) {
- EventType.TYPE_VIEW_SCREEN -> eventProperties.put("screen_name", "sign_up")
- EventType.TYPE_CLICK_BUTTON -> {
- eventProperties.put("button_name", "kakao_signup_button")
- .put("paging_number", 1)
- }
- else -> {}
- }
- } catch (e: JSONException) {
- System.err.println("Invalid JSON")
- e.printStackTrace()
- }
-
- when (type) {
- EventType.TYPE_VIEW_SCREEN -> amplitudeUtils.logEvent("view_signup", eventProperties)
- EventType.TYPE_CLICK_BUTTON -> amplitudeUtils.logEvent("click_button", eventProperties)
- else -> {}
- }
- }
-
private fun initLoginObserver() {
viewModel.loginState.flowWithLifecycle(lifecycle).onEach { state ->
when (state) {
@@ -78,11 +53,6 @@ class LoginActivity :
}
is UiState.Success -> {
- Timber.e("${state.data?.userId}")
- Timber.e("${state.data?.accessToken}")
- Timber.e("${state.data?.refreshToken}")
- Timber.e("${state.data?.isRegistered}")
-
if (state.data?.isRegistered == true) {
navigateTo()
} else {
@@ -106,4 +76,28 @@ class LoginActivity :
startActivity(this)
}
}
+
+ private fun sendEventToAmplitude(type: EventType) {
+ val eventProperties = JSONObject()
+
+ try {
+ when (type) {
+ EventType.TYPE_VIEW_SCREEN -> eventProperties.put("screen_name", "sign_up")
+ EventType.TYPE_CLICK_BUTTON -> {
+ eventProperties.put("button_name", "kakao_signup_button")
+ .put("paging_number", 1)
+ }
+ else -> {}
+ }
+ } catch (e: JSONException) {
+ System.err.println("Invalid JSON")
+ e.printStackTrace()
+ }
+
+ when (type) {
+ EventType.TYPE_VIEW_SCREEN -> amplitudeUtils.logEvent("view_signup", eventProperties)
+ EventType.TYPE_CLICK_BUTTON -> amplitudeUtils.logEvent("click_button", eventProperties)
+ else -> {}
+ }
+ }
}
diff --git a/app/src/main/java/org/go/sopt/winey/presentation/onboarding/login/LoginViewModel.kt b/app/src/main/java/org/go/sopt/winey/presentation/onboarding/login/LoginViewModel.kt
index ad367e93..21f30781 100644
--- a/app/src/main/java/org/go/sopt/winey/presentation/onboarding/login/LoginViewModel.kt
+++ b/app/src/main/java/org/go/sopt/winey/presentation/onboarding/login/LoginViewModel.kt
@@ -9,9 +9,7 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
-import kotlinx.coroutines.flow.first
import kotlinx.coroutines.launch
-import kotlinx.coroutines.withContext
import org.go.sopt.winey.data.model.remote.request.RequestLoginDto
import org.go.sopt.winey.data.model.remote.response.ResponseLoginDto
import org.go.sopt.winey.domain.repository.AuthRepository
@@ -28,15 +26,11 @@ class LoginViewModel @Inject constructor(
private val authRepository: AuthRepository,
private val dataStoreRepository: DataStoreRepository
) : ViewModel() {
- private val _isKakaoLogin = MutableStateFlow(false)
- val isKakaoLogin = _isKakaoLogin.asStateFlow()
-
private val _loginState = MutableStateFlow>(UiState.Empty)
val loginState: StateFlow> = _loginState.asStateFlow()
- val kakaoLoginCallback: (OAuthToken?, Throwable?) -> Unit = { token, error ->
+ private val kakaoLoginCallback: (OAuthToken?, Throwable?) -> Unit = { token, error ->
KakaoLoginCallback {
- _isKakaoLogin.value = true
Timber.d("액세스토큰 ${token?.accessToken}")
Timber.d("리프레시토큰 ${token?.refreshToken}")
if (token != null) {
@@ -52,17 +46,19 @@ class LoginViewModel @Inject constructor(
kakaoLoginRepository.loginKakao(kakaoLoginCallback, context)
}
- fun postLogin(socialToken: String, socialType: String) {
+ private fun postLogin(socialToken: String, socialType: String) {
viewModelScope.launch {
_loginState.value = UiState.Loading
authRepository.postLogin(socialToken, RequestLoginDto(socialType))
.onSuccess { response ->
- Timber.e("로그인 성공")
if (response != null) {
+ Timber.d("로그인 성공")
+ Timber.d("액세스 : ${response.accessToken} \n 리프레시 : ${response.refreshToken}")
+
saveAccessToken(response.accessToken, response.refreshToken)
saveUserId(response.userId)
- Timber.e("액세스 : ${response.accessToken} , 리프레시 : ${response.refreshToken}")
+
_loginState.value = UiState.Success(response)
} else {
Timber.e("response is null")
@@ -78,33 +74,21 @@ class LoginViewModel @Inject constructor(
}
}
- fun saveSocialToken(socialAccessToken: String, socialRefreshToken: String) =
+ private fun saveSocialToken(socialAccessToken: String, socialRefreshToken: String) =
viewModelScope.launch(Dispatchers.IO) {
dataStoreRepository.saveSocialToken(socialAccessToken, socialRefreshToken)
}
- suspend fun getSocialToken() = withContext(Dispatchers.IO) {
- dataStoreRepository.getSocialAccessToken().first()
- }
-
- fun saveAccessToken(accessToken: String, refreshToken: String) =
+ private fun saveAccessToken(accessToken: String, refreshToken: String) =
viewModelScope.launch(Dispatchers.IO) {
dataStoreRepository.saveAccessToken(accessToken, refreshToken)
}
- fun saveUserId(userId: Int) =
+ private fun saveUserId(userId: Int) =
viewModelScope.launch(Dispatchers.IO) {
dataStoreRepository.saveUserId(userId)
}
- suspend fun getAccessToken() = withContext(Dispatchers.IO) {
- dataStoreRepository.getAccessToken().first()
- }
-
- suspend fun getRefreshToken() = withContext(Dispatchers.IO) {
- dataStoreRepository.getRefreshToken().first()
- }
-
companion object {
private const val KAKAO = "KAKAO"
}
diff --git a/app/src/main/java/org/go/sopt/winey/presentation/splash/SplashActivity.kt b/app/src/main/java/org/go/sopt/winey/presentation/splash/SplashActivity.kt
index 0d0fae9e..96a2bd62 100644
--- a/app/src/main/java/org/go/sopt/winey/presentation/splash/SplashActivity.kt
+++ b/app/src/main/java/org/go/sopt/winey/presentation/splash/SplashActivity.kt
@@ -111,6 +111,13 @@ class SplashActivity : BindingActivity(R.layout.activity_
}
}
+ private inline fun navigateTo() {
+ Intent(this, T::class.java).apply {
+ addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK)
+ startActivity(this)
+ }
+ }
+
private fun checkAppUpdateInfo() {
val appUpdateInfoTask = appUpdateManager.appUpdateInfo
diff --git a/app/src/main/res/drawable/ic_wineyfeed_notification_new.xml b/app/src/main/res/drawable/ic_wineyfeed_notification_new.xml
index db5b80da..05a124d0 100644
--- a/app/src/main/res/drawable/ic_wineyfeed_notification_new.xml
+++ b/app/src/main/res/drawable/ic_wineyfeed_notification_new.xml
@@ -4,7 +4,7 @@
android:viewportWidth="48"
android:viewportHeight="48">
+ android:pathData="M29,19m-3,0a3,3 0,1 1,6 0a3,3 0,1 1,-6 0"
+ android:fillColor="#FF5150"/>
diff --git a/app/src/main/res/layout/activity_setting.xml b/app/src/main/res/layout/activity_setting.xml
new file mode 100644
index 00000000..7a62a270
--- /dev/null
+++ b/app/src/main/res/layout/activity_setting.xml
@@ -0,0 +1,287 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/fragment_my_page.xml b/app/src/main/res/layout/fragment_my_page.xml
index 8979f5a4..eadbd331 100644
--- a/app/src/main/res/layout/fragment_my_page.xml
+++ b/app/src/main/res/layout/fragment_my_page.xml
@@ -26,6 +26,7 @@
app:layout_constraintTop_toTopOf="parent" />
diff --git a/app/src/main/res/layout/fragment_winey_feed.xml b/app/src/main/res/layout/fragment_winey_feed.xml
index 4293241b..829fd56d 100644
--- a/app/src/main/res/layout/fragment_winey_feed.xml
+++ b/app/src/main/res/layout/fragment_winey_feed.xml
@@ -4,6 +4,7 @@
xmlns:tools="http://schemas.android.com/tools">
+
@@ -14,17 +15,19 @@
android:layout_height="match_parent">
+ android:layout_height="wrap_content"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintTop_toTopOf="parent">
-
+
+
+
+
+
+
+ android:clipToPadding="false"
+ android:nestedScrollingEnabled="false"
+ android:orientation="vertical"
+ android:paddingBottom="50dp"
+ app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
+ tools:listitem="@layout/item_wineyfeed_post" />
-
-
-
-
+
-
diff --git a/app/src/main/res/xml/mypage_noti_agree_motion_scene.xml b/app/src/main/res/xml/mypage_noti_agree_motion_scene.xml
index 3a56fd20..835624b8 100644
--- a/app/src/main/res/xml/mypage_noti_agree_motion_scene.xml
+++ b/app/src/main/res/xml/mypage_noti_agree_motion_scene.xml
@@ -24,12 +24,12 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="4dp"
- motion:layout_constraintBottom_toBottomOf="@+id/iv_mypage_switch"
- motion:layout_constraintStart_toStartOf="@+id/iv_mypage_switch"
- motion:layout_constraintTop_toTopOf="@+id/iv_mypage_switch"/>
+ motion:layout_constraintBottom_toBottomOf="@+id/iv_setting_switch"
+ motion:layout_constraintStart_toStartOf="@+id/iv_setting_switch"
+ motion:layout_constraintTop_toTopOf="@+id/iv_setting_switch"/>
+ motion:layout_constraintBottom_toBottomOf="@+id/iv_setting_switch"
+ motion:layout_constraintEnd_toEndOf="@+id/iv_setting_switch"
+ motion:layout_constraintTop_toTopOf="@+id/iv_setting_switch" />