Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
7 changes: 3 additions & 4 deletions DevLog/Presentation/ViewModel/TodoEditorViewModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@ final class TodoEditorViewModel: Store {
var tags: OrderedSet<String> = []
var tagText: String = ""
var focusOnEditor: Bool = false
var hasDueDate: Bool { dueDate != nil }
var tabViewTag: Tag = .editor
var isValidToSave: Bool {
!title.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty
Expand Down Expand Up @@ -141,10 +140,10 @@ final class TodoEditorViewModel: Store {
case .togglePinned:
state.isPinned.toggle()
case .toggleDueDate:
if state.hasDueDate {
state.dueDate = nil
} else {
if state.dueDate == nil {
state.dueDate = calendar.date(byAdding: .day, value: 1, to: Date())
} else {
state.dueDate = nil
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

.toggleDueDate 액션이 TodoEditorView에서 사용되지 않는 것으로 보입니다. 이 PR에서 변경된 UI에서는 마감일 설정/해제를 위해 .setDueDate 액션을 사용하고 있습니다. 만약 다른 곳에서도 .toggleDueDate를 사용하지 않는다면, 코드 명확성과 유지보수성 향상을 위해 Action enum에서 해당 케이스와 reduce 함수의 관련 로직을 제거하는 것을 고려해 보세요.

}

Expand Down
56 changes: 36 additions & 20 deletions DevLog/UI/Home/TodoEditorView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ struct TodoEditorView: View {
@Environment(\.dismiss) private var dismiss
@FocusState private var field: Field?
@State private var showDueDatePicker: Bool = false
private let calendar = Calendar.current
var onSubmit: ((Todo) -> Void)?

var body: some View {
Expand Down Expand Up @@ -175,30 +176,30 @@ struct TodoEditorView: View {
}
.adaptiveButtonStyle()
}
DueDatePicker(selection: Binding(
get: { viewModel.state.dueDate ?? Date() },
set: { viewModel.send(.setDueDate($0)) }
)) {
HStack {
Label {
Text("마감일")
} icon: {
Image(systemName: "calendar")
.foregroundStyle(.gray)
dueDateControl
}
}

private var dueDateControl: some View {
DueDatePicker(selection: Binding(
get: { viewModel.state.dueDate ?? Date() },
set: { viewModel.send(.setDueDate($0)) }
)) {
Label {
if let dueDate = viewModel.state.dueDate {
Tag(dueDateText(for: dueDate), isEditing: true) {
viewModel.send(.setDueDate(nil))
}
Image(systemName: "checkmark.square")
.symbolRenderingMode(.palette)
.foregroundStyle(
viewModel.state.hasDueDate ? .blue : .clear,
.gray
)
.onTapGesture {
viewModel.send(.setDueDate(viewModel.state.hasDueDate ? nil : Date()))
}
.padding(.vertical, -4)
} else {
Text("마감일")
}
.adaptiveButtonStyle()
} icon: {
Image(systemName: "calendar")
.foregroundStyle(.gray)
}
}
.adaptiveButtonStyle()
}

private func submit() {
Expand All @@ -210,6 +211,21 @@ struct TodoEditorView: View {
private enum Field: Hashable {
case title, description, tag
}

private func dueDateText(for dueDate: Date) -> String {
let currentYear = calendar.component(.year, from: Date())
let dueDateYear = calendar.component(.year, from: dueDate)

if currentYear == dueDateYear {
return dueDate.formatted(
.dateTime.month(.defaultDigits).day(.defaultDigits)
)
}

return dueDate.formatted(
.dateTime.year(.twoDigits).month(.defaultDigits).day(.defaultDigits)
)
}
Comment on lines +215 to +228

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

dueDateText(for:) 함수 내에서 Date()를 직접 호출하면 현재 시간에 의존하게 되어 테스트하기 어려워집니다. 함수를 순수 함수로 만들고 테스트 용이성을 높이기 위해 현재 날짜를 파라미터로 전달하고 기본값으로 Date()를 사용하는 것이 좋습니다.

Suggested change
private func dueDateText(for dueDate: Date) -> String {
let currentYear = calendar.component(.year, from: Date())
let dueDateYear = calendar.component(.year, from: dueDate)
if currentYear == dueDateYear {
return dueDate.formatted(
.dateTime.month(.defaultDigits).day(.defaultDigits)
)
}
return dueDate.formatted(
.dateTime.year(.twoDigits).month(.defaultDigits).day(.defaultDigits)
)
}
private func dueDateText(for dueDate: Date, now: Date = Date()) -> String {
let currentYear = calendar.component(.year, from: now)
let dueDateYear = calendar.component(.year, from: dueDate)
if currentYear == dueDateYear {
return dueDate.formatted(
.dateTime.month(.defaultDigits).day(.defaultDigits)
)
}
return dueDate.formatted(
.dateTime.year(.twoDigits).month(.defaultDigits).day(.defaultDigits)
)
}

}

private struct TagEditor<Content: View>: View {
Expand Down