Skip to content

Commit b23d9dd

Browse files
authored
[#203] TodoEditorView에서 수정 시 최초 값과 다를 때만 서버에 업데이트될 수 있도록 버튼을 제한한다 (#205)
* feat: 기존 데이터와 새 데이터를 비교하여 disabled 및 자체 로직에 반영 * refactor: 중복 코드 제거
1 parent a84968f commit b23d9dd

2 files changed

Lines changed: 41 additions & 26 deletions

File tree

DevLog/Presentation/ViewModel/TodoEditorViewModel.swift

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,27 @@ import OrderedCollections
1010

1111
@Observable
1212
final class TodoEditorViewModel: Store {
13+
private struct Draft: Equatable {
14+
let title: String
15+
let content: String
16+
let dueDate: Date?
17+
let tags: [String]
18+
19+
init(todo: Todo) {
20+
self.title = todo.title
21+
self.content = todo.content
22+
self.dueDate = todo.dueDate
23+
self.tags = todo.tags
24+
}
25+
26+
init(state: State) {
27+
self.title = state.title
28+
self.content = state.content
29+
self.dueDate = state.dueDate
30+
self.tags = Array(state.tags)
31+
}
32+
}
33+
1334
struct State: Equatable {
1435
var title: String = ""
1536
var content: String = ""
@@ -52,6 +73,16 @@ final class TodoEditorViewModel: Store {
5273
private let createdAt: Date?
5374
private let completedAt: Date?
5475
private let kind: TodoKind
76+
private let originalDraft: Draft?
77+
78+
var hasChanges: Bool {
79+
guard let originalDraft else { return true }
80+
return originalDraft != Draft(state: state)
81+
}
82+
83+
var isReadyToSubmit: Bool {
84+
state.isValidToSave && hasChanges
85+
}
5586

5687
// 새로운 Todo 생성용 생성자
5788
init(kind: TodoKind) {
@@ -63,6 +94,7 @@ final class TodoEditorViewModel: Store {
6394
self.createdAt = nil
6495
self.completedAt = nil
6596
self.kind = kind
97+
self.originalDraft = nil
6698
}
6799

68100
// 기존 Todo 편집용 생성자
@@ -75,6 +107,7 @@ final class TodoEditorViewModel: Store {
75107
self.createdAt = todo.createdAt
76108
self.completedAt = todo.completedAt
77109
self.kind = todo.kind
110+
self.originalDraft = Draft(todo: todo)
78111
state.title = todo.title
79112
state.content = todo.content
80113
state.dueDate = todo.dueDate
@@ -134,7 +167,7 @@ extension TodoEditorViewModel {
134167
}
135168
}
136169

137-
func upsertTodo() -> Todo {
170+
func makeTodo() -> Todo {
138171
let date = Date()
139172
return Todo(
140173
id: self.id,

DevLog/UI/Home/TodoEditorView.swift

Lines changed: 7 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -47,14 +47,11 @@ struct TodoEditorView: View {
4747
.navigationBarTitleDisplayMode(.inline)
4848
.toolbarBackground(.background, for: .navigationBar)
4949
.toolbar {
50-
ToolbarLeadingButton {
51-
dismiss()
52-
}
50+
ToolbarLeadingButton { dismiss() }
5351
ToolbarTrailingButton {
54-
onSubmit?(viewModel.upsertTodo())
55-
dismiss()
52+
submit()
5653
}
57-
.disabled(!viewModel.state.isValidToSave)
54+
.disabled(!viewModel.isReadyToSubmit)
5855
}
5956
}
6057
}
@@ -166,25 +163,10 @@ struct TodoEditorView: View {
166163
}
167164
}
168165

169-
@ToolbarContentBuilder
170-
private var toolBar: some ToolbarContent {
171-
ToolbarItem(placement: .topBarLeading) {
172-
Button {
173-
dismiss()
174-
} label: {
175-
Image(systemName: "xmark")
176-
.bold()
177-
}
178-
}
179-
ToolbarItem(placement: .topBarTrailing) {
180-
Button(action: {
181-
onSubmit?(viewModel.upsertTodo())
182-
dismiss()
183-
}) {
184-
Text("추가")
185-
}
186-
.disabled(!viewModel.state.isValidToSave)
187-
}
166+
private func submit() {
167+
let todo = viewModel.makeTodo()
168+
onSubmit?(todo)
169+
dismiss()
188170
}
189171

190172
private enum Field: Hashable {

0 commit comments

Comments
 (0)