diff --git a/app/src/main/java/com/android/go/sopt/winey/domain/entity/Notification.kt b/app/src/main/java/com/android/go/sopt/winey/domain/entity/Notification.kt new file mode 100644 index 00000000..ef92c5d9 --- /dev/null +++ b/app/src/main/java/com/android/go/sopt/winey/domain/entity/Notification.kt @@ -0,0 +1,12 @@ +package com.android.go.sopt.winey.domain.entity + +data class Notification( + val notiId: Int, + val notiReceiver: String, + val notiMessage: String, + val notiType: String, + val isChecked: Boolean, + val timeAgo: String, + val createdAt: String, + val linkId: Int +) diff --git a/app/src/main/java/com/android/go/sopt/winey/presentation/main/MainActivity.kt b/app/src/main/java/com/android/go/sopt/winey/presentation/main/MainActivity.kt index a9d026ed..7521f9d6 100644 --- a/app/src/main/java/com/android/go/sopt/winey/presentation/main/MainActivity.kt +++ b/app/src/main/java/com/android/go/sopt/winey/presentation/main/MainActivity.kt @@ -22,7 +22,6 @@ import com.android.go.sopt.winey.util.view.UiState import dagger.hilt.android.AndroidEntryPoint import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach -import retrofit2.HttpException @AndroidEntryPoint class MainActivity : BindingActivity(R.layout.activity_main) { @@ -40,7 +39,6 @@ class MainActivity : BindingActivity(R.layout.activity_main syncBottomNavigationSelection() setupLogoutState() - setupTokenState() showUploadSuccessSnackbar() } @@ -96,24 +94,6 @@ class MainActivity : BindingActivity(R.layout.activity_main }.launchIn(lifecycleScope) } - private fun setupTokenState() { - viewModel.getUserState.flowWithLifecycle(lifecycle).onEach { state -> - when (state) { - is UiState.Failure -> { - // todo: 메인 뷰모델에 있는 todo 주석 참고해주세요! - if (state is HttpException) { - if (state.code() == CODE_TOKEN_EXPIRED) { - viewModel.postLogout() - } - } - } - - else -> { - } - } - } - } - private fun navigateToLoginScreen() { Intent(this@MainActivity, LoginActivity::class.java).apply { addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP) @@ -129,7 +109,6 @@ class MainActivity : BindingActivity(R.layout.activity_main } companion object { - private const val CODE_TOKEN_EXPIRED = 401 private const val EXTRA_UPLOAD_KEY = "upload" } } diff --git a/app/src/main/java/com/android/go/sopt/winey/presentation/main/MainViewModel.kt b/app/src/main/java/com/android/go/sopt/winey/presentation/main/MainViewModel.kt index a4c55813..2af40065 100644 --- a/app/src/main/java/com/android/go/sopt/winey/presentation/main/MainViewModel.kt +++ b/app/src/main/java/com/android/go/sopt/winey/presentation/main/MainViewModel.kt @@ -39,10 +39,10 @@ class MainViewModel @Inject constructor( } .onFailure { t -> if (t is HttpException) { - Timber.e("FAIL GET USER IN MAIN: ${t.code()}") - - // todo: 메인 액티비티가 아니라 여기서 t.code() 이용해서 - // 리프레시 토큰 만료되면 로그아웃 되게 해야 될 거 같아요! + Timber.e("HTTP 실패 ${t.code()}") + if (t.code() == CODE_TOKEN_EXPIRED) { + postLogout() + } } Timber.e("${t.message}") _getUserState.value = UiState.Failure("${t.message}") @@ -69,4 +69,8 @@ class MainViewModel @Inject constructor( } } } + + companion object { + private const val CODE_TOKEN_EXPIRED = 401 + } } diff --git a/app/src/main/java/com/android/go/sopt/winey/presentation/main/mypage/MyPageFragment.kt b/app/src/main/java/com/android/go/sopt/winey/presentation/main/mypage/MyPageFragment.kt index 25065288..3aa724bb 100644 --- a/app/src/main/java/com/android/go/sopt/winey/presentation/main/mypage/MyPageFragment.kt +++ b/app/src/main/java/com/android/go/sopt/winey/presentation/main/mypage/MyPageFragment.kt @@ -45,6 +45,7 @@ class MyPageFragment : BindingFragment(R.layout.fragment_ super.onViewCreated(view, savedInstanceState) init1On1ButtonClickListener() + initTermsButtonClickListener() initLevelHelpButtonClickListener() initToMyFeedButtonClickListener() initLogoutButtonClickListener() @@ -81,6 +82,14 @@ class MyPageFragment : BindingFragment(R.layout.fragment_ } } + private fun initTermsButtonClickListener() { + binding.clMypageToTerms.setOnClickListener { + val url = TERMS_URL + val intent = Intent(Intent.ACTION_VIEW, Uri.parse(url)) + startActivity(intent) + } + } + private fun initLevelHelpButtonClickListener() { binding.btnMypageLevelHelp.setOnClickListener { val intent = Intent(context, MypageHelpActivity::class.java) @@ -177,23 +186,26 @@ class MyPageFragment : BindingFragment(R.layout.fragment_ bottomSheet.show(this.childFragmentManager, bottomSheet.tag) /*when (data.isOver) { - true -> { - val bottomSheet = TargetAmountBottomSheetFragment() - bottomSheet.show(this.childFragmentManager, bottomSheet.tag) - } + true -> { + val bottomSheet = TargetAmountBottomSheetFragment() + bottomSheet.show(this.childFragmentManager, bottomSheet.tag) + } - false -> { - val dialog = MyPageDialogFragment() - dialog.show(this.childFragmentManager, dialog.tag) - } - }*/ + false -> { + val dialog = MyPageDialogFragment() + dialog.show(this.childFragmentManager, dialog.tag) + } + }*/ } } - // todo: 여기 한 함수에 들어가는 코드량이 많습니다! 함수화 시켜주세요! @우상욱 private fun updateUserInfo(data: User?) { binding.data = data + handleIsOver(data) + handleUserLevel(data) + } + private fun handleIsOver(data: User?) { when (data?.isOver) { true -> { binding.tvMypageTargetAmount.text = getString(R.string.mypage_not_yet_set) @@ -213,6 +225,9 @@ class MyPageFragment : BindingFragment(R.layout.fragment_ null -> { } } + } + + private fun handleUserLevel(data: User?) { when (data?.userLevel) { LEVEL_COMMON -> { binding.ivMypageProgressbar.setImageResource(R.drawable.ic_mypage_lv1_progressbar) @@ -249,9 +264,9 @@ class MyPageFragment : BindingFragment(R.layout.fragment_ private const val LEVEL_NOBLESS = "귀족" private const val LEVEL_KING = "황제" private const val ONE_ON_ONE_URL = "https://open.kakao.com/o/s751Susf" + private const val TERMS_URL = "https://empty-weaver-a9f.notion.site/62b37962c661488ba5f60958c24753e1?pvs=4" private const val EXTRA_KEY = "PREV_SCREEN_NAME" private const val EXTRA_VALUE = "MyPageFragment" - private const val TAG_LOGOUT_DIALOG = "LOGOUT_DIALOG" private const val TAGE_WITHDRAW_DIALOG = "WITHDRAW_DIALOG" } diff --git a/app/src/main/java/com/android/go/sopt/winey/presentation/main/notification/NotificationActivity.kt b/app/src/main/java/com/android/go/sopt/winey/presentation/main/notification/NotificationActivity.kt new file mode 100644 index 00000000..9c47b161 --- /dev/null +++ b/app/src/main/java/com/android/go/sopt/winey/presentation/main/notification/NotificationActivity.kt @@ -0,0 +1,22 @@ +package com.android.go.sopt.winey.presentation.main.notification + +import android.os.Bundle +import androidx.activity.viewModels +import com.android.go.sopt.winey.R +import com.android.go.sopt.winey.databinding.ActivityNotificationBinding +import com.android.go.sopt.winey.util.binding.BindingActivity +import dagger.hilt.android.AndroidEntryPoint + +@AndroidEntryPoint +class NotificationActivity : BindingActivity(R.layout.activity_notification) { + private lateinit var notificationAdapter: NotificationAdapter + private val viewModel: NotificationViewModel by viewModels() + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + initNotificationAdapter() + } + + private fun initNotificationAdapter() { + notificationAdapter = NotificationAdapter() + } +} diff --git a/app/src/main/java/com/android/go/sopt/winey/presentation/main/notification/NotificationAdapter.kt b/app/src/main/java/com/android/go/sopt/winey/presentation/main/notification/NotificationAdapter.kt new file mode 100644 index 00000000..f0a942f2 --- /dev/null +++ b/app/src/main/java/com/android/go/sopt/winey/presentation/main/notification/NotificationAdapter.kt @@ -0,0 +1,45 @@ +package com.android.go.sopt.winey.presentation.main.notification + +import android.view.LayoutInflater +import android.view.ViewGroup +import androidx.recyclerview.widget.ListAdapter +import androidx.recyclerview.widget.RecyclerView +import com.android.go.sopt.winey.databinding.ItemNotificationPostBinding +import com.android.go.sopt.winey.domain.entity.Notification +import com.android.go.sopt.winey.util.view.ItemDiffCallback + +class NotificationAdapter : + ListAdapter(DiffUtil) { + + class NotificationViewHolder(private val binding: ItemNotificationPostBinding) : + RecyclerView.ViewHolder(binding.root) { + + fun onBind(data: Notification?) { + binding.apply { + this.data = data + if (data == null) { + return + } + binding.root.setOnClickListener { + } + } + } + } + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): NotificationViewHolder { + val binding = + ItemNotificationPostBinding.inflate(LayoutInflater.from(parent.context), parent, false) + return NotificationViewHolder(binding) + } + + override fun onBindViewHolder(holder: NotificationViewHolder, position: Int) { + holder.onBind(getItem(position)) + } + + companion object { + private val DiffUtil = ItemDiffCallback( + onItemsTheSame = { old, new -> old.notiId == new.notiId }, + onContentsTheSame = { old, new -> old == new } + ) + } +} diff --git a/app/src/main/java/com/android/go/sopt/winey/presentation/main/notification/NotificationViewModel.kt b/app/src/main/java/com/android/go/sopt/winey/presentation/main/notification/NotificationViewModel.kt new file mode 100644 index 00000000..3110db46 --- /dev/null +++ b/app/src/main/java/com/android/go/sopt/winey/presentation/main/notification/NotificationViewModel.kt @@ -0,0 +1,5 @@ +package com.android.go.sopt.winey.presentation.main.notification + +import androidx.lifecycle.ViewModel + +class NotificationViewModel : ViewModel() diff --git a/app/src/main/java/com/android/go/sopt/winey/util/binding/BindingAdapter.kt b/app/src/main/java/com/android/go/sopt/winey/util/binding/BindingAdapter.kt index a970dba6..31f85667 100644 --- a/app/src/main/java/com/android/go/sopt/winey/util/binding/BindingAdapter.kt +++ b/app/src/main/java/com/android/go/sopt/winey/util/binding/BindingAdapter.kt @@ -113,3 +113,41 @@ fun setLikeImage(view: ImageView, isLiked: Boolean) { } view.setImageResource(imageRes) } + +@BindingAdapter("notiType") +fun TextView.setNotiType(notiType: String) { + val resourceId = when (notiType) { + "RANKUPTO2", "RANKUPTO3", "RANKUPTO4" -> R.string.notification_rankup + "DELETERANKDOWNTO1", "DELETERANKDOWNTO2", "DELETERANKDOWNTO3" -> R.string.notification_rankdown + "GOALFAILED" -> R.string.notification_goal_failed + "LIKENOTI" -> R.string.notification_like + "COMMENTNOTI" -> R.string.notification_comment + "HOWTOLEVELUP" -> R.string.notification_how_to_levelup + else -> null + } + + if (resourceId != null) { + text = context.getString(resourceId) + } else { + text = "" + } +} + +@BindingAdapter("notiType") +fun ImageView.setNotiType(notiType: String) { + val drawableResourceId = when (notiType) { + "RANKUPTO2", "DELETERANKDOWNTO2" -> R.drawable.ic_notification_lv2 + "RANKUPTO3", "DELETERANKDOWNTO3" -> R.drawable.ic_notification_lv3 + "RANKUPTO4" -> R.drawable.ic_notification_lv4 + "DELETERANKDOWNTO1" -> R.drawable.ic_notification_lv1 + "GOALFAILED", "HOWTOLEVELUP" -> R.drawable.ic_notification_logo + "LIKENOTI" -> R.drawable.ic_notification_like + "COMMENTNOTI" -> R.drawable.ic_notification_comment + else -> 0 + } + + if (drawableResourceId != 0) { + setImageResource(drawableResourceId) + } else { + } +} diff --git a/app/src/main/res/drawable/ic_mypage_lv_help.xml b/app/src/main/res/drawable/ic_mypage_lv_help.xml index 02b6fba0..c030e6a0 100644 --- a/app/src/main/res/drawable/ic_mypage_lv_help.xml +++ b/app/src/main/res/drawable/ic_mypage_lv_help.xml @@ -1,17 +1,21 @@ - - - + android:width="30dp" + android:height="30dp" + android:viewportWidth="30" + android:viewportHeight="30"> + + + + + + diff --git a/app/src/main/res/drawable/ic_notification_comment.xml b/app/src/main/res/drawable/ic_notification_comment.xml new file mode 100644 index 00000000..3449151f --- /dev/null +++ b/app/src/main/res/drawable/ic_notification_comment.xml @@ -0,0 +1,14 @@ + + + + diff --git a/app/src/main/res/drawable/ic_notification_like.xml b/app/src/main/res/drawable/ic_notification_like.xml new file mode 100644 index 00000000..43aaae57 --- /dev/null +++ b/app/src/main/res/drawable/ic_notification_like.xml @@ -0,0 +1,20 @@ + + + + + + diff --git a/app/src/main/res/drawable/ic_notification_logo.xml b/app/src/main/res/drawable/ic_notification_logo.xml new file mode 100644 index 00000000..825e4f1c --- /dev/null +++ b/app/src/main/res/drawable/ic_notification_logo.xml @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/ic_notification_lv1.xml b/app/src/main/res/drawable/ic_notification_lv1.xml new file mode 100644 index 00000000..95fc9607 --- /dev/null +++ b/app/src/main/res/drawable/ic_notification_lv1.xml @@ -0,0 +1,109 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/ic_notification_lv2.xml b/app/src/main/res/drawable/ic_notification_lv2.xml new file mode 100644 index 00000000..414b06c6 --- /dev/null +++ b/app/src/main/res/drawable/ic_notification_lv2.xml @@ -0,0 +1,202 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/ic_notification_lv3.xml b/app/src/main/res/drawable/ic_notification_lv3.xml new file mode 100644 index 00000000..8f75ac5f --- /dev/null +++ b/app/src/main/res/drawable/ic_notification_lv3.xml @@ -0,0 +1,208 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/ic_notification_lv4.xml b/app/src/main/res/drawable/ic_notification_lv4.xml new file mode 100644 index 00000000..f3b7d9e1 --- /dev/null +++ b/app/src/main/res/drawable/ic_notification_lv4.xml @@ -0,0 +1,166 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/activity_notification.xml b/app/src/main/res/layout/activity_notification.xml new file mode 100644 index 00000000..182ce8f4 --- /dev/null +++ b/app/src/main/res/layout/activity_notification.xml @@ -0,0 +1,57 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/fragment_my_page.xml b/app/src/main/res/layout/fragment_my_page.xml index d88f0011..68b09b10 100644 --- a/app/src/main/res/layout/fragment_my_page.xml +++ b/app/src/main/res/layout/fragment_my_page.xml @@ -78,10 +78,11 @@ android:id="@+id/btn_mypage_level_help" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:background="@android:color/transparent" android:src="@drawable/ic_mypage_lv_help" + android:background="@android:color/transparent" app:layout_constraintStart_toEndOf="@id/tv_mypage_level_token" - app:layout_constraintTop_toTopOf="@id/tv_mypage_level_token" /> + app:layout_constraintTop_toTopOf="@id/tv_mypage_level_token" + app:layout_constraintBottom_toBottomOf="@id/tv_mypage_level_token"/> + + + + + + + + + + + app:layout_constraintTop_toBottomOf="@id/v_mypage_line9"> + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 36b0d7c5..915689bb 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -67,6 +67,7 @@ 절약 목표 기간이 지나지 않아\n 목표를 수정할 수 없어요 닫기 1:1 문의 + 이용약관 탈퇴하기 로그아웃 @@ -174,6 +175,15 @@ 버튼1 버튼2 + + 알림 + 등급 상승 + 등급 하락 + 목표 달성 실패 + 좋아요 + 댓글 + 위니 사용법 + 업로드가 완료되었습니다 :) 죄송합니다. 업로드에 실패했습니다 :(