From 8ff57348c7cef0489f7ae5be72f535efc17ad85b Mon Sep 17 00:00:00 2001 From: HyeseonBaek Date: Thu, 15 Feb 2024 17:31:12 +0900 Subject: [PATCH 01/11] =?UTF-8?q?[mod]=20#242=20=EB=A7=88=EC=9D=B4?= =?UTF-8?q?=ED=8E=98=EC=9D=B4=EC=A7=80=20=EC=95=84=EC=9D=B4=ED=85=9C=20?= =?UTF-8?q?=ED=83=80=EC=9E=85=20include=20=EB=A0=88=EC=9D=B4=EC=95=84?= =?UTF-8?q?=EC=9B=83=EC=97=90=20=EB=84=98=EA=B8=B0=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/res/layout/fragment_my_page.xml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/src/main/res/layout/fragment_my_page.xml b/app/src/main/res/layout/fragment_my_page.xml index 3f802198..60c4a134 100644 --- a/app/src/main/res/layout/fragment_my_page.xml +++ b/app/src/main/res/layout/fragment_my_page.xml @@ -284,6 +284,7 @@ android:layout_width="0dp" android:layout_height="wrap_content" android:layout_marginEnd="4dp" + app:item="@{`AMERICANO`}" app:layout_constraintEnd_toStartOf="@+id/l_mypage_item_chicken" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> @@ -295,6 +296,7 @@ android:layout_height="wrap_content" android:layout_marginStart="4dp" android:src="@drawable/ic_mypage_chicken" + app:item="@{`CHICKEN`}" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toEndOf="@id/l_mypage_item_coffee" app:layout_constraintTop_toTopOf="parent" /> @@ -317,6 +319,7 @@ android:layout_width="0dp" android:layout_height="wrap_content" android:layout_marginEnd="4dp" + app:item="@{`SNEAKERS`}" app:layout_constraintEnd_toStartOf="@+id/l_mypage_item_airpod" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> @@ -327,6 +330,7 @@ android:layout_width="0dp" android:layout_height="wrap_content" android:layout_marginStart="4dp" + app:item="@{`AIRPODS`}" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toEndOf="@id/l_mypage_item_sneakers" app:layout_constraintTop_toTopOf="parent" /> From 62e67ea70dd161122928b4ff890d64893cc2f64f Mon Sep 17 00:00:00 2001 From: HyeseonBaek Date: Thu, 15 Feb 2024 17:32:39 +0900 Subject: [PATCH 02/11] =?UTF-8?q?[feat]=20#242=20=EC=95=84=EC=9D=B4?= =?UTF-8?q?=ED=85=9C=20=ED=83=80=EC=9E=85=20=EB=B3=84=20=EB=82=B4=EC=9A=A9?= =?UTF-8?q?=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 간단한 text인데 각각 스타일이 모두 달라 textView 여러개로 분리했었는데, bindingAdapter에 spannableString 을 도입해 하나의 textView로 관리하는 방향으로 구현했다 --- .../sopt/winey/util/binding/BindingAdapter.kt | 86 +++++++++++ app/src/main/res/layout/item_mypage.xml | 141 +++++++----------- app/src/main/res/values/strings.xml | 2 + 3 files changed, 143 insertions(+), 86 deletions(-) diff --git a/app/src/main/java/org/go/sopt/winey/util/binding/BindingAdapter.kt b/app/src/main/java/org/go/sopt/winey/util/binding/BindingAdapter.kt index 6dba7e8f..b5e109cf 100644 --- a/app/src/main/java/org/go/sopt/winey/util/binding/BindingAdapter.kt +++ b/app/src/main/java/org/go/sopt/winey/util/binding/BindingAdapter.kt @@ -1,11 +1,16 @@ package org.go.sopt.winey.util.binding import android.net.Uri +import android.text.Spannable +import android.text.SpannableStringBuilder +import android.text.style.ForegroundColorSpan +import android.text.style.TextAppearanceSpan import android.view.View import android.widget.EditText import android.widget.ImageView import android.widget.TextView import androidx.appcompat.widget.AppCompatButton +import androidx.core.content.ContextCompat import androidx.databinding.BindingAdapter import coil.load import coil.transform.RoundedCornersTransformation @@ -323,3 +328,84 @@ fun CircleImageView.setWriterLevelImage(writerLevel: Int) { } setImageResource(drawableResId) } + +@BindingAdapter("setMyPageItemIcon") +fun ImageView.setMyPageItemIcon(iconType: String?) { + iconType?.let { + val drawableResId = when (it) { + "AMERICANO" -> R.drawable.ic_mypage_coffee + "SNEAKERS" -> R.drawable.ic_mypage_sneakers + "AIRPODS" -> R.drawable.ic_mypage_airpods + "CHICKEN" -> R.drawable.ic_mypage_chicken + else -> { + R.drawable.ic_mypage_chicken + } + } + setImageResource(drawableResId) + } +} + +@BindingAdapter("setMyPageItemDescription") +fun TextView.setMyPageItemDescription(iconType: String?) { + text = iconType?.let { + when (it) { + "AMERICANO" -> context.getString(R.string.mypage_description_eat, "아메리카노를") + "SNEAKERS" -> context.getString(R.string.mypage_description_buy, "운동화를") + "AIRPODS" -> context.getString(R.string.mypage_description_buy, "에어팟을") + "CHICKEN" -> context.getString(R.string.mypage_description_eat, "치킨을") + else -> " " + } + } ?: " " +} + +@BindingAdapter("setMyPageItemSavedAmount", "iconType") +fun TextView.setMyPageItemSavedAmount(savedAmount: Int, iconType: String) { + + val money: String = when (iconType) { + "AMERICANO" -> "5천원 x " + "SNEAKERS" -> "3만원 x " + "AIRPODS" -> "15만원 x " + "CHICKEN" -> "30만원 x " + else -> "" + } + + val amount: String = when (iconType) { + "AMERICANO" -> (savedAmount / 5000).toString() + "SNEAKERS" -> (savedAmount / 150000).toString() + "AIRPODS" -> (savedAmount / 300000).toString() + "CHICKEN" -> (savedAmount / 30000).toString() + else -> "" + } + + val measurement: String = when (iconType) { + "AMERICANO" -> " 잔" + "SNEAKERS" -> " 켤레" + "AIRPODS" -> " 개" + "CHICKEN" -> " 마리" + else -> "" + } + + val spannableString = SpannableStringBuilder() + .append(money) + .append(amount) + .append(measurement) + + spannableString.setSpan( + TextAppearanceSpan(context, R.style.TextAppearance_WINEY_detail_m_12), + 0, money.length, + Spannable.SPAN_EXCLUSIVE_EXCLUSIVE + ) + + spannableString.setSpan( + TextAppearanceSpan(context, R.style.TextAppearance_WINEY_Headline_b_24_xxl), + money.length, money.length + amount.length, + Spannable.SPAN_EXCLUSIVE_EXCLUSIVE + ) + + spannableString.setSpan( + ForegroundColorSpan(ContextCompat.getColor(context, R.color.gray_500)), + money.length + amount.length, money.length + amount.length + measurement.length, + Spannable.SPAN_EXCLUSIVE_EXCLUSIVE + ) + text = spannableString +} diff --git a/app/src/main/res/layout/item_mypage.xml b/app/src/main/res/layout/item_mypage.xml index e5f5e756..59104d0a 100644 --- a/app/src/main/res/layout/item_mypage.xml +++ b/app/src/main/res/layout/item_mypage.xml @@ -1,99 +1,68 @@ - - + + + + - + android:background="@drawable/shape_gray0_fill_12_rect"> - - + - + - + - + - + + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index df2f1c78..94eb5de8 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -109,6 +109,8 @@ 목표까지 남은 여정 위니를 만나고 최근 2주간 + %s 이만큼\n먹을 수 있어요 + %s 이만큼\n살 수 있어요 정말 로그아웃 하시겠어요? 로그아웃 후 장기간 미접속 시\n레벨이 내려갈 수 있습니다. From ff60e174322f95fe3e86ba3b5bbf3d5417de3ed9 Mon Sep 17 00:00:00 2001 From: HyeseonBaek Date: Sat, 17 Feb 2024 14:15:57 +0900 Subject: [PATCH 03/11] =?UTF-8?q?[chore]=20#242=20=ED=95=84=EC=9A=94=20?= =?UTF-8?q?=EC=9D=B4=EB=AF=B8=EC=A7=80=20=EB=A6=AC=EC=86=8C=EC=8A=A4=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../drawable/img_mypage_background_lv2.xml | 390 ++++++++ .../drawable/img_mypage_background_lv3.xml | 875 ++++++++++++++++++ .../drawable/img_mypage_background_lv4.xml | 308 ++++++ .../res/drawable/img_mypage_bubble_lv2.xml | 21 + .../res/drawable/img_mypage_bubble_lv3.xml | 21 + .../res/drawable/img_mypage_bubble_lv4.xml | 21 + .../res/drawable/img_mypage_saver_lv2.xml | 399 ++++++++ .../res/drawable/img_mypage_saver_lv3.xml | 331 +++++++ .../res/drawable/img_mypage_saver_lv4.xml | 459 +++++++++ 9 files changed, 2825 insertions(+) create mode 100644 app/src/main/res/drawable/img_mypage_background_lv2.xml create mode 100644 app/src/main/res/drawable/img_mypage_background_lv3.xml create mode 100644 app/src/main/res/drawable/img_mypage_background_lv4.xml create mode 100644 app/src/main/res/drawable/img_mypage_bubble_lv2.xml create mode 100644 app/src/main/res/drawable/img_mypage_bubble_lv3.xml create mode 100644 app/src/main/res/drawable/img_mypage_bubble_lv4.xml create mode 100644 app/src/main/res/drawable/img_mypage_saver_lv2.xml create mode 100644 app/src/main/res/drawable/img_mypage_saver_lv3.xml create mode 100644 app/src/main/res/drawable/img_mypage_saver_lv4.xml diff --git a/app/src/main/res/drawable/img_mypage_background_lv2.xml b/app/src/main/res/drawable/img_mypage_background_lv2.xml new file mode 100644 index 00000000..dc1b73e5 --- /dev/null +++ b/app/src/main/res/drawable/img_mypage_background_lv2.xml @@ -0,0 +1,390 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/img_mypage_background_lv3.xml b/app/src/main/res/drawable/img_mypage_background_lv3.xml new file mode 100644 index 00000000..7b2231ea --- /dev/null +++ b/app/src/main/res/drawable/img_mypage_background_lv3.xml @@ -0,0 +1,875 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/img_mypage_background_lv4.xml b/app/src/main/res/drawable/img_mypage_background_lv4.xml new file mode 100644 index 00000000..5be2410d --- /dev/null +++ b/app/src/main/res/drawable/img_mypage_background_lv4.xml @@ -0,0 +1,308 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/img_mypage_bubble_lv2.xml b/app/src/main/res/drawable/img_mypage_bubble_lv2.xml new file mode 100644 index 00000000..5fb495d4 --- /dev/null +++ b/app/src/main/res/drawable/img_mypage_bubble_lv2.xml @@ -0,0 +1,21 @@ + + + + + + + + diff --git a/app/src/main/res/drawable/img_mypage_bubble_lv3.xml b/app/src/main/res/drawable/img_mypage_bubble_lv3.xml new file mode 100644 index 00000000..a2142b99 --- /dev/null +++ b/app/src/main/res/drawable/img_mypage_bubble_lv3.xml @@ -0,0 +1,21 @@ + + + + + + + + diff --git a/app/src/main/res/drawable/img_mypage_bubble_lv4.xml b/app/src/main/res/drawable/img_mypage_bubble_lv4.xml new file mode 100644 index 00000000..c6ce2b53 --- /dev/null +++ b/app/src/main/res/drawable/img_mypage_bubble_lv4.xml @@ -0,0 +1,21 @@ + + + + + + + + diff --git a/app/src/main/res/drawable/img_mypage_saver_lv2.xml b/app/src/main/res/drawable/img_mypage_saver_lv2.xml new file mode 100644 index 00000000..c2c736a0 --- /dev/null +++ b/app/src/main/res/drawable/img_mypage_saver_lv2.xml @@ -0,0 +1,399 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/img_mypage_saver_lv3.xml b/app/src/main/res/drawable/img_mypage_saver_lv3.xml new file mode 100644 index 00000000..7f3a76f1 --- /dev/null +++ b/app/src/main/res/drawable/img_mypage_saver_lv3.xml @@ -0,0 +1,331 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/img_mypage_saver_lv4.xml b/app/src/main/res/drawable/img_mypage_saver_lv4.xml new file mode 100644 index 00000000..6f9dd1a7 --- /dev/null +++ b/app/src/main/res/drawable/img_mypage_saver_lv4.xml @@ -0,0 +1,459 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 6218b181e174e8b2454f85c52ffaf8c8a36101e5 Mon Sep 17 00:00:00 2001 From: HyeseonBaek Date: Sat, 17 Feb 2024 14:17:12 +0900 Subject: [PATCH 04/11] =?UTF-8?q?[mod]=20#242=20getUser=20=EB=B0=94?= =?UTF-8?q?=EB=80=90=20API=20=ED=98=95=ED=83=9C=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../remote/response/ResponseGetUserDto.kt | 66 +++++++------------ .../data/repository/AuthRepositoryImpl.kt | 4 +- .../repository/DataStoreRepositoryImpl.kt | 18 +++-- .../org/go/sopt/winey/domain/entity/User.kt | 14 ---- .../org/go/sopt/winey/domain/entity/UserV2.kt | 13 ++++ .../winey/domain/repository/AuthRepository.kt | 4 +- .../domain/repository/DataStoreRepository.kt | 6 +- 7 files changed, 57 insertions(+), 68 deletions(-) delete mode 100644 app/src/main/java/org/go/sopt/winey/domain/entity/User.kt create mode 100644 app/src/main/java/org/go/sopt/winey/domain/entity/UserV2.kt diff --git a/app/src/main/java/org/go/sopt/winey/data/model/remote/response/ResponseGetUserDto.kt b/app/src/main/java/org/go/sopt/winey/data/model/remote/response/ResponseGetUserDto.kt index 0d303a85..c96d2974 100644 --- a/app/src/main/java/org/go/sopt/winey/data/model/remote/response/ResponseGetUserDto.kt +++ b/app/src/main/java/org/go/sopt/winey/data/model/remote/response/ResponseGetUserDto.kt @@ -1,61 +1,43 @@ package org.go.sopt.winey.data.model.remote.response -import org.go.sopt.winey.domain.entity.User import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable +import org.go.sopt.winey.domain.entity.UserV2 @Serializable data class ResponseGetUserDto( - @SerialName("userResponseGoalDto") - val userResponseGoalDto: UserResponseGoalDto?, - @SerialName("userResponseUserDto") - val userResponseUserDto: UserResponseUserDto? + @SerialName("userData") + val userData: UserData, ) { @Serializable - data class UserResponseGoalDto( - @SerialName("duringGoalAmount") - val duringGoalAmount: Long, - @SerialName("duringGoalCount") - val duringGoalCount: Long, - @SerialName("isAttained") - val isAttained: Boolean, - @SerialName("isOver") - val isOver: Boolean, - @SerialName("targetDay") - val targetDay: Int, - @SerialName("targetMoney") - val targetMoney: Int, - @SerialName("dday") - val dday: Int - ) - - @Serializable - data class UserResponseUserDto( - @SerialName("nickname") - val nickname: String, + data class UserData( @SerialName("userId") val userId: Int, + @SerialName("nickname") + val nickname: String, @SerialName("userLevel") val userLevel: String, @SerialName("fcmIsAllowed") - val fcmIsAllowed: Boolean + val fcmIsAllowed: Boolean, + @SerialName("accumulatedAmount") + val accumulatedAmount: Int, + @SerialName("amountSavedHundredDays") + val amountSavedHundredDays: Int, + @SerialName("amountSavedTwoWeeks") + val amountSavedTwoWeeks: Int, + @SerialName("amountSpentTwoWeeks") + val amountSpentTwoWeeks: Int ) - fun toUser(): User { - val data = this - val userResponseUserDto = data.userResponseUserDto - - return User( - nickname = userResponseUserDto?.nickname.orEmpty(), - userLevel = userResponseUserDto?.userLevel.orEmpty(), - fcmIsAllowed = userResponseUserDto?.fcmIsAllowed ?: false, - duringGoalAmount = data.userResponseGoalDto?.duringGoalAmount ?: 0, - duringGoalCount = data.userResponseGoalDto?.duringGoalCount ?: 0, - targetMoney = data.userResponseGoalDto?.targetMoney ?: 0, - targetDay = data.userResponseGoalDto?.targetDay ?: 0, - dday = data.userResponseGoalDto?.dday ?: 0, - isOver = data.userResponseGoalDto?.isOver ?: true, - isAttained = data.userResponseGoalDto?.isAttained ?: false + fun toUser(): UserV2 { + return UserV2( + nickname = userData.nickname, + userLevel = userData.userLevel, + fcmIsAllowed = userData.fcmIsAllowed, + accumulatedAmount = userData.accumulatedAmount, + amountSavedHundredDays = userData.amountSavedHundredDays, + amountSavedTwoWeeks = userData.amountSavedTwoWeeks, + amountSpentTwoWeeks = userData.amountSpentTwoWeeks ) } } diff --git a/app/src/main/java/org/go/sopt/winey/data/repository/AuthRepositoryImpl.kt b/app/src/main/java/org/go/sopt/winey/data/repository/AuthRepositoryImpl.kt index d99e6a9e..49c90603 100644 --- a/app/src/main/java/org/go/sopt/winey/data/repository/AuthRepositoryImpl.kt +++ b/app/src/main/java/org/go/sopt/winey/data/repository/AuthRepositoryImpl.kt @@ -11,14 +11,14 @@ import org.go.sopt.winey.data.model.remote.response.ResponseLogoutDto import org.go.sopt.winey.data.model.remote.response.ResponseReIssueTokenDto import org.go.sopt.winey.data.source.AuthDataSource import org.go.sopt.winey.domain.entity.Goal -import org.go.sopt.winey.domain.entity.User +import org.go.sopt.winey.domain.entity.UserV2 import org.go.sopt.winey.domain.repository.AuthRepository import javax.inject.Inject class AuthRepositoryImpl @Inject constructor( private val authDataSource: AuthDataSource ) : AuthRepository { - override suspend fun getUser(): Result = + override suspend fun getUser(): Result = runCatching { authDataSource.getUser().data?.toUser() } diff --git a/app/src/main/java/org/go/sopt/winey/data/repository/DataStoreRepositoryImpl.kt b/app/src/main/java/org/go/sopt/winey/data/repository/DataStoreRepositoryImpl.kt index 6f81b101..4a812dde 100644 --- a/app/src/main/java/org/go/sopt/winey/data/repository/DataStoreRepositoryImpl.kt +++ b/app/src/main/java/org/go/sopt/winey/data/repository/DataStoreRepositoryImpl.kt @@ -10,7 +10,7 @@ import com.google.gson.Gson import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.catch import kotlinx.coroutines.flow.map -import org.go.sopt.winey.domain.entity.User +import org.go.sopt.winey.domain.entity.UserV2 import org.go.sopt.winey.domain.repository.DataStoreRepository import java.io.IOException import javax.inject.Inject @@ -91,14 +91,14 @@ class DataStoreRepositoryImpl @Inject constructor( } } - override suspend fun saveUserInfo(userInfo: User?) { + override suspend fun saveUserInfo(userInfo: UserV2?) { dataStore.edit { val json = Gson().toJson(userInfo) it[USER_INFO] = json } } - override suspend fun getUserInfo(): Flow { + override suspend fun getUserInfo(): Flow { return dataStore.data .catch { exception -> if (exception is IOException) { @@ -111,9 +111,17 @@ class DataStoreRepositoryImpl @Inject constructor( .map { val json = it[USER_INFO] try { - Gson().fromJson(json, User::class.java) + Gson().fromJson(json, UserV2::class.java) } catch (e: Exception) { - User() + UserV2( + nickname = "", + userLevel = "", + accumulatedAmount = 0, + amountSavedHundredDays = 0, + amountSavedTwoWeeks = 0, + amountSpentTwoWeeks = 0, + fcmIsAllowed = true + ) } } } diff --git a/app/src/main/java/org/go/sopt/winey/domain/entity/User.kt b/app/src/main/java/org/go/sopt/winey/domain/entity/User.kt deleted file mode 100644 index 5b031f0e..00000000 --- a/app/src/main/java/org/go/sopt/winey/domain/entity/User.kt +++ /dev/null @@ -1,14 +0,0 @@ -package org.go.sopt.winey.domain.entity - -data class User( - val nickname: String = "", - val userLevel: String = "", - val fcmIsAllowed: Boolean = false, - val duringGoalAmount: Long = 0, - val duringGoalCount: Long = 0, - val targetMoney: Int = 0, - val targetDay: Int = 0, - val dday: Int = 0, - val isOver: Boolean = false, - val isAttained: Boolean = false -) diff --git a/app/src/main/java/org/go/sopt/winey/domain/entity/UserV2.kt b/app/src/main/java/org/go/sopt/winey/domain/entity/UserV2.kt new file mode 100644 index 00000000..49052330 --- /dev/null +++ b/app/src/main/java/org/go/sopt/winey/domain/entity/UserV2.kt @@ -0,0 +1,13 @@ +package org.go.sopt.winey.domain.entity + +import kotlinx.serialization.SerialName + +data class UserV2 ( + val nickname: String, + val userLevel: String, + val fcmIsAllowed: Boolean, + val accumulatedAmount: Int, + val amountSavedHundredDays: Int, + val amountSavedTwoWeeks: Int, + val amountSpentTwoWeeks: Int +) diff --git a/app/src/main/java/org/go/sopt/winey/domain/repository/AuthRepository.kt b/app/src/main/java/org/go/sopt/winey/domain/repository/AuthRepository.kt index ac4dbd3a..d4dd35ca 100644 --- a/app/src/main/java/org/go/sopt/winey/domain/repository/AuthRepository.kt +++ b/app/src/main/java/org/go/sopt/winey/domain/repository/AuthRepository.kt @@ -8,10 +8,10 @@ import org.go.sopt.winey.data.model.remote.response.ResponseLoginDto import org.go.sopt.winey.data.model.remote.response.ResponseLogoutDto import org.go.sopt.winey.data.model.remote.response.ResponseReIssueTokenDto import org.go.sopt.winey.domain.entity.Goal -import org.go.sopt.winey.domain.entity.User +import org.go.sopt.winey.domain.entity.UserV2 interface AuthRepository { - suspend fun getUser(): Result + suspend fun getUser(): Result suspend fun postCreateGoal(requestCreateGoalDto: RequestCreateGoalDto): Result diff --git a/app/src/main/java/org/go/sopt/winey/domain/repository/DataStoreRepository.kt b/app/src/main/java/org/go/sopt/winey/domain/repository/DataStoreRepository.kt index 444578e3..2e6130c9 100644 --- a/app/src/main/java/org/go/sopt/winey/domain/repository/DataStoreRepository.kt +++ b/app/src/main/java/org/go/sopt/winey/domain/repository/DataStoreRepository.kt @@ -2,7 +2,7 @@ package org.go.sopt.winey.domain.repository import androidx.datastore.preferences.core.Preferences import kotlinx.coroutines.flow.Flow -import org.go.sopt.winey.domain.entity.User +import org.go.sopt.winey.domain.entity.UserV2 interface DataStoreRepository { suspend fun saveSocialToken(socialAccessToken: String, socialRefreshToken: String) @@ -25,9 +25,9 @@ interface DataStoreRepository { suspend fun getUserId(): Flow - suspend fun saveUserInfo(userInfo: User?) + suspend fun saveUserInfo(userInfo: UserV2?) - suspend fun getUserInfo(): Flow + suspend fun getUserInfo(): Flow suspend fun clearDataStore() } From 04fd5bdcae44901068f0e54f256fc0db95cbb336 Mon Sep 17 00:00:00 2001 From: HyeseonBaek Date: Sat, 17 Feb 2024 14:18:14 +0900 Subject: [PATCH 05/11] =?UTF-8?q?[mod]=20#242=20UserV2=20Entity=20?= =?UTF-8?q?=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../winey/presentation/main/MainViewModel.kt | 8 ++-- .../main/feed/WineyFeedFragment.kt | 38 +------------------ .../main/mypage/MyPageFragment.kt | 4 +- app/src/main/res/values/strings.xml | 3 ++ 4 files changed, 10 insertions(+), 43 deletions(-) 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 f274086f..269da462 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 @@ -11,7 +11,7 @@ import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.first import kotlinx.coroutines.launch import org.go.sopt.winey.data.model.remote.response.ResponseLogoutDto -import org.go.sopt.winey.domain.entity.User +import org.go.sopt.winey.domain.entity.UserV2 import org.go.sopt.winey.domain.repository.AuthRepository import org.go.sopt.winey.domain.repository.DataStoreRepository import org.go.sopt.winey.domain.repository.NotificationRepository @@ -26,8 +26,8 @@ class MainViewModel @Inject constructor( private val dataStoreRepository: DataStoreRepository, private val notificationRepository: NotificationRepository ) : ViewModel() { - private val _getUserState = MutableStateFlow>(UiState.Loading) - val getUserState: StateFlow> = _getUserState.asStateFlow() + private val _getUserState = MutableStateFlow>(UiState.Loading) + val getUserState: StateFlow> = _getUserState.asStateFlow() private val _logoutState = MutableStateFlow>(UiState.Empty) val logoutState: StateFlow> = _logoutState.asStateFlow() @@ -58,7 +58,7 @@ class MainViewModel @Inject constructor( } } - fun postLogout() { + private 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 4093f012..b85263f5 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 @@ -17,13 +17,11 @@ 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.User import org.go.sopt.winey.domain.entity.WineyFeed import org.go.sopt.winey.domain.repository.DataStoreRepository import org.go.sopt.winey.presentation.main.MainViewModel @@ -45,10 +43,10 @@ import org.go.sopt.winey.util.fragment.stringOf import org.go.sopt.winey.util.fragment.viewLifeCycle import org.go.sopt.winey.util.fragment.viewLifeCycleScope import org.go.sopt.winey.util.fragment.wineySnackbar -import org.go.sopt.winey.util.view.snackbar.SnackbarType import org.go.sopt.winey.util.view.UiState import org.go.sopt.winey.util.view.WineyPopupMenu import org.go.sopt.winey.util.view.setOnSingleClickListener +import org.go.sopt.winey.util.view.snackbar.SnackbarType import org.json.JSONException import org.json.JSONObject import timber.log.Timber @@ -429,40 +427,6 @@ class WineyFeedFragment : } } - /** 1차 릴리즈 당시, 절약 피드 업로드 (더 이상 사용 X) */ - private fun initGetUserStateObserver() { - viewLifeCycleScope.launch { - mainViewModel.getUserState.collect { state -> - when (state) { - is UiState.Success -> { - val data = dataStoreRepository.getUserInfo().firstOrNull() ?: return@collect - checkGoalSetting(data) - } - - is UiState.Failure -> { - snackBar(binding.root) { state.msg } - } - - else -> Timber.tag("failure").e(MSG_WINEYFEED_ERROR) - } - } - } - } - - private fun checkGoalSetting(data: User) { - // 목표를 설정한 적 없거나, 기간 내 목표 달성에 실패한 경우 - if (data.isOver) { - showDefaultGoalSettingDialog() - } - // 기간 내 목표 달성에 성공한 경우 - else if (data.isAttained) { - showCongratulationDialog() - } else { - // 새 목표를 설정한 경우 - //navigateToUpload() - } - } - private fun showDefaultGoalSettingDialog() { amplitudeUtils.logEvent("view_goalsetting_popup") 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 faba564a..ad08a3d0 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 @@ -25,7 +25,7 @@ import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.launch import org.go.sopt.winey.R import org.go.sopt.winey.databinding.FragmentMyPageBinding -import org.go.sopt.winey.domain.entity.User +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.main.mypage.myfeed.MyFeedFragment @@ -220,7 +220,7 @@ class MyPageFragment : BindingFragment(R.layout.fragment_ }.launchIn(lifecycleScope) } - private fun updateUserInfo(data: User) { + private fun updateUserInfo(data: UserV2) { binding.data = data } diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 94eb5de8..f40a318e 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -111,6 +111,9 @@ 최근 2주간 %s 이만큼\n먹을 수 있어요 %s 이만큼\n살 수 있어요 + 100일간 총 %d원을 아꼈네요. + %d원을 절약했어요 + %d원을 낭비했어요 정말 로그아웃 하시겠어요? 로그아웃 후 장기간 미접속 시\n레벨이 내려갈 수 있습니다. From af9af52e21d5909803dc4857198cacfe2bcb8db6 Mon Sep 17 00:00:00 2001 From: HyeseonBaek Date: Sat, 17 Feb 2024 14:26:48 +0900 Subject: [PATCH 06/11] =?UTF-8?q?[feat]=20#242=20getUser=20=EB=8D=B0?= =?UTF-8?q?=EC=9D=B4=ED=84=B0=20=EB=B0=94=EC=9D=B8=EB=94=A9=ED=95=B4=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../remote/response/ResponseGetUserDto.kt | 2 +- .../org/go/sopt/winey/domain/entity/UserV2.kt | 4 +- .../sopt/winey/util/binding/BindingAdapter.kt | 60 +++++++++++++++++-- app/src/main/res/layout/fragment_my_page.xml | 18 +++--- 4 files changed, 68 insertions(+), 16 deletions(-) diff --git a/app/src/main/java/org/go/sopt/winey/data/model/remote/response/ResponseGetUserDto.kt b/app/src/main/java/org/go/sopt/winey/data/model/remote/response/ResponseGetUserDto.kt index c96d2974..f946fd60 100644 --- a/app/src/main/java/org/go/sopt/winey/data/model/remote/response/ResponseGetUserDto.kt +++ b/app/src/main/java/org/go/sopt/winey/data/model/remote/response/ResponseGetUserDto.kt @@ -7,7 +7,7 @@ import org.go.sopt.winey.domain.entity.UserV2 @Serializable data class ResponseGetUserDto( @SerialName("userData") - val userData: UserData, + val userData: UserData ) { @Serializable data class UserData( diff --git a/app/src/main/java/org/go/sopt/winey/domain/entity/UserV2.kt b/app/src/main/java/org/go/sopt/winey/domain/entity/UserV2.kt index 49052330..62661c77 100644 --- a/app/src/main/java/org/go/sopt/winey/domain/entity/UserV2.kt +++ b/app/src/main/java/org/go/sopt/winey/domain/entity/UserV2.kt @@ -1,8 +1,6 @@ package org.go.sopt.winey.domain.entity -import kotlinx.serialization.SerialName - -data class UserV2 ( +data class UserV2( val nickname: String, val userLevel: String, val fcmIsAllowed: Boolean, diff --git a/app/src/main/java/org/go/sopt/winey/util/binding/BindingAdapter.kt b/app/src/main/java/org/go/sopt/winey/util/binding/BindingAdapter.kt index b5e109cf..68bd8e98 100644 --- a/app/src/main/java/org/go/sopt/winey/util/binding/BindingAdapter.kt +++ b/app/src/main/java/org/go/sopt/winey/util/binding/BindingAdapter.kt @@ -10,6 +10,7 @@ import android.widget.EditText import android.widget.ImageView import android.widget.TextView import androidx.appcompat.widget.AppCompatButton +import androidx.constraintlayout.widget.ConstraintLayout import androidx.core.content.ContextCompat import androidx.databinding.BindingAdapter import coil.load @@ -329,6 +330,55 @@ fun CircleImageView.setWriterLevelImage(writerLevel: Int) { setImageResource(drawableResId) } +@BindingAdapter("setMyPageLevelResource", "imageViewId") +fun ImageView.setMyPageLevelResource(userLevel: String?, imageViewId: String) { + userLevel?.let { userLevel -> + imageViewId.let { imageViewId -> + val imageResource: Int = when (imageViewId) { + "SAVER" -> { + when (userLevel) { + "평민" -> R.drawable.img_mypage_saver_lv1 + "기사" -> R.drawable.img_mypage_saver_lv2 + "귀족" -> R.drawable.img_mypage_saver_lv3 + "황제" -> R.drawable.img_mypage_saver_lv4 + else -> { + R.drawable.img_mypage_saver_lv1 + } + } + } + "BUBBLE" -> { + when (userLevel) { + "평민" -> R.drawable.img_mypage_bubble_lv1 + "기사" -> R.drawable.img_mypage_bubble_lv2 + "귀족" -> R.drawable.img_mypage_bubble_lv3 + "황제" -> R.drawable.img_mypage_bubble_lv4 + else -> { + R.drawable.img_mypage_bubble_lv1 + } + } + } + + else -> { R.drawable.img_mypage_saver_lv1 } + } + setImageResource(imageResource) + } + } +} + +@BindingAdapter("setMyPageLevelBackground") +fun ConstraintLayout.setMyPageLevelBackground(userLevel: String) { + val resourceId: Int = when (userLevel) { + "평민" -> R.drawable.img_mypage_background_lv1 + "기사" -> R.drawable.img_mypage_background_lv2 + "귀족" -> R.drawable.img_mypage_background_lv3 + "황제" -> R.drawable.img_mypage_background_lv4 + else -> { + R.drawable.img_mypage_background_lv1 + } + } + this.setBackgroundResource(resourceId) +} + @BindingAdapter("setMyPageItemIcon") fun ImageView.setMyPageItemIcon(iconType: String?) { iconType?.let { @@ -360,7 +410,6 @@ fun TextView.setMyPageItemDescription(iconType: String?) { @BindingAdapter("setMyPageItemSavedAmount", "iconType") fun TextView.setMyPageItemSavedAmount(savedAmount: Int, iconType: String) { - val money: String = when (iconType) { "AMERICANO" -> "5천원 x " "SNEAKERS" -> "3만원 x " @@ -392,19 +441,22 @@ fun TextView.setMyPageItemSavedAmount(savedAmount: Int, iconType: String) { spannableString.setSpan( TextAppearanceSpan(context, R.style.TextAppearance_WINEY_detail_m_12), - 0, money.length, + 0, + money.length, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE ) spannableString.setSpan( TextAppearanceSpan(context, R.style.TextAppearance_WINEY_Headline_b_24_xxl), - money.length, money.length + amount.length, + money.length, + money.length + amount.length, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE ) spannableString.setSpan( ForegroundColorSpan(ContextCompat.getColor(context, R.color.gray_500)), - money.length + amount.length, money.length + amount.length + measurement.length, + money.length + amount.length, + money.length + amount.length + measurement.length, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE ) text = spannableString diff --git a/app/src/main/res/layout/fragment_my_page.xml b/app/src/main/res/layout/fragment_my_page.xml index 60c4a134..d11b7479 100644 --- a/app/src/main/res/layout/fragment_my_page.xml +++ b/app/src/main/res/layout/fragment_my_page.xml @@ -6,7 +6,7 @@ + type="org.go.sopt.winey.domain.entity.UserV2" /> @@ -55,7 +55,7 @@ android:id="@+id/cl_mypage_profile" android:layout_width="match_parent" android:layout_height="wrap_content" - android:background="@drawable/img_mypage_background_lv1" + setMyPageLevelBackground="@{data.userLevel}" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent"> @@ -66,7 +66,8 @@ android:layout_height="wrap_content" android:layout_marginTop="33dp" android:layout_marginBottom="30dp" - android:src="@drawable/img_mypage_bubble_lv1" + app:setMyPageLevelResource="@{data.userLevel}" + app:imageViewId='@{"BUBBLE"}' app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> @@ -76,7 +77,8 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="30dp" - android:src="@drawable/img_mypage_saver_lv1" + app:setMyPageLevelResource="@{data.userLevel}" + app:imageViewId='@{"SAVER"}' app:layout_constraintBottom_toTopOf="@id/tv_mypage_edit_nickname" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" @@ -150,7 +152,7 @@ android:background="@drawable/shape_gray0_fill_16_rect" android:paddingHorizontal="10dp" android:paddingVertical="4dp" - android:text="LV. 기사" + android:text="@{@string/mypage_level_token(data.userLevel)}" android:textAppearance="@style/TextAppearance.WINEY.detail_m_12" android:textColor="@color/gray_600" app:layout_constraintEnd_toEndOf="parent" @@ -261,7 +263,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginHorizontal="16dp" - android:text="100일간 총 190,000원을 아꼈네요." + android:text="@{@string/mypage_save_for_100days(data.amountSavedHundredDays)}" android:textAppearance="@style/TextAppearance.WINEY.body_b_16" android:textColor="@color/gray_900" app:layout_constraintStart_toStartOf="parent" @@ -373,7 +375,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginStart="16dp" - android:text="190,000원을 절약했어요" + android:text="@{@string/mypage_save_for_2weeks(data.amountSavedTwoWeeks)}" android:textAppearance="@style/TextAppearance.WINEY.body_b_16" android:textColor="@color/gray_900" app:layout_constraintStart_toStartOf="parent" @@ -450,7 +452,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginStart="16dp" - android:text="190,000원을 낭비했어요" + android:text="@{@string/mypage_waste_for_2weeks(data.amountSpentTwoWeeks)}" android:textAppearance="@style/TextAppearance.WINEY.body_b_16" android:textColor="@color/gray_900" app:layout_constraintStart_toStartOf="parent" From 11aa1f885fda3eb68de7bc9e75a2e91258a8e187 Mon Sep 17 00:00:00 2001 From: HyeseonBaek Date: Sat, 17 Feb 2024 14:39:58 +0900 Subject: [PATCH 07/11] =?UTF-8?q?[feat]=20#242=20=EB=A7=88=EC=9D=B4?= =?UTF-8?q?=ED=94=BC=EB=93=9C,=20=EB=8B=89=EB=84=A4=EC=9E=84=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD=20=ED=8E=98=EC=9D=B4=EC=A7=80=20=ED=81=B4=EB=A6=AD=20?= =?UTF-8?q?=EB=A6=AC=EC=8A=A4=EB=84=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/mypage/MyPageFragment.kt | 31 +++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) 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 ad08a3d0..945c1da2 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 @@ -38,6 +38,7 @@ 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 import javax.inject.Inject @AndroidEntryPoint @@ -60,11 +61,21 @@ class MyPageFragment : BindingFragment(R.layout.fragment_ initUserData() initNavigation() + addListener() + addObserver() + + checkFromWineyFeed() + } + + private fun addListener() { + initEditNicknameButtonClickListener() + initMyFeedButtonClickListener() registerBackPressedCallback() + } + + private fun addObserver() { setupGetUserState() setupDeleteUserState() - - checkFromWineyFeed() } private fun initCheckNotificationPermission() { @@ -131,6 +142,18 @@ class MyPageFragment : BindingFragment(R.layout.fragment_ } } + private fun initEditNicknameButtonClickListener() { + binding.ivMypageEditNickname.setOnSingleClickListener { + navigateToNicknameScreen() + } + } + + private fun initMyFeedButtonClickListener() { + binding.btnMypageMyfeed.setOnSingleClickListener { + navigateToMyFeedScreen() + } + } + // 마이페이지 왔다가 다시 알림 화면으로 돌아가도록 private fun registerBackPressedCallback() { val callback = object : OnBackPressedCallback(true) { @@ -203,6 +226,10 @@ class MyPageFragment : BindingFragment(R.layout.fragment_ } } + private fun navigateToMyFeedScreen() { + navigateAndBackStack() + } + private fun setupGetUserState() { mainViewModel.getUserState.flowWithLifecycle(lifecycle).onEach { state -> when (state) { From 5331d1fc904d32f27a191787289b36f3deb44817 Mon Sep 17 00:00:00 2001 From: HyeseonBaek Date: Sat, 17 Feb 2024 14:50:20 +0900 Subject: [PATCH 08/11] =?UTF-8?q?[feat]=20#242=20=EA=B8=88=EC=95=A1=20?= =?UTF-8?q?=EB=8B=A8=EC=9C=84=20prefix,=20suffix=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/res/layout/fragment_my_page.xml | 14 +++++++++++--- app/src/main/res/layout/item_mypage.xml | 5 ++++- app/src/main/res/values/strings.xml | 7 ++++--- 3 files changed, 19 insertions(+), 7 deletions(-) diff --git a/app/src/main/res/layout/fragment_my_page.xml b/app/src/main/res/layout/fragment_my_page.xml index d11b7479..59171172 100644 --- a/app/src/main/res/layout/fragment_my_page.xml +++ b/app/src/main/res/layout/fragment_my_page.xml @@ -263,7 +263,9 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginHorizontal="16dp" - android:text="@{@string/mypage_save_for_100days(data.amountSavedHundredDays)}" + setAmount="@{data.amountSavedHundredDays}" + setPrefix="@{@string/mypage_save_for_100days_prefix}" + setSuffix="@{@string/mypage_save_for_100days_suffix}" android:textAppearance="@style/TextAppearance.WINEY.body_b_16" android:textColor="@color/gray_900" app:layout_constraintStart_toStartOf="parent" @@ -287,6 +289,7 @@ android:layout_height="wrap_content" android:layout_marginEnd="4dp" app:item="@{`AMERICANO`}" + app:savedAmount="@{data.amountSavedHundredDays}" app:layout_constraintEnd_toStartOf="@+id/l_mypage_item_chicken" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> @@ -299,6 +302,7 @@ android:layout_marginStart="4dp" android:src="@drawable/ic_mypage_chicken" app:item="@{`CHICKEN`}" + app:savedAmount="@{data.amountSavedHundredDays}" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toEndOf="@id/l_mypage_item_coffee" app:layout_constraintTop_toTopOf="parent" /> @@ -322,6 +326,7 @@ android:layout_height="wrap_content" android:layout_marginEnd="4dp" app:item="@{`SNEAKERS`}" + app:savedAmount="@{data.amountSavedHundredDays}" app:layout_constraintEnd_toStartOf="@+id/l_mypage_item_airpod" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> @@ -333,6 +338,7 @@ android:layout_height="wrap_content" android:layout_marginStart="4dp" app:item="@{`AIRPODS`}" + app:savedAmount="@{data.amountSavedHundredDays}" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toEndOf="@id/l_mypage_item_sneakers" app:layout_constraintTop_toTopOf="parent" /> @@ -375,7 +381,8 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginStart="16dp" - android:text="@{@string/mypage_save_for_2weeks(data.amountSavedTwoWeeks)}" + setAmount="@{data.amountSavedTwoWeeks}" + setSuffix="@{@string/mypage_save_for_2weeks}" android:textAppearance="@style/TextAppearance.WINEY.body_b_16" android:textColor="@color/gray_900" app:layout_constraintStart_toStartOf="parent" @@ -452,7 +459,8 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginStart="16dp" - android:text="@{@string/mypage_waste_for_2weeks(data.amountSpentTwoWeeks)}" + setAmount="@{data.amountSpentTwoWeeks}" + setSuffix="@{@string/mypage_waste_for_2weeks}" android:textAppearance="@style/TextAppearance.WINEY.body_b_16" android:textColor="@color/gray_900" app:layout_constraintStart_toStartOf="parent" diff --git a/app/src/main/res/layout/item_mypage.xml b/app/src/main/res/layout/item_mypage.xml index 59104d0a..5e890d5c 100644 --- a/app/src/main/res/layout/item_mypage.xml +++ b/app/src/main/res/layout/item_mypage.xml @@ -7,6 +7,9 @@ + 최근 2주간 %s 이만큼\n먹을 수 있어요 %s 이만큼\n살 수 있어요 - 100일간 총 %d원을 아꼈네요. - %d원을 절약했어요 - %d원을 낭비했어요 + 100일간 총\t + 원을 아꼈네요. + 원을 절약했어요 + 원을 낭비했어요 정말 로그아웃 하시겠어요? 로그아웃 후 장기간 미접속 시\n레벨이 내려갈 수 있습니다. From 8501b42014fe39aeb5fcbd35deea3f9263ec509a Mon Sep 17 00:00:00 2001 From: HyeseonBaek Date: Sat, 17 Feb 2024 19:25:48 +0900 Subject: [PATCH 09/11] =?UTF-8?q?[mod]=20#242=20=EB=A7=88=EC=9D=B4?= =?UTF-8?q?=ED=94=BC=EB=93=9C=20=ED=94=84=EB=9E=98=EA=B7=B8=EB=A8=BC?= =?UTF-8?q?=ED=8A=B8=EC=97=90=EC=84=9C=20=EC=95=A1=ED=8B=B0=EB=B9=84?= =?UTF-8?q?=ED=8B=B0=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/AndroidManifest.xml | 4 ++ .../main/mypage/MyPageFragment.kt | 8 ++- .../{MyFeedFragment.kt => MyFeedActivity.kt} | 55 +++++++------------ 3 files changed, 30 insertions(+), 37 deletions(-) rename app/src/main/java/org/go/sopt/winey/presentation/main/mypage/myfeed/{MyFeedFragment.kt => MyFeedActivity.kt} (84%) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index e95cc344..a532fb24 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -82,6 +82,10 @@ android:name=".presentation.main.notification.NotificationActivity" android:exported="false" android:screenOrientation="portrait" /> + 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 945c1da2..13bd9670 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 @@ -28,7 +28,7 @@ import org.go.sopt.winey.databinding.FragmentMyPageBinding 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.main.mypage.myfeed.MyFeedFragment +import org.go.sopt.winey.presentation.main.mypage.myfeed.MyFeedActivity 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 @@ -187,7 +187,7 @@ class MyPageFragment : BindingFragment(R.layout.fragment_ if (receivedBundle != null) { val value = receivedBundle.getBoolean(KEY_TO_MYFEED) if (value) { - navigateAndBackStack() + navigateToMyFeedScreen() arguments?.clear() } } @@ -227,7 +227,9 @@ class MyPageFragment : BindingFragment(R.layout.fragment_ } private fun navigateToMyFeedScreen() { - navigateAndBackStack() + Intent(requireContext(), MyFeedActivity::class.java).apply { + startActivity(this) + } } private fun setupGetUserState() { diff --git a/app/src/main/java/org/go/sopt/winey/presentation/main/mypage/myfeed/MyFeedFragment.kt b/app/src/main/java/org/go/sopt/winey/presentation/main/mypage/myfeed/MyFeedActivity.kt similarity index 84% rename from app/src/main/java/org/go/sopt/winey/presentation/main/mypage/myfeed/MyFeedFragment.kt rename to app/src/main/java/org/go/sopt/winey/presentation/main/mypage/myfeed/MyFeedActivity.kt index 3f244c39..d9401a37 100644 --- a/app/src/main/java/org/go/sopt/winey/presentation/main/mypage/myfeed/MyFeedFragment.kt +++ b/app/src/main/java/org/go/sopt/winey/presentation/main/mypage/myfeed/MyFeedActivity.kt @@ -3,11 +3,8 @@ package org.go.sopt.winey.presentation.main.mypage.myfeed import android.content.Intent import android.os.Bundle import android.view.View +import androidx.activity.viewModels import androidx.core.view.isVisible -import androidx.fragment.app.Fragment -import androidx.fragment.app.commit -import androidx.fragment.app.replace -import androidx.fragment.app.viewModels import androidx.lifecycle.flowWithLifecycle import androidx.lifecycle.lifecycleScope import androidx.paging.LoadState @@ -22,29 +19,26 @@ import org.go.sopt.winey.databinding.FragmentMyfeedBinding import org.go.sopt.winey.domain.entity.WineyFeed import org.go.sopt.winey.presentation.main.feed.WineyFeedLoadAdapter import org.go.sopt.winey.presentation.main.feed.detail.DetailActivity -import org.go.sopt.winey.presentation.main.mypage.MyPageFragment import org.go.sopt.winey.presentation.model.WineyDialogLabel -import org.go.sopt.winey.util.binding.BindingFragment +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.context.wineySnackbar import org.go.sopt.winey.util.fragment.WineyDialogFragment -import org.go.sopt.winey.util.fragment.snackBar -import org.go.sopt.winey.util.fragment.stringOf -import org.go.sopt.winey.util.fragment.viewLifeCycle -import org.go.sopt.winey.util.fragment.viewLifeCycleScope -import org.go.sopt.winey.util.fragment.wineySnackbar -import org.go.sopt.winey.util.view.snackbar.SnackbarType import org.go.sopt.winey.util.view.UiState import org.go.sopt.winey.util.view.WineyPopupMenu +import org.go.sopt.winey.util.view.snackbar.SnackbarType import timber.log.Timber @AndroidEntryPoint -class MyFeedFragment : BindingFragment(R.layout.fragment_myfeed) { +class MyFeedActivity : BindingActivity(R.layout.fragment_myfeed) { private val viewModel by viewModels() private lateinit var myFeedAdapter: MyFeedAdapter private lateinit var wineyFeedLoadAdapter: WineyFeedLoadAdapter private var clickedFeedId = -1 - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - super.onViewCreated(view, savedInstanceState) + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) removeRecyclerviewItemChangeAnimation() initAdapter() initBackButtonClickListener() @@ -66,7 +60,7 @@ class MyFeedFragment : BindingFragment(R.layout.fragment_ } private fun initGetDetailFeedStateObserver() { - viewModel.getDetailFeedState.flowWithLifecycle(viewLifeCycle) + viewModel.getDetailFeedState.flowWithLifecycle(lifecycle) .onEach { state -> when (state) { is UiState.Success -> { @@ -81,7 +75,7 @@ class MyFeedFragment : BindingFragment(R.layout.fragment_ else -> {} } - }.launchIn(viewLifeCycleScope) + }.launchIn(lifecycleScope) } private fun initAdapter() { @@ -144,18 +138,17 @@ class MyFeedFragment : BindingFragment(R.layout.fragment_ viewModel.deleteFeed(feed.feedId) } ) - dialog.show(parentFragmentManager, TAG_FEED_DELETE_DIALOG) + dialog.show(supportFragmentManager, TAG_FEED_DELETE_DIALOG) } private fun initBackButtonClickListener() { binding.imgMyfeedBack.setOnClickListener { - navigateTo() - parentFragmentManager.popBackStack() + finish() } } private fun initDeleteFeedStateObserver() { - viewModel.deleteMyFeedState.flowWithLifecycle(viewLifeCycle).onEach { state -> + viewModel.deleteMyFeedState.flowWithLifecycle(lifecycle).onEach { state -> when (state) { is UiState.Success -> { val response = state.data ?: return@onEach @@ -176,11 +169,11 @@ class MyFeedFragment : BindingFragment(R.layout.fragment_ else -> Timber.tag("failure").e(MSG_MYFEED_ERROR) } - }.launchIn(viewLifeCycleScope) + }.launchIn(lifecycleScope) } private fun deletePagingDataItem(feedId: Int) { - viewLifeCycleScope.launch { + lifecycleScope.launch { val newList = myFeedAdapter.deleteItem(feedId) checkEmptyList(newList) myFeedAdapter.submitData(PagingData.from(newList)) @@ -195,7 +188,7 @@ class MyFeedFragment : BindingFragment(R.layout.fragment_ } private fun initGetMyFeedListStateObserver() { - viewModel.getMyFeedListState.flowWithLifecycle(viewLifeCycle) + viewModel.getMyFeedListState.flowWithLifecycle(lifecycle) .onEach { state -> when (state) { is UiState.Success -> { @@ -211,7 +204,7 @@ class MyFeedFragment : BindingFragment(R.layout.fragment_ else -> {} } - }.launchIn(viewLifeCycleScope) + }.launchIn(lifecycleScope) } private fun initPagingLoadStateListener() { @@ -240,7 +233,7 @@ class MyFeedFragment : BindingFragment(R.layout.fragment_ } private fun initPostLikeStateObserver() { - viewModel.postMyFeedLikeState.flowWithLifecycle(viewLifeCycle).onEach { state -> + viewModel.postMyFeedLikeState.flowWithLifecycle(lifecycle).onEach { state -> when (state) { is UiState.Success -> { myFeedAdapter.updateLikeNumber( @@ -256,11 +249,11 @@ class MyFeedFragment : BindingFragment(R.layout.fragment_ else -> Timber.tag("failure").e(MSG_MYFEED_ERROR) } - }.launchIn(viewLifeCycleScope) + }.launchIn(lifecycleScope) } private fun navigateToDetail(wineyFeed: WineyFeed) { - Intent(requireContext(), DetailActivity::class.java).apply { + Intent(this, DetailActivity::class.java).apply { putExtra(KEY_FEED_ID, wineyFeed.feedId) putExtra(KEY_FEED_WRITER_ID, wineyFeed.userId) putExtra(KEY_PREV_SCREEN_NAME, VAL_MY_FEED_SCREEN) @@ -268,12 +261,6 @@ class MyFeedFragment : BindingFragment(R.layout.fragment_ } } - private inline fun navigateTo() { - parentFragmentManager.commit { - replace(R.id.fcv_main, T::class.simpleName) - } - } - companion object { private const val KEY_FEED_ID = "feedId" private const val KEY_FEED_WRITER_ID = "feedWriterId" From 7a3d51b8e29d15155fe7852f2bceeb0e2862088d Mon Sep 17 00:00:00 2001 From: HyeseonBaek Date: Mon, 19 Feb 2024 22:35:17 +0900 Subject: [PATCH 10/11] =?UTF-8?q?[ui]=20#242=20=EB=AA=A9=ED=91=9C=20?= =?UTF-8?q?=ED=99=95=EC=9D=B8=20=EC=B9=B4=EB=93=9C=20=EB=94=94=EC=9E=90?= =?UTF-8?q?=EC=9D=B8=20=EB=B0=98=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/res/drawable/ic_mypage_checked.xml | 18 ++ .../main/res/drawable/ic_mypage_unchecked.xml | 18 ++ ...rect.xml => shape_gray200_line_8_rect.xml} | 4 +- .../drawable/shape_gray50_fill_14_rect.xml | 7 + app/src/main/res/layout/fragment_my_page.xml | 205 ++++++++++++++---- 5 files changed, 206 insertions(+), 46 deletions(-) create mode 100644 app/src/main/res/drawable/ic_mypage_checked.xml create mode 100644 app/src/main/res/drawable/ic_mypage_unchecked.xml rename app/src/main/res/drawable/{shape_gray0_fill_16_rect.xml => shape_gray200_line_8_rect.xml} (71%) create mode 100644 app/src/main/res/drawable/shape_gray50_fill_14_rect.xml diff --git a/app/src/main/res/drawable/ic_mypage_checked.xml b/app/src/main/res/drawable/ic_mypage_checked.xml new file mode 100644 index 00000000..ecc37706 --- /dev/null +++ b/app/src/main/res/drawable/ic_mypage_checked.xml @@ -0,0 +1,18 @@ + + + + diff --git a/app/src/main/res/drawable/ic_mypage_unchecked.xml b/app/src/main/res/drawable/ic_mypage_unchecked.xml new file mode 100644 index 00000000..eefefc6d --- /dev/null +++ b/app/src/main/res/drawable/ic_mypage_unchecked.xml @@ -0,0 +1,18 @@ + + + + diff --git a/app/src/main/res/drawable/shape_gray0_fill_16_rect.xml b/app/src/main/res/drawable/shape_gray200_line_8_rect.xml similarity index 71% rename from app/src/main/res/drawable/shape_gray0_fill_16_rect.xml rename to app/src/main/res/drawable/shape_gray200_line_8_rect.xml index d0f51183..d05d923f 100644 --- a/app/src/main/res/drawable/shape_gray0_fill_16_rect.xml +++ b/app/src/main/res/drawable/shape_gray200_line_8_rect.xml @@ -1,10 +1,8 @@ - - + diff --git a/app/src/main/res/drawable/shape_gray50_fill_14_rect.xml b/app/src/main/res/drawable/shape_gray50_fill_14_rect.xml new file mode 100644 index 00000000..e1a7ffc2 --- /dev/null +++ b/app/src/main/res/drawable/shape_gray50_fill_14_rect.xml @@ -0,0 +1,7 @@ + + + + + diff --git a/app/src/main/res/layout/fragment_my_page.xml b/app/src/main/res/layout/fragment_my_page.xml index 59171172..3673e3c3 100644 --- a/app/src/main/res/layout/fragment_my_page.xml +++ b/app/src/main/res/layout/fragment_my_page.xml @@ -53,9 +53,9 @@ @@ -66,24 +66,22 @@ android:layout_height="wrap_content" android:layout_marginTop="33dp" android:layout_marginBottom="30dp" - app:setMyPageLevelResource="@{data.userLevel}" app:imageViewId='@{"BUBBLE"}' app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" - app:layout_constraintTop_toTopOf="parent" /> + app:layout_constraintTop_toTopOf="parent" + app:setMyPageLevelResource="@{data.userLevel}" /> - + app:layout_constraintTop_toBottomOf="@id/iv_mypage_bubble" + app:setMyPageLevelResource="@{data.userLevel}" /> + app:layout_constraintTop_toBottomOf="@id/iv_mypage_edit_nickname"> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + app:layout_constraintTop_toBottomOf="@id/cl_mypage_goal" /> + - + app:layout_constraintTop_toTopOf="parent" + app:savedAmount="@{data.amountSavedHundredDays}" /> + app:layout_constraintTop_toTopOf="parent" + app:savedAmount="@{data.amountSavedHundredDays}" /> @@ -326,10 +445,10 @@ android:layout_height="wrap_content" android:layout_marginEnd="4dp" app:item="@{`SNEAKERS`}" - app:savedAmount="@{data.amountSavedHundredDays}" app:layout_constraintEnd_toStartOf="@+id/l_mypage_item_airpod" app:layout_constraintStart_toStartOf="parent" - app:layout_constraintTop_toTopOf="parent" /> + app:layout_constraintTop_toTopOf="parent" + app:savedAmount="@{data.amountSavedHundredDays}" /> + app:layout_constraintTop_toTopOf="parent" + app:savedAmount="@{data.amountSavedHundredDays}" /> @@ -378,11 +497,11 @@ Date: Wed, 21 Feb 2024 16:00:08 +0900 Subject: [PATCH 11/11] =?UTF-8?q?[mod]=20#244=20nullable=20=ED=95=98?= =?UTF-8?q?=EC=A7=80=20=EC=95=8A=EA=B2=8C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../org/go/sopt/winey/util/binding/BindingAdapter.kt | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/org/go/sopt/winey/util/binding/BindingAdapter.kt b/app/src/main/java/org/go/sopt/winey/util/binding/BindingAdapter.kt index 68bd8e98..43d2cec3 100644 --- a/app/src/main/java/org/go/sopt/winey/util/binding/BindingAdapter.kt +++ b/app/src/main/java/org/go/sopt/winey/util/binding/BindingAdapter.kt @@ -331,8 +331,8 @@ fun CircleImageView.setWriterLevelImage(writerLevel: Int) { } @BindingAdapter("setMyPageLevelResource", "imageViewId") -fun ImageView.setMyPageLevelResource(userLevel: String?, imageViewId: String) { - userLevel?.let { userLevel -> +fun ImageView.setMyPageLevelResource(userLevel: String, imageViewId: String) { + userLevel.let { userLevel -> imageViewId.let { imageViewId -> val imageResource: Int = when (imageViewId) { "SAVER" -> { @@ -346,6 +346,7 @@ fun ImageView.setMyPageLevelResource(userLevel: String?, imageViewId: String) { } } } + "BUBBLE" -> { when (userLevel) { "평민" -> R.drawable.img_mypage_bubble_lv1 @@ -358,7 +359,9 @@ fun ImageView.setMyPageLevelResource(userLevel: String?, imageViewId: String) { } } - else -> { R.drawable.img_mypage_saver_lv1 } + else -> { + R.drawable.img_mypage_saver_lv1 + } } setImageResource(imageResource) }