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: 8 additions & 0 deletions DevLog/App/Assembler/DomainAssembler.swift
Original file line number Diff line number Diff line change
Expand Up @@ -154,5 +154,13 @@ private extension DomainAssembler {
container.register(UpdateProfileHeatmapActivityTypesUseCase.self) {
UpdateProfileHeatmapActivityTypesUseCaseImpl(container.resolve(UserPreferencesRepository.self))
}

container.register(FetchTodayDisplayOptionsUseCase.self) {
FetchTodayDisplayOptionsUseCaseImpl(container.resolve(UserPreferencesRepository.self))
}

container.register(UpdateTodayDisplayOptionsUseCase.self) {
UpdateTodayDisplayOptionsUseCaseImpl(container.resolve(UserPreferencesRepository.self))
}
}
}
3 changes: 2 additions & 1 deletion DevLog/Data/DTO/TodoCursorDTO.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import Foundation

struct TodoCursorDTO {
let orderedAt: Date
let primarySortDate: Date?
let secondarySortDate: Date?
let documentID: String
}
6 changes: 4 additions & 2 deletions DevLog/Data/Mapper/TodoMapping.swift
Original file line number Diff line number Diff line change
Expand Up @@ -50,14 +50,16 @@ extension TodoResponse {
extension TodoCursorDTO {
func toDomain() -> TodoCursor {
TodoCursor(
orderedAt: orderedAt,
primarySortDate: primarySortDate,
secondarySortDate: secondarySortDate,
documentID: documentID
)
}

static func fromDomain(_ cursor: TodoCursor) -> Self {
TodoCursorDTO(
orderedAt: cursor.orderedAt,
primarySortDate: cursor.primarySortDate,
secondarySortDate: cursor.secondarySortDate,
documentID: cursor.documentID
)
}
Expand Down
21 changes: 21 additions & 0 deletions DevLog/Data/Repository/UserPreferencesRepositoryImpl.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ final class UserPreferencesRepositoryImpl: UserPreferencesRepository {
static let pushTimeFilter = "PushNotification.timeFilter"
static let pushUnreadOnly = "PushNotification.showUnreadOnly"
static let profileHeatmapActivityTypes = "Profile.heatmap.activityTypes"
static let todayDueDateVisibility = "Today.dueDateVisibility"
static let todayFocusVisibility = "Today.focusVisibility"
}

private let store: UserDefaultsStore
Expand Down Expand Up @@ -101,4 +103,23 @@ final class UserPreferencesRepositoryImpl: UserPreferencesRepository {
func setProfileHeatmapActivityTypes(_ activityTypes: [String]) {
store.setStringArray(activityTypes, forKey: Key.profileHeatmapActivityTypes)
}

func todayDisplayOptions() -> TodayDisplayOptions {
let dueDateVisibilityRawValue = store.string(forKey: Key.todayDueDateVisibility)
let focusVisibilityRawValue = store.string(forKey: Key.todayFocusVisibility)

return TodayDisplayOptions(
dueDateVisibility: TodayDisplayOptions.DueDateVisibility(
rawValue: dueDateVisibilityRawValue ?? ""
) ?? .all,
focusVisibility: TodayDisplayOptions.FocusVisibility(
rawValue: focusVisibilityRawValue ?? ""
) ?? .all
)
}

func setTodayDisplayOptions(_ options: TodayDisplayOptions) {
store.setString(options.dueDateVisibility.rawValue, forKey: Key.todayDueDateVisibility)
store.setString(options.focusVisibility.rawValue, forKey: Key.todayFocusVisibility)
}
}
29 changes: 29 additions & 0 deletions DevLog/Domain/Entity/TodayDisplayOptions.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
//
// TodayDisplayOptions.swift
// DevLog
//
// Created by opfic on 3/6/26.
//

import Foundation

struct TodayDisplayOptions: Equatable {
enum DueDateVisibility: String, CaseIterable, Equatable {
case all
case withDueDateOnly
case withoutDueDateOnly
}

enum FocusVisibility: String, CaseIterable, Equatable {
case all
case focusedOnly
}

var dueDateVisibility: DueDateVisibility
var focusVisibility: FocusVisibility

static let `default` = TodayDisplayOptions(
dueDateVisibility: .all,
focusVisibility: .all
)
}
3 changes: 2 additions & 1 deletion DevLog/Domain/Entity/TodoCursor.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import Foundation

struct TodoCursor {
let orderedAt: Date
let primarySortDate: Date?
let secondarySortDate: Date?
let documentID: String
}
12 changes: 12 additions & 0 deletions DevLog/Domain/Entity/TodoQuery.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,16 @@ struct TodoQuery: Equatable {
enum SortTarget: Equatable, Hashable {
case createdAt
case updatedAt
case dueDate

var fieldName: String {
switch self {
case .createdAt:
return "createdAt"
case .updatedAt:
return "updatedAt"
case .dueDate:
return "dueDate"
}
}
}
Expand Down Expand Up @@ -48,10 +51,17 @@ struct TodoQuery: Equatable {
}
}

enum DueDateFilter: Equatable, Hashable {
case all
case withDueDate
case withoutDueDate
}

var kind: TodoKind?
var keyword: String?
var isPinned: Bool?
var completionFilter: CompletionFilter
var dueDateFilter: DueDateFilter
var createdAtFrom: Date?
var createdAtTo: Date?
var sortTarget: SortTarget
Expand All @@ -64,6 +74,7 @@ struct TodoQuery: Equatable {
keyword: String? = nil,
isPinned: Bool? = nil,
completionFilter: CompletionFilter = .all,
dueDateFilter: DueDateFilter = .all,
createdAtFrom: Date? = nil,
createdAtTo: Date? = nil,
sortTarget: SortTarget = .createdAt,
Expand All @@ -75,6 +86,7 @@ struct TodoQuery: Equatable {
self.keyword = keyword
self.isPinned = isPinned
self.completionFilter = completionFilter
self.dueDateFilter = dueDateFilter
self.createdAtFrom = createdAtFrom
self.createdAtTo = createdAtTo
self.sortTarget = sortTarget
Expand Down
3 changes: 3 additions & 0 deletions DevLog/Domain/Protocol/UserPreferencesRepository.swift
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,7 @@ protocol UserPreferencesRepository {

func profileHeatmapActivityTypes() -> [String]
func setProfileHeatmapActivityTypes(_ activityTypes: [String])

func todayDisplayOptions() -> TodayDisplayOptions
func setTodayDisplayOptions(_ options: TodayDisplayOptions)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
//
// FetchTodayDisplayOptionsUseCase.swift
// DevLog
//
// Created by opfic on 3/6/26.
//

protocol FetchTodayDisplayOptionsUseCase {
func execute() -> TodayDisplayOptions
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
//
// FetchTodayDisplayOptionsUseCaseImpl.swift
// DevLog
//
// Created by opfic on 3/6/26.
//

final class FetchTodayDisplayOptionsUseCaseImpl: FetchTodayDisplayOptionsUseCase {
private let repository: UserPreferencesRepository

init(_ repository: UserPreferencesRepository) {
self.repository = repository
}

func execute() -> TodayDisplayOptions {
repository.todayDisplayOptions()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
//
// UpdateTodayDisplayOptionsUseCase.swift
// DevLog
//
// Created by opfic on 3/6/26.
//

protocol UpdateTodayDisplayOptionsUseCase {
func execute(_ options: TodayDisplayOptions)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
//
// UpdateTodayDisplayOptionsUseCaseImpl.swift
// DevLog
//
// Created by opfic on 3/6/26.
//

final class UpdateTodayDisplayOptionsUseCaseImpl: UpdateTodayDisplayOptionsUseCase {
private let repository: UserPreferencesRepository

init(_ repository: UserPreferencesRepository) {
self.repository = repository
}

func execute(_ options: TodayDisplayOptions) {
repository.setTodayDisplayOptions(options)
}
}
Loading