콘텐츠 상세

- 소장만, 대여만 가능시 구매하기 버튼 배경색 변경
- 소장만, 대여만 가능시 구매하기 버튼을 터치하면 바로 구매확인 다이얼로그 표시
This commit is contained in:
Yu Sung 2024-11-08 21:06:24 +09:00
parent 696aed5c00
commit f6ae14d614
5 changed files with 87 additions and 80 deletions

View File

@ -10,7 +10,8 @@ import SwiftUI
struct ContentDetailPurchaseButton: View { struct ContentDetailPurchaseButton: View {
let price: Int let price: Int
let isOnlyRental: Bool let title: String
let backgroundColor: Color
var body: some View { var body: some View {
HStack(spacing: 0) { HStack(spacing: 0) {
@ -29,13 +30,13 @@ struct ContentDetailPurchaseButton: View {
.font(.custom(Font.light.rawValue, size: 12)) .font(.custom(Font.light.rawValue, size: 12))
.foregroundColor(.white) .foregroundColor(.white)
Text(isOnlyRental ? " 대여하기" : " 구매하기") Text(title)
.font(.custom(Font.bold.rawValue, size: 14.7)) .font(.custom(Font.bold.rawValue, size: 14.7))
.foregroundColor(.white) .foregroundColor(.white)
} }
.frame(maxWidth: .infinity) .frame(maxWidth: .infinity)
.frame(height: 48.7) .frame(height: 48.7)
.background(Color.button) .background(backgroundColor)
.cornerRadius(5.3) .cornerRadius(5.3)
.padding(.top, 18.3) .padding(.top, 18.3)
} }

View File

@ -123,13 +123,23 @@ struct ContentDetailView: View {
.padding(.top, 18.3) .padding(.top, 18.3)
.padding(.horizontal, 13.3) .padding(.horizontal, 13.3)
} else { } else {
ContentDetailPurchaseButton(price: audioContent.price, isOnlyRental: audioContent.isOnlyRental) ContentDetailPurchaseButton(
price: audioContent.price,
title: audioContent.purchaseOption == .RENT_ONLY ? " 대여하기" :
audioContent.purchaseOption == .BUY_ONLY ? " 소장하기" : " 구매하기",
backgroundColor: audioContent.purchaseOption == .RENT_ONLY ? Color(hex: "548f7d") :
audioContent.purchaseOption == .BUY_ONLY ? Color(hex: "59548f") :
Color.button
)
.contentShape(Rectangle()) .contentShape(Rectangle())
.padding(.horizontal, 13.3) .padding(.horizontal, 13.3)
.onTapGesture { .onTapGesture {
if let _ = audioContent.totalContentCount, let _ = audioContent.remainingContentCount { if audioContent.purchaseOption == .BUY_ONLY || (audioContent.totalContentCount != nil && audioContent.remainingContentCount != nil) {
viewModel.orderType = .KEEP viewModel.orderType = .KEEP
isShowOrderConfirmView = true isShowOrderConfirmView = true
} else if audioContent.purchaseOption == .RENT_ONLY {
viewModel.orderType = .RENTAL
isShowOrderConfirmView = true
} else { } else {
isShowOrderView = true isShowOrderView = true
} }
@ -204,7 +214,6 @@ struct ContentDetailView: View {
ContentOrderDialogView( ContentOrderDialogView(
isShowing: $isShowOrderView, isShowing: $isShowOrderView,
price: audioContent.price, price: audioContent.price,
isOnlyRental: audioContent.isOnlyRental,
onTapPurchase: { onTapPurchase: {
viewModel.orderType = $0 viewModel.orderType = $0
isShowOrderConfirmView = true isShowOrderConfirmView = true
@ -228,9 +237,14 @@ struct ContentDetailView: View {
VStack(spacing: 0) { VStack(spacing: 0) {
ContentOrderConfirmDialogView( ContentOrderConfirmDialogView(
isShowing: $isShowOrderConfirmView, isShowing: $isShowOrderConfirmView,
audioContent: audioContent, title: audioContent.title,
price: audioContent.purchaseOption == .BOTH && orderType == .RENTAL ? Int(ceil(Double(audioContent.price) * 0.7)) : audioContent.price,
duration: audioContent.duration,
themeStr: audioContent.themeStr,
coverImageUrl: audioContent.coverImageUrl,
creatorNickname: audioContent.creator.nickname,
creatorProfileImageUrl: audioContent.creator.profileImageUrl,
orderType: orderType, orderType: orderType,
isOnlyRental: audioContent.isOnlyRental,
onClickConfirm: { onClickConfirm: {
if UserDefaults.int(forKey: .userId) == 17958 { if UserDefaults.int(forKey: .userId) == 17958 {
AppState.shared AppState.shared
@ -239,7 +253,8 @@ struct ContentDetailView: View {
orderType: orderType, orderType: orderType,
contentId: audioContent.contentId, contentId: audioContent.contentId,
title: audioContent.title, title: audioContent.title,
can: !audioContent.isOnlyRental && orderType == .RENTAL ? Int(ceil(Double(audioContent.price) * 0.7)) : audioContent.price can: audioContent.purchaseOption == .BOTH && orderType == .RENTAL ? Int(ceil(Double(audioContent.price) * 0.7)) :
audioContent.price
) )
) )
} else { } else {

View File

@ -12,9 +12,15 @@ struct ContentOrderConfirmDialogView: View {
@Binding var isShowing: Bool @Binding var isShowing: Bool
let audioContent: GetAudioContentDetailResponse let title: String
let price: Int
let duration: String
let themeStr: String
let coverImageUrl: String
let creatorNickname: String
let creatorProfileImageUrl: String
let orderType: OrderType let orderType: OrderType
let isOnlyRental: Bool
let onClickConfirm: () -> Void let onClickConfirm: () -> Void
var body: some View { var body: some View {
@ -31,7 +37,7 @@ struct ContentOrderConfirmDialogView: View {
HStack(spacing: 11) { HStack(spacing: 11) {
ZStack(alignment: .topLeading) { ZStack(alignment: .topLeading) {
KFImage(URL(string: audioContent.coverImageUrl)) KFImage(URL(string: coverImageUrl))
.cancelOnDisappear(true) .cancelOnDisappear(true)
.downsampling( .downsampling(
size: CGSize( size: CGSize(
@ -46,20 +52,20 @@ struct ContentOrderConfirmDialogView: View {
} }
VStack(alignment: .leading, spacing: 0) { VStack(alignment: .leading, spacing: 0) {
Text(audioContent.themeStr) Text(themeStr)
.font(.custom(Font.medium.rawValue, size: 8)) .font(.custom(Font.medium.rawValue, size: 8))
.foregroundColor(Color(hex: "3bac6a")) .foregroundColor(Color(hex: "3bac6a"))
.padding(2.3) .padding(2.3)
.background(Color(hex: "28312b")) .background(Color(hex: "28312b"))
.cornerRadius(2) .cornerRadius(2)
Text(audioContent.title) Text(title)
.font(.custom(Font.bold.rawValue, size: 11.3)) .font(.custom(Font.bold.rawValue, size: 11.3))
.foregroundColor(Color.grayd2) .foregroundColor(Color.grayd2)
.padding(.top, 2) .padding(.top, 2)
HStack(spacing: 4.3) { HStack(spacing: 4.3) {
KFImage(URL(string: audioContent.creator.profileImageUrl)) KFImage(URL(string: creatorProfileImageUrl))
.cancelOnDisappear(true) .cancelOnDisappear(true)
.downsampling( .downsampling(
size: CGSize( size: CGSize(
@ -71,13 +77,13 @@ struct ContentOrderConfirmDialogView: View {
.frame(width: 13.3, height: 13.3) .frame(width: 13.3, height: 13.3)
.clipShape(Circle()) .clipShape(Circle())
Text(audioContent.creator.nickname) Text(creatorNickname)
.font(.custom(Font.medium.rawValue, size: 10)) .font(.custom(Font.medium.rawValue, size: 10))
.foregroundColor(Color.gray77) .foregroundColor(Color.gray77)
} }
.padding(.top, 6.7) .padding(.top, 6.7)
Text(audioContent.duration) Text(duration)
.font(.custom(Font.medium.rawValue, size: 11)) .font(.custom(Font.medium.rawValue, size: 11))
.foregroundColor(Color.gray77) .foregroundColor(Color.gray77)
.padding(.top, 6.7) .padding(.top, 6.7)
@ -114,25 +120,13 @@ struct ContentOrderConfirmDialogView: View {
.resizable() .resizable()
.frame(width: 16.7, height: 16.7) .frame(width: 16.7, height: 16.7)
if orderType == .RENTAL { Text("\(price)")
Text("\(isOnlyRental ? audioContent.price : Int(ceil(Double(audioContent.price) * 0.7)))") .font(.custom(Font.bold.rawValue, size: 13.3))
.font(.custom(Font.bold.rawValue, size: 13.3)) .foregroundColor(Color.grayee)
.foregroundColor(Color.grayee)
} else {
Text("\(audioContent.price)")
.font(.custom(Font.bold.rawValue, size: 13.3))
.foregroundColor(Color.grayee)
}
} else { } else {
if orderType == .RENTAL { Text("\(price * 110)")
Text("\(isOnlyRental ? audioContent.price * 110 : Int(ceil(Double(audioContent.price) * 0.7)) * 110)") .font(.custom(Font.bold.rawValue, size: 13.3))
.font(.custom(Font.bold.rawValue, size: 13.3)) .foregroundColor(Color.grayee)
.foregroundColor(Color.grayee)
} else {
Text("\(audioContent.price * 110)")
.font(.custom(Font.bold.rawValue, size: 13.3))
.foregroundColor(Color.grayee)
}
} }
Spacer() Spacer()

View File

@ -12,7 +12,6 @@ struct ContentOrderDialogView: View {
@Binding var isShowing: Bool @Binding var isShowing: Bool
let price: Int let price: Int
let isOnlyRental: Bool
let onTapPurchase: (OrderType) -> Void let onTapPurchase: (OrderType) -> Void
var body: some View { var body: some View {
@ -47,11 +46,11 @@ struct ContentOrderDialogView: View {
} }
if UserDefaults.int(forKey: .userId) == 17958 { if UserDefaults.int(forKey: .userId) == 17958 {
Text(isOnlyRental ? "\(price * 110)" : "\(Int(ceil(Double(price) * 0.7)) * 110)") Text("\(Int(ceil(Double(price) * 0.7)) * 110)")
.font(.custom(Font.bold.rawValue, size: 13.3)) .font(.custom(Font.bold.rawValue, size: 13.3))
.foregroundColor(Color.grayee) .foregroundColor(Color.grayee)
} else { } else {
Text(isOnlyRental ? "\(price)" : "\(Int(ceil(Double(price) * 0.7)))") Text("\(Int(ceil(Double(price) * 0.7)))")
.font(.custom(Font.bold.rawValue, size: 13.3)) .font(.custom(Font.bold.rawValue, size: 13.3))
.foregroundColor(Color.grayee) .foregroundColor(Color.grayee)
} }
@ -72,52 +71,50 @@ struct ContentOrderDialogView: View {
} }
} }
if !isOnlyRental { HStack(spacing: 0) {
HStack(spacing: 0) { VStack(alignment: .leading, spacing: 5.3) {
VStack(alignment: .leading, spacing: 5.3) { Text("소장")
Text("소장") .font(.custom(Font.bold.rawValue, size: 13.3))
.foregroundColor(.white)
Text("(서비스 종료시까지)")
.font(.custom(Font.light.rawValue, size: 12))
.foregroundColor(.white)
}
Spacer()
HStack(spacing: 8) {
if UserDefaults.int(forKey: .userId) != 17958 {
Image("ic_can")
.resizable()
.frame(width: 16.7, height: 16.7)
}
if UserDefaults.int(forKey: .userId) == 17958 {
Text("\(price * 110)")
.font(.custom(Font.bold.rawValue, size: 13.3)) .font(.custom(Font.bold.rawValue, size: 13.3))
.foregroundColor(.white) .foregroundColor(Color.grayee)
} else {
Text("(서비스 종료시까지)") Text("\(price)")
.font(.custom(Font.light.rawValue, size: 12)) .font(.custom(Font.bold.rawValue, size: 13.3))
.foregroundColor(.white) .foregroundColor(Color.grayee)
} }
Spacer() if UserDefaults.int(forKey: .userId) == 17958 {
Text("")
HStack(spacing: 8) { .font(.custom(Font.bold.rawValue, size: 13.3))
if UserDefaults.int(forKey: .userId) != 17958 { .foregroundColor(Color.grayee)
Image("ic_can")
.resizable()
.frame(width: 16.7, height: 16.7)
}
if UserDefaults.int(forKey: .userId) == 17958 {
Text("\(price * 110)")
.font(.custom(Font.bold.rawValue, size: 13.3))
.foregroundColor(Color.grayee)
} else {
Text("\(price)")
.font(.custom(Font.bold.rawValue, size: 13.3))
.foregroundColor(Color.grayee)
}
if UserDefaults.int(forKey: .userId) == 17958 {
Text("")
.font(.custom(Font.bold.rawValue, size: 13.3))
.foregroundColor(Color.grayee)
}
}
.padding(.vertical, 8)
.padding(.horizontal, 13.3)
.background(Color.button)
.cornerRadius(5.3)
.onTapGesture {
onTapPurchase(.KEEP)
isShowing = false
} }
} }
.padding(.vertical, 8)
.padding(.horizontal, 13.3)
.background(Color.button)
.cornerRadius(5.3)
.onTapGesture {
onTapPurchase(.KEEP)
isShowing = false
}
} }
} }
.padding(24) .padding(24)

View File

@ -24,8 +24,8 @@ struct GetAudioContentDetailResponse: Decodable {
let isActivePreview: Bool let isActivePreview: Bool
let isAdult: Bool let isAdult: Bool
let isMosaic: Bool let isMosaic: Bool
let isOnlyRental: Bool
let existOrdered: Bool let existOrdered: Bool
let purchaseOption: PurchaseOption
let orderType: OrderType? let orderType: OrderType?
let remainingTime: String? let remainingTime: String?
let creatorOtherContentList: [OtherContentResponse] let creatorOtherContentList: [OtherContentResponse]