From 25e44eb02ec37242f27b25a74ba6114f833662c3 Mon Sep 17 00:00:00 2001 From: opficdev Date: Fri, 27 Feb 2026 01:01:22 +0900 Subject: [PATCH 1/3] =?UTF-8?q?fix:=20pendingTask=EA=B0=80=20=EC=A1=B4?= =?UTF-8?q?=EC=9E=AC=ED=95=98=EB=A9=B4=20=EB=B0=94=EB=A1=9C=20=EC=8B=A4?= =?UTF-8?q?=ED=96=89=EC=8B=9C=ED=82=A4=EB=8F=84=EB=A1=9D=20=EC=88=98?= =?UTF-8?q?=EC=A0=95=ED=95=98=EC=97=AC=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ViewModel/PushNotificationListViewModel.swift | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/DevLog/Presentation/ViewModel/PushNotificationListViewModel.swift b/DevLog/Presentation/ViewModel/PushNotificationListViewModel.swift index a745180..62b9456 100644 --- a/DevLog/Presentation/ViewModel/PushNotificationListViewModel.swift +++ b/DevLog/Presentation/ViewModel/PushNotificationListViewModel.swift @@ -161,11 +161,17 @@ private extension PushNotificationListViewModel { func reduceByUser(_ action: Action, state: inout State) -> [SideEffect] { switch action { case .deleteNotification(let item): - if let index = state.notifications.firstIndex(where: { $0.id == item.id }) { - state.pendingTask = (item, index) - state.notifications.remove(at: index) - setToast(&state, isPresented: true, for: .delete) + var effects: [SideEffect] = [] + if let (pendingItem, _) = state.pendingTask { + effects.append(.delete(pendingItem)) + } + guard let index = state.notifications.firstIndex(where: { $0.id == item.id }) else { + return [] } + state.pendingTask = (item, index) + state.notifications.remove(at: index) + setToast(&state, isPresented: true, for: .delete) + return effects case .toggleRead(let item): if let index = state.notifications.firstIndex(where: { $0.id == item.id }) { state.notifications[index].isRead.toggle() From fd048841d8f87aa633b69f798bcca7b3b75e821a Mon Sep 17 00:00:00 2001 From: opficdev Date: Fri, 27 Feb 2026 01:15:00 +0900 Subject: [PATCH 2/3] =?UTF-8?q?refactor:=20=EC=9D=B8=EB=8D=B1=EC=8A=A4=20?= =?UTF-8?q?=EB=AA=BB=EC=B0=BE=EB=8A=94=EA=B2=83=EA=B3=BC=20=EB=B3=84?= =?UTF-8?q?=EA=B0=9C=EB=A1=9C=20=EC=82=AD=EC=A0=9C=20=EC=9E=91=EC=97=85?= =?UTF-8?q?=EC=9D=80=20=EC=A7=84=ED=96=89=EB=90=98=EB=8F=84=EB=A1=9D=20?= =?UTF-8?q?=EA=B0=9C=EC=84=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ViewModel/PushNotificationListViewModel.swift | 13 +++++++------ .../Presentation/ViewModel/TodoListViewModel.swift | 11 ++++++----- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/DevLog/Presentation/ViewModel/PushNotificationListViewModel.swift b/DevLog/Presentation/ViewModel/PushNotificationListViewModel.swift index 62b9456..52727b4 100644 --- a/DevLog/Presentation/ViewModel/PushNotificationListViewModel.swift +++ b/DevLog/Presentation/ViewModel/PushNotificationListViewModel.swift @@ -163,14 +163,15 @@ private extension PushNotificationListViewModel { case .deleteNotification(let item): var effects: [SideEffect] = [] if let (pendingItem, _) = state.pendingTask { - effects.append(.delete(pendingItem)) + effects = [.delete(pendingItem)] } - guard let index = state.notifications.firstIndex(where: { $0.id == item.id }) else { - return [] + + if let index = state.notifications.firstIndex(where: { $0.id == item.id }) { + state.pendingTask = (item, index) + state.notifications.remove(at: index) + setToast(&state, isPresented: true, for: .delete) } - state.pendingTask = (item, index) - state.notifications.remove(at: index) - setToast(&state, isPresented: true, for: .delete) + return effects case .toggleRead(let item): if let index = state.notifications.firstIndex(where: { $0.id == item.id }) { diff --git a/DevLog/Presentation/ViewModel/TodoListViewModel.swift b/DevLog/Presentation/ViewModel/TodoListViewModel.swift index 73e5746..0da5a01 100644 --- a/DevLog/Presentation/ViewModel/TodoListViewModel.swift +++ b/DevLog/Presentation/ViewModel/TodoListViewModel.swift @@ -185,12 +185,13 @@ private extension TodoListViewModel { if let (pendingItem, _) = state.pendingTask { effects = [.delete(pendingItem.id)] } - guard let index = state.todos.firstIndex(where: { $0.id == todo.id }) else { - return [] + + if let index = state.todos.firstIndex(where: { $0.id == todo.id }) { + state.pendingTask = (todo, index) + state.todos.remove(at: index) + setToast(&state, isPresented: true) } - state.pendingTask = (todo, index) - state.todos.remove(at: index) - setToast(&state, isPresented: true) + return effects case .tapFilterOption(let option): state.filterOption = option From d099f0124c6ef1281593b6728c8cbcacdaa1182e Mon Sep 17 00:00:00 2001 From: opficdev Date: Fri, 27 Feb 2026 01:17:02 +0900 Subject: [PATCH 3/3] =?UTF-8?q?refactor:=20=EB=B6=88=ED=95=84=EC=9A=94=20?= =?UTF-8?q?=ED=83=80=EC=9E=85=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../PushNotificationListViewModel.swift | 54 ++++++------------- 1 file changed, 15 insertions(+), 39 deletions(-) diff --git a/DevLog/Presentation/ViewModel/PushNotificationListViewModel.swift b/DevLog/Presentation/ViewModel/PushNotificationListViewModel.swift index 52727b4..9ae123c 100644 --- a/DevLog/Presentation/ViewModel/PushNotificationListViewModel.swift +++ b/DevLog/Presentation/ViewModel/PushNotificationListViewModel.swift @@ -13,10 +13,8 @@ final class PushNotificationListViewModel: Store { var showAlert: Bool = false var showToast: Bool = false var alertTitle: String = "" - var alertType: AlertType? var alertMessage: String = "" var toastMessage: String = "" - var toastType: ToastType? var isLoading: Bool = false var hasMore: Bool = false var nextCursor: PushNotificationCursor? @@ -32,8 +30,8 @@ final class PushNotificationListViewModel: Store { case toggleRead(PushNotification) case undoDelete case confirmDelete - case setAlert(isPresented: Bool, type: AlertType? = nil) - case setToast(isPresented: Bool, type: ToastType? = nil) + case setAlert(isPresented: Bool) + case setToast(isPresented: Bool) case setLoading(Bool) case appendNotifications([PushNotification], nextCursor: PushNotificationCursor?) case resetPagination @@ -52,14 +50,6 @@ final class PushNotificationListViewModel: Store { case toggleRead(String) } - enum AlertType { - case error - } - - enum ToastType { - case delete - } - @Published private(set) var state: State private let fetchUseCase: FetchPushNotificationsUseCase private let deleteUseCase: DeletePushNotificationUseCase @@ -128,7 +118,7 @@ final class PushNotificationListViewModel: Store { let hasMore = page.items.count == query.pageSize && page.nextCursor != nil send(.setHasMore(hasMore)) } catch { - send(.setAlert(isPresented: true, type: .error)) + send(.setAlert(isPresented: true)) } } @@ -139,7 +129,7 @@ final class PushNotificationListViewModel: Store { send(.setLoading(true)) try await deleteUseCase.execute(notification.id) } catch { - send(.setAlert(isPresented: true, type: .error)) + send(.setAlert(isPresented: true)) } } case .toggleRead(let todoID): @@ -149,7 +139,7 @@ final class PushNotificationListViewModel: Store { send(.setLoading(true)) try await toggleReadUseCase.execute(todoID) } catch { - send(.setAlert(isPresented: true, type: .error)) + send(.setAlert(isPresented: true)) } } } @@ -169,7 +159,7 @@ private extension PushNotificationListViewModel { if let index = state.notifications.firstIndex(where: { $0.id == item.id }) { state.pendingTask = (item, index) state.notifications.remove(at: index) - setToast(&state, isPresented: true, for: .delete) + setToast(&state, isPresented: true) } return effects @@ -182,8 +172,8 @@ private extension PushNotificationListViewModel { guard let (item, index) = state.pendingTask else { return [] } state.notifications.insert(item, at: index) state.pendingTask = nil - case .setAlert(let isPresented, let type): - setAlert(&state, isPresented: isPresented, for: type) + case .setAlert(let isPresented): + setAlert(&state, isPresented: isPresented) case .toggleSortOption: state.query.sortOrder = state.query.sortOrder == .latest ? .oldest : .latest updateQueryUseCase.execute(state.query) @@ -228,8 +218,8 @@ private extension PushNotificationListViewModel { guard let (item, _) = state.pendingTask else { return [] } state.pendingTask = nil return [.delete(item)] - case .setToast(let isPresented, let type): - setToast(&state, isPresented: isPresented, for: type) + case .setToast(let isPresented): + setToast(&state, isPresented: isPresented) case .setSelectedTodoID(let todoID): state.selectedTodoID = todoID default: @@ -266,32 +256,18 @@ private extension PushNotificationListViewModel { private extension PushNotificationListViewModel { func setAlert( _ state: inout State, - isPresented: Bool, - for type: AlertType? + isPresented: Bool ) { - switch type { - case .error: - state.alertTitle = "오류" - state.alertMessage = "문제가 발생했습니다. 잠시 후 다시 시도해주세요." - case .none: - state.alertTitle = "" - state.alertMessage = "" - } - state.alertType = type + state.alertTitle = "오류" + state.alertMessage = "문제가 발생했습니다. 잠시 후 다시 시도해주세요." state.showAlert = isPresented } func setToast( _ state: inout State, - isPresented: Bool, - for type: ToastType? + isPresented: Bool ) { - switch type { - case .delete: - state.toastMessage = "실행 취소" - case .none: - state.toastMessage = "" - } + state.toastMessage = "실행 취소" state.showToast = isPresented } }