feat(creator): 커뮤니티 아이템 표시를 통일한다

This commit is contained in:
Yu Sung
2026-08-10 15:11:02 +09:00
parent 89c070875c
commit c372d4a522
15 changed files with 1377 additions and 183 deletions

View File

@@ -25,7 +25,9 @@ struct CreatorChannelCommunityPostDetailContentView: View {
.frame(maxWidth: .infinity, alignment: .leading)
mediaContent
reactionBar
if !isPaidLocked {
reactionBar
}
}
.padding(SodaSpacing.s14)
.frame(maxWidth: .infinity, alignment: .leading)
@@ -154,32 +156,30 @@ struct CreatorChannelCommunityPostDetailContentView: View {
private var reactionBar: some View {
HStack(spacing: 15) {
if isPaidLocked == false {
if detail.isCommentAvailable {
HStack(spacing: SodaSpacing.s4) {
Image("ic_feed_community_reply")
.resizable()
.frame(width: 18, height: 18)
if detail.isCommentAvailable {
HStack(spacing: SodaSpacing.s4) {
Image("ic_feed_community_reply")
.resizable()
.frame(width: 18, height: 18)
Text("\(detail.commentCount)")
.appFont(size: 16, weight: .regular)
.foregroundColor(Color.gray500)
}
Text("\(detail.commentCount)")
.appFont(size: 16, weight: .regular)
.foregroundColor(Color.gray500)
}
Button(action: onTapLike) {
HStack(spacing: SodaSpacing.s4) {
Image(detail.isLiked ? "ic_feed_community_heart_fill" : "ic_feed_community_heart")
.resizable()
.frame(width: 18, height: 18)
Text("\(detail.likeCount)")
.appFont(size: 16, weight: .regular)
.foregroundColor(Color.gray500)
}
}
.buttonStyle(.plain)
}
Button(action: onTapLike) {
HStack(spacing: SodaSpacing.s4) {
Image(detail.isLiked ? "ic_feed_community_heart_fill" : "ic_feed_community_heart")
.resizable()
.frame(width: 18, height: 18)
Text("\(detail.likeCount)")
.appFont(size: 16, weight: .regular)
.foregroundColor(Color.gray500)
}
}
.buttonStyle(.plain)
}
.frame(height: 24)
}

View File

@@ -19,7 +19,7 @@ struct CreatorChannelCommunityPostDetailView: View {
CreatorChannelCommunityPostDetailContentView(
detail: detail,
onTapLike: viewModel.toggleLike,
onTapPurchase: showPurchaseError
onTapPurchase: viewModel.presentPurchaseDialog
)
if detail.isCommentAvailable {
@@ -69,6 +69,14 @@ struct CreatorChannelCommunityPostDetailView: View {
onDimmedTap: dismissDeleteDialog
)
}
if viewModel.isShowPurchaseDialog, let detail = viewModel.detail {
CommunityPostPurchaseDialog(
isShowing: $viewModel.isShowPurchaseDialog,
can: detail.price,
confirmAction: viewModel.purchaseCommunityPost
)
}
}
.navigationBarBackButtonHidden(true)
.onAppear {
@@ -112,9 +120,4 @@ struct CreatorChannelCommunityPostDetailView: View {
)
}
private func showPurchaseError() {
viewModel.errorMessage = I18n.Common.commonError
viewModel.isShowPopup = true
}
}

View File

@@ -24,6 +24,7 @@ final class CreatorChannelCommunityPostDetailViewModel: ObservableObject {
@Published var editingComment: CreatorChannelCommunityCommentResponse?
@Published var deletingComment: CreatorChannelCommunityCommentResponse?
@Published var isShowDeleteDialog = false
@Published var isShowPurchaseDialog = false
@Published var page = 0
@Published var size = 20
@Published var hasNext = false
@@ -182,6 +183,49 @@ final class CreatorChannelCommunityPostDetailViewModel: ObservableObject {
.store(in: &subscription)
}
func presentPurchaseDialog() {
guard let detail, detail.price > 0, detail.existOrdered == false, isOwnPost == false else { return }
isShowPurchaseDialog = true
}
func purchaseCommunityPost() {
guard postId > 0, isLoading == false else { return }
isLoading = true
communityRepository.purchaseCommunityPost(postId: postId)
.sink { [weak self] result in
guard let self else { return }
switch result {
case .finished:
DEBUG_LOG("finish")
case .failure(let error):
ERROR_LOG(error.localizedDescription)
self.applyFailureState()
}
} receiveValue: { [weak self] response in
guard let self else { return }
self.isLoading = false
do {
let decoded = try JSONDecoder().decode(ApiResponseWithoutData.self, from: response.data)
if decoded.success {
self.onCommunityRefresh?()
self.fetchDetail(postId: self.postId)
} else {
self.errorMessage = decoded.message ?? I18n.Common.commonError
self.isShowPopup = true
}
} catch {
ERROR_LOG(error.localizedDescription)
self.errorMessage = I18n.Common.commonError
self.isShowPopup = true
}
}
.store(in: &subscription)
}
func sendComment() {
guard isCommentSendEnabled else { return }