Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[CAT-289] 집중 시간 저장 #47

Merged
merged 14 commits into from
Aug 21, 2024
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
33 changes: 33 additions & 0 deletions Projects/Domain/AppService/Sources/AppService.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

import Logger
import DatabaseClientInterface
import UserDefaultsClientInterface

import RealmSwift

Expand All @@ -32,3 +33,35 @@ public func initilizeDatabaseSystem(

try await databaseClient.initialize(configuration)
}


let isDisturbAlarmOnKey = "mohanyang_userdefaults_isDisturmAlarmOnKey"

public func setDisturbAlarm(
userDefaultsClient: UserDefaultsClient,
isEnabled: Bool
) async -> Void {
await userDefaultsClient.setBool(isEnabled, isDisturbAlarmOnKey)
}

public func getDisturbAlarm(
userDefaultsClient: UserDefaultsClient
) -> Bool {
return userDefaultsClient.boolForKey(isDisturbAlarmOnKey)
}


let isTimerAlarmOnKey = "mohanyang_userdefaults_isTimerAlarmOnKey"

public func setTimerAlarm(
userDefaultsClient: UserDefaultsClient,
isEnabled: Bool
) async -> Void {
await userDefaultsClient.setBool(isEnabled, isTimerAlarmOnKey)
}

public func getTimerAlarm(
userDefaultsClient: UserDefaultsClient
) -> Bool {
return userDefaultsClient.boolForKey(isTimerAlarmOnKey)
}
16 changes: 16 additions & 0 deletions Projects/Domain/CatService/Interface/Model/CatFactory.swift
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ public struct AnyCat: CatFactoryProtocol, Identifiable, Equatable {
public var focusEndPushTitle: String { base.focusEndPushTitle }
public var restEndPushTitle: String { base.restEndPushTitle }
public var disturbPushTitle: String { base.disturbPushTitle }
public var tooltipMessage: String { base.tooltipMessage }

public static func == (lhs: AnyCat, rhs: AnyCat) -> Bool {
lhs.base.id == rhs.base.id
Expand All @@ -56,6 +57,11 @@ public struct CheeseCat: CatFactoryProtocol {
public var focusEndPushTitle: String = "집중이 끝났다냥! 이제 나랑 놀아달라냥"
public var restEndPushTitle: String = "이제 다시 집중해볼까냥?"
public var disturbPushTitle: String = "날 두고 어디갔냥.."

public var tooltipMessage: String {
let messages = ["나랑 함께할 시간이다냥!", "자주 와서 쓰다듬어 달라냥", "집중이 잘 될 거 같다냥"]
return messages.randomElement() ?? ""
}
}

// MARK: BLACK CAT
Expand All @@ -76,6 +82,11 @@ public struct BlackCat: CatFactoryProtocol {
public var focusEndPushTitle: String = "집중이 끝났다냥! 이제 나랑 놀아달라냥"
public var restEndPushTitle: String = "이제 다시 집중해볼까냥?"
public var disturbPushTitle: String = "날 두고 어디갔냥.."

public var tooltipMessage: String {
let messages = ["나랑 함께할 시간이다냥!", "자주 와서 쓰다듬어 달라냥", "집중이 잘 될 거 같다냥"]
return messages.randomElement() ?? ""
}
}

// MARK: THREE_COLOR CAT
Expand All @@ -96,6 +107,11 @@ public struct ThreeColorCat: CatFactoryProtocol {
public var focusEndPushTitle: String = "집중이 끝났다냥! 원하는 만큼 집중했냥?"
public var restEndPushTitle: String = "집중할 시간이다냥! 빨리 들어오라냥"
public var disturbPushTitle: String = "지금 뭐하고 있냥? 내가 감시하고 있다냥"

public var tooltipMessage: String {
let messages = ["\"시간이 없어서\"는 변명이다냥", "휴대폰 그만보고 집중하라냥", "기회란 금새 왔다 사라진다냥"]
return messages.randomElement() ?? ""
}
}

// MARK: MAKE CAT
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,5 @@ public protocol CatFactoryProtocol {
var focusEndPushTitle: String { get }
var restEndPushTitle: String { get }
var disturbPushTitle: String { get }
var tooltipMessage: String { get }
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ public struct FocusTimeHistory: Encodable, Persistable {
let doneAt: Date

public init(
clientFocusTimeId: String,
clientFocusTimeId: String = UUID().uuidString,
categoryNo: Int,
focusedTime: String,
restedTime: String,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,16 @@ extension PomodoroCategory {
let dateComponents = DateComponents.durationFrom8601String(restTime)
return dateComponents?.minute ?? 0
}

public var focusTimeSeconds: Int {
let dateComponents = DateComponents.durationFrom8601String(focusTime)
return (dateComponents?.minute ?? 0) * 60
}

public var restTimeSeconds: Int {
let dateComponents = DateComponents.durationFrom8601String(restTime)
return (dateComponents?.minute ?? 0) * 60
}
}

public enum PomodoroCategoryCode: String, PersistableEnum, Codable {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,7 @@ public struct PomodoroService {
public var changeSelectedCategory: @Sendable (_ userDefaultsClient: UserDefaultsClient, _ categoryID: Int) async -> Void
public var getSelectedCategory: @Sendable (_ userDefaultsClient: UserDefaultsClient, _ databaseClient: DatabaseClient) async throws -> PomodoroCategory?
public var changeCategoryTime: @Sendable (_ apiClient: APIClient, _ categoryID: Int, _ request: EditCategoryRequest) async throws -> Void

public var saveFocusTimeHistory: @Sendable (_ apiClient: APIClient, _ databaseClinet: DatabaseClient, _ request: [FocusTimeHistory]) async throws -> Void
public var saveFocusTimeHistory: @Sendable (_ apiClient: APIClient, _ databaseClient: DatabaseClient, _ request: [FocusTimeHistory]) async throws -> Void
public var getFocusTimeSummaries: @Sendable (_ apiClient: APIClient) async throws -> FocusTimeSummary
}

Expand Down
4 changes: 2 additions & 2 deletions Projects/Domain/PomodoroService/Sources/PomodoroService.swift
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,11 @@ extension PomodoroService: DependencyKey {
_ = try await apiClient.apiRequest(request: api, as: EmptyResponse.self)
},
saveFocusTimeHistory: { apiClient, databaseClient, request in
let api = FocusTimeAPI.saveFocusTimes(request: request)
_ = try await apiClient.apiRequest(request: api, as: EmptyResponse.self)
for focusTime in request {
try await databaseClient.create(object: focusTime)
}
let api = FocusTimeAPI.saveFocusTimes(request: request)
_ = try await apiClient.apiRequest(request: api, as: EmptyResponse.self)
},
getFocusTimeSummaries: { apiClient in
let api = FocusTimeAPI.getSummaries
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,9 @@ public struct NamingCatView: View {
VStack(spacing: 40) {
Spacer()

ZStack {
Rectangle()
.foregroundStyle(Alias.Color.Background.secondary)
store.catRiv.view()
.setTooltipTarget(tooltip: DownDirectionTooltip.self)
}
.frame(height: 240)
store.catRiv.view()
.setTooltipTarget(tooltip: DownDirectionTooltip.self)
.frame(maxHeight: 240)

VStack(spacing: Alias.Spacing.small) {
HStack {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,15 +42,11 @@ public struct SelectCatView: View {
}

Spacer(minLength: Alias.Spacing.xLarge)

VStack(spacing: Alias.Spacing.small) {
CatPushNotificationExampleView(selectedCat: $store.selectedCat)
ZStack {
Rectangle()
.foregroundStyle(Alias.Color.Background.secondary)
store.catRiv.view()
}
.frame(maxHeight: 240)
store.catRiv.view()
.frame(maxHeight: 240)
}

Spacer(minLength: Alias.Spacing.large)
Expand Down
44 changes: 42 additions & 2 deletions Projects/Feature/HomeFeature/Sources/Home/HomeCore.swift
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ public struct HomeCore {
}

case .setHomeCatTooltip:
state.homeCatTooltip = .init(title: "오랜만이다냥") // TODO: - 문구 랜덤변경하기
state.homeCatTooltip = .init(title: state.selectedCat.tooltipMessage)
return .none

case let .setHomeCategoryGuideTooltip(tooltip):
Expand Down Expand Up @@ -207,10 +207,30 @@ public struct HomeCore {

case .timeSelect:
return .none

case .myPage:
return .none

case let .focusPomodoro(.presented(.saveHistory(focusTimeBySeconds, restTimeBySeconds))), // FocusPomodoro
let .focusPomodoro(.presented(.restWaiting(.presented(.saveHistory(focusTimeBySeconds, restTimeBySeconds))))), // RestWaiting
let .focusPomodoro(.presented(.restWaiting(.presented(.restPomodoro(.presented(.saveHistory(focusTimeBySeconds, restTimeBySeconds))))))): // RestPomodoro
guard let selectedCategoryID = state.selectedCategory?.id else { return .none }
if focusTimeBySeconds >= 60 {
return .run { _ in
try await self.saveFocusTime(
selectedCategoryID: selectedCategoryID,
focusTimeBySeconds: focusTimeBySeconds,
restTimeBySeconds: restTimeBySeconds
)
}
} else {
state.toast = DefaultToast(
message: "최소 1분 이상은 집중해야 기록돼요",
image: DesignSystemAsset.Image._24Clock.swiftUIImage
)
return .none
}

case .focusPomodoro(.presented(.restWaiting(.presented(.goToHomeByOver60Minute)))):
state.focusPomodoro = nil
state.dialog = DefaultDialog(
Expand All @@ -230,4 +250,24 @@ public struct HomeCore {
return .none
}
}

func saveFocusTime(
selectedCategoryID: Int,
focusTimeBySeconds: Int,
restTimeBySeconds: Int
) async throws -> Void {
let focusedTime = DateComponents(minute: focusTimeBySeconds / 60, second: focusTimeBySeconds % 60).to8601DurationString()
let restedTime = DateComponents(minute: restTimeBySeconds / 60, second: restTimeBySeconds % 60).to8601DurationString()
let request = FocusTimeHistory(
categoryNo: selectedCategoryID,
focusedTime: focusedTime,
restedTime: restedTime,
doneAt: Date()
)
try await self.pomodoroService.saveFocusTimeHistory(
apiClient: self.apiClient,
databaseClient: self.databaseClient,
request: [request]
)
}
}
21 changes: 7 additions & 14 deletions Projects/Feature/HomeFeature/Sources/Home/HomeView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,7 @@ public struct HomeView: View {

public var body: some View {
NavigationContainer(
leading: {
Spacer()
},
leading: { Spacer() },
trailing: {
Button(
icon: DesignSystemAsset.Image._24MenuPrimary.swiftUIImage,
Expand All @@ -40,17 +38,12 @@ public struct HomeView: View {
) {
VStack(spacing: 40) {
VStack(spacing: Alias.Spacing.xLarge) {

ZStack {
Rectangle()
.fill(Alias.Color.Background.secondary)
store.catRiv.view()
.setTooltipTarget(tooltip: HomeCatDialogueTooltip.self)
.onTapGesture {
store.catRiv.triggerInput(store.selectedCat.rivTriggerName)
}
}
.frame(width: 240, height: 240)
store.catRiv.view()
.setTooltipTarget(tooltip: HomeCatDialogueTooltip.self)
.onTapGesture {
store.catRiv.triggerInput(store.selectedCat.rivTriggerName)
}
.frame(width: 240, height: 240)

Text("치즈냥")
.font(Typography.header4)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,5 @@ public struct HomeCatDialogueTooltip: Tooltip {

public var targetCornerRadius: CGFloat? { nil }

public var padding: CGFloat { -12 }
public var padding: CGFloat { -30 }
}
18 changes: 11 additions & 7 deletions Projects/Feature/MyPageFeature/Sources/MyPage/MyPageCore.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import UserServiceInterface
import CatServiceInterface
import UserDefaultsClientInterface
import NetworkTrackingInterface
import AppService

import ComposableArchitecture

Expand Down Expand Up @@ -41,9 +42,6 @@ public struct MyPageCore {
@Dependency(APIClient.self) var apiClient
@Dependency(UserService.self) var userService
@Dependency(UserDefaultsClient.self) var userDefaultsClient
@Dependency(NetworkTracking.self) var networkTracking
let isTimerAlarmOnKey = "mohanyang_userdefaults_isTimerAlarmOnKey"
let isDisturbAlarmOnKey = "mohanyang_userdefaults_isDisturmAlarmOnKey"

public init() {}

Expand All @@ -58,8 +56,8 @@ public struct MyPageCore {
private func core(state: inout State, action: Action) -> EffectOf<Self> {
switch action {
case .onAppear:
state.isTimerAlarmOn = userDefaultsClient.boolForKey(isTimerAlarmOnKey)
state.isDisturbAlarmOn = userDefaultsClient.boolForKey(isDisturbAlarmOnKey)
state.isTimerAlarmOn = getTimerAlarm(userDefaultsClient: self.userDefaultsClient)
state.isDisturbAlarmOn = getDisturbAlarm(userDefaultsClient: self.userDefaultsClient)
return .run { send in
let data = try await userService.getUserInfo(apiClient: apiClient)
await send(._responseUserInfo(data))
Expand Down Expand Up @@ -94,12 +92,18 @@ public struct MyPageCore {

case .binding(\.isTimerAlarmOn):
return .run { [isTimerAlarmOn = state.isTimerAlarmOn] _ in
await userDefaultsClient.setBool(isTimerAlarmOn, isTimerAlarmOnKey)
await setTimerAlarm(
userDefaultsClient: self.userDefaultsClient,
isEnabled: isTimerAlarmOn
)
}

case .binding(\.isDisturbAlarmOn):
return .run { [isDisturbAlarmOn = state.isDisturbAlarmOn] _ in
await userDefaultsClient.setBool(isDisturbAlarmOn, isDisturbAlarmOnKey)
await setDisturbAlarm(
userDefaultsClient: self.userDefaultsClient,
isEnabled: isDisturbAlarmOn
)
}

case .binding:
Expand Down
Loading
Loading