diff --git a/app/build.gradle b/app/build.gradle index 87559580..2464ba40 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -177,8 +177,8 @@ dependencies { implementation "com.gauravk.audiovisualizer:audiovisualizer:0.9.2" // Glide - implementation 'com.github.bumptech.glide:glide:4.12.0' - annotationProcessor 'com.github.bumptech.glide:compiler:4.12.0' + implementation 'com.github.bumptech.glide:glide:5.0.5' + annotationProcessor 'com.github.bumptech.glide:compiler:5.0.5' implementation "com.michalsvec:single-row-calednar:1.0.0" diff --git a/app/src/main/java/kr/co/vividnext/sodalive/explorer/profile/GetCreatorProfileResponse.kt b/app/src/main/java/kr/co/vividnext/sodalive/explorer/profile/GetCreatorProfileResponse.kt index 5a8f0a7d..00054cf6 100644 --- a/app/src/main/java/kr/co/vividnext/sodalive/explorer/profile/GetCreatorProfileResponse.kt +++ b/app/src/main/java/kr/co/vividnext/sodalive/explorer/profile/GetCreatorProfileResponse.kt @@ -15,6 +15,12 @@ data class GetCreatorProfileResponse( val liveRoomList: List, @SerializedName("contentList") val contentList: List, + @SerializedName("latestContent") + val latestContent: GetAudioContentListItem?, + @SerializedName("totalContentCount") + val totalContentCount: Long, + @SerializedName("ownedContentCount") + val ownedContentCount: Long, @SerializedName("notice") val notice: String, @SerializedName("communityPostList") @@ -64,6 +70,7 @@ data class LiveRoomResponse( @SerializedName("content") val content: String, @SerializedName("isPaid") val isPaid: Boolean, @SerializedName("beginDateTime") val beginDateTime: String, + @SerializedName("beginDateTimeUtc") val beginDateTimeUtc: String, @SerializedName("coverImageUrl") val coverImageUrl: String, @SerializedName("isAdult") val isAdult: Boolean, @SerializedName("price") val price: Int, diff --git a/app/src/main/java/kr/co/vividnext/sodalive/explorer/profile/UserProfileLiveAdapter.kt b/app/src/main/java/kr/co/vividnext/sodalive/explorer/profile/UserProfileLiveAdapter.kt index e234de5a..5e37fe4d 100644 --- a/app/src/main/java/kr/co/vividnext/sodalive/explorer/profile/UserProfileLiveAdapter.kt +++ b/app/src/main/java/kr/co/vividnext/sodalive/explorer/profile/UserProfileLiveAdapter.kt @@ -5,13 +5,16 @@ import android.content.Context import android.view.LayoutInflater import android.view.View import android.view.ViewGroup -import androidx.core.content.ContextCompat import androidx.recyclerview.widget.RecyclerView -import coil.load -import coil.transform.RoundedCornersTransformation +import com.bumptech.glide.Glide +import com.bumptech.glide.load.MultiTransformation +import com.bumptech.glide.load.resource.bitmap.CenterCrop +import com.bumptech.glide.load.resource.bitmap.RoundedCorners import kr.co.vividnext.sodalive.R -import kr.co.vividnext.sodalive.databinding.ItemUserProfileLiveBinding +import kr.co.vividnext.sodalive.databinding.ItemCreatorProfileLiveCardBinding import kr.co.vividnext.sodalive.extensions.dpToPx +import kr.co.vividnext.sodalive.extensions.moneyFormat +import kr.co.vividnext.sodalive.extensions.parseUtcIsoLocalDateTime class UserProfileLiveAdapter( private val onClickParticipant: (LiveRoomResponse) -> Unit, @@ -22,103 +25,87 @@ class UserProfileLiveAdapter( inner class ViewHolder( private val context: Context, - private val binding: ItemUserProfileLiveBinding + private val binding: ItemCreatorProfileLiveCardBinding ) : RecyclerView.ViewHolder(binding.root) { @SuppressLint("SetTextI18n") fun bind(item: LiveRoomResponse) { - binding.ivCover.load(item.coverImageUrl) { - crossfade(true) - placeholder(R.drawable.ic_place_holder) - transformations(RoundedCornersTransformation(4.7f.dpToPx())) + Glide.with(context) + .load(item.coverImageUrl) + .placeholder(R.drawable.ic_place_holder) + .transform( + MultiTransformation( + CenterCrop(), + RoundedCorners(16f.dpToPx().toInt()) + ) + ) + .into(binding.ivProfile) + + binding.tvTitle.text = item.title + binding.tvNickname.text = item.managerNickname + + val dateMap = item.beginDateTimeUtc.parseUtcIsoLocalDateTime() + binding.tvDayOfWeek.text = dateMap["dayOfWeek"] + + binding.ivLock.visibility = if (item.isPrivateRoom) { + View.VISIBLE + } else { + View.GONE } - binding.tvDate.text = item.beginDateTime - binding.tvNickname.text = item.managerNickname - binding.tvTitle.text = item.title - if (item.isActive && !item.channelName.isNullOrBlank()) { - binding.bgCover.visibility = View.GONE - binding.tvStatus.text = "LIVE" - binding.tvStatus.setTextColor(ContextCompat.getColor(context, R.color.color_ff5c49)) - binding.tvStatus.setBackgroundResource( - R.drawable.bg_round_corner_3_3_transparent_ff5c49 - ) + // on-air 상태인 라이브 + binding.tvOnAir.visibility = View.VISIBLE + binding.llDate.visibility = View.GONE - binding.tvParticipate.text = if (!item.isPaid && item.price > 0) { - "${item.price}캔으로 지금 참여하기" + binding.tvTime.text = "On Air" + binding.tvCompleteReservation.visibility = View.GONE + + if (item.price <= 0) { + binding.llCan.visibility = View.GONE + binding.tvFree.visibility = View.VISIBLE } else { - "지금 참여하기" + binding.tvFree.visibility = View.GONE + binding.llCan.visibility = View.VISIBLE + + binding.tvCan.text = item.price.moneyFormat() } - - binding.tvParticipate.setOnClickListener { onClickParticipant(item) } - - binding.tvParticipate.setTextColor( - ContextCompat.getColor( - context, - R.color.white - ) - ) - binding.tvParticipate.setBackgroundResource( - R.drawable.bg_round_corner_5_3_dd4500 - ) } else if (item.isActive && item.channelName.isNullOrBlank()) { - binding.bgCover.visibility = View.GONE - binding.tvStatus.text = "예정" - binding.tvStatus.setTextColor(ContextCompat.getColor(context, R.color.color_fdca2f)) - binding.tvStatus.setBackgroundResource( - R.drawable.bg_round_corner_3_3_transparent_fdca2f - ) + // on-air가 아닌 상태의 라이브 + binding.tvOnAir.visibility = View.GONE + binding.llDate.visibility = View.VISIBLE + + binding.tvTime.text = dateMap["time"] + binding.tvMonth.text = "${dateMap["month"]}월" + binding.tvDay.text = dateMap["day"] if (item.isReservation) { - binding.tvParticipate.text = "예약완료" - binding.tvParticipate.setTextColor( - ContextCompat.getColor(context, R.color.color_777777) - ) - binding.tvParticipate.setBackgroundResource( - R.drawable.bg_round_corner_5_3_525252 - ) + binding.llCan.visibility = View.GONE + binding.tvFree.visibility = View.GONE + binding.tvCompleteReservation.visibility = View.VISIBLE + } else if (item.price <= 0) { + binding.llCan.visibility = View.GONE + binding.tvCompleteReservation.visibility = View.GONE + binding.tvFree.visibility = View.VISIBLE } else { - binding.tvParticipate.text = if (item.price > 0) { - "${item.price}캔으로 예약하기" - } else { - "예약하기" - } + binding.tvFree.visibility = View.GONE + binding.tvCompleteReservation.visibility = View.GONE + binding.llCan.visibility = View.VISIBLE - binding.tvParticipate.setOnClickListener { onClickReservation(item) } - - binding.tvParticipate.setTextColor( - ContextCompat.getColor( - context, - R.color.black - ) - ) - binding.tvParticipate.setBackgroundResource( - R.drawable.bg_round_corner_5_3_fdca2f - ) + binding.tvCan.text = item.price.moneyFormat() } - } else { - binding.bgCover.visibility = View.VISIBLE - binding.tvStatus.text = "종료" - binding.tvStatus.setTextColor(ContextCompat.getColor(context, R.color.color_777777)) - binding.tvStatus.setBackgroundResource( - R.drawable.bg_round_corner_3_3_transparent_777777 - ) - binding.tvParticipate.text = "다시듣기를 지원하지 않습니다" - - binding.tvParticipate.setTextColor( - ContextCompat.getColor(context, R.color.color_777777) - ) - binding.tvParticipate.setBackgroundResource( - R.drawable.bg_round_corner_5_3_525252 - ) + binding.ivLock.visibility = if (item.isPrivateRoom) { + View.VISIBLE + } else { + View.GONE + } } } } override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ViewHolder( parent.context, - ItemUserProfileLiveBinding.inflate( + ItemCreatorProfileLiveCardBinding.inflate( LayoutInflater.from(parent.context), parent, false diff --git a/app/src/main/java/kr/co/vividnext/sodalive/extensions/StringExtensions.kt b/app/src/main/java/kr/co/vividnext/sodalive/extensions/StringExtensions.kt index 16c8dfab..81a4f216 100644 --- a/app/src/main/java/kr/co/vividnext/sodalive/extensions/StringExtensions.kt +++ b/app/src/main/java/kr/co/vividnext/sodalive/extensions/StringExtensions.kt @@ -7,6 +7,7 @@ import java.text.NumberFormat import java.text.SimpleDateFormat import java.util.Currency import java.util.Locale +import java.util.TimeZone fun String.convertDateFormat( from: String, @@ -67,3 +68,31 @@ fun String.formatMoney(currencyCode: String, locale: Locale = Locale.getDefault( val bd = this.toBigDecimal() return nf.format(bd) } + +fun String.parseUtcIsoLocalDateTime(): Map { + // 1. 서버가 내려준 포맷: "yyyy-MM-dd'T'HH:mm:ss" + val utcFormat = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss", Locale.getDefault()) + utcFormat.timeZone = TimeZone.getTimeZone("UTC") // 서버가 UTC 기준으로 보낸 것 + + // 2. Date 객체 생성 + val date = utcFormat.parse(this)!! + + // 3. 월 (1~12) + val month = SimpleDateFormat("M", Locale.getDefault()).format(date) + + // 4. 일 (1~31) + val day = SimpleDateFormat("d", Locale.getDefault()).format(date) + + // 5. 요일 (예: "Mon", "목") + val dayOfWeek = SimpleDateFormat("E", Locale.getDefault()).format(date) + + // 6. 시간 (예: "AM 05:00") + val time = SimpleDateFormat("a hh:mm", Locale.getDefault()).format(date) + + return mapOf( + "month" to month, + "day" to day, + "dayOfWeek" to dayOfWeek, + "time" to time + ) +} diff --git a/app/src/main/java/kr/co/vividnext/sodalive/live/reservation/LiveReservationAdapter.kt b/app/src/main/java/kr/co/vividnext/sodalive/live/reservation/LiveReservationAdapter.kt index d8c57537..438441b3 100644 --- a/app/src/main/java/kr/co/vividnext/sodalive/live/reservation/LiveReservationAdapter.kt +++ b/app/src/main/java/kr/co/vividnext/sodalive/live/reservation/LiveReservationAdapter.kt @@ -14,10 +14,8 @@ import kr.co.vividnext.sodalive.databinding.ItemMyLiveReservationBinding import kr.co.vividnext.sodalive.databinding.LiveBookingCardBinding import kr.co.vividnext.sodalive.extensions.dpToPx import kr.co.vividnext.sodalive.extensions.moneyFormat +import kr.co.vividnext.sodalive.extensions.parseUtcIsoLocalDateTime import kr.co.vividnext.sodalive.live.GetRoomListResponse -import java.text.SimpleDateFormat -import java.util.Locale -import java.util.TimeZone class LiveReservationAdapter( private val isMain: Boolean = false, @@ -82,7 +80,7 @@ class LiveReservationAdapter( @SuppressLint("SetTextI18n") fun bind(item: GetRoomListResponse) { - val dateMap = parseUtcIsoLocalDateTime(item.beginDateTimeUtc) + val dateMap = item.beginDateTimeUtc.parseUtcIsoLocalDateTime() Glide .with(context) @@ -137,7 +135,7 @@ class LiveReservationAdapter( View.GONE } - val dateMap = parseUtcIsoLocalDateTime(item.beginDateTimeUtc) + val dateMap = item.beginDateTimeUtc.parseUtcIsoLocalDateTime() Glide .with(context) @@ -173,32 +171,4 @@ class LiveReservationAdapter( binding.root.setOnClickListener { onClick(item) } } } - - private fun parseUtcIsoLocalDateTime(utcString: String): Map { - // 1. 서버가 내려준 포맷: "yyyy-MM-dd'T'HH:mm:ss" - val utcFormat = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss", Locale.getDefault()) - utcFormat.timeZone = TimeZone.getTimeZone("UTC") // 서버가 UTC 기준으로 보낸 것 - - // 2. Date 객체 생성 - val date = utcFormat.parse(utcString)!! - - // 3. 월 (1~12) - val month = SimpleDateFormat("M", Locale.getDefault()).format(date) - - // 4. 일 (1~31) - val day = SimpleDateFormat("d", Locale.getDefault()).format(date) - - // 5. 요일 (예: "Mon", "목") - val dayOfWeek = SimpleDateFormat("E", Locale.getDefault()).format(date) - - // 6. 시간 (예: "AM 05:00") - val time = SimpleDateFormat("a hh:mm", Locale.getDefault()).format(date) - - return mapOf( - "month" to month, - "day" to day, - "dayOfWeek" to dayOfWeek, - "time" to time - ) - } } diff --git a/app/src/main/res/drawable/bg_round_corner_12_3bb9f1.xml b/app/src/main/res/drawable/bg_round_corner_12_3bb9f1.xml new file mode 100644 index 00000000..61e202b2 --- /dev/null +++ b/app/src/main/res/drawable/bg_round_corner_12_3bb9f1.xml @@ -0,0 +1,8 @@ + + + + + + diff --git a/app/src/main/res/drawable/bg_round_corner_999_ff5c49.xml b/app/src/main/res/drawable/bg_round_corner_999_ff5c49.xml new file mode 100644 index 00000000..ef5d9be2 --- /dev/null +++ b/app/src/main/res/drawable/bg_round_corner_999_ff5c49.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/app/src/main/res/layout/activity_user_profile.xml b/app/src/main/res/layout/activity_user_profile.xml index 2645d0ee..ccdcbfb4 100644 --- a/app/src/main/res/layout/activity_user_profile.xml +++ b/app/src/main/res/layout/activity_user_profile.xml @@ -65,21 +65,6 @@ android:textSize="32sp" tools:text="김상담김상담김상담" /> - - + + diff --git a/app/src/main/res/layout/item_creator_profile_live_card.xml b/app/src/main/res/layout/item_creator_profile_live_card.xml new file mode 100644 index 00000000..b387a55c --- /dev/null +++ b/app/src/main/res/layout/item_creator_profile_live_card.xml @@ -0,0 +1,251 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/layout_user_profile_audio_content.xml b/app/src/main/res/layout/layout_user_profile_audio_content.xml index 0042c7d8..080661a8 100644 --- a/app/src/main/res/layout/layout_user_profile_audio_content.xml +++ b/app/src/main/res/layout/layout_user_profile_audio_content.xml @@ -14,17 +14,17 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentStart="true" - android:fontFamily="@font/gmarket_sans_bold" + android:fontFamily="@font/pretendard_bold" android:text="콘텐츠" - android:textColor="@color/color_eeeeee" - android:textSize="16.7sp" /> + android:textColor="@color/white" + android:textSize="26sp" /> @@ -19,7 +19,7 @@ android:id="@+id/ll_roulette_menu" android:layout_width="match_parent" android:layout_height="wrap_content" - android:layout_marginTop="21.3dp" + android:layout_marginTop="14dp" android:orientation="horizontal" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" @@ -30,35 +30,35 @@ android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" - android:background="@drawable/bg_round_corner_4_7_3bb9f1" - android:fontFamily="@font/gmarket_sans_bold" + android:background="@drawable/bg_round_corner_12_3bb9f1" + android:fontFamily="@font/pretendard_bold" android:gravity="center" - android:paddingVertical="17dp" + android:paddingVertical="12dp" android:text="룰렛 설정" android:textColor="@color/white" - android:textSize="14.7sp" /> + android:textSize="16sp" /> + android:textSize="16sp" />