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-274] NetworkTracking 모듈 및 마이페이지 오프라인 대응 #48

Merged
merged 6 commits into from
Aug 21, 2024
Merged
Show file tree
Hide file tree
Changes from 5 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
Binary file modified DependencyGraph/mohanyang_dev_graph.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified DependencyGraph/mohanyang_prod_graph.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,5 @@ public enum Domain: String, Modulable {
case UserService
case CatService
case PomodoroService
case NetworkTracking
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
//
// NetworkTrackingInterface.swift
// NetworkTracking
//
// Created by 김지현 on 8/21/24.
//

import Foundation
import Network

import Dependencies
import DependenciesMacros

@DependencyClient
public struct NetworkTracking {
//public var start: @Sendable () -> Void
public var updateNetworkConnected: @Sendable () -> AsyncStream<Bool> = { .never }
//public var cancel: @Sendable () -> Void
}

extension NetworkTracking: TestDependencyKey {
public static let previewValue = Self()
public static let testValue = Self()
}
20 changes: 20 additions & 0 deletions Projects/Domain/NetworkTracking/Project.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import ProjectDescription
import ProjectDescriptionHelpers

@_spi(Domain)
@_spi(Core)
import DependencyPlugin

let project: Project = .makeTMABasedProject(
module: Domain.NetworkTracking,
scripts: [],
targets: [
.sources,
.interface
],
dependencies: [
.interface: [
.dependency(rootModule: Core.self)
]
]
)
41 changes: 41 additions & 0 deletions Projects/Domain/NetworkTracking/Sources/NetworkTracking.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
//
// NetworkTracking.swift
// NetworkTracking
//
// Created by 김지현 on 8/21/24.
//

import Foundation
import Network

import NetworkTrackingInterface

import Dependencies

extension NetworkTracking: DependencyKey {
public static let liveValue: NetworkTracking = .live()

public static func live() -> NetworkTracking {
let networkMonitor = NWPathMonitor()
let globalQueue = DispatchQueue.global()

return NetworkTracking(
updateNetworkConnected: {
networkMonitor.start(queue: globalQueue)
return AsyncStream<Bool> { continuation in
let initialState = networkMonitor.currentPath.status == .satisfied ? true : false
continuation.yield(initialState)

networkMonitor.pathUpdateHandler = { path in
let isConnected = path.status == .satisfied ? true : false
continuation.yield(isConnected)
}

continuation.onTermination = { _ in
networkMonitor.cancel()
}
}
}
)
}
}
11 changes: 11 additions & 0 deletions Projects/Feature/CatFeature/Sources/NamingCat/NamingCatCore.swift
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ public struct NamingCatCore {
var route: Route
var selectedCat: AnyCat
var text: String = ""
var isButtonDisabled: Bool = false
var inputFieldError: NamingCatError?
var tooltip: DownDirectionTooltip? = .init()
var catRiv: RiveViewModel = Rive.catSelectRiv(stateMachineName: "State Machine_selectCat")
Expand Down Expand Up @@ -62,6 +63,9 @@ public struct NamingCatCore {

switch action {
case .onAppear:
if state.route == .myPage {
state.isButtonDisabled = true
}
state.catRiv.stop()
state.catRiv.triggerInput(state.selectedCat.rivTriggerName)
return .none
Expand Down Expand Up @@ -99,6 +103,13 @@ public struct NamingCatCore {

case .binding(\.text):
state.inputFieldError = setError(state.text)
if state.text == "" && state.route == .myPage {
state.isButtonDisabled = true
} else if state.inputFieldError != nil {
state.isButtonDisabled = true
} else if state.inputFieldError == nil {
state.isButtonDisabled = false
}
return .none

case .binding:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ public struct NamingCatView: View {
store.catRiv.view()
.setTooltipTarget(tooltip: DownDirectionTooltip.self)
}
.frame(maxHeight: 240)
.frame(height: 240)

VStack(spacing: Alias.Spacing.small) {
HStack {
Expand All @@ -57,7 +57,7 @@ public struct NamingCatView: View {
store.send(.namedButtonTapped)
}
.buttonStyle(.box(level: .primary, size: .large, width: .low))
.disabled(store.inputFieldError != nil)
.disabled(store.isButtonDisabled)
.padding(.bottom, Alias.Spacing.small)
}
.padding(.horizontal, Alias.Spacing.xLarge)
Expand Down
17 changes: 16 additions & 1 deletion Projects/Feature/MyPageFeature/Sources/MyPage/MyPageCore.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import APIClientInterface
import UserServiceInterface
import CatServiceInterface
import UserDefaultsClientInterface
import NetworkTrackingInterface

import ComposableArchitecture

Expand All @@ -22,22 +23,25 @@ public struct MyPageCore {
var cat: AnyCat? = nil
var isTimerAlarmOn: Bool = false
var isDisturbAlarmOn: Bool = false
var isInternetConnected: Bool = false
var isNetworkConnected: Bool = false
let feedbackURLString: String = "https://forms.gle/wEUPH9Tvxgua4hCZ9"
@Presents var myCat: MyCatCore.State?
}

public enum Action: BindableAction {
case onAppear
case task
case myCatDetailTapped
case _responseUserInfo(UserDTO.Response.GetUserInfoResponseDTO)
case _fetchNetworkConntection(Bool)
case myCat(PresentationAction<MyCatCore.Action>)
case binding(BindingAction<State>)
}

@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"

Expand All @@ -61,6 +65,13 @@ public struct MyPageCore {
await send(._responseUserInfo(data))
}

case .task:
return .run { send in
for await isConnected in networkTracking.updateNetworkConnected() {
await send(._fetchNetworkConntection(isConnected))
}
}

case .myCatDetailTapped:
guard let cat = state.cat else { return .none }
state.myCat = MyCatCore.State(cat: cat)
Expand All @@ -74,6 +85,10 @@ public struct MyPageCore {
)
return .none

case ._fetchNetworkConntection(let isConntected):
state.isNetworkConnected = isConntected
return .none

case .myCat:
return .none

Expand Down
39 changes: 25 additions & 14 deletions Projects/Feature/MyPageFeature/Sources/MyPage/MyPageView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@ import ComposableArchitecture

public struct MyPageView: View {
@Bindable var store: StoreOf<MyPageCore>

public init(store: StoreOf<MyPageCore>) {
self.store = store
}

public var body: some View {
NavigationContainer(
title: Text("마이페이지"),
Expand All @@ -27,17 +27,22 @@ public struct MyPageView: View {
ScrollView {
VStack(spacing: Alias.Spacing.medium) {

MyCatSectionView(name: store.cat?.name ?? "")
.padding(.all, Alias.Spacing.xLarge)
.background(
RoundedRectangle(cornerRadius: Alias.BorderRadius.small)
.foregroundStyle(Alias.Color.Background.secondary)
)
.onTapGesture {
MyCatSectionView(
name: store.cat?.name ?? "",
isNetworkConntected: $store.isNetworkConnected
)
.padding(.all, Alias.Spacing.xLarge)
.background(
RoundedRectangle(cornerRadius: Alias.BorderRadius.small)
.foregroundStyle(Alias.Color.Background.secondary)
)
.onTapGesture {
if store.isNetworkConnected {
store.send(.myCatDetailTapped)
}
}

StatisticSectionView(isInternetConnected: $store.isInternetConnected)
StatisticSectionView(isNetworkConnected: $store.isNetworkConnected)
.padding(.all, Alias.Spacing.xLarge)
.background(
RoundedRectangle(cornerRadius: Alias.BorderRadius.medium)
Expand Down Expand Up @@ -89,6 +94,9 @@ public struct MyPageView: View {
) { store in
MyCatView(store: store)
}
.task {
await store.send(.task).finish()
}
.onAppear {
store.send(.onAppear)
}
Expand All @@ -103,6 +111,7 @@ public struct MyPageView: View {

struct MyCatSectionView: View {
let name: String
@Binding var isNetworkConntected: Bool

var body: some View {
HStack {
Expand All @@ -115,19 +124,21 @@ struct MyCatSectionView: View {
.foregroundStyle(Color.black)
}
Spacer()
DesignSystemAsset.Image._24ChevronRightPrimary.swiftUIImage
if isNetworkConntected {
DesignSystemAsset.Image._24ChevronRightPrimary.swiftUIImage
}
}
}
}

struct StatisticSectionView: View {
@Binding var isInternetConnected: Bool
@Binding var isNetworkConnected: Bool

var body: some View {
ZStack {
VStack(spacing: Alias.Spacing.medium) {
Spacer()
if isInternetConnected {
if isNetworkConnected {
DesignSystemAsset.Image.imgUpdateStatistics.swiftUIImage
} else {
DesignSystemAsset.Image.imgOfflineStatistics.swiftUIImage
Expand All @@ -153,7 +164,7 @@ struct AlarmSectionView: View {
let title: String
let subTitle: String
@Binding var isOn: Bool

var body: some View {
HStack(spacing: 0) {
VStack(alignment: .leading, spacing: Alias.Spacing.xSmall) {
Expand Down
Loading