Skip to content

Commit c16aec7

Browse files
authored
[#150] ProfileView에 UI 요소를 추가한다 (#161)
* feat: 매 분기마다의 Todo의 생성 / 완료에 대해 맵을 보여주도록 구성 * fix: 년 분기가 달라질 때 패딩값이 자동으로 수정되는 현상 해결 * feat: 분기 단위로 Todo 생성 / 완료 히트맵을 보여주도록 구성 * fix: 분기 이동이 되지 않는 현상 수정 * ui: 테두리로 구분하는 대신 채우기로 변경 * feat: UserDefaults로 활동 설정값을 저장하여 영속성 보장 * ui: 맵을 탭하면 해당 날짜에 해당하는 활동을 보여주도록 추가 * feat: 특정 활동을 탭하면 해당 활동의 상세 내용을 볼 수 있도록 추가 * refactor: 비슷한 UI요소 컴포넌트화 * chore: 디렉토리명 오타 수정 * ui: 년도가 상시 보이도록 추가 * refactor: 터치성 개선 * ui: 투명도 애니메이션만 적용 * ui: 상세 내용을 내비게이션해서 보여주도록 변경 * ui: TodoDetailContentView가 배경색을 가지도록 수정 * refactor: 키워드 원문을 로그에서 보이지 않도록 하고, nil이 아닌 쿼리만 보이도록 개선 * refactor: 계산 변수들은 State 밖으로 분리 * refactor: 오류 발생 시 얼럿을 띄우도록 개선 * refactor: monthMaxCount가 각 day 셀에 대해 반복적으로 계산되는 형태를 한번만 하도록 개선 * refactor: Calendar 중복 생성 제거 * refactor: 뷰에서 Presentation 책임 제거 * fix: 활동이 있더라도 내림에 의해 0으로 계산되어 보이지 않는 형태 방지 * refactor: 동일 로직 메서드화 * refactor: 중복 코드 최소화 * refactor: 100개 단위로 페이지네이션 형태를 통해 모든 데이터 받아오기 * refactor: 캐시 제거 후 딕셔너리로 데이터르 변환해 날짜 조회 시 성능 개선 * refactor: 좀 더 안전하도록 로직 수정 * refactor: 불필요 메서드 제거
1 parent 9998a25 commit c16aec7

33 files changed

Lines changed: 1069 additions & 114 deletions

DevLog/App/Assembler/DomainAssembler.swift

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,10 @@ private extension DomainAssembler {
6363
FetchTodosByKindUseCaseImpl(container.resolve(TodoRepository.self))
6464
}
6565

66+
container.register(FetchTodosByDateRangeUseCase.self) {
67+
FetchTodosByDateRangeUseCaseImpl(container.resolve(TodoRepository.self))
68+
}
69+
6670
container.register(FetchTodosByKeywordUseCase.self) {
6771
FetchTodosByKeywordUseCaseImpl(container.resolve(TodoRepository.self))
6872
}
@@ -154,5 +158,13 @@ private extension DomainAssembler {
154158
container.register(UpdatePushNotificationQueryUseCase.self) {
155159
UpdatePushNotificationQueryUseCaseImpl(container.resolve(UserPreferencesRepository.self))
156160
}
161+
162+
container.register(FetchProfileHeatmapActivityTypesUseCase.self) {
163+
FetchProfileHeatmapActivityTypesUseCaseImpl(container.resolve(UserPreferencesRepository.self))
164+
}
165+
166+
container.register(UpdateProfileHeatmapActivityTypesUseCase.self) {
167+
UpdateProfileHeatmapActivityTypesUseCaseImpl(container.resolve(UserPreferencesRepository.self))
168+
}
157169
}
158170
}

DevLog/Data/Repository/UserPreferencesRepositoryImpl.swift

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ final class UserPreferencesRepositoryImpl: UserPreferencesRepository {
1616
static let pushSortOrder = "PushNotification.sortOption"
1717
static let pushTimeFilter = "PushNotification.timeFilter"
1818
static let pushUnreadOnly = "PushNotification.showUnreadOnly"
19+
static let profileHeatmapActivityTypes = "Profile.heatmap.activityTypes"
1920
}
2021

2122
private let store: UserDefaultsStore
@@ -92,4 +93,12 @@ final class UserPreferencesRepositoryImpl: UserPreferencesRepository {
9293
func setPushNotificationUnreadOnly(_ value: Bool) {
9394
store.setBool(value, forKey: Key.pushUnreadOnly)
9495
}
96+
97+
func profileHeatmapActivityTypes() -> [String] {
98+
store.stringArray(forKey: Key.profileHeatmapActivityTypes)
99+
}
100+
101+
func setProfileHeatmapActivityTypes(_ activityTypes: [String]) {
102+
store.setStringArray(activityTypes, forKey: Key.profileHeatmapActivityTypes)
103+
}
95104
}

DevLog/Domain/Entity/TodoQuery.swift

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,21 +5,35 @@
55
// Created by opfic on 2/21/26.
66
//
77

8+
import Foundation
9+
810
struct TodoQuery {
911
let kind: TodoKind?
1012
let keyword: String?
1113
let isPinned: Bool?
14+
let createdAtFrom: Date?
15+
let createdAtTo: Date?
16+
let createdAtDescending: Bool
1217
let pageSize: Int
18+
let fetchAllPages: Bool
1319

1420
init(
1521
kind: TodoKind? = nil,
1622
keyword: String? = nil,
1723
isPinned: Bool? = nil,
18-
pageSize: Int = 20
24+
createdAtFrom: Date? = nil,
25+
createdAtTo: Date? = nil,
26+
createdAtDescending: Bool = true,
27+
pageSize: Int = 20,
28+
fetchAllPages: Bool = false
1929
) {
2030
self.kind = kind
2131
self.keyword = keyword
2232
self.isPinned = isPinned
33+
self.createdAtFrom = createdAtFrom
34+
self.createdAtTo = createdAtTo
35+
self.createdAtDescending = createdAtDescending
2336
self.pageSize = pageSize
37+
self.fetchAllPages = fetchAllPages
2438
}
2539
}

DevLog/Domain/Protocol/UserPreferencesRepository.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,4 +27,7 @@ protocol UserPreferencesRepository {
2727

2828
func pushNotificationUnreadOnly() -> Bool
2929
func setPushNotificationUnreadOnly(_ value: Bool)
30+
31+
func profileHeatmapActivityTypes() -> [String]
32+
func setProfileHeatmapActivityTypes(_ activityTypes: [String])
3033
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
//
2+
// FetchTodosByDateRangeUseCase.swift
3+
// DevLog
4+
//
5+
// Created by opfic on 3/1/26.
6+
//
7+
8+
import Foundation
9+
10+
protocol FetchTodosByDateRangeUseCase {
11+
func execute(from startDate: Date, to endDate: Date) async throws -> [Todo]
12+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
//
2+
// FetchTodosByDateRangeUseCaseImpl.swift
3+
// DevLog
4+
//
5+
// Created by opfic on 3/1/26.
6+
//
7+
8+
import Foundation
9+
10+
final class FetchTodosByDateRangeUseCaseImpl: FetchTodosByDateRangeUseCase {
11+
private let repository: TodoRepository
12+
13+
init(_ repository: TodoRepository) {
14+
self.repository = repository
15+
}
16+
17+
func execute(from startDate: Date, to endDate: Date) async throws -> [Todo] {
18+
let query = TodoQuery(
19+
createdAtFrom: startDate,
20+
createdAtTo: endDate,
21+
pageSize: 100,
22+
fetchAllPages: true
23+
)
24+
let page = try await repository.fetchTodos(query, cursor: nil)
25+
return page.items
26+
}
27+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
//
2+
// FetchProfileHeatmapActivityTypesUseCase.swift
3+
// DevLog
4+
//
5+
// Created by 최윤진 on 3/2/26.
6+
//
7+
8+
protocol FetchProfileHeatmapActivityTypesUseCase {
9+
func execute() -> [String]
10+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
//
2+
// FetchProfileHeatmapActivityTypesUseCaseImpl.swift
3+
// DevLog
4+
//
5+
// Created by 최윤진 on 3/2/26.
6+
//
7+
8+
final class FetchProfileHeatmapActivityTypesUseCaseImpl: FetchProfileHeatmapActivityTypesUseCase {
9+
private let repository: UserPreferencesRepository
10+
11+
init(_ repository: UserPreferencesRepository) {
12+
self.repository = repository
13+
}
14+
15+
func execute() -> [String] {
16+
repository.profileHeatmapActivityTypes()
17+
}
18+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
//
2+
// UpdateProfileHeatmapActivityTypesUseCase.swift
3+
// DevLog
4+
//
5+
// Created by 최윤진 on 3/2/26.
6+
//
7+
8+
protocol UpdateProfileHeatmapActivityTypesUseCase {
9+
func execute(_ activityTypes: [String])
10+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
//
2+
// UpdateProfileHeatmapActivityTypesUseCaseImpl.swift
3+
// DevLog
4+
//
5+
// Created by 최윤진 on 3/2/26.
6+
//
7+
8+
final class UpdateProfileHeatmapActivityTypesUseCaseImpl: UpdateProfileHeatmapActivityTypesUseCase {
9+
private let repository: UserPreferencesRepository
10+
11+
init(_ repository: UserPreferencesRepository) {
12+
self.repository = repository
13+
}
14+
15+
func execute(_ activityTypes: [String]) {
16+
repository.setProfileHeatmapActivityTypes(activityTypes)
17+
}
18+
}

0 commit comments

Comments
 (0)