커뮤니티 유료 게시글 조회, 구매 기능 추가

This commit is contained in:
Yu Sung
2024-05-24 16:19:43 +09:00
parent 0a96509b35
commit 3ae5ea776c
13 changed files with 337 additions and 63 deletions

View File

@@ -0,0 +1,39 @@
//
// CreatorCommunityAllItemLockView.swift
// SodaLive
//
// Created by klaus on 5/24/24.
//
import SwiftUI
struct CreatorCommunityAllItemLockView: View {
let price: Int
let onClickPurchaseContent: () -> Void
var body: some View {
VStack(spacing: 26.7) {
Image("ic_lock_bb")
Text("\(price)캔으로 게시글 보기")
.font(.custom(Font.bold.rawValue, size: 12))
.foregroundColor(Color.button)
.padding(.horizontal, 21)
.padding(.vertical, 11)
.overlay(
RoundedRectangle(cornerRadius: 26.7)
.stroke(Color.button, lineWidth: 1)
)
.onTapGesture { onClickPurchaseContent() }
}
.frame(width: screenSize().width - 42, height: screenSize().width - 42)
.background(Color.gray33)
.cornerRadius(5.3)
}
}
#Preview {
CreatorCommunityAllItemLockView(price: 100) {
}
}

View File

@@ -15,6 +15,7 @@ struct CreatorCommunityAllItemView: View {
let onClickComment: () -> Void
let onClickWriteComment: (String) -> Void
let onClickShowReportMenu: () -> Void
let onClickPurchaseContent: () -> Void
@State var isLike = false
@State var likeCount = 0
@@ -25,13 +26,15 @@ struct CreatorCommunityAllItemView: View {
onClickLike: @escaping () -> Void,
onClickComment: @escaping () -> Void,
onClickWriteComment: @escaping (String) -> Void,
onClickShowReportMenu: @escaping () -> Void
onClickShowReportMenu: @escaping () -> Void,
onClickPurchaseContent: @escaping () -> Void
) {
self.item = item
self.onClickLike = onClickLike
self.onClickComment = onClickComment
self.onClickWriteComment = onClickWriteComment
self.onClickShowReportMenu = onClickShowReportMenu
self.onClickPurchaseContent = onClickPurchaseContent
self._isLike = State(initialValue: item.isLike)
self._likeCount = State(initialValue: item.likeCount)
@@ -58,66 +61,74 @@ struct CreatorCommunityAllItemView: View {
Spacer()
Image("ic_seemore_vertical")
.padding(.trailing, 8.3)
.onTapGesture { onClickShowReportMenu() }
if item.price <= 0 || item.existOrdered {
Image("ic_seemore_vertical")
.padding(.trailing, 8.3)
.onTapGesture { onClickShowReportMenu() }
}
}
DetectableTextView(text: item.content, textSize: 13.3, font: Font.medium.rawValue)
.frame(
width: screenSize().width - 16,
height: textHeight
)
.onAppear {
self.textHeight = self.estimatedHeight(
for: item.content,
width: screenSize().width - 16
if item.price <= 0 || item.existOrdered {
DetectableTextView(text: item.content, textSize: 13.3, font: Font.medium.rawValue)
.frame(
width: screenSize().width - 16,
height: textHeight
)
}
.onChange(of: item.content) { newText in
self.textHeight = self.estimatedHeight(
for: newText,
width: screenSize().width - 16
)
}
if let imageUrl = item.imageUrl {
KFImage(URL(string: imageUrl))
.resizable()
.frame(maxWidth: .infinity)
.scaledToFit()
}
HStack(spacing: 8) {
IconAndTitleToggleButton(
isChecked: isLike,
title: "\(likeCount)",
normalIconName: "ic_audio_content_heart_normal",
checkedIconName: "ic_audio_content_heart_pressed"
) {
if isLike {
isLike = false
likeCount -= 1
} else {
isLike = true
likeCount += 1
.onAppear {
self.textHeight = self.estimatedHeight(
for: item.content,
width: screenSize().width - 16
)
}
onClickLike()
.onChange(of: item.content) { newText in
self.textHeight = self.estimatedHeight(
for: newText,
width: screenSize().width - 16
)
}
if let imageUrl = item.imageUrl {
KFImage(URL(string: imageUrl))
.resizable()
.frame(maxWidth: .infinity)
.scaledToFit()
}
}
.frame(maxWidth: .infinity, alignment: .leading)
if item.isCommentAvailable {
CreatorCommunityCommentView(
commentCount: item.commentCount,
commentItem: item.firstComment,
onClickWriteComment: onClickWriteComment
)
.onTapGesture {
if item.commentCount > 0 {
onClickComment()
HStack(spacing: 8) {
IconAndTitleToggleButton(
isChecked: isLike,
title: "\(likeCount)",
normalIconName: "ic_audio_content_heart_normal",
checkedIconName: "ic_audio_content_heart_pressed"
) {
if isLike {
isLike = false
likeCount -= 1
} else {
isLike = true
likeCount += 1
}
onClickLike()
}
}
.frame(maxWidth: .infinity, alignment: .leading)
if item.isCommentAvailable {
CreatorCommunityCommentView(
commentCount: item.commentCount,
commentItem: item.firstComment,
onClickWriteComment: onClickWriteComment
)
.onTapGesture {
if item.commentCount > 0 {
onClickComment()
}
}
}
} else {
CreatorCommunityAllItemLockView(
price: item.price,
onClickPurchaseContent: onClickPurchaseContent)
}
}
.padding(.horizontal, 8)
@@ -144,10 +155,12 @@ struct CreatorCommunityAllItemView_Previews: PreviewProvider {
creatorProfileUrl: "https://test-cf.sodalive.net/profile/default-profile.png",
imageUrl: "https://test-cf.sodalive.net/profile/default-profile.png",
content: "너무 조하유 앞으로도 좋은 라이브 많이 들려주세요!너무 조하유 앞으로도 좋은 라이브 많이 들려주세요!너무 조하유 앞으로도 좋은 라이브 많이 들려주세요!너무 조하유 앞으로도 좋은 라이브 많이 들려주세요!너무 조하유 앞으로도 좋은 라이브 많이 들려주세요!너무 조하유 앞으로도 좋은 라이브 많이 들려주세요!너무 조하유 앞으로도 좋은 라이브 많이 들려주세요!너무 조하유 앞으로도 좋은 라이브 많이 들려주세요!너무 조하유 앞으로도 좋은 라이브 많이 들려주세요!너무 조하유 앞으로도 좋은 라이브 많이 들려주세요!너무 조하유 앞으로도 좋은 라이브 많이 들려주세요!너무 조하유 앞으로도 좋은 라이브 많이 들려주세요!",
price: 10,
date: "3일전",
isCommentAvailable: false,
isAdult: false,
isLike: true,
existOrdered: false,
likeCount: 10,
commentCount: 0,
firstComment: nil
@@ -155,7 +168,8 @@ struct CreatorCommunityAllItemView_Previews: PreviewProvider {
onClickLike: {},
onClickComment: {},
onClickWriteComment: { _ in },
onClickShowReportMenu: {}
onClickShowReportMenu: {},
onClickPurchaseContent: {}
)
}
}

View File

@@ -41,6 +41,12 @@ struct CreatorCommunityAllView: View {
onClickShowReportMenu: {
viewModel.postId = item.postId
viewModel.isShowReportMenu = true
},
onClickPurchaseContent: {
viewModel.postId = item.postId
viewModel.postPrice = item.price
viewModel.postIndex = index
viewModel.isShowPostPurchaseView = true
}
)
.onAppear {
@@ -121,6 +127,15 @@ struct CreatorCommunityAllView: View {
}
)
}
if viewModel.isShowPostPurchaseView {
CommunityPostPurchaseDialog(
isShowing: $viewModel.isShowPostPurchaseView,
can: viewModel.postPrice
) {
viewModel.purchaseCommunityPost()
}
}
}
}
.popup(isPresented: $viewModel.isShowPopup, type: .toast, position: .top, autohideIn: 2) {

View File

@@ -21,6 +21,8 @@ class CreatorCommunityAllViewModel: ObservableObject {
@Published private(set) var communityPostList = [GetCommunityPostListResponse]()
@Published var postId = 0
@Published var postPrice = 0
@Published var postIndex = -1
@Published var isShowCommentListView = false {
didSet {
@@ -46,6 +48,16 @@ class CreatorCommunityAllViewModel: ObservableObject {
}
}
@Published var isShowPostPurchaseView = false {
didSet {
if !isShowPostPurchaseView {
postId = 0
postPrice = 0
postIndex = -1
}
}
}
var creatorId = 0
var page = 1
@@ -254,4 +266,51 @@ class CreatorCommunityAllViewModel: ObservableObject {
self.isLoading = false
}
}
func purchaseCommunityPost() {
let postId = postId
let postIndex = postIndex
if !isLoading {
isLoading = true
repository
.purchaseCommunityPost(postId: postId)
.sink { result in
switch result {
case .finished:
DEBUG_LOG("finish")
case .failure(let error):
ERROR_LOG(error.localizedDescription)
}
} receiveValue: { [unowned self] response in
let responseData = response.data
do {
let jsonDecoder = JSONDecoder()
let decoded = try jsonDecoder.decode(ApiResponse<GetCommunityPostListResponse>.self, from: responseData)
if let data = decoded.data, decoded.success {
if postIndex >= 0 {
communityPostList[postIndex] = data
}
} else {
if let message = decoded.message {
self.errorMessage = message
} else {
self.errorMessage = "다시 시도해 주세요.\n계속 같은 문제가 발생할 경우 고객센터로 문의 주시기 바랍니다."
}
self.isShowPopup = true
}
} catch {
self.errorMessage = "다시 시도해 주세요.\n계속 같은 문제가 발생할 경우 고객센터로 문의 주시기 바랍니다."
self.isShowPopup = true
}
self.isLoading = false
}
.store(in: &subscription)
}
}
}

View File

@@ -0,0 +1,14 @@
//
// PurchasePostRequest.swift
// SodaLive
//
// Created by klaus on 5/24/24.
//
import Foundation
struct PurchasePostRequest: Encodable {
let postId: Int
let container: String = "ios"
let timezone: String = TimeZone.current.identifier
}