Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 8 additions & 5 deletions ByeBoo-iOS/ByeBoo-iOS/Data/Network/EndPoint/CommonQuestAPI.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ enum CommonQuestAPI {
case postCommonQuest(questID: Int, dto: SaveCommonQuestRequestDTO)
case fetchCommonQuest(date: String, cursor: Int?)
case updateCommonQuest(answerID: Int, dto: UpdateCommonQuestRequestDTO)
case deleteCommonQuest(answerID: Int)
}

extension CommonQuestAPI: EndPoint {
Expand All @@ -27,7 +28,7 @@ extension CommonQuestAPI: EndPoint {
return "/\(questID)"
case .fetchCommonQuest:
return ""
case .updateCommonQuest(let answerID, _):
case .updateCommonQuest(let answerID, _), .deleteCommonQuest(let answerID):
return "/\(answerID)"
}
}
Expand All @@ -40,12 +41,14 @@ extension CommonQuestAPI: EndPoint {
return .get
case .updateCommonQuest:
return .patch
case .deleteCommonQuest:
return .delete
}
}

var headers: HeaderType {
switch self {
case .postCommonQuest, .fetchCommonQuest, .updateCommonQuest:
case .postCommonQuest, .fetchCommonQuest, .updateCommonQuest, .deleteCommonQuest:
return .withAuth
}
}
Expand All @@ -54,14 +57,14 @@ extension CommonQuestAPI: EndPoint {
switch self {
case .postCommonQuest, .updateCommonQuest:
return JSONEncoding.default
case .fetchCommonQuest:
case .fetchCommonQuest, .deleteCommonQuest:
return URLEncoding.default
}
}

var queryParameters: [String : String]? {
switch self {
case .postCommonQuest, .updateCommonQuest:
case .postCommonQuest, .updateCommonQuest, .deleteCommonQuest:
return nil
case .fetchCommonQuest(let date, let cursor):
if let cursor {
Expand All @@ -78,7 +81,7 @@ extension CommonQuestAPI: EndPoint {
switch self {
case .postCommonQuest(_, let dto):
return try? dto.toDictionary()
case .fetchCommonQuest:
case .fetchCommonQuest, .deleteCommonQuest:
return nil
case .updateCommonQuest(_, let dto):
return try? dto.toDictionary()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,4 +54,10 @@ struct DefaultCommonQuestRepository: CommonQuestInterface {
)
)
}

func deleteCommonQuest(answerID: Int) async throws {
try await network.request(
CommonQuestAPI.deleteCommonQuest(answerID: answerID)
)
}
}
4 changes: 4 additions & 0 deletions ByeBoo-iOS/ByeBoo-iOS/Domain/DomainDependencyAssembler.swift
Original file line number Diff line number Diff line change
Expand Up @@ -203,5 +203,9 @@ struct DomainDependencyAssembler: DependencyAssembler {
DIContainer.shared.register(type: ReportsCommonQuestAnswerUseCase.self) { _ in
return DefaultReportsCommonQuestAnswerUseCase(repository: reportsRepository)
}

DIContainer.shared.register(type: DeleteCommonQuestUseCase.self) { _ in
return DefaultDeleteCommonQuestUseCase(repository: commonQuestRepository)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,5 @@ protocol CommonQuestInterface {
func saveCommonQuest(questID: Int, answer: String) async throws
func fetchCommonQuest(date: String, cursor: Int?) async throws -> CommonQuestAnswersEntity
func updateCommonQuest(answerID: Int, answer: String) async throws
func deleteCommonQuest(answerID: Int) async throws
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
//
// DeleteCommonQuestUseCase.swift
// ByeBoo-iOS
//
// Created by APPLE on 3/10/26.
//

protocol DeleteCommonQuestUseCase {
func execute(answerID: Int) async throws
}

struct DefaultDeleteCommonQuestUseCase: DeleteCommonQuestUseCase {

private let repository: CommonQuestInterface

init(repository: CommonQuestInterface) {
self.repository = repository
}

func execute(answerID: Int) async throws {
try await repository.deleteCommonQuest(answerID: answerID)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,15 @@ protocol BlockReportProtocol: AnyObject {
func completeBlockReport(type: CommonQuestArchiveType.Action)
}

protocol DeleteCommonQuestDelegate: AnyObject {
func completeDeleteCommonQuest()
}

final class CommonQuestBottomSheetViewController: BaseViewController {

private let yesAnswer = "예"
private let noAnswer = "아니오"
Comment on lines +30 to +31
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

나중에 이런 literal 값들 따로 관리할 수 있도록 하면 좋을 것 같은데 어떻게 생각하세용 ?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

아 좋아요좋아요 Literal 폴더 하나 만드시죠


private var rootView = CommonQuestBottomSheetView(sheetType: .other)
private let viewModel: CommonQuestBottomSheetViewModel
private var writerID: Int = 0
Expand All @@ -37,6 +44,7 @@ final class CommonQuestBottomSheetViewController: BaseViewController {

weak var blockDelegate: BlockReportProtocol?
weak var bottomDelegate: CommonQuestBottomSheetDelegate?
weak var deleteDelegate: DeleteCommonQuestDelegate?

init(viewModel: CommonQuestBottomSheetViewModel) {
self.viewModel = viewModel
Expand Down Expand Up @@ -65,6 +73,9 @@ final class CommonQuestBottomSheetViewController: BaseViewController {
item.isUserInteractionEnabled = true
}
}
}

extension CommonQuestBottomSheetViewController {

func configure(
sheeetType: CommonQuestArchiveType,
Expand Down Expand Up @@ -115,8 +126,8 @@ final class CommonQuestBottomSheetViewController: BaseViewController {
)
}
case .delete:
// TODO: 삭제하기
ByeBooLogger.debug("delete")
guard let answerID else { return }
presentDeleteQuestModal(answerID: answerID)
case .block:
viewModel.action(.block(userID: writerID))
case .report:
Expand All @@ -130,6 +141,27 @@ final class CommonQuestBottomSheetViewController: BaseViewController {
private func dismissButtonDidTap() {
presentingViewController?.dismiss(animated: true)
}

private func presentDeleteQuestModal(answerID: Int) {
let modalView = createModalView()
let action: () -> Void = { self.viewModel.action(.delete(answerID: answerID)) }

ModalBuilder(
modalView: modalView,
action: action,
rootViewController: self
).present()
}

private func createModalView() -> ConfirmModalView {
let dismissButton: ByeBooButton? = ByeBooButton(titleText: noAnswer, type: .outline)
let actionButton = ByeBooButton(titleText: yesAnswer, type: .enabled)
return ConfirmModalView(
modalType: .delete,
dismissButton: dismissButton,
actionButton: actionButton
)
}
}

extension CommonQuestBottomSheetViewController {
Expand Down Expand Up @@ -163,5 +195,23 @@ extension CommonQuestBottomSheetViewController {
}
}
.store(in: &cancellables)

viewModel.output.deleteQuestPublisher
.receive(on: DispatchQueue.main)
.sink { [weak self] result in
switch result {
case .success():
ByeBooLogger.debug("삭제 성공")

guard let self else { return }

self.dismiss(animated: false) { [weak self] in
self?.deleteDelegate?.completeDeleteCommonQuest()
}
case .failure(let error):
ByeBooLogger.debug(error)
}
}
.store(in: &cancellables)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,36 +12,43 @@ final class CommonQuestBottomSheetViewModel {

private var reportQuestSubject: PassthroughSubject<Result<Void, ByeBooError>, Never> = .init()
private var blockUserSubject: PassthroughSubject<Result<Void, ByeBooError>, Never> = .init()
private var deleteQuestSubject: PassthroughSubject<Result<Void, ByeBooError>, Never> = .init()

var output: Output {
Output(
reportQuestPublisher: reportQuestSubject.eraseToAnyPublisher(),
blockUserPublisher: blockUserSubject.eraseToAnyPublisher()
blockUserPublisher: blockUserSubject.eraseToAnyPublisher(),
deleteQuestPublisher: deleteQuestSubject.eraseToAnyPublisher()
)
}

private let blockUserUseCase: BlockUserUseCase
private let reportCommonQuestUseCase: ReportsCommonQuestAnswerUseCase
private let deleteCommonQuestUseCase: DeleteCommonQuestUseCase
private var cancellables = Set<AnyCancellable>()

init(
blockUserUseCase: BlockUserUseCase,
reportCommonQuestUseCase: ReportsCommonQuestAnswerUseCase
reportCommonQuestUseCase: ReportsCommonQuestAnswerUseCase,
deleteCommonQuestUseCase: DeleteCommonQuestUseCase
) {
self.blockUserUseCase = blockUserUseCase
self.reportCommonQuestUseCase = reportCommonQuestUseCase
self.deleteCommonQuestUseCase = deleteCommonQuestUseCase
}
}

extension CommonQuestBottomSheetViewModel: ViewModelType {
enum Input {
case block(userID: Int)
case report(answerID: Int)
case delete(answerID: Int)
}

struct Output {
let reportQuestPublisher: AnyPublisher<Result<Void, ByeBooError>, Never>
let blockUserPublisher: AnyPublisher<Result<Void, ByeBooError>, Never>
let deleteQuestPublisher: AnyPublisher<Result<Void, ByeBooError>, Never>
}

func action(_ trigger: Input) {
Expand All @@ -50,6 +57,8 @@ extension CommonQuestBottomSheetViewModel: ViewModelType {
blockUser(userID: userID)
case .report(let answerID):
reportCommonQuest(answerID: answerID)
case .delete(let answerID):
deleteCommonQuest(answerID: answerID)
}
}
}
Expand All @@ -61,11 +70,7 @@ extension CommonQuestBottomSheetViewModel {
try await blockUserUseCase.execute(userID: userID)
blockUserSubject.send(.success(()))
} catch {
guard let error = error as? ByeBooError else {
return
}
ByeBooLogger.error(error as ByeBooError)
blockUserSubject.send(.failure(error))
sendError(error: error)
}
}
}
Expand All @@ -76,12 +81,27 @@ extension CommonQuestBottomSheetViewModel {
try await reportCommonQuestUseCase.execute(answerID: answerID)
reportQuestSubject.send(.success(()))
} catch {
guard let error = error as? ByeBooError else {
return
}
ByeBooLogger.error(error as ByeBooError)
reportQuestSubject.send(.failure(error))
sendError(error: error)
}
}
}

private func deleteCommonQuest(answerID: Int) {
Task {
do {
try await deleteCommonQuestUseCase.execute(answerID: answerID)
deleteQuestSubject.send(.success(()))
} catch {
sendError(error: error)
}
}
}

private func sendError(error: Error) {
guard let error = error as? ByeBooError else {
return
}
ByeBooLogger.error(error as ByeBooError)
reportQuestSubject.send(.failure(error))
Comment on lines +100 to +105
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

오호

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ enum ConfirmModalType {
case logout
case withdraw
case block
case delete

var title: String {
switch self {
Expand All @@ -20,6 +21,8 @@ enum ConfirmModalType {
"정말 탈퇴하시겠어요?"
case .block:
"차단을 해제하시겠어요?"
case .delete:
"정말 삭제하시겠어요?"
}
}

Expand All @@ -29,6 +32,8 @@ enum ConfirmModalType {
nil
case .withdraw:
"탈퇴 시 모든 데이터가 삭제됩니다."
case .delete:
"삭제한 답변은 다시 복구할 수 없습니다."
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -364,7 +364,7 @@ extension MyPageViewController {
self.viewModel.action(.withdrawActionButtonDidTap)

Mixpanel.mainInstance().track(event: MyPageEvents.Name.withdrawConfirmClick)
case .block:
case .block, .delete:
break
}
}
Expand Down
Loading
Loading