커뮤니티 유료 게시글 조회, 구매 기능 추가
This commit is contained in:
parent
0a96509b35
commit
3ae5ea776c
|
@ -0,0 +1,21 @@
|
||||||
|
{
|
||||||
|
"images" : [
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "1x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "2x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename" : "ic_lock_bb.png",
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "3x"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
Binary file not shown.
After Width: | Height: | Size: 2.0 KiB |
|
@ -0,0 +1,92 @@
|
||||||
|
//
|
||||||
|
// CommunityPostPurchaseDialog.swift
|
||||||
|
// SodaLive
|
||||||
|
//
|
||||||
|
// Created by klaus on 5/24/24.
|
||||||
|
//
|
||||||
|
|
||||||
|
import SwiftUI
|
||||||
|
|
||||||
|
struct CommunityPostPurchaseDialog: View {
|
||||||
|
|
||||||
|
@Binding var isShowing: Bool
|
||||||
|
|
||||||
|
let can: Int
|
||||||
|
let confirmAction: () -> Void
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
GeometryReader { geo in
|
||||||
|
ZStack {
|
||||||
|
Color.black
|
||||||
|
.opacity(0.5)
|
||||||
|
.frame(width: geo.size.width, height: geo.size.height)
|
||||||
|
|
||||||
|
VStack(spacing: 0) {
|
||||||
|
Text("게시글 보기")
|
||||||
|
.font(.custom(Font.bold.rawValue, size: 18.3))
|
||||||
|
.foregroundColor(Color.graybb)
|
||||||
|
.padding(.top, 40)
|
||||||
|
|
||||||
|
Text("게시글을\n확인하시겠습니까?")
|
||||||
|
.font(.custom(Font.medium.rawValue, size: 15))
|
||||||
|
.foregroundColor(Color.graybb)
|
||||||
|
.multilineTextAlignment(.center)
|
||||||
|
.padding(.top, 12)
|
||||||
|
.padding(.horizontal, 13.3)
|
||||||
|
|
||||||
|
HStack(spacing: 13.3) {
|
||||||
|
Text("취소")
|
||||||
|
.font(.custom(Font.bold.rawValue, size: 15.3))
|
||||||
|
.foregroundColor(Color.button)
|
||||||
|
.padding(.vertical, 16)
|
||||||
|
.frame(width: (geo.size.width - 66.7) / 3)
|
||||||
|
.background(Color.bg)
|
||||||
|
.cornerRadius(8)
|
||||||
|
.overlay(
|
||||||
|
RoundedRectangle(cornerRadius: 8)
|
||||||
|
.stroke(Color.button, lineWidth: 1)
|
||||||
|
)
|
||||||
|
.onTapGesture {
|
||||||
|
isShowing = false
|
||||||
|
}
|
||||||
|
|
||||||
|
HStack(spacing: 0) {
|
||||||
|
Text("\(can)")
|
||||||
|
.font(.custom(Font.bold.rawValue, size: 15.3))
|
||||||
|
.foregroundColor(Color.white)
|
||||||
|
|
||||||
|
Image("ic_can")
|
||||||
|
.resizable()
|
||||||
|
.frame(width: 20, height: 20)
|
||||||
|
|
||||||
|
Text("으로 보기")
|
||||||
|
.font(.custom(Font.bold.rawValue, size: 15.3))
|
||||||
|
.foregroundColor(Color.white)
|
||||||
|
}
|
||||||
|
.padding(.vertical, 16)
|
||||||
|
.frame(width: (geo.size.width - 66.7) * 2 / 3)
|
||||||
|
.background(Color.button)
|
||||||
|
.cornerRadius(8)
|
||||||
|
.onTapGesture {
|
||||||
|
confirmAction()
|
||||||
|
isShowing = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.padding(.top, 26.7)
|
||||||
|
.padding(.bottom, 16.7)
|
||||||
|
}
|
||||||
|
.frame(width: geo.size.width - 26.7, alignment: .center)
|
||||||
|
.background(Color.gray22)
|
||||||
|
.cornerRadius(10)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#Preview {
|
||||||
|
CommunityPostPurchaseDialog(
|
||||||
|
isShowing: .constant(true),
|
||||||
|
can: 10,
|
||||||
|
confirmAction: {}
|
||||||
|
)
|
||||||
|
}
|
|
@ -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) {
|
||||||
|
}
|
||||||
|
}
|
|
@ -15,6 +15,7 @@ struct CreatorCommunityAllItemView: View {
|
||||||
let onClickComment: () -> Void
|
let onClickComment: () -> Void
|
||||||
let onClickWriteComment: (String) -> Void
|
let onClickWriteComment: (String) -> Void
|
||||||
let onClickShowReportMenu: () -> Void
|
let onClickShowReportMenu: () -> Void
|
||||||
|
let onClickPurchaseContent: () -> Void
|
||||||
|
|
||||||
@State var isLike = false
|
@State var isLike = false
|
||||||
@State var likeCount = 0
|
@State var likeCount = 0
|
||||||
|
@ -25,13 +26,15 @@ struct CreatorCommunityAllItemView: View {
|
||||||
onClickLike: @escaping () -> Void,
|
onClickLike: @escaping () -> Void,
|
||||||
onClickComment: @escaping () -> Void,
|
onClickComment: @escaping () -> Void,
|
||||||
onClickWriteComment: @escaping (String) -> Void,
|
onClickWriteComment: @escaping (String) -> Void,
|
||||||
onClickShowReportMenu: @escaping () -> Void
|
onClickShowReportMenu: @escaping () -> Void,
|
||||||
|
onClickPurchaseContent: @escaping () -> Void
|
||||||
) {
|
) {
|
||||||
self.item = item
|
self.item = item
|
||||||
self.onClickLike = onClickLike
|
self.onClickLike = onClickLike
|
||||||
self.onClickComment = onClickComment
|
self.onClickComment = onClickComment
|
||||||
self.onClickWriteComment = onClickWriteComment
|
self.onClickWriteComment = onClickWriteComment
|
||||||
self.onClickShowReportMenu = onClickShowReportMenu
|
self.onClickShowReportMenu = onClickShowReportMenu
|
||||||
|
self.onClickPurchaseContent = onClickPurchaseContent
|
||||||
|
|
||||||
self._isLike = State(initialValue: item.isLike)
|
self._isLike = State(initialValue: item.isLike)
|
||||||
self._likeCount = State(initialValue: item.likeCount)
|
self._likeCount = State(initialValue: item.likeCount)
|
||||||
|
@ -58,66 +61,74 @@ struct CreatorCommunityAllItemView: View {
|
||||||
|
|
||||||
Spacer()
|
Spacer()
|
||||||
|
|
||||||
Image("ic_seemore_vertical")
|
if item.price <= 0 || item.existOrdered {
|
||||||
.padding(.trailing, 8.3)
|
Image("ic_seemore_vertical")
|
||||||
.onTapGesture { onClickShowReportMenu() }
|
.padding(.trailing, 8.3)
|
||||||
|
.onTapGesture { onClickShowReportMenu() }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DetectableTextView(text: item.content, textSize: 13.3, font: Font.medium.rawValue)
|
if item.price <= 0 || item.existOrdered {
|
||||||
.frame(
|
DetectableTextView(text: item.content, textSize: 13.3, font: Font.medium.rawValue)
|
||||||
width: screenSize().width - 16,
|
.frame(
|
||||||
height: textHeight
|
width: screenSize().width - 16,
|
||||||
)
|
height: textHeight
|
||||||
.onAppear {
|
|
||||||
self.textHeight = self.estimatedHeight(
|
|
||||||
for: item.content,
|
|
||||||
width: screenSize().width - 16
|
|
||||||
)
|
)
|
||||||
}
|
.onAppear {
|
||||||
.onChange(of: item.content) { newText in
|
self.textHeight = self.estimatedHeight(
|
||||||
self.textHeight = self.estimatedHeight(
|
for: item.content,
|
||||||
for: newText,
|
width: screenSize().width - 16
|
||||||
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
|
|
||||||
}
|
}
|
||||||
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)
|
HStack(spacing: 8) {
|
||||||
|
IconAndTitleToggleButton(
|
||||||
if item.isCommentAvailable {
|
isChecked: isLike,
|
||||||
CreatorCommunityCommentView(
|
title: "\(likeCount)",
|
||||||
commentCount: item.commentCount,
|
normalIconName: "ic_audio_content_heart_normal",
|
||||||
commentItem: item.firstComment,
|
checkedIconName: "ic_audio_content_heart_pressed"
|
||||||
onClickWriteComment: onClickWriteComment
|
) {
|
||||||
)
|
if isLike {
|
||||||
.onTapGesture {
|
isLike = false
|
||||||
if item.commentCount > 0 {
|
likeCount -= 1
|
||||||
onClickComment()
|
} 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)
|
.padding(.horizontal, 8)
|
||||||
|
@ -144,10 +155,12 @@ struct CreatorCommunityAllItemView_Previews: PreviewProvider {
|
||||||
creatorProfileUrl: "https://test-cf.sodalive.net/profile/default-profile.png",
|
creatorProfileUrl: "https://test-cf.sodalive.net/profile/default-profile.png",
|
||||||
imageUrl: "https://test-cf.sodalive.net/profile/default-profile.png",
|
imageUrl: "https://test-cf.sodalive.net/profile/default-profile.png",
|
||||||
content: "너무 조하유 앞으로도 좋은 라이브 많이 들려주세요!너무 조하유 앞으로도 좋은 라이브 많이 들려주세요!너무 조하유 앞으로도 좋은 라이브 많이 들려주세요!너무 조하유 앞으로도 좋은 라이브 많이 들려주세요!너무 조하유 앞으로도 좋은 라이브 많이 들려주세요!너무 조하유 앞으로도 좋은 라이브 많이 들려주세요!너무 조하유 앞으로도 좋은 라이브 많이 들려주세요!너무 조하유 앞으로도 좋은 라이브 많이 들려주세요!너무 조하유 앞으로도 좋은 라이브 많이 들려주세요!너무 조하유 앞으로도 좋은 라이브 많이 들려주세요!너무 조하유 앞으로도 좋은 라이브 많이 들려주세요!너무 조하유 앞으로도 좋은 라이브 많이 들려주세요!",
|
content: "너무 조하유 앞으로도 좋은 라이브 많이 들려주세요!너무 조하유 앞으로도 좋은 라이브 많이 들려주세요!너무 조하유 앞으로도 좋은 라이브 많이 들려주세요!너무 조하유 앞으로도 좋은 라이브 많이 들려주세요!너무 조하유 앞으로도 좋은 라이브 많이 들려주세요!너무 조하유 앞으로도 좋은 라이브 많이 들려주세요!너무 조하유 앞으로도 좋은 라이브 많이 들려주세요!너무 조하유 앞으로도 좋은 라이브 많이 들려주세요!너무 조하유 앞으로도 좋은 라이브 많이 들려주세요!너무 조하유 앞으로도 좋은 라이브 많이 들려주세요!너무 조하유 앞으로도 좋은 라이브 많이 들려주세요!너무 조하유 앞으로도 좋은 라이브 많이 들려주세요!",
|
||||||
|
price: 10,
|
||||||
date: "3일전",
|
date: "3일전",
|
||||||
isCommentAvailable: false,
|
isCommentAvailable: false,
|
||||||
isAdult: false,
|
isAdult: false,
|
||||||
isLike: true,
|
isLike: true,
|
||||||
|
existOrdered: false,
|
||||||
likeCount: 10,
|
likeCount: 10,
|
||||||
commentCount: 0,
|
commentCount: 0,
|
||||||
firstComment: nil
|
firstComment: nil
|
||||||
|
@ -155,7 +168,8 @@ struct CreatorCommunityAllItemView_Previews: PreviewProvider {
|
||||||
onClickLike: {},
|
onClickLike: {},
|
||||||
onClickComment: {},
|
onClickComment: {},
|
||||||
onClickWriteComment: { _ in },
|
onClickWriteComment: { _ in },
|
||||||
onClickShowReportMenu: {}
|
onClickShowReportMenu: {},
|
||||||
|
onClickPurchaseContent: {}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,6 +41,12 @@ struct CreatorCommunityAllView: View {
|
||||||
onClickShowReportMenu: {
|
onClickShowReportMenu: {
|
||||||
viewModel.postId = item.postId
|
viewModel.postId = item.postId
|
||||||
viewModel.isShowReportMenu = true
|
viewModel.isShowReportMenu = true
|
||||||
|
},
|
||||||
|
onClickPurchaseContent: {
|
||||||
|
viewModel.postId = item.postId
|
||||||
|
viewModel.postPrice = item.price
|
||||||
|
viewModel.postIndex = index
|
||||||
|
viewModel.isShowPostPurchaseView = true
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
.onAppear {
|
.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) {
|
.popup(isPresented: $viewModel.isShowPopup, type: .toast, position: .top, autohideIn: 2) {
|
||||||
|
|
|
@ -21,6 +21,8 @@ class CreatorCommunityAllViewModel: ObservableObject {
|
||||||
@Published private(set) var communityPostList = [GetCommunityPostListResponse]()
|
@Published private(set) var communityPostList = [GetCommunityPostListResponse]()
|
||||||
|
|
||||||
@Published var postId = 0
|
@Published var postId = 0
|
||||||
|
@Published var postPrice = 0
|
||||||
|
@Published var postIndex = -1
|
||||||
|
|
||||||
@Published var isShowCommentListView = false {
|
@Published var isShowCommentListView = false {
|
||||||
didSet {
|
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 creatorId = 0
|
||||||
|
|
||||||
var page = 1
|
var page = 1
|
||||||
|
@ -254,4 +266,51 @@ class CreatorCommunityAllViewModel: ObservableObject {
|
||||||
self.isLoading = false
|
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)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
}
|
|
@ -19,6 +19,7 @@ enum CreatorCommunityApi {
|
||||||
case getCommentReplyList(commentId: Int, page: Int, size: Int)
|
case getCommentReplyList(commentId: Int, page: Int, size: Int)
|
||||||
case modifyComment(request: ModifyCommunityPostCommentRequest)
|
case modifyComment(request: ModifyCommunityPostCommentRequest)
|
||||||
case getLatestPostListFromCreatorsYouFollow
|
case getLatestPostListFromCreatorsYouFollow
|
||||||
|
case purchaseCommunityPost(postId: Int)
|
||||||
}
|
}
|
||||||
|
|
||||||
extension CreatorCommunityApi: TargetType {
|
extension CreatorCommunityApi: TargetType {
|
||||||
|
@ -48,12 +49,15 @@ extension CreatorCommunityApi: TargetType {
|
||||||
|
|
||||||
case .getLatestPostListFromCreatorsYouFollow:
|
case .getLatestPostListFromCreatorsYouFollow:
|
||||||
return "/creator-community/latest"
|
return "/creator-community/latest"
|
||||||
|
|
||||||
|
case .purchaseCommunityPost:
|
||||||
|
return "/creator-community/purchase"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var method: Moya.Method {
|
var method: Moya.Method {
|
||||||
switch self {
|
switch self {
|
||||||
case .createCommunityPost, .communityPostLike, .createCommunityPostComment:
|
case .createCommunityPost, .communityPostLike, .createCommunityPostComment, .purchaseCommunityPost:
|
||||||
return .post
|
return .post
|
||||||
|
|
||||||
case .getCommunityPostList, .getCommunityPostCommentList, .getCommentReplyList, .getCommunityPostDetail, .getLatestPostListFromCreatorsYouFollow:
|
case .getCommunityPostList, .getCommunityPostCommentList, .getCommentReplyList, .getCommunityPostDetail, .getLatestPostListFromCreatorsYouFollow:
|
||||||
|
@ -115,6 +119,9 @@ extension CreatorCommunityApi: TargetType {
|
||||||
case .getLatestPostListFromCreatorsYouFollow:
|
case .getLatestPostListFromCreatorsYouFollow:
|
||||||
let parameters = ["timezone": TimeZone.current.identifier] as [String: Any]
|
let parameters = ["timezone": TimeZone.current.identifier] as [String: Any]
|
||||||
return .requestParameters(parameters: parameters, encoding: URLEncoding.queryString)
|
return .requestParameters(parameters: parameters, encoding: URLEncoding.queryString)
|
||||||
|
|
||||||
|
case .purchaseCommunityPost(let postId):
|
||||||
|
return .requestJSONEncodable(PurchasePostRequest(postId: postId))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,19 +22,19 @@ struct CreatorCommunityItemView: View {
|
||||||
|
|
||||||
Text(item.creatorNickname)
|
Text(item.creatorNickname)
|
||||||
.font(.custom(Font.medium.rawValue, size: 13.3))
|
.font(.custom(Font.medium.rawValue, size: 13.3))
|
||||||
.foregroundColor(Color(hex: "eeeeee"))
|
.foregroundColor(Color.grayee)
|
||||||
|
|
||||||
Spacer()
|
Spacer()
|
||||||
|
|
||||||
Text(item.date)
|
Text(item.date)
|
||||||
.font(.custom(Font.light.rawValue, size: 13.3))
|
.font(.custom(Font.light.rawValue, size: 13.3))
|
||||||
.foregroundColor(Color(hex: "777777"))
|
.foregroundColor(Color.gray77)
|
||||||
}
|
}
|
||||||
|
|
||||||
HStack(spacing: 0) {
|
HStack(spacing: 0) {
|
||||||
Text(item.content)
|
Text(item.content)
|
||||||
.font(.custom(Font.medium.rawValue, size: 12))
|
.font(.custom(Font.medium.rawValue, size: 12))
|
||||||
.foregroundColor(Color(hex: "bbbbbb"))
|
.foregroundColor(Color.graybb)
|
||||||
.fixedSize(horizontal: false, vertical: true)
|
.fixedSize(horizontal: false, vertical: true)
|
||||||
.lineLimit(3)
|
.lineLimit(3)
|
||||||
|
|
||||||
|
@ -45,9 +45,10 @@ struct CreatorCommunityItemView: View {
|
||||||
.resizable()
|
.resizable()
|
||||||
.frame(width: 53.3, height: 53.3)
|
.frame(width: 53.3, height: 53.3)
|
||||||
.cornerRadius(4.7)
|
.cornerRadius(4.7)
|
||||||
|
.blur(radius: item.existOrdered ? 0 : 15)
|
||||||
} else {
|
} else {
|
||||||
Rectangle()
|
Rectangle()
|
||||||
.foregroundColor(Color(hex: "222222").opacity(0))
|
.foregroundColor(Color.gray22.opacity(0))
|
||||||
.frame(width: 53.3, height: 53.3)
|
.frame(width: 53.3, height: 53.3)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -60,7 +61,7 @@ struct CreatorCommunityItemView: View {
|
||||||
|
|
||||||
Text("\(item.likeCount)")
|
Text("\(item.likeCount)")
|
||||||
.font(.custom(Font.medium.rawValue, size: 11))
|
.font(.custom(Font.medium.rawValue, size: 11))
|
||||||
.foregroundColor(Color(hex: "777777"))
|
.foregroundColor(Color.gray77)
|
||||||
}
|
}
|
||||||
|
|
||||||
HStack(spacing: 6) {
|
HStack(spacing: 6) {
|
||||||
|
@ -70,13 +71,13 @@ struct CreatorCommunityItemView: View {
|
||||||
|
|
||||||
Text("\(item.commentCount)")
|
Text("\(item.commentCount)")
|
||||||
.font(.custom(Font.medium.rawValue, size: 11))
|
.font(.custom(Font.medium.rawValue, size: 11))
|
||||||
.foregroundColor(Color(hex: "777777"))
|
.foregroundColor(Color.gray77)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.frame(maxWidth: .infinity, alignment: .leading)
|
.frame(maxWidth: .infinity, alignment: .leading)
|
||||||
.padding(13.3)
|
.padding(13.3)
|
||||||
.background(Color(hex: "222222"))
|
.background(Color.gray22)
|
||||||
.cornerRadius(11)
|
.cornerRadius(11)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -91,10 +92,12 @@ struct CreatorCommunityItemView_Previews: PreviewProvider {
|
||||||
creatorProfileUrl: "https://test-cf.sodalive.net/profile/default-profile.png",
|
creatorProfileUrl: "https://test-cf.sodalive.net/profile/default-profile.png",
|
||||||
imageUrl: "https://test-cf.sodalive.net/profile/default-profile.png",
|
imageUrl: "https://test-cf.sodalive.net/profile/default-profile.png",
|
||||||
content: "안녕하세요",
|
content: "안녕하세요",
|
||||||
|
price: 10,
|
||||||
date: "3일전",
|
date: "3일전",
|
||||||
isCommentAvailable: false,
|
isCommentAvailable: false,
|
||||||
isAdult: false,
|
isAdult: false,
|
||||||
isLike: false,
|
isLike: false,
|
||||||
|
existOrdered: false,
|
||||||
likeCount: 10,
|
likeCount: 10,
|
||||||
commentCount: 0,
|
commentCount: 0,
|
||||||
firstComment: nil
|
firstComment: nil
|
||||||
|
|
|
@ -52,4 +52,8 @@ class CreatorCommunityRepository {
|
||||||
func getLatestPostListFromCreatorsYouFollow() -> AnyPublisher<Response, MoyaError> {
|
func getLatestPostListFromCreatorsYouFollow() -> AnyPublisher<Response, MoyaError> {
|
||||||
return api.requestPublisher(.getLatestPostListFromCreatorsYouFollow)
|
return api.requestPublisher(.getLatestPostListFromCreatorsYouFollow)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func purchaseCommunityPost(postId: Int) -> AnyPublisher<Response, MoyaError> {
|
||||||
|
return api.requestPublisher(.purchaseCommunityPost(postId: postId))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,10 +12,12 @@ struct GetCommunityPostListResponse: Decodable {
|
||||||
let creatorProfileUrl: String
|
let creatorProfileUrl: String
|
||||||
let imageUrl: String?
|
let imageUrl: String?
|
||||||
let content: String
|
let content: String
|
||||||
|
let price: Int
|
||||||
let date: String
|
let date: String
|
||||||
let isCommentAvailable: Bool
|
let isCommentAvailable: Bool
|
||||||
let isAdult: Bool
|
let isAdult: Bool
|
||||||
let isLike: Bool
|
let isLike: Bool
|
||||||
|
let existOrdered: Bool
|
||||||
let likeCount: Int
|
let likeCount: Int
|
||||||
let commentCount: Int
|
let commentCount: Int
|
||||||
let firstComment: GetCommunityPostCommentListItem?
|
let firstComment: GetCommunityPostCommentListItem?
|
||||||
|
|
|
@ -38,10 +38,12 @@ struct SectionCommunityPostView_Previews: PreviewProvider {
|
||||||
creatorProfileUrl: "https://test-cf.sodalive.net/profile/default-profile.png",
|
creatorProfileUrl: "https://test-cf.sodalive.net/profile/default-profile.png",
|
||||||
imageUrl: "https://test-cf.sodalive.net/profile/default-profile.png",
|
imageUrl: "https://test-cf.sodalive.net/profile/default-profile.png",
|
||||||
content: "라이브 많이 들려주세요!너무 조하유 앞으로도 좋은 라이브 많이 들려주세요!너무 조하유 앞으로도 좋은 라이브 많이 들려주세요!",
|
content: "라이브 많이 들려주세요!너무 조하유 앞으로도 좋은 라이브 많이 들려주세요!너무 조하유 앞으로도 좋은 라이브 많이 들려주세요!",
|
||||||
|
price: 10,
|
||||||
date: "3일전",
|
date: "3일전",
|
||||||
isCommentAvailable: false,
|
isCommentAvailable: false,
|
||||||
isAdult: false,
|
isAdult: false,
|
||||||
isLike: true,
|
isLike: true,
|
||||||
|
existOrdered: false,
|
||||||
likeCount: 10,
|
likeCount: 10,
|
||||||
commentCount: 0,
|
commentCount: 0,
|
||||||
firstComment: nil
|
firstComment: nil
|
||||||
|
@ -53,10 +55,12 @@ struct SectionCommunityPostView_Previews: PreviewProvider {
|
||||||
creatorProfileUrl: "https://test-cf.sodalive.net/profile/default-profile.png",
|
creatorProfileUrl: "https://test-cf.sodalive.net/profile/default-profile.png",
|
||||||
imageUrl: "https://test-cf.sodalive.net/profile/default-profile.png",
|
imageUrl: "https://test-cf.sodalive.net/profile/default-profile.png",
|
||||||
content: "너무 조하유 앞으로도 좋은 라이브 많이 들려주세요!너무 조하유 앞으로도 좋은 라이브 많이 들려주세요!너무 조하유 앞으로도 좋은 라이브 많이 들려주세요!너무 조하유 앞으로도 좋은 라이브 많이 들려주세요!너무 조하유 앞으로도 좋은 라이브 많이 들려주세요!너무 조하유 앞으로도 좋은 라이브 많이 들려주세요!너무 조하유 앞으로도 좋은 라이브 많이 들려주세요!너무 조하유 앞으로도 좋은 라이브 많이 들려주세요!너무 조하유 앞으로도 좋은 라이브 많이 들려주세요!너무 조하유 앞으로도 좋은 라이브 많이 들려주세요!너무 조하유 앞으로도 좋은 라이브 많이 들려주세요!너무 조하유 앞으로도 좋은 라이브 많이 들려주세요!",
|
content: "너무 조하유 앞으로도 좋은 라이브 많이 들려주세요!너무 조하유 앞으로도 좋은 라이브 많이 들려주세요!너무 조하유 앞으로도 좋은 라이브 많이 들려주세요!너무 조하유 앞으로도 좋은 라이브 많이 들려주세요!너무 조하유 앞으로도 좋은 라이브 많이 들려주세요!너무 조하유 앞으로도 좋은 라이브 많이 들려주세요!너무 조하유 앞으로도 좋은 라이브 많이 들려주세요!너무 조하유 앞으로도 좋은 라이브 많이 들려주세요!너무 조하유 앞으로도 좋은 라이브 많이 들려주세요!너무 조하유 앞으로도 좋은 라이브 많이 들려주세요!너무 조하유 앞으로도 좋은 라이브 많이 들려주세요!너무 조하유 앞으로도 좋은 라이브 많이 들려주세요!",
|
||||||
|
price: 10,
|
||||||
date: "3일전",
|
date: "3일전",
|
||||||
isCommentAvailable: false,
|
isCommentAvailable: false,
|
||||||
isAdult: false,
|
isAdult: false,
|
||||||
isLike: true,
|
isLike: true,
|
||||||
|
existOrdered: false,
|
||||||
likeCount: 20,
|
likeCount: 20,
|
||||||
commentCount: 0,
|
commentCount: 0,
|
||||||
firstComment: nil
|
firstComment: nil
|
||||||
|
|
Loading…
Reference in New Issue