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
46 changes: 32 additions & 14 deletions Application/DevLogData/Sources/Mapper/TodoMapping.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,39 @@ import DevLogCore
import DevLogDomain

public extension TodoRequest {
static func fromDomain(_ entity: Todo) -> Self {
static func fromDomain(_ todo: Todo) -> Self {
TodoRequest(
id: todo.id,
isPinned: todo.isPinned,
isCompleted: todo.isCompleted,
isChecked: todo.isChecked,
title: todo.title,
content: todo.content,
createdAt: todo.createdAt,
updatedAt: todo.updatedAt,
completedAt: todo.completedAt,
deletedAt: todo.deletedAt,
dueDate: todo.dueDate,
tags: todo.tags,
category: todo.category.storageValue
)
}

static func fromDomain(_ todoDraft: TodoDraft) -> Self {
TodoRequest(
id: entity.id,
isPinned: entity.isPinned,
isCompleted: entity.isCompleted,
isChecked: entity.isChecked,
title: entity.title,
content: entity.content,
createdAt: entity.createdAt,
updatedAt: entity.updatedAt,
completedAt: entity.completedAt,
deletedAt: entity.deletedAt,
dueDate: entity.dueDate,
tags: entity.tags,
category: entity.category.storageValue
id: todoDraft.id,
isPinned: todoDraft.isPinned,
isCompleted: todoDraft.isCompleted,
isChecked: todoDraft.isChecked,
title: todoDraft.title,
content: todoDraft.content,
createdAt: todoDraft.createdAt,
updatedAt: todoDraft.updatedAt,
completedAt: todoDraft.completedAt,
deletedAt: nil,
dueDate: todoDraft.dueDate,
tags: todoDraft.tags,
category: todoDraft.category.storageValue
)
}
}
Expand Down
13 changes: 11 additions & 2 deletions Application/DevLogData/Sources/Repository/TodoRepositoryImpl.swift
Original file line number Diff line number Diff line change
Expand Up @@ -105,9 +105,18 @@ final class TodoRepositoryImpl: TodoRepository {
}

func upsertTodo(_ todo: Todo) async throws {
let request = TodoRequest.fromDomain(todo)
let todoRequest = TodoRequest.fromDomain(todo)
try await upsertTodo(todoRequest)
}

func upsertTodo(_ todoDraft: TodoDraft) async throws {
let todoRequest = TodoRequest.fromDomain(todoDraft)
try await upsertTodo(todoRequest)
}

private func upsertTodo(_ todoRequest: TodoRequest) async throws {
do {
try await todoService.upsertTodo(request: request)
try await todoService.upsertTodo(request: todoRequest)
widgetSyncEventBus.publish(.syncRequested)
} catch {
throw error.toDomain()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,10 @@ private actor WidgetSyncTodoRepositorySpy: TodoRepository {
throw WidgetSyncTodoRepositorySpyError.unexpectedCall
}

func upsertTodo(_ todoDraft: TodoDraft) async throws {
throw WidgetSyncTodoRepositorySpyError.unexpectedCall
}

func deleteTodo(_ todoId: String) async throws {
throw WidgetSyncTodoRepositorySpyError.unexpectedCall
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
5F978D87E2642CFA203A01EB /* FetchTodayDisplayOptionsUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3E9EFA52FBE798894A263625 /* FetchTodayDisplayOptionsUseCase.swift */; };
60B31EFA1482AD2F1A83B13F /* FetchPushNotificationsUseCaseImpl.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4AAB919C7D411DB4D9168030 /* FetchPushNotificationsUseCaseImpl.swift */; };
6437BF9BCF3C6702C627B7AC /* FetchHeatmapActivityTypesUseCaseImpl.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2C878DA61089719667B00EE1 /* FetchHeatmapActivityTypesUseCaseImpl.swift */; };
64F70B07260067A13C7F0FE0 /* TodoDraft.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D715313032680FBCAEC3272 /* TodoDraft.swift */; };
6669BB8F446C8A59B4EDEB82 /* ObserveUnreadPushCountUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = A6BC92678E2D3F131E95AA44 /* ObserveUnreadPushCountUseCase.swift */; };
6994DB7AC479B55D96759204 /* SystemTodoCategory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7DC9E59B49502EBE884E79F7 /* SystemTodoCategory.swift */; };
6A1A2DDE4A21808768208B29 /* UpdatePushSettingsUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = C43411396CEB5611FD6DC065 /* UpdatePushSettingsUseCase.swift */; };
Expand Down Expand Up @@ -167,6 +168,7 @@
0919CFDC9E74DC60E2EA82DA /* UIFont.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIFont.swift; sourceTree = "<group>"; };
0C2E5255AF2FDDCCF84C8B1E /* UpdatePushSettingsUseCaseImpl.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UpdatePushSettingsUseCaseImpl.swift; sourceTree = "<group>"; };
0C449AA008FB11BE56D5339B /* UpdateRecentSearchQueriesUseCase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UpdateRecentSearchQueriesUseCase.swift; sourceTree = "<group>"; };
0D715313032680FBCAEC3272 /* TodoDraft.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TodoDraft.swift; sourceTree = "<group>"; };
0DE4C7B87FC4BDDA0F36164F /* TodoCategoryPreference.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TodoCategoryPreference.swift; sourceTree = "<group>"; };
0DE6079177C9C1BEB7729105 /* ObserveNetworkConnectivityUseCaseImpl.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ObserveNetworkConnectivityUseCaseImpl.swift; sourceTree = "<group>"; };
0FFA6212304F79947234F6B6 /* FetchTodoCategoryPreferencesUseCaseImpl.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FetchTodoCategoryPreferencesUseCaseImpl.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -460,6 +462,7 @@
8FB3EADEF22E74D670F9AC07 /* TodoCategory.swift */,
0DE4C7B87FC4BDDA0F36164F /* TodoCategoryPreference.swift */,
D568A3D0C748AC2EBA756981 /* TodoCursor.swift */,
0D715313032680FBCAEC3272 /* TodoDraft.swift */,
9215705C81F1AC8DFF028D5B /* TodoPage.swift */,
ABA9FA543E3197EF5DF55ECB /* TodoReference.swift */,
79E7E7D9AB8EC8B90D6DF0BD /* UserProfile.swift */,
Expand Down Expand Up @@ -912,6 +915,7 @@
A9B574CED797235C974185A2 /* TodoCategory.swift in Sources */,
EDA93E3E36530BA704D41A68 /* TodoCategoryPreference.swift in Sources */,
C3253442982CCFCC7736197E /* TodoCursor.swift in Sources */,
64F70B07260067A13C7F0FE0 /* TodoDraft.swift in Sources */,
C8E9E1FB4F3F5B7851612EB2 /* TodoPage.swift in Sources */,
41E798191E4C30558452302F /* TodoReference.swift in Sources */,
F7063A1AB3A294E8BB2E585A /* UserProfile.swift in Sources */,
Expand Down
4 changes: 2 additions & 2 deletions Application/DevLogDomain/Sources/Entity/Todo.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ public struct Todo: Hashable {
public var isPinned: Bool // 해당 할 일이 상단에 고정되어 있는지 여부
public var isCompleted: Bool // 해당 할 일의 완료 여부
public var isChecked: Bool // 해당 할 일의 체크 여부
public var number: Int? // 사용자에게 노출되는 Todo 번호
public var number: Int // 사용자에게 노출되는 Todo 번호
public var title: String // 할 일의 제목
public var content: String // 할 일의 설명
public var createdAt: Date // 할 일 생성 날짜
Expand All @@ -28,7 +28,7 @@ public struct Todo: Hashable {
isPinned: Bool,
isCompleted: Bool,
isChecked: Bool,
number: Int?,
number: Int,
title: String,
content: String,
createdAt: Date,
Expand Down
79 changes: 79 additions & 0 deletions Application/DevLogDomain/Sources/Entity/TodoDraft.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
//
// TodoDraft.swift
// DevLogDomain
//
// Created by opfic on 6/2/26.
//

import Foundation

public struct TodoDraft: Equatable {
public var id: String
public var isPinned: Bool
public var isCompleted: Bool
public var isChecked: Bool
public var title: String
public var content: String
public var createdAt: Date
public var updatedAt: Date
public var completedAt: Date?
public var dueDate: Date?
public var tags: [String]
public var category: TodoCategory

public init(
id: String,
isPinned: Bool,
isCompleted: Bool,
isChecked: Bool,
title: String,
content: String,
createdAt: Date,
updatedAt: Date,
completedAt: Date?,
dueDate: Date?,
tags: [String],
category: TodoCategory
) {
self.id = id
self.isPinned = isPinned
self.isCompleted = isCompleted
self.isChecked = isChecked
self.title = title
self.content = content
self.createdAt = createdAt
self.updatedAt = updatedAt
self.completedAt = completedAt
self.dueDate = dueDate
self.tags = tags
self.category = category
}

public init(todo: Todo) {
self.id = todo.id
self.isPinned = todo.isPinned
self.isCompleted = todo.isCompleted
self.isChecked = todo.isChecked
self.title = todo.title
self.content = todo.content
self.createdAt = todo.createdAt
self.updatedAt = todo.updatedAt
self.completedAt = todo.completedAt
self.dueDate = todo.dueDate
self.tags = todo.tags
self.category = todo.category
}

public static func == (lhs: TodoDraft, rhs: TodoDraft) -> Bool {
lhs.id == rhs.id &&
lhs.isPinned == rhs.isPinned &&
lhs.isCompleted == rhs.isCompleted &&
lhs.isChecked == rhs.isChecked &&
lhs.title == rhs.title &&
lhs.content == rhs.content &&
lhs.completedAt == rhs.completedAt &&
lhs.dueDate == rhs.dueDate &&
lhs.tags == rhs.tags &&
lhs.category == rhs.category
}
Comment thread
opficdev marked this conversation as resolved.
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ public protocol TodoRepository {
func fetchTodo(_ todoId: String) async throws -> Todo
func fetchReferences(_ numbers: [Int]) async throws -> [Int: TodoReference]
func upsertTodo(_ todo: Todo) async throws
func upsertTodo(_ todoDraft: TodoDraft) async throws
func deleteTodo(_ todoId: String) async throws
func undoDeleteTodo(_ todoId: String) async throws
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,5 @@

public protocol UpsertTodoUseCase {
func execute(_ todo: Todo) async throws
func execute(_ todoDraft: TodoDraft) async throws
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,8 @@ public final class UpsertTodoUseCaseImpl: UpsertTodoUseCase {
public func execute(_ todo: Todo) async throws {
try await repository.upsertTodo(todo)
}

public func execute(_ todoDraft: TodoDraft) async throws {
try await repository.upsertTodo(todoDraft)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,8 @@ final class HomeViewCoordinator {

cancellable = windowEvent.submits
.sink { [weak self] submit in
guard submit.value.matchesCreate(source: .home) else { return }
guard case .create(let value) = submit,
value.matchesCreate(source: .home) else { return }
self?.viewModel.send(.fetchData)
}
}
Expand All @@ -59,7 +60,7 @@ final class HomeViewCoordinator {
fetchReferenceItemsUseCase: container.resolve(FetchReferenceItemsUseCase.self),
upsertTodoUseCase: container.resolve(UpsertTodoUseCase.self),
trackAnalyticsEventUseCase: container.resolve(TrackAnalyticsEventUseCase.self),
onUpsertSuccess: { [weak self] _ in
onCreateSuccess: { [weak self] in
self?.viewModel.send(.setPresentation(.todoEditor, false))
self?.viewModel.send(.fetchData)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,12 @@ struct TodoDetailView: View {
var body: some View {
ZStack {
Color(.systemGroupedBackground).ignoresSafeArea()
if let todo = viewModel.state.todo, let number = todo.number {
if let todo = viewModel.state.todo {
TodoDetailContentView(
title: todo.title,
content: todo.content,
referenceItems: viewModel.state.referenceItems,
number: number,
number: todo.number,
onOpenTodoID: { viewModel.send(.setSelectedTodoId(TodoIdItem(id: $0))) }
)
} else if viewModel.state.isLoading {
Expand Down Expand Up @@ -69,7 +69,7 @@ struct TodoDetailView: View {
fetchPreferencesUseCase: container.resolve(FetchTodoCategoryPreferencesUseCase.self),
fetchReferenceItemsUseCase: container.resolve(FetchReferenceItemsUseCase.self),
upsertTodoUseCase: container.resolve(UpsertTodoUseCase.self),
onUpsertSuccess: { todo in
onUpdateSuccess: { todo in
viewModel.send(.setShowEditor(false))
viewModel.send(.setTodo(todo))
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -208,8 +208,7 @@ struct TodoEditorView: View {
}

private func submit() {
let todo = viewModel.makeTodo()
viewModel.send(.upsertTodo(todo))
viewModel.send(.upsertTodo)
}

private func close() {
Expand Down
Loading