From 21c8026b94fa852498c4ed2deb8f8fa1d0dcdf0c Mon Sep 17 00:00:00 2001 From: opficdev Date: Fri, 17 Apr 2026 21:09:54 +0900 Subject: [PATCH 1/5] =?UTF-8?q?style:=20Domain=20=EA=B3=84=EC=B8=B5?= =?UTF-8?q?=EC=97=90=EC=84=9C=20=ED=9E=88=ED=8A=B8=EB=A7=B5=20=EA=B4=80?= =?UTF-8?q?=EB=A0=A8=20Profile=20=EC=A0=91=EB=91=90=EC=96=B4=20=EC=A0=9C?= =?UTF-8?q?=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- DevLog/App/Assembler/DomainAssembler.swift | 8 ++++---- DevLog/Domain/Protocol/UserPreferencesRepository.swift | 4 ++-- .../Profile/FetchHeatmapActivityTypesUseCase.swift | 10 ++++++++++ ...wift => FetchHeatmapActivityTypesUseCaseImpl.swift} | 6 +++--- .../FetchProfileHeatmapActivityTypesUseCase.swift | 10 ---------- ...e.swift => UpdateHeatmapActivityTypesUseCase.swift} | 4 ++-- ...ift => UpdateHeatmapActivityTypesUseCaseImpl.swift} | 6 +++--- 7 files changed, 24 insertions(+), 24 deletions(-) create mode 100644 DevLog/Domain/UseCase/UserPreferences/Profile/FetchHeatmapActivityTypesUseCase.swift rename DevLog/Domain/UseCase/UserPreferences/Profile/{FetchProfileHeatmapActivityTypesUseCaseImpl.swift => FetchHeatmapActivityTypesUseCaseImpl.swift} (55%) delete mode 100644 DevLog/Domain/UseCase/UserPreferences/Profile/FetchProfileHeatmapActivityTypesUseCase.swift rename DevLog/Domain/UseCase/UserPreferences/Profile/{UpdateProfileHeatmapActivityTypesUseCase.swift => UpdateHeatmapActivityTypesUseCase.swift} (50%) rename DevLog/Domain/UseCase/UserPreferences/Profile/{UpdateProfileHeatmapActivityTypesUseCaseImpl.swift => UpdateHeatmapActivityTypesUseCaseImpl.swift} (54%) diff --git a/DevLog/App/Assembler/DomainAssembler.swift b/DevLog/App/Assembler/DomainAssembler.swift index 9824e444..920c4965 100644 --- a/DevLog/App/Assembler/DomainAssembler.swift +++ b/DevLog/App/Assembler/DomainAssembler.swift @@ -191,12 +191,12 @@ private extension DomainAssembler { UpdatePushNotificationQueryUseCaseImpl(container.resolve(UserPreferencesRepository.self)) } - container.register(FetchProfileHeatmapActivityTypesUseCase.self) { - FetchProfileHeatmapActivityTypesUseCaseImpl(container.resolve(UserPreferencesRepository.self)) + container.register(FetchHeatmapActivityTypesUseCase.self) { + FetchHeatmapActivityTypesUseCaseImpl(container.resolve(UserPreferencesRepository.self)) } - container.register(UpdateProfileHeatmapActivityTypesUseCase.self) { - UpdateProfileHeatmapActivityTypesUseCaseImpl(container.resolve(UserPreferencesRepository.self)) + container.register(UpdateHeatmapActivityTypesUseCase.self) { + UpdateHeatmapActivityTypesUseCaseImpl(container.resolve(UserPreferencesRepository.self)) } container.register(FetchTodayDisplayOptionsUseCase.self) { diff --git a/DevLog/Domain/Protocol/UserPreferencesRepository.swift b/DevLog/Domain/Protocol/UserPreferencesRepository.swift index 204d7f26..75c26600 100644 --- a/DevLog/Domain/Protocol/UserPreferencesRepository.swift +++ b/DevLog/Domain/Protocol/UserPreferencesRepository.swift @@ -25,8 +25,8 @@ protocol UserPreferencesRepository { func pushNotificationUnreadOnly() -> Bool func setPushNotificationUnreadOnly(_ value: Bool) - func profileHeatmapActivityTypes() -> [String] - func setProfileHeatmapActivityTypes(_ activityTypes: [String]) + func heatmapActivityTypes() -> [String] + func setHeatmapActivityTypes(_ activityTypes: [String]) func todayDisplayOptions() -> TodayDisplayOptions func setTodayDisplayOptions(_ options: TodayDisplayOptions) diff --git a/DevLog/Domain/UseCase/UserPreferences/Profile/FetchHeatmapActivityTypesUseCase.swift b/DevLog/Domain/UseCase/UserPreferences/Profile/FetchHeatmapActivityTypesUseCase.swift new file mode 100644 index 00000000..62fe1a61 --- /dev/null +++ b/DevLog/Domain/UseCase/UserPreferences/Profile/FetchHeatmapActivityTypesUseCase.swift @@ -0,0 +1,10 @@ +// +// FetchHeatmapActivityTypesUseCase.swift +// DevLog +// +// Created by 최윤진 on 3/2/26. +// + +protocol FetchHeatmapActivityTypesUseCase { + func execute() -> [String] +} diff --git a/DevLog/Domain/UseCase/UserPreferences/Profile/FetchProfileHeatmapActivityTypesUseCaseImpl.swift b/DevLog/Domain/UseCase/UserPreferences/Profile/FetchHeatmapActivityTypesUseCaseImpl.swift similarity index 55% rename from DevLog/Domain/UseCase/UserPreferences/Profile/FetchProfileHeatmapActivityTypesUseCaseImpl.swift rename to DevLog/Domain/UseCase/UserPreferences/Profile/FetchHeatmapActivityTypesUseCaseImpl.swift index e7df1677..32b05fd5 100644 --- a/DevLog/Domain/UseCase/UserPreferences/Profile/FetchProfileHeatmapActivityTypesUseCaseImpl.swift +++ b/DevLog/Domain/UseCase/UserPreferences/Profile/FetchHeatmapActivityTypesUseCaseImpl.swift @@ -1,11 +1,11 @@ // -// FetchProfileHeatmapActivityTypesUseCaseImpl.swift +// FetchHeatmapActivityTypesUseCaseImpl.swift // DevLog // // Created by 최윤진 on 3/2/26. // -final class FetchProfileHeatmapActivityTypesUseCaseImpl: FetchProfileHeatmapActivityTypesUseCase { +final class FetchHeatmapActivityTypesUseCaseImpl: FetchHeatmapActivityTypesUseCase { private let repository: UserPreferencesRepository init(_ repository: UserPreferencesRepository) { @@ -13,6 +13,6 @@ final class FetchProfileHeatmapActivityTypesUseCaseImpl: FetchProfileHeatmapActi } func execute() -> [String] { - repository.profileHeatmapActivityTypes() + repository.heatmapActivityTypes() } } diff --git a/DevLog/Domain/UseCase/UserPreferences/Profile/FetchProfileHeatmapActivityTypesUseCase.swift b/DevLog/Domain/UseCase/UserPreferences/Profile/FetchProfileHeatmapActivityTypesUseCase.swift deleted file mode 100644 index 65ee9370..00000000 --- a/DevLog/Domain/UseCase/UserPreferences/Profile/FetchProfileHeatmapActivityTypesUseCase.swift +++ /dev/null @@ -1,10 +0,0 @@ -// -// FetchProfileHeatmapActivityTypesUseCase.swift -// DevLog -// -// Created by 최윤진 on 3/2/26. -// - -protocol FetchProfileHeatmapActivityTypesUseCase { - func execute() -> [String] -} diff --git a/DevLog/Domain/UseCase/UserPreferences/Profile/UpdateProfileHeatmapActivityTypesUseCase.swift b/DevLog/Domain/UseCase/UserPreferences/Profile/UpdateHeatmapActivityTypesUseCase.swift similarity index 50% rename from DevLog/Domain/UseCase/UserPreferences/Profile/UpdateProfileHeatmapActivityTypesUseCase.swift rename to DevLog/Domain/UseCase/UserPreferences/Profile/UpdateHeatmapActivityTypesUseCase.swift index 4f85f287..8dbebe92 100644 --- a/DevLog/Domain/UseCase/UserPreferences/Profile/UpdateProfileHeatmapActivityTypesUseCase.swift +++ b/DevLog/Domain/UseCase/UserPreferences/Profile/UpdateHeatmapActivityTypesUseCase.swift @@ -1,10 +1,10 @@ // -// UpdateProfileHeatmapActivityTypesUseCase.swift +// UpdateHeatmapActivityTypesUseCase.swift // DevLog // // Created by 최윤진 on 3/2/26. // -protocol UpdateProfileHeatmapActivityTypesUseCase { +protocol UpdateHeatmapActivityTypesUseCase { func execute(_ activityTypes: [String]) } diff --git a/DevLog/Domain/UseCase/UserPreferences/Profile/UpdateProfileHeatmapActivityTypesUseCaseImpl.swift b/DevLog/Domain/UseCase/UserPreferences/Profile/UpdateHeatmapActivityTypesUseCaseImpl.swift similarity index 54% rename from DevLog/Domain/UseCase/UserPreferences/Profile/UpdateProfileHeatmapActivityTypesUseCaseImpl.swift rename to DevLog/Domain/UseCase/UserPreferences/Profile/UpdateHeatmapActivityTypesUseCaseImpl.swift index 2a43f1f6..6769416b 100644 --- a/DevLog/Domain/UseCase/UserPreferences/Profile/UpdateProfileHeatmapActivityTypesUseCaseImpl.swift +++ b/DevLog/Domain/UseCase/UserPreferences/Profile/UpdateHeatmapActivityTypesUseCaseImpl.swift @@ -1,11 +1,11 @@ // -// UpdateProfileHeatmapActivityTypesUseCaseImpl.swift +// UpdateHeatmapActivityTypesUseCaseImpl.swift // DevLog // // Created by 최윤진 on 3/2/26. // -final class UpdateProfileHeatmapActivityTypesUseCaseImpl: UpdateProfileHeatmapActivityTypesUseCase { +final class UpdateHeatmapActivityTypesUseCaseImpl: UpdateHeatmapActivityTypesUseCase { private let repository: UserPreferencesRepository init(_ repository: UserPreferencesRepository) { @@ -13,6 +13,6 @@ final class UpdateProfileHeatmapActivityTypesUseCaseImpl: UpdateProfileHeatmapAc } func execute(_ activityTypes: [String]) { - repository.setProfileHeatmapActivityTypes(activityTypes) + repository.setHeatmapActivityTypes(activityTypes) } } From b7e085de995f88f8cb1dee7f0edb2cfc7ea5f8f5 Mon Sep 17 00:00:00 2001 From: opficdev Date: Fri, 17 Apr 2026 21:11:28 +0900 Subject: [PATCH 2/5] =?UTF-8?q?style:=20Data=20=EA=B3=84=EC=B8=B5=EC=97=90?= =?UTF-8?q?=EC=84=9C=20=ED=9E=88=ED=8A=B8=EB=A7=B5=20=EA=B4=80=EB=A0=A8=20?= =?UTF-8?q?Profile=20=EC=A0=91=EB=91=90=EC=96=B4=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Repository/UserPreferencesRepositoryImpl.swift | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/DevLog/Data/Repository/UserPreferencesRepositoryImpl.swift b/DevLog/Data/Repository/UserPreferencesRepositoryImpl.swift index e8f2045d..c8bbdd1a 100644 --- a/DevLog/Data/Repository/UserPreferencesRepositoryImpl.swift +++ b/DevLog/Data/Repository/UserPreferencesRepositoryImpl.swift @@ -15,7 +15,7 @@ final class UserPreferencesRepositoryImpl: UserPreferencesRepository { static let pushSortOrder = "PushNotification.sortOption" static let pushTimeFilter = "PushNotification.timeFilter" static let pushUnreadOnly = "PushNotification.showUnreadOnly" - static let profileHeatmapActivityTypes = "Profile.heatmap.activityTypes" + static let heatmapActivityTypes = "Profile.heatmap.activityTypes" static let todayDueDateVisibility = "Today.dueDateVisibility" static let todayFocusVisibility = "Today.focusVisibility" } @@ -84,12 +84,12 @@ final class UserPreferencesRepositoryImpl: UserPreferencesRepository { store.setBool(value, forKey: Key.pushUnreadOnly) } - func profileHeatmapActivityTypes() -> [String] { - store.stringArray(forKey: Key.profileHeatmapActivityTypes) + func heatmapActivityTypes() -> [String] { + store.stringArray(forKey: Key.heatmapActivityTypes) } - func setProfileHeatmapActivityTypes(_ activityTypes: [String]) { - store.setStringArray(activityTypes, forKey: Key.profileHeatmapActivityTypes) + func setHeatmapActivityTypes(_ activityTypes: [String]) { + store.setStringArray(activityTypes, forKey: Key.heatmapActivityTypes) } func todayDisplayOptions() -> TodayDisplayOptions { From 523a65af86cb4fad8d708efe7f35b23854bc5af2 Mon Sep 17 00:00:00 2001 From: opficdev Date: Fri, 17 Apr 2026 21:12:09 +0900 Subject: [PATCH 3/5] =?UTF-8?q?style:=20Presentation=20=EA=B3=84=EC=B8=B5?= =?UTF-8?q?=EC=97=90=EC=84=9C=20=ED=9E=88=ED=8A=B8=EB=A7=B5=20=EA=B4=80?= =?UTF-8?q?=EB=A0=A8=20Profile=20=EC=A0=91=EB=91=90=EC=96=B4=20=EC=A0=9C?= =?UTF-8?q?=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...tyItem.swift => HeatmapActivityItem.swift} | 6 +- ...fileActivityDay.swift => HeatmapDay.swift} | 4 +- ...ActivityMonth.swift => HeatmapMonth.swift} | 6 +- ...vityQuarter.swift => HeatmapQuarter.swift} | 6 +- .../ViewModel/ProfileViewModel.swift | 86 +++++++++---------- 5 files changed, 54 insertions(+), 54 deletions(-) rename DevLog/Presentation/Structure/Profile/{ProfileActivityItem.swift => HeatmapActivityItem.swift} (86%) rename DevLog/Presentation/Structure/Profile/{ProfileActivityDay.swift => HeatmapDay.swift} (74%) rename DevLog/Presentation/Structure/Profile/{ProfileActivityMonth.swift => HeatmapMonth.swift} (51%) rename DevLog/Presentation/Structure/Profile/{ProfileActivityQuarter.swift => HeatmapQuarter.swift} (51%) diff --git a/DevLog/Presentation/Structure/Profile/ProfileActivityItem.swift b/DevLog/Presentation/Structure/Profile/HeatmapActivityItem.swift similarity index 86% rename from DevLog/Presentation/Structure/Profile/ProfileActivityItem.swift rename to DevLog/Presentation/Structure/Profile/HeatmapActivityItem.swift index 01414f76..24344843 100644 --- a/DevLog/Presentation/Structure/Profile/ProfileActivityItem.swift +++ b/DevLog/Presentation/Structure/Profile/HeatmapActivityItem.swift @@ -1,5 +1,5 @@ // -// ProfileActivityItem.swift +// HeatmapActivityItem.swift // DevLog // // Created by opfic on 3/2/26. @@ -7,7 +7,7 @@ import Foundation -struct ProfileActivityItem: Identifiable, Hashable, Comparable { +struct HeatmapActivityItem: Identifiable, Hashable, Comparable { var id: String { todoId } let todoId: String let title: String @@ -36,7 +36,7 @@ struct ProfileActivityItem: Identifiable, Hashable, Comparable { self.isDeleted = todo.deletedAt != nil } - static func < (lhs: ProfileActivityItem, rhs: ProfileActivityItem) -> Bool { + static func < (lhs: HeatmapActivityItem, rhs: HeatmapActivityItem) -> Bool { lhs.number < rhs.number } } diff --git a/DevLog/Presentation/Structure/Profile/ProfileActivityDay.swift b/DevLog/Presentation/Structure/Profile/HeatmapDay.swift similarity index 74% rename from DevLog/Presentation/Structure/Profile/ProfileActivityDay.swift rename to DevLog/Presentation/Structure/Profile/HeatmapDay.swift index c386d307..ed7b3dae 100644 --- a/DevLog/Presentation/Structure/Profile/ProfileActivityDay.swift +++ b/DevLog/Presentation/Structure/Profile/HeatmapDay.swift @@ -1,5 +1,5 @@ // -// ProfileActivityDay.swift +// HeatmapDay.swift // DevLog // // Created by opfic on 3/2/26. @@ -7,7 +7,7 @@ import Foundation -struct ProfileActivityDay: Hashable { +struct HeatmapDay: Hashable { let date: Date let createdCount: Int let completedCount: Int diff --git a/DevLog/Presentation/Structure/Profile/ProfileActivityMonth.swift b/DevLog/Presentation/Structure/Profile/HeatmapMonth.swift similarity index 51% rename from DevLog/Presentation/Structure/Profile/ProfileActivityMonth.swift rename to DevLog/Presentation/Structure/Profile/HeatmapMonth.swift index c7215c84..49af6186 100644 --- a/DevLog/Presentation/Structure/Profile/ProfileActivityMonth.swift +++ b/DevLog/Presentation/Structure/Profile/HeatmapMonth.swift @@ -1,5 +1,5 @@ // -// ProfileActivityMonth.swift +// HeatmapMonth.swift // DevLog // // Created by opfic on 3/2/26. @@ -7,8 +7,8 @@ import Foundation -struct ProfileActivityMonth: Identifiable, Hashable { +struct HeatmapMonth: Identifiable, Hashable { var id: Date { monthStart } let monthStart: Date - let weeks: [[ProfileActivityDay]] + let weeks: [[HeatmapDay]] } diff --git a/DevLog/Presentation/Structure/Profile/ProfileActivityQuarter.swift b/DevLog/Presentation/Structure/Profile/HeatmapQuarter.swift similarity index 51% rename from DevLog/Presentation/Structure/Profile/ProfileActivityQuarter.swift rename to DevLog/Presentation/Structure/Profile/HeatmapQuarter.swift index 7377e3d9..b2b8f4a4 100644 --- a/DevLog/Presentation/Structure/Profile/ProfileActivityQuarter.swift +++ b/DevLog/Presentation/Structure/Profile/HeatmapQuarter.swift @@ -1,5 +1,5 @@ // -// ProfileActivityQuarter.swift +// HeatmapQuarter.swift // DevLog // // Created by opfic on 3/2/26. @@ -7,8 +7,8 @@ import Foundation -struct ProfileActivityQuarter: Identifiable, Hashable { +struct HeatmapQuarter: Identifiable, Hashable { var id: Date { quarterStart } let quarterStart: Date - let months: [ProfileActivityMonth] + let months: [HeatmapMonth] } diff --git a/DevLog/Presentation/ViewModel/ProfileViewModel.swift b/DevLog/Presentation/ViewModel/ProfileViewModel.swift index 197bf429..0c11e9ec 100644 --- a/DevLog/Presentation/ViewModel/ProfileViewModel.swift +++ b/DevLog/Presentation/ViewModel/ProfileViewModel.swift @@ -21,10 +21,10 @@ final class ProfileViewModel: Store { var selectedQuarterStart: Date? var showQuarterPicker: Bool = false var selectedQuarterPickerYear = Calendar.current.component(.year, from: Date()) - var activityQuarter: ProfileActivityQuarter? - var dayActivitiesByDate: [Date: [ProfileActivityItem]] = [:] + var activityQuarter: HeatmapQuarter? + var dayActivitiesByDate: [Date: [HeatmapActivityItem]] = [:] var selectedActivityKinds: Set = [.created, .completed, .deleted] - var selectedDay: ProfileActivityDay? + var selectedDay: HeatmapDay? var showDoneButton: Bool = false var showAlert: Bool = false var alertTitle: String = "" @@ -41,8 +41,8 @@ final class ProfileViewModel: Store { case fetchUserData(UserProfile) case setActivityQuarter( quarterStart: Date, - quarter: ProfileActivityQuarter, - dayActivitiesByDate: [Date: [ProfileActivityItem]] + quarter: HeatmapQuarter, + dayActivitiesByDate: [Date: [HeatmapActivityItem]] ) case setQuarterPickerPresented(Bool) case setQuarterPickerYear(Int) @@ -51,7 +51,7 @@ final class ProfileViewModel: Store { case moveToCurrentQuarter case moveQuarter(Int) case toggleActivityKind(ActivityKind) - case selectDay(ProfileActivityDay?) + case selectDay(HeatmapDay?) case updateStatusMessage(String) case updateStatusTextFieldFocus(Bool) } @@ -69,8 +69,8 @@ final class ProfileViewModel: Store { private let fetchTodosUseCase: FetchTodosUseCase private let upsertStatusMessageUseCase: UpsertStatusMessageUseCase private let networkConnectivityUseCase: ObserveNetworkConnectivityUseCase - private let fetchHeatmapActivityTypesUseCase: FetchProfileHeatmapActivityTypesUseCase - private let updateHeatmapActivityTypesUseCase: UpdateProfileHeatmapActivityTypesUseCase + private let fetchHeatmapActivityTypesUseCase: FetchHeatmapActivityTypesUseCase + private let updateHeatmapActivityTypesUseCase: UpdateHeatmapActivityTypesUseCase private let widgetCoordinator: HeatmapWidgetSyncCoordinator private let calendar = Calendar.current private let loadingState = LoadingState() @@ -82,8 +82,8 @@ final class ProfileViewModel: Store { fetchTodosUseCase: FetchTodosUseCase, upsertStatusMessageUseCase: UpsertStatusMessageUseCase, networkConnectivityUseCase: ObserveNetworkConnectivityUseCase, - fetchHeatmapActivityTypesUseCase: FetchProfileHeatmapActivityTypesUseCase, - updateHeatmapActivityTypesUseCase: UpdateProfileHeatmapActivityTypesUseCase + fetchHeatmapActivityTypesUseCase: FetchHeatmapActivityTypesUseCase, + updateHeatmapActivityTypesUseCase: UpdateHeatmapActivityTypesUseCase ) { self.fetchUserDataUseCase = fetchUserDataUseCase self.fetchTodosUseCase = fetchTodosUseCase @@ -252,7 +252,7 @@ final class ProfileViewModel: Store { } } -private struct ProfileActivityCounts { +private struct HeatmapActivityCounts { var createdCount = 0 var completedCount = 0 var deletedCount = 0 @@ -269,7 +269,7 @@ private struct ProfileActivityCounts { } } -private struct ProfileActivityEntry { +private struct HeatmapActivityEntry { var todo: Todo var activityKinds: Set } @@ -296,7 +296,7 @@ extension ProfileViewModel { ) } - var selectedDayActivities: [ProfileActivityItem] { + var selectedDayActivities: [HeatmapActivityItem] { guard let selectedDay = state.selectedDay else { return [] } let dayStart = calendar.startOfDay(for: selectedDay.date) let activities = state.dayActivitiesByDate[dayStart] ?? [] @@ -369,9 +369,9 @@ private extension ProfileViewModel { func fetchQuarterActivityData( from quarterStart: Date - ) async throws -> (quarter: ProfileActivityQuarter, dayActivitiesByDate: [Date: [ProfileActivityItem]]) { + ) async throws -> (quarter: HeatmapQuarter, dayActivitiesByDate: [Date: [HeatmapActivityItem]]) { guard let nextQuarterStart = calendar.date(byAdding: .month, value: 3, to: quarterStart) else { - return (ProfileActivityQuarter(quarterStart: quarterStart, months: []), [:]) + return (HeatmapQuarter(quarterStart: quarterStart, months: []), [:]) } async let createdTodoPage = fetchTodosUseCase.execute( @@ -438,9 +438,9 @@ private extension ProfileViewModel { } func makeActivityMonths( - dailyCountsByDate: [Date: ProfileActivityCounts], + dailyCountsByDate: [Date: HeatmapActivityCounts], quarterStart: Date - ) -> [ProfileActivityMonth] { + ) -> [HeatmapMonth] { let monthStarts = (0..<3).compactMap { calendar.date(byAdding: .month, value: $0, to: quarterStart) } @@ -456,27 +456,27 @@ private extension ProfileViewModel { func makeActivityMonth( monthStart: Date, - dailyCountsByDate: [Date: ProfileActivityCounts], + dailyCountsByDate: [Date: HeatmapActivityCounts], calendar: Calendar - ) -> ProfileActivityMonth { + ) -> HeatmapMonth { guard let monthInterval = calendar.dateInterval(of: .month, for: monthStart), let monthLastDay = calendar.date(byAdding: .day, value: -1, to: monthInterval.end), let firstWeekInterval = calendar.dateInterval(of: .weekOfYear, for: monthInterval.start), let lastWeekInterval = calendar.dateInterval(of: .weekOfYear, for: monthLastDay) else { - return ProfileActivityMonth(monthStart: monthStart, weeks: []) + return HeatmapMonth(monthStart: monthStart, weeks: []) } - var days: [ProfileActivityDay] = [] + var days: [HeatmapDay] = [] var cursor = firstWeekInterval.start while cursor < lastWeekInterval.end { let normalizedDate = calendar.startOfDay(for: cursor) let isInMonth = calendar.isDate(normalizedDate, equalTo: monthStart, toGranularity: .month) - let dailyCounts = dailyCountsByDate[normalizedDate] ?? ProfileActivityCounts() + let dailyCounts = dailyCountsByDate[normalizedDate] ?? HeatmapActivityCounts() let createdCount = isInMonth ? dailyCounts.createdCount : 0 let completedCount = isInMonth ? dailyCounts.completedCount : 0 let deletedCount = isInMonth ? dailyCounts.deletedCount : 0 days.append( - ProfileActivityDay( + HeatmapDay( date: normalizedDate, createdCount: createdCount, completedCount: completedCount, @@ -488,7 +488,7 @@ private extension ProfileViewModel { cursor = nextDay } - var weeks: [[ProfileActivityDay]] = [] + var weeks: [[HeatmapDay]] = [] var index = 0 while index < days.count { let endIndex = min(index + 7, days.count) @@ -496,7 +496,7 @@ private extension ProfileViewModel { index += 7 } - return ProfileActivityMonth(monthStart: monthStart, weeks: weeks) + return HeatmapMonth(monthStart: monthStart, weeks: weeks) } func quarterStart(for date: Date) -> Date? { @@ -532,12 +532,12 @@ private extension ProfileViewModel { completedTodos: [Todo], deletedTodos: [Todo], quarterStart: Date - ) -> (quarter: ProfileActivityQuarter, dayActivitiesByDate: [Date: [ProfileActivityItem]]) { - var dailyCountsByDate: [Date: ProfileActivityCounts] = [:] - var activityEntriesByDate: [Date: [String: ProfileActivityEntry]] = [:] + ) -> (quarter: HeatmapQuarter, dayActivitiesByDate: [Date: [HeatmapActivityItem]]) { + var dailyCountsByDate: [Date: HeatmapActivityCounts] = [:] + var activityEntriesByDate: [Date: [String: HeatmapActivityEntry]] = [:] for todo in createdTodos { - appendProfileActivity( + appendHeatmapActivity( todo: todo, kind: .created, occurredAt: todo.createdAt, @@ -548,7 +548,7 @@ private extension ProfileViewModel { for todo in completedTodos { guard let completedAt = todo.completedAt else { continue } - appendProfileActivity( + appendHeatmapActivity( todo: todo, kind: .completed, occurredAt: completedAt, @@ -559,7 +559,7 @@ private extension ProfileViewModel { for todo in deletedTodos { guard let deletedAt = todo.deletedAt else { continue } - appendProfileActivity( + appendHeatmapActivity( todo: todo, kind: .deleted, occurredAt: deletedAt, @@ -568,13 +568,13 @@ private extension ProfileViewModel { ) } - let quarter = ProfileActivityQuarter( + let quarter = HeatmapQuarter( quarterStart: quarterStart, months: makeActivityMonths(dailyCountsByDate: dailyCountsByDate, quarterStart: quarterStart) ) let dayActivitiesByDate = activityEntriesByDate.mapValues { activityEntries in activityEntries.values.compactMap { activityEntry in - ProfileActivityItem( + HeatmapActivityItem( todo: activityEntry.todo, activityKinds: orderedActivityKinds(from: activityEntry.activityKinds) ) @@ -584,23 +584,23 @@ private extension ProfileViewModel { return (quarter, dayActivitiesByDate) } - func appendProfileActivity( + func appendHeatmapActivity( todo: Todo, kind: ActivityKind, occurredAt: Date, - dailyCountsByDate: inout [Date: ProfileActivityCounts], - activityEntriesByDate: inout [Date: [String: ProfileActivityEntry]] + dailyCountsByDate: inout [Date: HeatmapActivityCounts], + activityEntriesByDate: inout [Date: [String: HeatmapActivityEntry]] ) { let dayStart = calendar.startOfDay(for: occurredAt) - var profileActivityCounts = dailyCountsByDate[dayStart] ?? ProfileActivityCounts() - profileActivityCounts.increment(kind) - dailyCountsByDate[dayStart] = profileActivityCounts + var heatmapActivityCounts = dailyCountsByDate[dayStart] ?? HeatmapActivityCounts() + heatmapActivityCounts.increment(kind) + dailyCountsByDate[dayStart] = heatmapActivityCounts var activityEntries = activityEntriesByDate[dayStart] ?? [:] - var profileActivityEntry = activityEntries[todo.id] ?? ProfileActivityEntry(todo: todo, activityKinds: []) - profileActivityEntry.todo = todo - profileActivityEntry.activityKinds.insert(kind) - activityEntries[todo.id] = profileActivityEntry + var heatmapActivityEntry = activityEntries[todo.id] ?? HeatmapActivityEntry(todo: todo, activityKinds: []) + heatmapActivityEntry.todo = todo + heatmapActivityEntry.activityKinds.insert(kind) + activityEntries[todo.id] = heatmapActivityEntry activityEntriesByDate[dayStart] = activityEntries } From e5867f9d23f72601a9032aa55609e0e2075cda75 Mon Sep 17 00:00:00 2001 From: opficdev Date: Fri, 17 Apr 2026 21:12:43 +0900 Subject: [PATCH 4/5] =?UTF-8?q?style:=20UI=20=EA=B3=84=EC=B8=B5=EC=97=90?= =?UTF-8?q?=EC=84=9C=20=ED=9E=88=ED=8A=B8=EB=A7=B5=20=EA=B4=80=EB=A0=A8=20?= =?UTF-8?q?Profile=20=EC=A0=91=EB=91=90=EC=96=B4=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- DevLog/UI/Common/MainView.swift | 4 +- ...ileHeatmapView.swift => HeatmapView.swift} | 38 +++++++++---------- DevLog/UI/Profile/ProfileView.swift | 4 +- 3 files changed, 23 insertions(+), 23 deletions(-) rename DevLog/UI/Profile/{ProfileHeatmapView.swift => HeatmapView.swift} (88%) diff --git a/DevLog/UI/Common/MainView.swift b/DevLog/UI/Common/MainView.swift index 1acfeb9e..b527bd99 100644 --- a/DevLog/UI/Common/MainView.swift +++ b/DevLog/UI/Common/MainView.swift @@ -57,8 +57,8 @@ struct MainView: View { fetchTodosUseCase: container.resolve(FetchTodosUseCase.self), upsertStatusMessageUseCase: container.resolve(UpsertStatusMessageUseCase.self), networkConnectivityUseCase: container.resolve(ObserveNetworkConnectivityUseCase.self), - fetchHeatmapActivityTypesUseCase: container.resolve(FetchProfileHeatmapActivityTypesUseCase.self), - updateHeatmapActivityTypesUseCase: container.resolve(UpdateProfileHeatmapActivityTypesUseCase.self) + fetchHeatmapActivityTypesUseCase: container.resolve(FetchHeatmapActivityTypesUseCase.self), + updateHeatmapActivityTypesUseCase: container.resolve(UpdateHeatmapActivityTypesUseCase.self) )) .tabItem { Image(systemName: "person.crop.circle.fill") diff --git a/DevLog/UI/Profile/ProfileHeatmapView.swift b/DevLog/UI/Profile/HeatmapView.swift similarity index 88% rename from DevLog/UI/Profile/ProfileHeatmapView.swift rename to DevLog/UI/Profile/HeatmapView.swift index 6b862733..35ac46b3 100644 --- a/DevLog/UI/Profile/ProfileHeatmapView.swift +++ b/DevLog/UI/Profile/HeatmapView.swift @@ -1,5 +1,5 @@ // -// ProfileHeatmapView.swift +// HeatmapView.swift // DevLog // // Created by 최윤진 on 3/2/26. @@ -7,16 +7,16 @@ import SwiftUI -struct ProfileHeatmapView: View { +struct HeatmapView: View { @Environment(\.safeAreaInsets) private var safeAreaInsets @Environment(\.sceneWidth) private var sceneWidth - let quarter: ProfileActivityQuarter + let quarter: HeatmapQuarter let selectedActivityKinds: Set - let selectedDay: ProfileActivityDay? - let onSelectDay: (ProfileActivityDay) -> Void + let selectedDay: HeatmapDay? + let onSelectDay: (HeatmapDay) -> Void var body: some View { - let layout = ProfileHeatmapLayout( + let layout = HeatmapLayout( availableWidth: availableWidth, weekCounts: quarter.months.map(\.weeks.count) ) @@ -40,7 +40,7 @@ struct ProfileHeatmapView: View { } @ViewBuilder - private func weekdayLabel(layout: ProfileHeatmapLayout) -> some View { + private func weekdayLabel(layout: HeatmapLayout) -> some View { let labels: [Int: String] = [ 2: String(localized: "profile_weekday_mon"), 4: String(localized: "profile_weekday_wed"), @@ -76,7 +76,7 @@ struct ProfileHeatmapView: View { .padding(.top, layout.weekdayTopPadding) } - private func smallestWeekdayLabelFontSize(labels: [String], layout: ProfileHeatmapLayout) -> CGFloat { + private func smallestWeekdayLabelFontSize(labels: [String], layout: HeatmapLayout) -> CGFloat { let captionFont = UIFont.preferredFont(forTextStyle: .caption2) let availableWidth = max(layout.cellSize, 1) @@ -113,7 +113,7 @@ struct ProfileHeatmapView: View { .max() ?? 0 } - private func dayCount(for day: ProfileActivityDay) -> Int { + private func dayCount(for day: HeatmapDay) -> Int { var value = 0 if selectedActivityKinds.contains(.created) { value += day.createdCount @@ -128,7 +128,7 @@ struct ProfileHeatmapView: View { } } -private struct ProfileHeatmapLayout { +private struct HeatmapLayout { let cellSize: CGFloat let cellSpacing: CGFloat = 4 let monthSpacing: CGFloat = 12 @@ -160,12 +160,12 @@ private struct ProfileHeatmapLayout { private struct MonthCompactHeatmapView: View { @Environment(\.colorScheme) private var colorScheme - let month: ProfileActivityMonth + let month: HeatmapMonth let maxCount: Int - let layout: ProfileHeatmapLayout + let layout: HeatmapLayout let selectedActivityKinds: Set - let selectedDay: ProfileActivityDay? - let onSelectDay: (ProfileActivityDay) -> Void + let selectedDay: HeatmapDay? + let onSelectDay: (HeatmapDay) -> Void private let orderedWeekdays = Array(1...7) var body: some View { @@ -207,23 +207,23 @@ private struct MonthCompactHeatmapView: View { } } - private func isSelected(_ day: ProfileActivityDay?) -> Bool { + private func isSelected(_ day: HeatmapDay?) -> Bool { guard let day, let selectedDay, day.isVisible else { return false } return Calendar.current.isDate(day.date, inSameDayAs: selectedDay.date) } - private func selectionInnerBorderColor(for day: ProfileActivityDay?) -> Color { + private func selectionInnerBorderColor(for day: HeatmapDay?) -> Color { isSelected(day) ? .white : .clear } - private func selectionOuterBorderColor(for day: ProfileActivityDay?) -> Color { + private func selectionOuterBorderColor(for day: HeatmapDay?) -> Color { if isSelected(day) && colorScheme == .light { return Color.gray } return .clear } - private func fillColor(for day: ProfileActivityDay?, with maxCount: Int) -> Color { + private func fillColor(for day: HeatmapDay?, with maxCount: Int) -> Color { guard let day, day.isVisible else { return .clear } let count = dayCount(for: day) if count == 0 { @@ -232,7 +232,7 @@ private struct MonthCompactHeatmapView: View { return Color.blue.opacity(opacity(for: count, max: maxCount)) } - private func dayCount(for day: ProfileActivityDay) -> Int { + private func dayCount(for day: HeatmapDay) -> Int { var value = 0 if selectedActivityKinds.contains(.created) { value += day.createdCount diff --git a/DevLog/UI/Profile/ProfileView.swift b/DevLog/UI/Profile/ProfileView.swift index 9723059b..947f612f 100644 --- a/DevLog/UI/Profile/ProfileView.swift +++ b/DevLog/UI/Profile/ProfileView.swift @@ -155,7 +155,7 @@ struct ProfileView: View { quarterNavigator if let quarter = viewModel.state.activityQuarter { - ProfileHeatmapView( + HeatmapView( quarter: quarter, selectedActivityKinds: viewModel.state.selectedActivityKinds, selectedDay: viewModel.state.selectedDay, @@ -332,7 +332,7 @@ struct ProfileView: View { } @ViewBuilder - private func selectedDayDetailSection(for day: ProfileActivityDay) -> some View { + private func selectedDayDetailSection(for day: HeatmapDay) -> some View { let activities = viewModel.selectedDayActivities VStack(alignment: .leading, spacing: 12) { From ceadf6e31e4ad54e43a8eae014a3fa6048cde008 Mon Sep 17 00:00:00 2001 From: opficdev Date: Fri, 17 Apr 2026 21:21:59 +0900 Subject: [PATCH 5/5] =?UTF-8?q?docs:=20=EC=84=A4=EB=AA=85=20=EC=A3=BC?= =?UTF-8?q?=EC=84=9D=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/pull_request_template.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index fec87575..cca6ad61 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -1,6 +1,6 @@ ## 🔗 연관된 이슈 -> 이슈 번호를 입력해주세요. (예: #12) -> 이슈가 완전히 해결되었다면 아래에 예약어를 남겨주세요. + + - closed #이슈번호 ## 📝 작업 내용