커뮤니티 댓글, 답글 추가 APi 적용
This commit is contained in:
parent
02764f5fe8
commit
cb3a564a29
|
@ -0,0 +1,150 @@
|
|||
//
|
||||
// CreatorCommunityCommentItemView.swift
|
||||
// SodaLive
|
||||
//
|
||||
// Created by klaus on 2023/12/20.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
import Kingfisher
|
||||
|
||||
struct CreatorCommunityCommentItemView: View {
|
||||
let creatorId: Int
|
||||
let postId: Int
|
||||
let commentItem: GetCommunityPostCommentListItem
|
||||
let isReplyComment: Bool
|
||||
let isShowPopupMenuButton: Bool
|
||||
|
||||
let modifyComment: (Int, String) -> Void
|
||||
let onClickDelete: (Int) -> Void
|
||||
|
||||
@State var isShowPopupMenu: Bool = false
|
||||
@State var isModeModify: Bool = false
|
||||
@State var comment: String = ""
|
||||
|
||||
var body: some View {
|
||||
ZStack(alignment: .topTrailing) {
|
||||
VStack(alignment: .leading, spacing: 0) {
|
||||
HStack(spacing: 6.7) {
|
||||
KFImage(URL(string: commentItem.profileUrl))
|
||||
.resizable()
|
||||
.frame(width: 40, height: 40)
|
||||
.clipShape(Circle())
|
||||
|
||||
VStack(alignment: .leading, spacing: 0) {
|
||||
Text(commentItem.nickname)
|
||||
.font(.custom(Font.medium.rawValue, size: 13.3))
|
||||
.foregroundColor(Color(hex: "eeeeee"))
|
||||
|
||||
Text(commentItem.date)
|
||||
.font(.custom(Font.medium.rawValue, size: 10.3))
|
||||
.foregroundColor(Color(hex: "525252"))
|
||||
.padding(.top, 4)
|
||||
}
|
||||
|
||||
Spacer()
|
||||
|
||||
if isShowPopupMenuButton && (creatorId == UserDefaults.int(forKey: .userId) || commentItem.writerId == UserDefaults.int(forKey: .userId)) {
|
||||
Image("ic_seemore_vertical")
|
||||
.onTapGesture { isShowPopupMenu.toggle() }
|
||||
}
|
||||
}
|
||||
|
||||
HStack(spacing: 0) {
|
||||
if isModeModify {
|
||||
HStack(spacing: 0) {
|
||||
TextField("댓글을 입력해 보세요.", text: $comment)
|
||||
.autocapitalization(.none)
|
||||
.disableAutocorrection(true)
|
||||
.font(.custom(Font.medium.rawValue, size: 13.3))
|
||||
.foregroundColor(Color(hex: "eeeeee"))
|
||||
.accentColor(Color(hex: "3bb9f1"))
|
||||
.keyboardType(.default)
|
||||
.padding(.horizontal, 13.3)
|
||||
|
||||
Spacer()
|
||||
|
||||
Image("btn_message_send")
|
||||
.resizable()
|
||||
.frame(width: 35, height: 35)
|
||||
.padding(6.7)
|
||||
.onTapGesture {
|
||||
hideKeyboard()
|
||||
if commentItem.comment != comment {
|
||||
modifyComment(commentItem.id, comment)
|
||||
}
|
||||
isModeModify = false
|
||||
}
|
||||
}
|
||||
.background(Color(hex: "232323"))
|
||||
.cornerRadius(10)
|
||||
.overlay(
|
||||
RoundedRectangle(cornerRadius: 10)
|
||||
.strokeBorder(lineWidth: 1)
|
||||
.foregroundColor(Color(hex: "3bb9f1"))
|
||||
)
|
||||
} else {
|
||||
VStack(alignment: .leading, spacing: 13.3) {
|
||||
Text(commentItem.comment)
|
||||
.font(.custom(Font.medium.rawValue, size: 12))
|
||||
.foregroundColor(Color(hex: "777777"))
|
||||
.fixedSize(horizontal: false, vertical: true)
|
||||
.padding(.top, 13.3)
|
||||
|
||||
if !isReplyComment {
|
||||
NavigationLink(
|
||||
destination: CreatorCommunityCommentReplyView(
|
||||
creatorId: creatorId,
|
||||
postId: postId,
|
||||
parentComment: commentItem
|
||||
)
|
||||
) {
|
||||
Text(commentItem.replyCount > 0 ? "답글 \(commentItem.replyCount)개" : "답글 쓰기")
|
||||
.font(.custom(Font.medium.rawValue, size: 13.3))
|
||||
.foregroundColor(Color(hex: "9970ff"))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Spacer()
|
||||
}
|
||||
.padding(.leading, 46.7)
|
||||
|
||||
Rectangle()
|
||||
.foregroundColor(Color(hex: "595959"))
|
||||
.frame(height: 0.5)
|
||||
.padding(.top, 16.7)
|
||||
}
|
||||
|
||||
if isShowPopupMenu {
|
||||
VStack(spacing: 10) {
|
||||
if commentItem.writerId == UserDefaults.int(forKey: .userId) {
|
||||
Text("수정")
|
||||
.font(.custom(Font.medium.rawValue, size: 14))
|
||||
.foregroundColor(Color(hex: "777777"))
|
||||
.onTapGesture {
|
||||
isModeModify = true
|
||||
isShowPopupMenu = false
|
||||
}
|
||||
}
|
||||
|
||||
if creatorId == UserDefaults.int(forKey: .userId) ||
|
||||
commentItem.writerId == UserDefaults.int(forKey: .userId)
|
||||
{
|
||||
Text("삭제")
|
||||
.font(.custom(Font.medium.rawValue, size: 14))
|
||||
.foregroundColor(Color(hex: "777777"))
|
||||
.onTapGesture {
|
||||
onClickDelete(commentItem.id)
|
||||
isShowPopupMenu = false
|
||||
}
|
||||
}
|
||||
}
|
||||
.padding(10)
|
||||
.background(Color(hex: "222222"))
|
||||
}
|
||||
}
|
||||
.onAppear { comment = commentItem.comment }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,185 @@
|
|||
//
|
||||
// CreatorCommunityCommentListView.swift
|
||||
// SodaLive
|
||||
//
|
||||
// Created by klaus on 2023/12/20.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
import Kingfisher
|
||||
|
||||
struct CreatorCommunityCommentListView: View {
|
||||
|
||||
@Binding var isPresented: Bool
|
||||
|
||||
let creatorId: Int
|
||||
let postId: Int
|
||||
|
||||
@State private var commentId: Int = 0
|
||||
@State private var isShowDeletePopup: Bool = false
|
||||
@StateObject var viewModel = CreatorCommunityCommentListViewModel()
|
||||
|
||||
var body: some View {
|
||||
NavigationView {
|
||||
ZStack {
|
||||
VStack(spacing: 0) {
|
||||
HStack(spacing: 0) {
|
||||
Text("댓글")
|
||||
.font(.custom(Font.medium.rawValue, size: 14.7))
|
||||
.foregroundColor(.white)
|
||||
.padding(.leading, 13.3)
|
||||
|
||||
Text("\(viewModel.totalCommentCount)")
|
||||
.font(.custom(Font.medium.rawValue, size: 12))
|
||||
.foregroundColor(Color(hex: "909090"))
|
||||
.padding(.leading, 6.7)
|
||||
|
||||
Spacer()
|
||||
|
||||
Image("ic_close_white")
|
||||
.onTapGesture { isPresented = false}
|
||||
}
|
||||
.padding(.horizontal, 13.3)
|
||||
.padding(.top, 12)
|
||||
|
||||
Rectangle()
|
||||
.foregroundColor(Color(hex: "595959"))
|
||||
.frame(height: 0.5)
|
||||
.padding(.top, 12)
|
||||
.padding(.bottom, 13.3)
|
||||
.padding(.horizontal, 13.3)
|
||||
|
||||
HStack(spacing: 8) {
|
||||
KFImage(URL(string: UserDefaults.string(forKey: .profileImage)))
|
||||
.cancelOnDisappear(true)
|
||||
.downsampling(size: CGSize(width: 33.3, height: 33.3))
|
||||
.resizable()
|
||||
.frame(width: 33.3, height: 33.3)
|
||||
.clipShape(Circle())
|
||||
|
||||
HStack(spacing: 0) {
|
||||
TextField("댓글을 입력해 보세요.", text: $viewModel.comment)
|
||||
.autocapitalization(.none)
|
||||
.disableAutocorrection(true)
|
||||
.font(.custom(Font.medium.rawValue, size: 13.3))
|
||||
.foregroundColor(Color(hex: "eeeeee"))
|
||||
.accentColor(Color(hex: "3bb9f1"))
|
||||
.keyboardType(.default)
|
||||
.padding(.horizontal, 13.3)
|
||||
|
||||
Spacer()
|
||||
|
||||
Image("btn_message_send")
|
||||
.resizable()
|
||||
.frame(width: 35, height: 35)
|
||||
.padding(6.7)
|
||||
.onTapGesture {
|
||||
hideKeyboard()
|
||||
viewModel.createCommunityPostComment()
|
||||
}
|
||||
}
|
||||
.background(Color(hex: "232323"))
|
||||
.cornerRadius(10)
|
||||
.overlay(
|
||||
RoundedRectangle(cornerRadius: 10)
|
||||
.strokeBorder(lineWidth: 1)
|
||||
.foregroundColor(Color(hex: "3bb9f1"))
|
||||
)
|
||||
|
||||
Spacer()
|
||||
}
|
||||
.padding(.horizontal, 13.3)
|
||||
|
||||
Rectangle()
|
||||
.foregroundColor(Color(hex: "595959"))
|
||||
.frame(height: 0.5)
|
||||
.padding(.top, 12)
|
||||
.padding(.bottom, 13.3)
|
||||
.padding(.horizontal, 13.3)
|
||||
|
||||
ScrollView(.vertical, showsIndicators: false) {
|
||||
LazyVStack(spacing: 13.3) {
|
||||
ForEach(0..<viewModel.commentList.count, id: \.self) { index in
|
||||
let comment = viewModel.commentList[index]
|
||||
VStack {
|
||||
CreatorCommunityCommentItemView(
|
||||
creatorId: creatorId,
|
||||
postId: postId,
|
||||
commentItem: comment,
|
||||
isReplyComment: false,
|
||||
isShowPopupMenuButton: true,
|
||||
modifyComment: { commentId, comment in
|
||||
hideKeyboard()
|
||||
},
|
||||
onClickDelete: {
|
||||
commentId = $0
|
||||
isShowDeletePopup = true
|
||||
}
|
||||
)
|
||||
.padding(.horizontal, 26.7)
|
||||
.onAppear {
|
||||
if index == viewModel.commentList.count - 1 {
|
||||
viewModel.getCommentList()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if isShowDeletePopup && commentId > 0 {
|
||||
SodaDialog(
|
||||
title: "댓글 삭제",
|
||||
desc: "삭제하시겠습니까?",
|
||||
confirmButtonTitle: "삭제",
|
||||
confirmButtonAction: {
|
||||
commentId = 0
|
||||
isShowDeletePopup = false
|
||||
},
|
||||
cancelButtonTitle: "취소",
|
||||
cancelButtonAction: {
|
||||
commentId = 0
|
||||
isShowDeletePopup = false
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
if viewModel.isLoading {
|
||||
LoadingView()
|
||||
}
|
||||
}
|
||||
.onAppear {
|
||||
viewModel.postId = postId
|
||||
viewModel.getCommentList()
|
||||
}
|
||||
.popup(isPresented: $viewModel.isShowPopup, type: .toast, position: .top, autohideIn: 2) {
|
||||
GeometryReader { geo in
|
||||
HStack {
|
||||
Spacer()
|
||||
Text(viewModel.errorMessage)
|
||||
.padding(.vertical, 13.3)
|
||||
.frame(width: screenSize().width - 66.7, alignment: .center)
|
||||
.font(.custom(Font.medium.rawValue, size: 12))
|
||||
.background(Color(hex: "9970ff"))
|
||||
.foregroundColor(Color.white)
|
||||
.multilineTextAlignment(.center)
|
||||
.cornerRadius(20)
|
||||
.padding(.top, 66.7)
|
||||
Spacer()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct CreatorCommunityCommentListView_Previews: PreviewProvider {
|
||||
static var previews: some View {
|
||||
CreatorCommunityCommentListView(
|
||||
isPresented: .constant(true),
|
||||
creatorId: 0,
|
||||
postId: 0
|
||||
)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,122 @@
|
|||
//
|
||||
// CreatorCommunityCommentListViewModel.swift
|
||||
// SodaLive
|
||||
//
|
||||
// Created by klaus on 2023/12/20.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import Combine
|
||||
|
||||
final class CreatorCommunityCommentListViewModel: ObservableObject {
|
||||
private let repository = CreatorCommunityRepository()
|
||||
private var subscription = Set<AnyCancellable>()
|
||||
|
||||
@Published var isLoading = false
|
||||
@Published var errorMessage = ""
|
||||
@Published var isShowPopup = false
|
||||
|
||||
@Published var comment = ""
|
||||
@Published var totalCommentCount = 0
|
||||
@Published var commentList = [GetCommunityPostCommentListItem]()
|
||||
|
||||
var postId = 0
|
||||
var page = 1
|
||||
var isLast = false
|
||||
private let pageSize = 10
|
||||
|
||||
func getCommentList() {
|
||||
if (!isLast && !isLoading) {
|
||||
repository
|
||||
.getCommunityPostCommentList(postId: postId, page: page, size: pageSize)
|
||||
.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<GetCommunityPostCommentListResponse>.self, from: responseData)
|
||||
|
||||
if let data = decoded.data, decoded.success {
|
||||
if page == 1 {
|
||||
commentList.removeAll()
|
||||
}
|
||||
|
||||
if !data.items.isEmpty {
|
||||
page += 1
|
||||
self.totalCommentCount = data.totalCount
|
||||
self.commentList.append(contentsOf: data.items)
|
||||
} else {
|
||||
isLast = true
|
||||
}
|
||||
} 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)
|
||||
}
|
||||
}
|
||||
|
||||
func createCommunityPostComment(parentId: Int? = nil) {
|
||||
if !isLoading {
|
||||
isLoading = true
|
||||
|
||||
repository.createCommunityPostComment(comment: comment, postId: postId, parentId: parentId)
|
||||
.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
|
||||
self.isLoading = false
|
||||
|
||||
do {
|
||||
let jsonDecoder = JSONDecoder()
|
||||
let decoded = try jsonDecoder.decode(ApiResponseWithoutData.self, from: responseData)
|
||||
|
||||
if decoded.success {
|
||||
DispatchQueue.main.async {
|
||||
self.comment = ""
|
||||
self.page = 1
|
||||
self.isLast = false
|
||||
self.getCommentList()
|
||||
}
|
||||
} else {
|
||||
if let message = decoded.message {
|
||||
self.errorMessage = message
|
||||
} else {
|
||||
self.errorMessage = "다시 시도해 주세요.\n계속 같은 문제가 발생할 경우 고객센터로 문의 주시기 바랍니다."
|
||||
}
|
||||
|
||||
self.isShowPopup = true
|
||||
}
|
||||
} catch {
|
||||
self.errorMessage = "다시 시도해 주세요.\n계속 같은 문제가 발생할 경우 고객센터로 문의 주시기 바랍니다."
|
||||
self.isShowPopup = true
|
||||
}
|
||||
}
|
||||
.store(in: &subscription)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,182 @@
|
|||
//
|
||||
// CreatorCommunityCommentReplyView.swift
|
||||
// SodaLive
|
||||
//
|
||||
// Created by klaus on 2023/12/20.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
import Kingfisher
|
||||
|
||||
struct CreatorCommunityCommentReplyView: View {
|
||||
|
||||
let creatorId: Int
|
||||
let postId: Int
|
||||
let parentComment: GetCommunityPostCommentListItem
|
||||
|
||||
@Environment(\.presentationMode) var presentationMode: Binding<PresentationMode>
|
||||
@StateObject var viewModel = CreatorCommunityCommentReplyViewModel()
|
||||
|
||||
@State private var commentId: Int = 0
|
||||
@State private var isShowDeletePopup: Bool = false
|
||||
|
||||
var body: some View {
|
||||
ZStack {
|
||||
VStack(spacing: 0) {
|
||||
HStack(spacing: 6.7) {
|
||||
Image("ic_back")
|
||||
|
||||
Text("답글")
|
||||
.font(.custom(Font.medium.rawValue, size: 14.7))
|
||||
.foregroundColor(.white)
|
||||
|
||||
Spacer()
|
||||
}
|
||||
.padding(.horizontal, 13.3)
|
||||
.padding(.top, 12)
|
||||
.onTapGesture { presentationMode.wrappedValue.dismiss() }
|
||||
|
||||
Rectangle()
|
||||
.foregroundColor(Color(hex: "595959"))
|
||||
.frame(height: 0.5)
|
||||
.padding(.top, 12)
|
||||
.padding(.bottom, 13.3)
|
||||
.padding(.horizontal, 13.3)
|
||||
|
||||
HStack(spacing: 8) {
|
||||
KFImage(URL(string: UserDefaults.string(forKey: .profileImage)))
|
||||
.cancelOnDisappear(true)
|
||||
.downsampling(size: CGSize(width: 33.3, height: 33.3))
|
||||
.resizable()
|
||||
.frame(width: 33.3, height: 33.3)
|
||||
.clipShape(Circle())
|
||||
|
||||
HStack(spacing: 0) {
|
||||
TextField("댓글을 입력해 보세요.", text: $viewModel.comment)
|
||||
.autocapitalization(.none)
|
||||
.disableAutocorrection(true)
|
||||
.font(.custom(Font.medium.rawValue, size: 13.3))
|
||||
.foregroundColor(Color(hex: "eeeeee"))
|
||||
.accentColor(Color(hex: "3bb9f1"))
|
||||
.keyboardType(.default)
|
||||
.padding(.horizontal, 13.3)
|
||||
|
||||
Spacer()
|
||||
|
||||
Image("btn_message_send")
|
||||
.resizable()
|
||||
.frame(width: 35, height: 35)
|
||||
.padding(6.7)
|
||||
.onTapGesture {
|
||||
hideKeyboard()
|
||||
viewModel.createCommunityPostComment(parentId: parentComment.id)
|
||||
}
|
||||
}
|
||||
.background(Color(hex: "232323"))
|
||||
.cornerRadius(10)
|
||||
.overlay(
|
||||
RoundedRectangle(cornerRadius: 10)
|
||||
.strokeBorder(lineWidth: 1)
|
||||
.foregroundColor(Color(hex: "3bb9f1"))
|
||||
)
|
||||
|
||||
Spacer()
|
||||
}
|
||||
.padding(.horizontal, 13.3)
|
||||
|
||||
Rectangle()
|
||||
.foregroundColor(Color(hex: "595959"))
|
||||
.frame(height: 0.5)
|
||||
.padding(.top, 12)
|
||||
.padding(.bottom, 13.3)
|
||||
.padding(.horizontal, 13.3)
|
||||
|
||||
CreatorCommunityCommentItemView(
|
||||
creatorId: creatorId,
|
||||
postId: postId,
|
||||
commentItem: parentComment,
|
||||
isReplyComment: true,
|
||||
isShowPopupMenuButton: false,
|
||||
modifyComment: { _, _ in },
|
||||
onClickDelete: { _ in }
|
||||
)
|
||||
.padding(.horizontal, 26.7)
|
||||
.padding(.bottom, 13.3)
|
||||
|
||||
ScrollView(.vertical, showsIndicators: false) {
|
||||
LazyVStack(spacing: 13.3) {
|
||||
ForEach(0..<viewModel.commentList.count, id: \.self) { index in
|
||||
let comment = viewModel.commentList[index]
|
||||
CreatorCommunityCommentItemView(
|
||||
creatorId: creatorId,
|
||||
postId: postId,
|
||||
commentItem: comment,
|
||||
isReplyComment: true,
|
||||
isShowPopupMenuButton: true,
|
||||
modifyComment: { commentId, comment in
|
||||
hideKeyboard()
|
||||
},
|
||||
onClickDelete: {
|
||||
commentId = $0
|
||||
isShowDeletePopup = true
|
||||
}
|
||||
)
|
||||
.padding(.horizontal, 26.7)
|
||||
.onAppear {
|
||||
if index == viewModel.commentList.count - 1 {
|
||||
viewModel.getCommentList()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.navigationTitle("")
|
||||
.navigationBarBackButtonHidden()
|
||||
|
||||
if isShowDeletePopup && commentId > 0 {
|
||||
SodaDialog(
|
||||
title: "댓글 삭제",
|
||||
desc: "삭제하시겠습니까?",
|
||||
confirmButtonTitle: "삭제",
|
||||
confirmButtonAction: {
|
||||
commentId = 0
|
||||
isShowDeletePopup = false
|
||||
},
|
||||
cancelButtonTitle: "취소",
|
||||
cancelButtonAction: {
|
||||
commentId = 0
|
||||
isShowDeletePopup = false
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
if viewModel.isLoading {
|
||||
LoadingView()
|
||||
}
|
||||
}
|
||||
.onAppear {
|
||||
viewModel.postId = postId
|
||||
viewModel.commentId = parentComment.id
|
||||
viewModel.getCommentList()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct CreatorCommunityCommentReplyView_Previews: PreviewProvider {
|
||||
static var previews: some View {
|
||||
CreatorCommunityCommentReplyView(
|
||||
creatorId: 0,
|
||||
postId: 0,
|
||||
parentComment: GetCommunityPostCommentListItem(
|
||||
id: 0,
|
||||
writerId: 0,
|
||||
nickname: "댓글",
|
||||
profileUrl: "",
|
||||
comment: "부모 댓글입니다.",
|
||||
date: "1시간전",
|
||||
replyCount: 1
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,124 @@
|
|||
//
|
||||
// CreatorCommunityCommentReplyViewModel.swift
|
||||
// SodaLive
|
||||
//
|
||||
// Created by klaus on 2023/12/20.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import Combine
|
||||
|
||||
final class CreatorCommunityCommentReplyViewModel: ObservableObject {
|
||||
|
||||
private let repository = CreatorCommunityRepository()
|
||||
private var subscription = Set<AnyCancellable>()
|
||||
|
||||
@Published var isLoading = false
|
||||
@Published var errorMessage = ""
|
||||
@Published var isShowPopup = false
|
||||
|
||||
@Published var comment = ""
|
||||
@Published var totalCommentCount = 0
|
||||
@Published var commentList = [GetCommunityPostCommentListItem]()
|
||||
|
||||
var postId = 0
|
||||
var commentId = 0
|
||||
var page = 1
|
||||
var isLast = false
|
||||
private let pageSize = 10
|
||||
|
||||
func getCommentList() {
|
||||
if (!isLast && !isLoading) {
|
||||
repository
|
||||
.getCommentReplyList(commentId: commentId, page: page, size: pageSize)
|
||||
.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<GetCommunityPostCommentListResponse>.self, from: responseData)
|
||||
|
||||
if let data = decoded.data, decoded.success {
|
||||
if page == 1 {
|
||||
commentList.removeAll()
|
||||
}
|
||||
|
||||
if !data.items.isEmpty {
|
||||
page += 1
|
||||
self.totalCommentCount = data.totalCount
|
||||
self.commentList.append(contentsOf: data.items)
|
||||
} else {
|
||||
isLast = true
|
||||
}
|
||||
} 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)
|
||||
}
|
||||
}
|
||||
|
||||
func createCommunityPostComment(parentId: Int? = nil) {
|
||||
if !isLoading {
|
||||
isLoading = true
|
||||
|
||||
repository.createCommunityPostComment(comment: comment, postId: postId, parentId: parentId)
|
||||
.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
|
||||
self.isLoading = false
|
||||
|
||||
do {
|
||||
let jsonDecoder = JSONDecoder()
|
||||
let decoded = try jsonDecoder.decode(ApiResponseWithoutData.self, from: responseData)
|
||||
|
||||
if decoded.success {
|
||||
DispatchQueue.main.async {
|
||||
self.comment = ""
|
||||
self.page = 1
|
||||
self.isLast = false
|
||||
self.getCommentList()
|
||||
}
|
||||
} else {
|
||||
if let message = decoded.message {
|
||||
self.errorMessage = message
|
||||
} else {
|
||||
self.errorMessage = "다시 시도해 주세요.\n계속 같은 문제가 발생할 경우 고객센터로 문의 주시기 바랍니다."
|
||||
}
|
||||
|
||||
self.isShowPopup = true
|
||||
}
|
||||
} catch {
|
||||
self.errorMessage = "다시 시도해 주세요.\n계속 같은 문제가 발생할 경우 고객센터로 문의 주시기 바랍니다."
|
||||
self.isShowPopup = true
|
||||
}
|
||||
}
|
||||
.store(in: &subscription)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -12,6 +12,7 @@ struct CreatorCommunityAllItemView: View {
|
|||
|
||||
let item: GetCommunityPostListResponse
|
||||
let onClickLike: () -> Void
|
||||
let onClickComment: () -> Void
|
||||
let onClickWriteComment: (String) -> Void
|
||||
|
||||
@State var isExpandContent = false
|
||||
|
@ -21,10 +22,12 @@ struct CreatorCommunityAllItemView: View {
|
|||
init(
|
||||
item: GetCommunityPostListResponse,
|
||||
onClickLike: @escaping () -> Void,
|
||||
onClickComment: @escaping () -> Void,
|
||||
onClickWriteComment: @escaping (String) -> Void
|
||||
) {
|
||||
self.item = item
|
||||
self.onClickLike = onClickLike
|
||||
self.onClickComment = onClickComment
|
||||
self.onClickWriteComment = onClickWriteComment
|
||||
|
||||
self._isLike = State(initialValue: item.isLike)
|
||||
|
@ -96,8 +99,14 @@ struct CreatorCommunityAllItemView: View {
|
|||
commentItem: item.firstComment,
|
||||
onClickWriteComment: onClickWriteComment
|
||||
)
|
||||
.onTapGesture {
|
||||
if item.commentCount > 0 {
|
||||
onClickComment()
|
||||
}
|
||||
}
|
||||
}
|
||||
.padding(6.7)
|
||||
.padding(.horizontal, 8)
|
||||
.padding(.vertical, 11)
|
||||
.background(Color(hex: "222222"))
|
||||
.cornerRadius(5.3)
|
||||
}
|
||||
|
@ -119,6 +128,7 @@ struct CreatorCommunityAllItemView_Previews: PreviewProvider {
|
|||
firstComment: nil
|
||||
),
|
||||
onClickLike: {},
|
||||
onClickComment: {},
|
||||
onClickWriteComment: { _ in }
|
||||
)
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@ struct CreatorCommunityAllView: View {
|
|||
|
||||
let creatorId: Int
|
||||
|
||||
@State var isShowingReportView = false
|
||||
@State private var isShowingReportView = false
|
||||
@StateObject var viewModel = CreatorCommunityAllViewModel()
|
||||
|
||||
var body: some View {
|
||||
|
@ -28,6 +28,9 @@ struct CreatorCommunityAllView: View {
|
|||
onClickLike: {
|
||||
viewModel.communityPostLike(postId: item.postId)
|
||||
},
|
||||
onClickComment: {
|
||||
viewModel.postId = item.postId
|
||||
},
|
||||
onClickWriteComment: { comment in
|
||||
viewModel.createCommunityPostComment(
|
||||
comment: comment,
|
||||
|
@ -42,10 +45,19 @@ struct CreatorCommunityAllView: View {
|
|||
}
|
||||
}
|
||||
}
|
||||
.padding(.horizontal, 13.3)
|
||||
.padding(.vertical, 5.3)
|
||||
.padding(5.3)
|
||||
}
|
||||
}
|
||||
.sheet(
|
||||
isPresented: $viewModel.isShowCommentListView,
|
||||
content: {
|
||||
CreatorCommunityCommentListView(
|
||||
isPresented: $viewModel.isShowCommentListView,
|
||||
creatorId: creatorId,
|
||||
postId: viewModel.postId
|
||||
)
|
||||
}
|
||||
)
|
||||
|
||||
if isShowingReportView {
|
||||
CreatorCommunityReportView(isShowing: $isShowingReportView) { _ in
|
||||
|
|
|
@ -19,6 +19,22 @@ class CreatorCommunityAllViewModel: ObservableObject {
|
|||
@Published var isShowPopup = false
|
||||
@Published private(set) var communityPostList = [GetCommunityPostListResponse]()
|
||||
|
||||
@Published var postId = 0 {
|
||||
didSet {
|
||||
if postId > 0 {
|
||||
isShowCommentListView = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Published var isShowCommentListView = false {
|
||||
didSet {
|
||||
if !isShowCommentListView {
|
||||
postId = 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var creatorId = 0
|
||||
|
||||
var page = 1
|
||||
|
|
|
@ -13,6 +13,8 @@ enum CreatorCommunityApi {
|
|||
case getCommunityPostList(creatorId: Int, page: Int, size: Int)
|
||||
case communityPostLike(postId: Int)
|
||||
case createCommunityPostComment(comment: String, postId: Int, parentId: Int?)
|
||||
case getCommunityPostCommentList(postId: Int, page: Int, size: Int)
|
||||
case getCommentReplyList(commentId: Int, page: Int, size: Int)
|
||||
}
|
||||
|
||||
extension CreatorCommunityApi: TargetType {
|
||||
|
@ -30,6 +32,12 @@ extension CreatorCommunityApi: TargetType {
|
|||
|
||||
case .createCommunityPostComment:
|
||||
return "/creator-community/comment"
|
||||
|
||||
case .getCommunityPostCommentList(let postId, _, _):
|
||||
return "/creator-community/\(postId)/comment"
|
||||
|
||||
case .getCommentReplyList(let commentId, _, _):
|
||||
return "/creator-community/comment/\(commentId)"
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -38,7 +46,7 @@ extension CreatorCommunityApi: TargetType {
|
|||
case .createCommunityPost, .communityPostLike, .createCommunityPostComment:
|
||||
return .post
|
||||
|
||||
case .getCommunityPostList:
|
||||
case .getCommunityPostList, .getCommunityPostCommentList, .getCommentReplyList:
|
||||
return .get
|
||||
}
|
||||
}
|
||||
|
@ -64,6 +72,22 @@ extension CreatorCommunityApi: TargetType {
|
|||
case .createCommunityPostComment(let comment, let postId, let parentId):
|
||||
let request = CreateCommunityPostCommentRequest(comment: comment, postId: postId, parentId: parentId)
|
||||
return .requestJSONEncodable(request)
|
||||
|
||||
case .getCommunityPostCommentList(_, let page, let size):
|
||||
let parameters = [
|
||||
"page": page - 1,
|
||||
"size": size,
|
||||
"timezone": TimeZone.current.identifier
|
||||
] as [String: Any]
|
||||
return .requestParameters(parameters: parameters, encoding: URLEncoding.queryString)
|
||||
|
||||
case .getCommentReplyList(_, let page, let size):
|
||||
let parameters = [
|
||||
"page": page - 1,
|
||||
"size": size,
|
||||
"timezone": TimeZone.current.identifier
|
||||
] as [String: Any]
|
||||
return .requestParameters(parameters: parameters, encoding: URLEncoding.queryString)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -28,4 +28,12 @@ class CreatorCommunityRepository {
|
|||
func createCommunityPostComment(comment: String, postId: Int, parentId: Int?) -> AnyPublisher<Response, MoyaError> {
|
||||
return api.requestPublisher(.createCommunityPostComment(comment: comment, postId: postId, parentId: parentId))
|
||||
}
|
||||
|
||||
func getCommunityPostCommentList(postId: Int, page: Int, size: Int) -> AnyPublisher<Response, MoyaError> {
|
||||
return api.requestPublisher(.getCommunityPostCommentList(postId: postId, page: page, size: size))
|
||||
}
|
||||
|
||||
func getCommentReplyList(commentId: Int, page: Int, size: Int) -> AnyPublisher<Response, MoyaError> {
|
||||
return api.requestPublisher(.getCommentReplyList(commentId: commentId, page: page, size: size))
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue