Skip to content

Commit a01d071

Browse files
committed
refactor: Todo 추가 / 수정 책임을 에디터로 이동
1 parent 958b19e commit a01d071

15 files changed

Lines changed: 105 additions & 93 deletions

Application/DevLogPresentation/Sources/Home/Home/HomeView.swift

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,7 @@ struct HomeView: View {
5151
)) {
5252
if let selectedCategory = coordinator.viewModel.state.selectedTodoCategory {
5353
TodoEditorView(
54-
viewModel: coordinator.makeTodoEditorViewModel(category: selectedCategory),
55-
onSubmit: { coordinator.viewModel.send(.addTodo($0)) }
54+
viewModel: coordinator.makeTodoEditorViewModel(category: selectedCategory)
5655
)
5756
}
5857
}
@@ -405,9 +404,8 @@ struct HomeView: View {
405404
}
406405

407406
private func handleTodoEditorSubmit(_ submit: TodoEditorWindowSubmit?) {
408-
guard let submit,
409-
submit.value.matchesCreate(source: .home) else { return }
410-
coordinator.viewModel.send(.addTodo(submit.todo))
407+
guard let submit, submit.value.matchesCreate(source: .home) else { return }
408+
coordinator.viewModel.send(.fetchData)
411409
}
412410

413411
}

Application/DevLogPresentation/Sources/Home/Home/HomeViewCoordinator.swift

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ final class HomeViewCoordinator {
2424
addWebPageUseCase: container.resolve(AddWebPageUseCase.self),
2525
deleteWebPageUseCase: container.resolve(DeleteWebPageUseCase.self),
2626
undoDeleteWebPageUseCase: container.resolve(UndoDeleteWebPageUseCase.self),
27-
upsertTodoUseCase: container.resolve(UpsertTodoUseCase.self),
2827
fetchTodosUseCase: container.resolve(FetchTodosUseCase.self),
2928
fetchWebPagesUseCase: container.resolve(FetchWebPagesUseCase.self),
3029
networkConnectivityUseCase: container.resolve(ObserveNetworkConnectivityUseCase.self),
@@ -44,7 +43,13 @@ final class HomeViewCoordinator {
4443
TodoEditorViewModel(
4544
category: category,
4645
fetchPreferencesUseCase: diContainer.resolve(FetchTodoCategoryPreferencesUseCase.self),
47-
fetchReferenceItemsUseCase: diContainer.resolve(FetchReferenceItemsUseCase.self)
46+
fetchReferenceItemsUseCase: diContainer.resolve(FetchReferenceItemsUseCase.self),
47+
upsertTodoUseCase: diContainer.resolve(UpsertTodoUseCase.self),
48+
trackAnalyticsEventUseCase: diContainer.resolve(TrackAnalyticsEventUseCase.self),
49+
onUpsertSuccess: { [weak self] _ in
50+
self?.viewModel.send(.setPresentation(.todoEditor, false))
51+
self?.viewModel.send(.fetchData)
52+
}
4853
)
4954
}
5055

Application/DevLogPresentation/Sources/Home/Home/HomeViewModel.swift

Lines changed: 1 addition & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,6 @@ final class HomeViewModel: Store {
5050
case tapTodoCategory(TodoCategory)
5151
case orderTodoCategory([TodoCategoryItem])
5252
case setTodoCategory([TodoCategoryItem])
53-
case addTodo(Todo)
5453
case updateRecentTodos([RecentTodoItem])
5554
case updateWebPageURLInput(String)
5655
case addWebPage
@@ -60,7 +59,6 @@ final class HomeViewModel: Store {
6059
}
6160

6261
enum SideEffect {
63-
case addTodo(Todo)
6462
case addWebPage(String)
6563
case deleteWebPage(WebPageItem)
6664
case undoDeleteWebPage(String)
@@ -103,7 +101,6 @@ final class HomeViewModel: Store {
103101
private(set) var state = State()
104102
private let fetchPreferencesUseCase: FetchTodoCategoryPreferencesUseCase
105103
private let updatePreferencesUseCase: UpdateTodoCategoryPreferencesUseCase
106-
private let upsertTodoUseCase: UpsertTodoUseCase
107104
private let addWebPageUseCase: AddWebPageUseCase
108105
private let deleteWebPageUseCase: DeleteWebPageUseCase
109106
private let undoDeleteWebPageUseCase: UndoDeleteWebPageUseCase
@@ -121,7 +118,6 @@ final class HomeViewModel: Store {
121118
addWebPageUseCase: AddWebPageUseCase,
122119
deleteWebPageUseCase: DeleteWebPageUseCase,
123120
undoDeleteWebPageUseCase: UndoDeleteWebPageUseCase,
124-
upsertTodoUseCase: UpsertTodoUseCase,
125121
fetchTodosUseCase: FetchTodosUseCase,
126122
fetchWebPagesUseCase: FetchWebPagesUseCase,
127123
networkConnectivityUseCase: ObserveNetworkConnectivityUseCase,
@@ -132,7 +128,6 @@ final class HomeViewModel: Store {
132128
self.addWebPageUseCase = addWebPageUseCase
133129
self.deleteWebPageUseCase = deleteWebPageUseCase
134130
self.undoDeleteWebPageUseCase = undoDeleteWebPageUseCase
135-
self.upsertTodoUseCase = upsertTodoUseCase
136131
self.fetchTodosUseCase = fetchTodosUseCase
137132
self.fetchWebPagesUseCase = fetchWebPagesUseCase
138133
self.networkConnectivityUseCase = networkConnectivityUseCase
@@ -149,7 +144,7 @@ final class HomeViewModel: Store {
149144
case .networkStatusChanged(let isConnected):
150145
state.isNetworkConnected = isConnected
151146
case .fetchData, .setPresentation, .setAlert, .setToast, .refreshWebPages,
152-
.tapTodoCategory, .orderTodoCategory, .addTodo, .updateWebPageURLInput,
147+
.tapTodoCategory, .orderTodoCategory, .updateWebPageURLInput,
153148
.addWebPage, .deleteWebPage, .undoDeleteWebPage:
154149
effects = reduceByView(action, state: &state)
155150

@@ -183,23 +178,6 @@ final class HomeViewModel: Store {
183178
send(.setAlert(isPresented: true, type: .error))
184179
}
185180
}
186-
case .addTodo(let todo):
187-
beginLoading(for: .overlay, mode: .delayed)
188-
Task {
189-
do {
190-
defer { endLoading(for: .overlay, mode: .delayed) }
191-
try await upsertTodoUseCase.execute(todo)
192-
trackAnalyticsEventUseCase.execute(.todoCreate)
193-
let page = try await fetchRecentTodos()
194-
let items = page.items
195-
.filter { $0.createdAt != $0.updatedAt }
196-
.prefix(5)
197-
.compactMap { RecentTodoItem(from: $0) }
198-
send(.updateRecentTodos(items))
199-
} catch {
200-
send(.setAlert(isPresented: true, type: .error))
201-
}
202-
}
203181
case .fetchRecentTodos:
204182
beginLoading(for: .recentTodos, mode: .immediate)
205183
Task {
@@ -305,8 +283,6 @@ private extension HomeViewModel {
305283
state.preferences = preferences
306284
state.recentTodos = syncRecentTodos(state.recentTodos, preferences: preferences)
307285
return [.updateTodoCategoryPreferences(preferences)]
308-
case .addTodo(let todo):
309-
return [.addTodo(todo)]
310286
case .updateWebPageURLInput(let text):
311287
state.webPageURLInput = text
312288
case .addWebPage:

Application/DevLogPresentation/Sources/Home/TodoDetailView.swift

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,6 @@ struct TodoDetailView: View {
5050
TodoDetailView(viewModel: TodoDetailViewModel(
5151
fetchTodoUseCase: container.resolve(FetchTodoByIdUseCase.self),
5252
fetchReferenceItemsUseCase: container.resolve(FetchReferenceItemsUseCase.self),
53-
upsertUseCase: container.resolve(UpsertTodoUseCase.self),
5453
todoId: item.id,
5554
showEditButton: false
5655
))
@@ -72,9 +71,13 @@ struct TodoDetailView: View {
7271
viewModel: TodoEditorViewModel(
7372
todo: todo,
7473
fetchPreferencesUseCase: container.resolve(FetchTodoCategoryPreferencesUseCase.self),
75-
fetchReferenceItemsUseCase: container.resolve(FetchReferenceItemsUseCase.self)
76-
),
77-
onSubmit: { viewModel.send(.upsertTodo($0)) }
74+
fetchReferenceItemsUseCase: container.resolve(FetchReferenceItemsUseCase.self),
75+
upsertTodoUseCase: container.resolve(UpsertTodoUseCase.self),
76+
onUpsertSuccess: { todo in
77+
viewModel.send(.setShowEditor(false))
78+
viewModel.send(.setTodo(todo))
79+
}
80+
)
7881
)
7982
}
8083
}
@@ -119,7 +122,7 @@ struct TodoDetailView: View {
119122
private func handleTodoEditorSubmit(_ submit: TodoEditorWindowSubmit?) {
120123
guard let submit,
121124
submit.value.matchesEdit(todoId: viewModel.todoId) else { return }
122-
viewModel.send(.upsertTodo(submit.todo))
125+
viewModel.send(.setTodo(submit.todo))
123126
}
124127

125128
@ViewBuilder

Application/DevLogPresentation/Sources/Home/TodoDetailViewModel.swift

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -31,33 +31,28 @@ final class TodoDetailViewModel: Store {
3131
case setTodo(Todo)
3232
case setReferenceItems([Int: TodoReferenceItem])
3333
case setLoading(Bool)
34-
case upsertTodo(Todo)
3534
}
3635

3736
enum SideEffect {
3837
case fetchTodo
3938
case resolveMarkdown(String)
40-
case upsertTodo(Todo)
4139
}
4240

4341
private(set) var state: State = .init()
4442
let todoId: String
4543
let showEditButton: Bool
4644
private let fetchTodoUseCase: FetchTodoByIdUseCase
4745
private let fetchReferenceItemsUseCase: FetchReferenceItemsUseCase
48-
private let upsertUseCase: UpsertTodoUseCase
4946
private let loadingState = LoadingState()
5047

5148
init(
5249
fetchTodoUseCase: FetchTodoByIdUseCase,
5350
fetchReferenceItemsUseCase: FetchReferenceItemsUseCase,
54-
upsertUseCase: UpsertTodoUseCase,
5551
todoId: String,
5652
showEditButton: Bool = true
5753
) {
5854
self.fetchTodoUseCase = fetchTodoUseCase
5955
self.fetchReferenceItemsUseCase = fetchReferenceItemsUseCase
60-
self.upsertUseCase = upsertUseCase
6156
self.todoId = todoId
6257
self.showEditButton = showEditButton
6358
}
@@ -85,8 +80,6 @@ final class TodoDetailViewModel: Store {
8580
state.referenceItems = items
8681
case .setLoading(let value):
8782
state.isLoading = value
88-
case .upsertTodo(let todo):
89-
effects = [.upsertTodo(todo)]
9083
}
9184

9285
if self.state != state { self.state = state }
@@ -122,17 +115,6 @@ final class TodoDetailViewModel: Store {
122115

123116
send(.setReferenceItems(referenceItems))
124117
}
125-
case .upsertTodo(let todo):
126-
beginLoading(.delayed)
127-
Task {
128-
do {
129-
defer { endLoading(.delayed) }
130-
try await upsertUseCase.execute(todo)
131-
send(.setTodo(todo))
132-
} catch {
133-
send(.setAlert(true))
134-
}
135-
}
136118
}
137119
}
138120
}

Application/DevLogPresentation/Sources/Home/TodoEditorView.swift

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ struct TodoEditorView: View {
1818
@Environment(\.isiOSAppOnMac) private var isiOSAppOnMac
1919
@FocusState private var field: Field?
2020
private let calendar = Calendar.current
21-
var onSubmit: ((Todo) -> Void)?
2221
var onClose: (() -> Void)?
2322

2423
var body: some View {
@@ -65,7 +64,6 @@ struct TodoEditorView: View {
6564
TodoDetailView(viewModel: TodoDetailViewModel(
6665
fetchTodoUseCase: container.resolve(FetchTodoByIdUseCase.self),
6766
fetchReferenceItemsUseCase: container.resolve(FetchReferenceItemsUseCase.self),
68-
upsertUseCase: container.resolve(UpsertTodoUseCase.self),
6967
todoId: item.id,
7068
showEditButton: false
7169
))
@@ -92,7 +90,18 @@ struct TodoEditorView: View {
9290
ToolbarTrailingButton {
9391
submit()
9492
}
95-
.disabled(!viewModel.isReadyToSubmit)
93+
.disabled(!viewModel.isReadyToSubmit || viewModel.state.isLoading)
94+
}
95+
.alert(
96+
viewModel.state.alertTitle,
97+
isPresented: Binding(
98+
get: { viewModel.state.showAlert },
99+
set: { viewModel.send(.setAlert($0)) }
100+
)
101+
) {
102+
Button(String(localized: "common_close"), role: .cancel) { }
103+
} message: {
104+
Text(viewModel.state.alertMessage)
96105
}
97106
}
98107
}
@@ -200,8 +209,7 @@ struct TodoEditorView: View {
200209

201210
private func submit() {
202211
let todo = viewModel.makeTodo()
203-
onSubmit?(todo)
204-
close()
212+
viewModel.send(.upsertTodo(todo))
205213
}
206214

207215
private func close() {

0 commit comments

Comments
 (0)