Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[QA] 운동 뷰 QA 1차 수정 #140

Merged
merged 28 commits into from
Apr 8, 2024
Merged
Show file tree
Hide file tree
Changes from 27 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
8f46bb5
Merge branch 'develop' into feat/#117-change-exercise
hyunjium Mar 25, 2024
971f976
Merge branch 'feat/#117-change-exercise' into hotfix/#135-home-qa
hyunjium Mar 27, 2024
0ccade1
Merge branch 'hotfix/#135-home-qa' into feat/#117-change-exercise
hyunjium Mar 27, 2024
f803442
Merge branch 'feat/#117-change-exercise' into develop
hyunjium Mar 27, 2024
05f47c3
Revert "Merge branch 'feat/#117-change-exercise' into develop"
hyunjium Mar 27, 2024
8d36f64
Merge branch 'develop' into feat/#117-change-exercise
hyunjium Mar 27, 2024
bbde544
[feat] #117
hyunjium Mar 27, 2024
ad67a49
[feat] #117 오늘 미션 인증 사진 나오게 수정
hyunjium Mar 27, 2024
3322c0d
[chore] #117 오늘 미션 인증 사진 비율 수정
hyunjium Mar 27, 2024
adcc8db
[mod] #139 운동 뷰 오늘 미션, 히스토리 둘 다 나오게 수정
hyunjium Apr 3, 2024
2591806
[mod] #139 신발 이미지 투명도 제거한 이미지로 변경
hyunjium Apr 3, 2024
61a7fbd
[mod] #139 상대방에 맞춰서 아이콘 설정, 버블 설정
hyunjium Apr 3, 2024
5d6a398
[mod] #139 이미지 짧은 쪽 기준으로 상자 꽉차게 출력되도록 수정
hyunjium Apr 3, 2024
d46c455
[mod] #139 이미지 모서리 둥글게 수정
hyunjium Apr 3, 2024
bba903a
[chore] #139 운동중 버블 변경(디자인팀 색 수정)
hyunjium Apr 3, 2024
2ac639f
[chore] #139 물음표 textview랑 분리
hyunjium Apr 3, 2024
c9185c5
[feat] #139 오늘 미션이랑 히스토리 둘 다 없을 때, 빨간색 파일 화면 나오게 수정
hyunjium Apr 3, 2024
b32142d
Merge branch 'develop' into feat/#117-change-exercise
hyunjium Apr 3, 2024
10fe16b
[chore] #139 빈칸 지움
hyunjium Apr 3, 2024
0c5e094
[chore] #139 빈칸 지움
hyunjium Apr 3, 2024
4e9529c
[chore] #139 red 50 색 변경
hyunjium Apr 3, 2024
f49362d
[chore] #139 물음표 padding 값 수정
hyunjium Apr 3, 2024
fed92f1
[feat] #139 이미지 모서리 둥글게 하기 coil 사용
hyunjium Apr 4, 2024
ad259d0
[chore] #139 글자 잘리는 부분 아래로 내리기
hyunjium Apr 4, 2024
2cb494a
[feat] #139 일단은 말풍선 구현 1차
hyunjium Apr 5, 2024
f74637b
[chore] #139 에러 수정
hyunjium Apr 5, 2024
fe104a8
[feat] #139 말풍선 구현 2차(말풍선 위치 윗쪽으로 수정)
hyunjium Apr 8, 2024
2f25755
[fix] #117 홈 부분 수정
l2zh Apr 8, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,12 @@ dependencies {
// dataStore
implementation 'androidx.datastore:datastore-preferences:1.0.0'

//coil
implementation("io.coil-kt:coil:2.0.0-rc03")

//tooltip
implementation "com.github.skydoves:balloon:1.4.6"

// test
androidTestImplementation 'org.jetbrains.kotlinx:kotlinx-coroutines-test:1.6.4'
androidTestImplementation 'com.squareup.okhttp3:mockwebserver:4.10.0'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ data class ResponseExerciseDto(
@Serializable
data class ExerciseHistoryData(
@SerialName("user_type") val userType: String,
@SerialName("opponent_user_type") val opponentUserType: String,
@SerialName("today_mission") val todayMission: MissionContent?,
@SerialName("mission_history") val missionHistory: List<MissionHistory>?,
) {
Expand All @@ -39,8 +40,11 @@ data class ResponseExerciseDto(
}

fun toExerciseData(): ExerciseData {
fun String.removeDayOfTheWeek(): String = this.removeRange(length - 4 until length)
val list: MutableList<ExerciseItemInfo> =
if (data.todayMission == null && data.missionHistory?.isEmpty() == true) {
if (data.todayMission == null && data.missionHistory!!.isEmpty()) {
mutableListOf()
} else if (data.todayMission == null && data.missionHistory!!.size == 1 && data.missionHistory[0].date.removeDayOfTheWeek() == LocalDate.now().prettyString) {
mutableListOf()
} else if (data.todayMission == null) {
mutableListOf(
Expand Down Expand Up @@ -68,7 +72,6 @@ data class ResponseExerciseDto(
}

data.missionHistory?.forEach {
fun String.removeDayOfTheWeek(): String = this.removeRange(length - 4 until length)
if (it.date.removeDayOfTheWeek() != LocalDate.now().prettyString) {
list.add(
ExerciseItemInfo.EachDateItemInfo(
Expand All @@ -83,6 +86,6 @@ data class ResponseExerciseDto(
)
}
}
return ExerciseData(data.userType, list)
return ExerciseData(data.userType, data.opponentUserType, list)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package sopt.motivoo.domain.entity.exercise

class ExerciseData(
val userType: String,
val opponentUserType: String,
val exerciseItemInfoList: List<ExerciseItemInfo>,
) {
sealed class ExerciseItemInfo {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,18 @@ import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import sopt.motivoo.databinding.ItemExerciseBinding
import sopt.motivoo.databinding.ItemExerciseNoticeBinding
import sopt.motivoo.databinding.ItemExerciseTodayBinding
import sopt.motivoo.domain.entity.exercise.ExerciseData.ExerciseItemInfo

class ExerciseAdapter(private val userType: String) :
class ExerciseAdapter(private val userType: String, private val opponentUserType: String) :
RecyclerView.Adapter<RecyclerView.ViewHolder>() {
private var exerciseItemInfoList: List<ExerciseItemInfo> = emptyList()

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
val inflater = LayoutInflater.from(parent.context)
return when (viewType) {
NOTICE_INFO_TYPE -> {
val binding = ItemExerciseNoticeBinding.inflate(inflater, parent, false)
val binding = ItemExerciseTodayBinding.inflate(inflater, parent, false)
ExerciseNoticeViewHolder(binding)
}

Expand All @@ -30,12 +30,19 @@ class ExerciseAdapter(private val userType: String) :
when (holder) {
is ExerciseNoticeViewHolder -> {
val noticeInfo = exerciseItemInfoList[position]
holder.onBind(noticeInfo as ExerciseItemInfo.NoticeItemInfo, userType)
holder.onBind(
noticeInfo as ExerciseItemInfo.NoticeItemInfo,
userType,
opponentUserType,
itemCount
)
}

is ExerciseEachDateInfoViewHolder -> {
val dateExerciseInfo = exerciseItemInfoList[position]
holder.onBind(dateExerciseInfo as ExerciseItemInfo.EachDateItemInfo, userType, itemCount)
holder.onBind(
dateExerciseInfo as ExerciseItemInfo.EachDateItemInfo, opponentUserType
)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,10 @@ class ExerciseFragment : BindingFragment<FragmentExerciseBinding>(R.layout.fragm
}

private fun initAdapter(exerciseData: ExerciseData) {
val adapter = ExerciseAdapter(userType = exerciseData.userType)
val adapter = ExerciseAdapter(
userType = exerciseData.userType,
opponentUserType = exerciseData.opponentUserType
)
adapter.updateItemList(exerciseList = exerciseData.exerciseItemInfoList)
binding.rvExerciseEachDateExercise.adapter = adapter
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,15 @@ import androidx.core.content.ContextCompat
import androidx.navigation.findNavController
import androidx.recyclerview.widget.RecyclerView
import coil.load
import coil.transform.RoundedCornersTransformation
import com.skydoves.balloon.ArrowPositionRules
import com.skydoves.balloon.Balloon
import com.skydoves.balloon.BalloonSizeSpec
import sopt.motivoo.R
import sopt.motivoo.databinding.ItemExerciseBinding
import sopt.motivoo.databinding.ItemExerciseNoticeBinding
import sopt.motivoo.databinding.ItemExerciseTodayBinding
import sopt.motivoo.domain.entity.exercise.ExerciseData.ExerciseItemInfo
import sopt.motivoo.presentation.exercise.ExerciseFragment.Companion.CHILD
import sopt.motivoo.util.extension.prettyString
import java.time.LocalDate

class ExerciseEachDateInfoViewHolder(
private val binding: ItemExerciseBinding,
Expand All @@ -21,39 +23,27 @@ class ExerciseEachDateInfoViewHolder(

fun onBind(
exerciseItemInfoData: ExerciseItemInfo.EachDateItemInfo,
userType: String,
itemSize: Int,
opponentUserType: String,
) {
setHistoryOrNot(exerciseItemInfoData, userType, itemSize)
setHistory(exerciseItemInfoData, opponentUserType)
}

private fun setHistoryOrNot(
private fun setHistory(
exerciseItemInfoData: ExerciseItemInfo.EachDateItemInfo,
userType: String,
itemSize: Int,
opponentUserType: String,
) {
with(binding) {
fun String.removeDayOfTheWeek(): String = this.removeRange(length - 4 until length)
if (itemSize == 2 && exerciseItemInfoData.date!!.removeDayOfTheWeek() == LocalDate.now().prettyString) {
ivExerciseEmptyHistory.visibility = View.VISIBLE
ivItemExerciseLeftImage.visibility = View.GONE
tvItemExerciseMyExercise.visibility = View.GONE
tvItemExerciseOpponentExercise.visibility = View.GONE
ivItemExerciseRightImage.visibility = View.GONE
} else {
ivExerciseEmptyHistory.visibility = View.GONE
initText(exerciseItemInfoData, binding, userType)
initImage(exerciseItemInfoData, binding)
val context = binding.root.context
checkStatus(exerciseItemInfoData, binding, context)
}
initText(exerciseItemInfoData, binding, opponentUserType)
val context = binding.root.context
initImage(context, exerciseItemInfoData, binding)
checkStatus(exerciseItemInfoData, binding, context)
}
}

private fun initText(
exerciseItemInfoData: ExerciseItemInfo.EachDateItemInfo,
binding: ItemExerciseBinding,
userType: String,
opponentUserType: String,
) {
with(binding) {
tvItemExerciseDate.text = exerciseItemInfoData.date
Expand All @@ -62,26 +52,36 @@ class ExerciseEachDateInfoViewHolder(
tvItemExerciseMyState.text = exerciseItemInfoData.myMissionStatus
tvItemExerciseParentState.text = exerciseItemInfoData.opponentMissionStatus
tvItemExerciseOpponentExercise.text =
if (userType == CHILD) root.context.getString(R.string.exercise_parent_exercise) else root.context.getString(
R.string.exercise_child_exercise
if (opponentUserType == CHILD) root.context.getString(R.string.exercise_child_exercise) else root.context.getString(
R.string.exercise_parent_exercise
)
}
}

private fun dpToPx(context: Context, dp: Float): Float {
return dp * (context.resources.displayMetrics.density)
}

private fun initImage(
context: Context,
exerciseItemInfoData: ExerciseItemInfo.EachDateItemInfo,
binding: ItemExerciseBinding,
) {
val pxValue = dpToPx(context, 8f)
with(binding) {
if (exerciseItemInfoData.myMissionImgUrl != null) {
ivItemExerciseLeftImage.load(exerciseItemInfoData.myMissionImgUrl)
ivItemExerciseLeftImage.load(exerciseItemInfoData.myMissionImgUrl) {
transformations(RoundedCornersTransformation(pxValue))
}
} else if (exerciseItemInfoData.myMissionStatus == "없음") {
ivItemExerciseLeftImage.setImageResource(R.drawable.img_choose_exercise)
} else {
ivItemExerciseLeftImage.setImageResource(R.drawable.img_success_next_exercise)
}
if (exerciseItemInfoData.opponentMissionImgUrl != null) {
ivItemExerciseRightImage.load(exerciseItemInfoData.opponentMissionImgUrl)
ivItemExerciseRightImage.load(exerciseItemInfoData.opponentMissionImgUrl) {
transformations(RoundedCornersTransformation(pxValue))
}
} else if (exerciseItemInfoData.opponentMissionStatus == "없음") {
ivItemExerciseRightImage.setImageResource(R.drawable.img_choose_exercise)
} else {
Expand Down Expand Up @@ -126,23 +126,58 @@ class ExerciseEachDateInfoViewHolder(
}
}

class ExerciseNoticeViewHolder(private val binding: ItemExerciseNoticeBinding) :
class ExerciseNoticeViewHolder(private val binding: ItemExerciseTodayBinding) :
RecyclerView.ViewHolder(binding.root) {
fun onBind(exerciseNoticeData: ExerciseItemInfo.NoticeItemInfo, userType: String) {
setCharacterIcon(userType)
fun onBind(
exerciseNoticeData: ExerciseItemInfo.NoticeItemInfo,
userType: String,
opponentUserType: String,
itemCount: Int,
) {
clickQuestionMark()
setCharacterIcon(userType, opponentUserType)
setText(exerciseNoticeData)
setEmptyHistory(itemCount)
}

private fun setCharacterIcon(userType: String) {
if (userType == CHILD) {
binding.ivExerciseTodayIconLeft.setImageResource(R.drawable.ic_child_left)
binding.ivExerciseTodayIconRight.setImageResource(R.drawable.ic_parent_right)
} else {
binding.ivExerciseTodayIconLeft.setImageResource(R.drawable.ic_parent_left)
binding.ivExerciseTodayIconRight.setImageResource(R.drawable.ic_child_right)
private fun clickQuestionMark() {
val context = binding.root.context
val balloon = Balloon.Builder(context)
.setHeight(BalloonSizeSpec.WRAP)
.setWidth(BalloonSizeSpec.WRAP)
.setTextResource(R.string.exercise_today_question_notice)
.setArrowColorResource(R.color.white_FFFFFF)
.setBackgroundColorResource(R.color.white_FFFFFF)
.setTextColorResource(R.color.gray_800_303031)
.setTextSize(15f)
.setTextTypeface(R.font.pretendard)
.setPaddingLeft(11)
.setPaddingRight(15)
.setPaddingTop(14)
.setPaddingBottom(15)
.setMarginTop(3)
.setArrowPositionRules(ArrowPositionRules.ALIGN_ANCHOR)
.setIconDrawableResource(R.drawable.ic_notice)
.setCornerRadius(6f)
.setArrowPosition(0.5f)
.setElevation(5)
.setArrowSize(13)
.build()

binding.ivExerciseTodayIconQuestion.setOnClickListener {
balloon.showAlignTop(binding.ivExerciseTodayIconQuestion)
}
}

private fun setCharacterIcon(userType: String, opponentUserType: String) {
if (userType == CHILD) binding.ivExerciseTodayIconLeft.setImageResource(R.drawable.ic_child_left) else binding.ivExerciseTodayIconLeft.setImageResource(
R.drawable.ic_parent_left
)
if (opponentUserType == CHILD) binding.ivExerciseTodayIconRight.setImageResource(R.drawable.ic_child_right) else binding.ivExerciseTodayIconRight.setImageResource(
R.drawable.ic_parent_right
)
}

private fun setText(exerciseNoticeData: ExerciseItemInfo.NoticeItemInfo) {
val context = binding.root.context
if (exerciseNoticeData.missionContent == null) {
Expand All @@ -156,7 +191,7 @@ class ExerciseNoticeViewHolder(private val binding: ItemExerciseNoticeBinding) :
with(binding) {
tvExerciseTodayExercise.text =
context.getString(R.string.exercise_please_select_today_mission)
clExerciseSelectTodayMission.visibility = View.VISIBLE
clExerciseTodaySelectTodayMission.visibility = View.VISIBLE
tvExerciseTodayMission.visibility = View.GONE
ivExerciseTodayBubbleLeft.visibility = View.GONE
ivExerciseTodayBubbleRight.visibility = View.GONE
Expand All @@ -165,7 +200,7 @@ class ExerciseNoticeViewHolder(private val binding: ItemExerciseNoticeBinding) :
}

private fun setClickEvents() {
binding.clExerciseSelectTodayMission.setOnClickListener {
binding.clExerciseTodaySelectTodayMission.setOnClickListener {
it.findNavController().navigate(R.id.action_exerciseFragment_to_homeFragment)
}
}
Expand All @@ -176,28 +211,44 @@ class ExerciseNoticeViewHolder(private val binding: ItemExerciseNoticeBinding) :
) {
with(binding) {
tvExerciseTodayExercise.text = context.getString(R.string.exercise_today_exercise)
clExerciseSelectTodayMission.visibility = View.GONE
clExerciseTodaySelectTodayMission.visibility = View.GONE
tvExerciseTodayMission.text = exerciseNoticeData.missionContent
}
setTodayImageAndBubble(exerciseNoticeData)
setTodayImageAndBubble(context, exerciseNoticeData)
}

private fun dpToPx(context: Context, dp: Float): Float {
return dp * (context.resources.displayMetrics.density)
}

private fun setTodayImageAndBubble(
context: Context,
exerciseNoticeData: ExerciseItemInfo.NoticeItemInfo,
) {
val pxValue = dpToPx(context, 8f)
if (exerciseNoticeData.missionDate == exerciseNoticeData.todayDate) {
if (exerciseNoticeData.myMissionStatus == ExerciseEachDateInfoViewHolder.STATE_SUCCESS_TYPE) {
binding.ivExerciseTodayBubbleLeft.setImageResource(R.drawable.ic_bubble_success)
binding.ivExerciseTodayImageLeft.load(exerciseNoticeData.myMissionImgUrl)
binding.ivExerciseTodayImageLeft.load(exerciseNoticeData.myMissionImgUrl) {
transformations(RoundedCornersTransformation(pxValue))
}
} else {
binding.ivExerciseTodayBubbleLeft.setImageResource(R.drawable.ic_bubble_exercising)
}
if (exerciseNoticeData.opponentMissionStatus == ExerciseEachDateInfoViewHolder.STATE_SUCCESS_TYPE) {
binding.ivExerciseTodayBubbleRight.setImageResource(R.drawable.ic_bubble_success)
binding.ivExerciseTodayImageRight.load(exerciseNoticeData.opponentMissionImgUrl)
binding.ivExerciseTodayImageRight.load(exerciseNoticeData.opponentMissionImgUrl) {
transformations(RoundedCornersTransformation(pxValue))
}
} else {
binding.ivExerciseTodayBubbleRight.setImageResource(R.drawable.ic_bubble_exercising)
}
}
}

private fun setEmptyHistory(itemCount: Int) {
if (itemCount >= 2) {
binding.ivExerciseTodayEmptyHistory.visibility = View.GONE
}
}
}
Loading
Loading