fix(creator): 팬Talk 답글 수정을 확인한다
This commit is contained in:
@@ -3475,6 +3475,18 @@ If you block this user, the following features will be restricted.
|
||||
static var replyPlaceholder: String {
|
||||
pick(ko: "답글을 입력하세요", en: "Enter a reply", ja: "返信を入力してください")
|
||||
}
|
||||
|
||||
static var replaceReplyTitle: String {
|
||||
pick(ko: "답글을 수정할까요?", en: "Replace your reply?", ja: "返信を修正しますか?")
|
||||
}
|
||||
|
||||
static var replaceReplyMessage: String {
|
||||
pick(ko: "이미 작성한 답글이 있어요. 확인을 누르면 기존 답글이 새 내용으로 수정됩니다.", en: "You already have a reply. If you continue, the existing reply will be updated with the new content.", ja: "すでに返信があります。確認すると既存の返信が新しい内容に修正されます。")
|
||||
}
|
||||
|
||||
static var replaceReplyConfirm: String {
|
||||
pick(ko: "수정하기", en: "Update", ja: "修正する")
|
||||
}
|
||||
}
|
||||
|
||||
enum CreatorChannelFanTalk {
|
||||
|
||||
@@ -20,7 +20,7 @@ struct CreatorChannelFanTalkListItem: View {
|
||||
.frame(maxWidth: .infinity, alignment: .leading)
|
||||
.padding(.leading, 50)
|
||||
.background(alignment: .topLeading) {
|
||||
if fanTalk.creatorReplies.isEmpty == false {
|
||||
if fanTalk.latestCreatorReply != nil {
|
||||
GeometryReader { proxy in
|
||||
CreatorChannelFanTalkReplyConnector()
|
||||
.stroke(Color.gray800, style: StrokeStyle(lineWidth: 2, lineCap: .round, lineJoin: .round))
|
||||
@@ -29,7 +29,7 @@ struct CreatorChannelFanTalkListItem: View {
|
||||
}
|
||||
}
|
||||
|
||||
if fanTalk.creatorReplies.isEmpty == false {
|
||||
if fanTalk.latestCreatorReply != nil {
|
||||
replies
|
||||
.padding(.leading, 50)
|
||||
}
|
||||
@@ -95,7 +95,7 @@ struct CreatorChannelFanTalkListItem: View {
|
||||
|
||||
private var replies: some View {
|
||||
VStack(alignment: .leading, spacing: SodaSpacing.s8) {
|
||||
ForEach(fanTalk.creatorReplies) { reply in
|
||||
if let reply = fanTalk.latestCreatorReply {
|
||||
replyCard(reply)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,6 +18,21 @@ struct CreatorChannelFanTalkItemResponse: Decodable, Identifiable {
|
||||
let creatorReplies: [CreatorChannelFanTalkReplyResponse]
|
||||
|
||||
var id: Int { fanTalkId }
|
||||
|
||||
var latestCreatorReply: CreatorChannelFanTalkReplyResponse? {
|
||||
creatorReplies.max { lhs, rhs in
|
||||
switch (DateParser.parse(lhs.createdAtUtc), DateParser.parse(rhs.createdAtUtc)) {
|
||||
case let (lhsDate?, rhsDate?):
|
||||
return lhsDate < rhsDate
|
||||
case (nil, _?):
|
||||
return true
|
||||
case (_?, nil):
|
||||
return false
|
||||
case (nil, nil):
|
||||
return lhs.createdAtUtc < rhs.createdAtUtc
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct CreatorChannelFanTalkReplyResponse: Decodable, Identifiable {
|
||||
|
||||
@@ -60,6 +60,22 @@ struct CreatorChannelReplyDetailView: View {
|
||||
onDimmedTap: dismissDeleteDialog
|
||||
)
|
||||
}
|
||||
|
||||
if viewModel.isShowReplaceReplyDialog {
|
||||
SodaV2ActionModal(
|
||||
title: I18n.CreatorChannelReplyDetail.replaceReplyTitle,
|
||||
message: I18n.CreatorChannelReplyDetail.replaceReplyMessage,
|
||||
button1: SodaV2ActionModalButton(
|
||||
label: I18n.CreatorChannelReplyDetail.replaceReplyConfirm,
|
||||
action: viewModel.confirmReplaceReply
|
||||
),
|
||||
button2: SodaV2ActionModalButton(
|
||||
label: I18n.Common.cancel,
|
||||
action: viewModel.dismissReplaceReplyDialog
|
||||
),
|
||||
onDimmedTap: viewModel.dismissReplaceReplyDialog
|
||||
)
|
||||
}
|
||||
}
|
||||
.navigationBarBackButtonHidden(true)
|
||||
.onAppear {
|
||||
|
||||
@@ -28,6 +28,7 @@ final class CreatorChannelReplyDetailViewModel: ObservableObject {
|
||||
@Published var editingItem: CreatorChannelReplyDetailDisplayItem?
|
||||
@Published var deletingItem: CreatorChannelReplyDetailDisplayItem?
|
||||
@Published var isShowDeleteDialog = false
|
||||
@Published var isShowReplaceReplyDialog = false
|
||||
|
||||
var isSendEnabled: Bool {
|
||||
replyText.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty == false
|
||||
@@ -53,9 +54,9 @@ final class CreatorChannelReplyDetailViewModel: ObservableObject {
|
||||
fetchCommunityReplies(reset: true)
|
||||
case .fanTalk(let creatorId, let parentFanTalk):
|
||||
parentItem = CreatorChannelReplyDetailDisplayItem(fanTalk: parentFanTalk)
|
||||
replies = parentFanTalk.creatorReplies.map {
|
||||
replies = parentFanTalk.latestCreatorReply.map {
|
||||
CreatorChannelReplyDetailDisplayItem(fanTalkReply: $0, creatorId: creatorId)
|
||||
}
|
||||
}.map { [$0] } ?? []
|
||||
}
|
||||
}
|
||||
|
||||
@@ -118,11 +119,23 @@ final class CreatorChannelReplyDetailViewModel: ObservableObject {
|
||||
|
||||
if let editingItem {
|
||||
modify(item: editingItem)
|
||||
} else if existingFanTalkCreatorReply != nil {
|
||||
isShowReplaceReplyDialog = true
|
||||
} else {
|
||||
createReply()
|
||||
}
|
||||
}
|
||||
|
||||
func dismissReplaceReplyDialog() {
|
||||
isShowReplaceReplyDialog = false
|
||||
}
|
||||
|
||||
func confirmReplaceReply() {
|
||||
guard let existingFanTalkCreatorReply, isLoading == false else { return }
|
||||
isShowReplaceReplyDialog = false
|
||||
modify(item: existingFanTalkCreatorReply)
|
||||
}
|
||||
|
||||
func confirmDelete() {
|
||||
guard let deletingItem, isLoading == false else { return }
|
||||
isShowDeleteDialog = false
|
||||
@@ -328,9 +341,9 @@ final class CreatorChannelReplyDetailViewModel: ObservableObject {
|
||||
if let data = decoded.data, decoded.success {
|
||||
if let fanTalk = data.fanTalks.first(where: { $0.fanTalkId == parentFanTalk.fanTalkId }) {
|
||||
self.isLoading = false
|
||||
self.replies = fanTalk.creatorReplies.map {
|
||||
self.replies = fanTalk.latestCreatorReply.map {
|
||||
CreatorChannelReplyDetailDisplayItem(fanTalkReply: $0, creatorId: creatorId)
|
||||
}
|
||||
}.map { [$0] } ?? []
|
||||
} else if data.hasNext {
|
||||
self.fetchFanTalkReplies(page: page + 1)
|
||||
} else {
|
||||
@@ -435,6 +448,11 @@ final class CreatorChannelReplyDetailViewModel: ObservableObject {
|
||||
return false
|
||||
}
|
||||
|
||||
private var existingFanTalkCreatorReply: CreatorChannelReplyDetailDisplayItem? {
|
||||
guard case .fanTalk = context else { return nil }
|
||||
return replies.first { $0.isCreatorReply }
|
||||
}
|
||||
|
||||
private func communityRepliesPublisher(page: Int) -> AnyPublisher<Response, MoyaError> {
|
||||
switch context {
|
||||
case .community(_, _, let parentComment):
|
||||
|
||||
Reference in New Issue
Block a user