Skip to content

Commit

Permalink
[feat] #154 PokitSplit ์ž‘์„ฑ
Browse files Browse the repository at this point in the history
  • Loading branch information
ShapeKim98 committed Oct 24, 2024
1 parent 517a208 commit 6d5e154
Show file tree
Hide file tree
Showing 2 changed files with 289 additions and 0 deletions.
220 changes: 220 additions & 0 deletions Projects/App/Sources/MainTabSplit/Pokit/PokitSplitFeature.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,220 @@
//
// PokitSplitFeature.swift
// App
//
// Created by ๊น€๋„ํ˜• on 10/24/24.

import ComposableArchitecture
import FeaturePokit
import FeatureCategoryDetail
import FeatureCategorySetting
import FeatureCategorySharing
import FeatureSetting
import FeatureContentSetting
import FeatureContentDetail
import FeatureRemind
import FeatureContentDetail
import Domain
import Util

@Reducer
public struct PokitSplitFeature {
/// - Dependency

/// - State
@ObservableState
public struct State: Equatable {
var ํฌํ‚ท: PokitRootFeature.State = .init()
var ์นดํ…Œ๊ณ ๋ฆฌ์ƒ์„ธ: CategoryDetailFeature.State?
var ๋งํฌ์ถ”๊ฐ€๋ฐ์ˆ˜์ •: ContentSettingFeature.State = .init()

@Presents
var ํฌํ‚ท์ถ”๊ฐ€๋ฐ์ˆ˜์ •: PokitCategorySettingFeature.State?
@Presents
var ๊ฒ€์ƒ‰: PokitSearchFeature.State?
@Presents
var ์„ค์ •: PokitSettingFeature.State?
@Presents
var ๋งํฌ์ƒ์„ธ: ContentDetailFeature.State?

@Shared(.inMemory("SelectCategory"))
var categoryId: Int?
@Shared(.inMemory("PushTapped"))
var isPushTapped: Bool = false

public init() {}
}

/// - Action
public enum Action: FeatureAction, ViewAction {
case view(View)
case inner(InnerAction)
case async(AsyncAction)
case scope(ScopeAction)
case delegate(DelegateAction)
case ํฌํ‚ท(PokitRootFeature.Action)
case ์นดํ…Œ๊ณ ๋ฆฌ์ƒ์„ธ(CategoryDetailFeature.Action)
case ๋งํฌ์ถ”๊ฐ€๋ฐ์ˆ˜์ •(ContentSettingFeature.Action)
case ํฌํ‚ท์ถ”๊ฐ€๋ฐ์ˆ˜์ •(PokitCategorySettingFeature.Action)
case ๊ฒ€์ƒ‰(PokitSearchFeature.Action)
case ์„ค์ •(PokitSettingFeature.Action)
case ๋งํฌ์ƒ์„ธ(ContentDetailFeature.Action)

@CasePathable
public enum View: Equatable {
case ๋ทฐ๊ฐ€_๋‚˜ํƒ€๋‚ฌ์„๋•Œ
}

public enum InnerAction: Equatable {
case ์นดํ…Œ๊ณ ๋ฆฌ_์ƒ์„ธ_ํ™œ์„ฑํ™”(BaseCategoryItem)
}

public enum AsyncAction: Equatable { case doNothing }

public enum ScopeAction {
case ํฌํ‚ท(PokitRootFeature.Action)
case ์นดํ…Œ๊ณ ๋ฆฌ์ƒ์„ธ(CategoryDetailFeature.Action)
case ๋งํฌ์ถ”๊ฐ€๋ฐ์ˆ˜์ •(ContentSettingFeature.Action)
case ํฌํ‚ท์ถ”๊ฐ€๋ฐ์ˆ˜์ •(PokitCategorySettingFeature.Action)
case ๊ฒ€์ƒ‰(PokitSearchFeature.Action)
case ์„ค์ •(PokitSettingFeature.Action)
case ๋งํฌ์ƒ์„ธ(ContentDetailFeature.Action)
}

public enum DelegateAction: Equatable { case ์—†์Œ }
}

/// - Initiallizer
public init() {}

/// - Reducer Core
private func core(into state: inout State, action: Action) -> Effect<Action> {
switch action {
/// - View
case .view(let viewAction):
return handleViewAction(viewAction, state: &state)

/// - Inner
case .inner(let innerAction):
return handleInnerAction(innerAction, state: &state)

/// - Async
case .async(let asyncAction):
return handleAsyncAction(asyncAction, state: &state)

/// - Scope
case .scope(let scopeAction):
return handleScopeAction(scopeAction, state: &state)

/// - Delegate
case .delegate(let delegateAction):
return handleDelegateAction(delegateAction, state: &state)
case .ํฌํ‚ท(let pokitAction):
return .send(.scope(.ํฌํ‚ท(pokitAction)))
case .์นดํ…Œ๊ณ ๋ฆฌ์ƒ์„ธ(let categoryDetailAction):
return .send(.scope(.์นดํ…Œ๊ณ ๋ฆฌ์ƒ์„ธ(categoryDetailAction)))
case .๋งํฌ์ถ”๊ฐ€๋ฐ์ˆ˜์ •(let contentSettingAction):
return .send(.scope(.๋งํฌ์ถ”๊ฐ€๋ฐ์ˆ˜์ •(contentSettingAction)))
case .ํฌํ‚ท์ถ”๊ฐ€๋ฐ์ˆ˜์ •(let categorySettingAction):
return .send(.scope(.ํฌํ‚ท์ถ”๊ฐ€๋ฐ์ˆ˜์ •(categorySettingAction)))
case .๊ฒ€์ƒ‰(let searchAction):
return .send(.scope(.๊ฒ€์ƒ‰(searchAction)))
case .์„ค์ •(let settingAction):
return .send(.scope(.์„ค์ •(settingAction)))
case .๋งํฌ์ƒ์„ธ(let contentDetailAction):
return .send(.scope(.๋งํฌ์ƒ์„ธ(contentDetailAction)))
}
}

/// - Reducer body
public var body: some ReducerOf<Self> {
Scope(state: \.ํฌํ‚ท, action: \.ํฌํ‚ท) {
PokitRootFeature()
}
Scope(state: \.๋งํฌ์ถ”๊ฐ€๋ฐ์ˆ˜์ •, action: \.๋งํฌ์ถ”๊ฐ€๋ฐ์ˆ˜์ •) {
ContentSettingFeature()
}

Reduce(self.core)
.ifLet(\.์นดํ…Œ๊ณ ๋ฆฌ์ƒ์„ธ, action: \.์นดํ…Œ๊ณ ๋ฆฌ์ƒ์„ธ) {
CategoryDetailFeature()
}
.ifLet(\.ํฌํ‚ท์ถ”๊ฐ€๋ฐ์ˆ˜์ •, action: \.ํฌํ‚ท์ถ”๊ฐ€๋ฐ์ˆ˜์ •) {
PokitCategorySettingFeature()
}
.ifLet(\.๊ฒ€์ƒ‰, action: \.๊ฒ€์ƒ‰) {
PokitSearchFeature()
}
.ifLet(\.์„ค์ •, action: \.์„ค์ •) {
PokitSettingFeature()
}
.ifLet(\.๋งํฌ์ƒ์„ธ, action: \.๋งํฌ์ƒ์„ธ) {
ContentDetailFeature()
}
}
}
//MARK: - FeatureAction Effect
private extension PokitSplitFeature {
/// - View Effect
func handleViewAction(_ action: Action.View, state: inout State) -> Effect<Action> {
return .none
}

/// - Inner Effect
func handleInnerAction(_ action: Action.InnerAction, state: inout State) -> Effect<Action> {
switch action {
case let .์นดํ…Œ๊ณ ๋ฆฌ_์ƒ์„ธ_ํ™œ์„ฑํ™”(category):
state.์นดํ…Œ๊ณ ๋ฆฌ์ƒ์„ธ = .init(category: category)
return .none
}
}

/// - Async Effect
func handleAsyncAction(_ action: Action.AsyncAction, state: inout State) -> Effect<Action> {
return .none
}

/// - Scope Effect
func handleScopeAction(_ action: Action.ScopeAction, state: inout State) -> Effect<Action> {
switch action {
case let .ํฌํ‚ท(.delegate(.categoryTapped(category))):
state.categoryId = category.id
return .send(.inner(.์นดํ…Œ๊ณ ๋ฆฌ_์ƒ์„ธ_ํ™œ์„ฑํ™”(category)))
case .ํฌํ‚ท(.delegate(.์นดํ…Œ๊ณ ๋ฆฌ_์‚ญ์ œ)):
state.์นดํ…Œ๊ณ ๋ฆฌ์ƒ์„ธ = nil
return .none
case .ํฌํ‚ท:
return .none

case .์นดํ…Œ๊ณ ๋ฆฌ์ƒ์„ธ:
return .none

case .๋งํฌ์ถ”๊ฐ€๋ฐ์ˆ˜์ •:
return .none

case .ํฌํ‚ท์ถ”๊ฐ€๋ฐ์ˆ˜์ •:
return .none

case .๊ฒ€์ƒ‰:
return .none

case .์„ค์ •:
return .none

case .๋งํฌ์ƒ์„ธ:
return .none
}
}

/// - Delegate Effect
func handleDelegateAction(_ action: Action.DelegateAction, state: inout State) -> Effect<Action> {
return .none
}
}

extension PokitSplitFeature {
@Reducer
enum Path {
case ์•Œ๋ฆผํ•จ(PokitAlertBoxFeature)
}
}
69 changes: 69 additions & 0 deletions Projects/App/Sources/MainTabSplit/Pokit/PokitSplitView.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
//
// PokitSplitView.swift
// App
//
// Created by ๊น€๋„ํ˜• on 10/24/24.

import SwiftUI

import ComposableArchitecture
import FeaturePokit
import FeatureRemind
import FeatureSetting
import FeatureCategorySetting
import FeatureContentDetail
import FeatureContentSetting
import FeatureCategoryDetail
import FeatureContentList
import FeatureCategorySharing

@ViewAction(for: PokitSplitFeature.self)
public struct PokitSplitView: View {
/// - Properties
public var store: StoreOf<PokitSplitFeature>

/// - Initializer
public init(store: StoreOf<PokitSplitFeature>) {
self.store = store
}
}
//MARK: - View
public extension PokitSplitView {
var body: some View {
WithPerceptionTracking {
NavigationSplitView(columnVisibility: .constant(.all)) {
PokitRootView(store: store.scope(state: \.ํฌํ‚ท, action: \.ํฌํ‚ท))
.toolbar(.hidden, for: .navigationBar)
} detail: {
detail
.toolbar(.hidden, for: .navigationBar)
}
}
}
}
//MARK: - Configure View
private extension PokitSplitView {
var detail: some View {
HStack(spacing: 0) {
if let store = store.scope(state: \.์นดํ…Œ๊ณ ๋ฆฌ์ƒ์„ธ, action: \.์นดํ…Œ๊ณ ๋ฆฌ์ƒ์„ธ) {
CategoryDetailView(store: store)
} else {
Spacer()
}

ContentSettingView(store: store.scope(state: \.๋งํฌ์ถ”๊ฐ€๋ฐ์ˆ˜์ •, action: \.๋งํฌ์ถ”๊ฐ€๋ฐ์ˆ˜์ •))
.frame(width: 375)
}
}
}
//MARK: - Preview
#Preview {
PokitSplitView(
store: Store(
initialState: .init(),
reducer: { PokitSplitFeature() }
)
)
}


0 comments on commit 6d5e154

Please sign in to comment.