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
8 changes: 0 additions & 8 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 All @@ -62,7 +61,6 @@ final class TodoEditorViewModel: Store {
case setTagText(String)
case setTitle(String)
case togglePinned
case toggleDueDate
}

enum SideEffect { }
Expand Down Expand Up @@ -140,12 +138,6 @@ final class TodoEditorViewModel: Store {
state.tabViewTag = tag
case .togglePinned:
state.isPinned.toggle()
case .toggleDueDate:
if state.hasDueDate {
state.dueDate = nil
} else {
state.dueDate = calendar.date(byAdding: .day, value: 1, to: Date())
}
}

if self.state != state { self.state = state }
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