Skip to content

Commit

Permalink
[chore] #154 PokitSplit Delegate ์—ฐ๊ฒฐ
Browse files Browse the repository at this point in the history
  • Loading branch information
ShapeKim98 committed Oct 26, 2024
1 parent 7ebaad9 commit 7911cf0
Show file tree
Hide file tree
Showing 8 changed files with 209 additions and 77 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ private extension MainTabSplitFeature {
case .์ถ”๊ฐ€_๋ฒ„ํŠผ_๋ˆŒ๋ €์„๋•Œ:
switch state {
case .pokit:
return .send(.pokit(.delegate(.๋งํฌ์ถ”๊ฐ€๋ฐ์ˆ˜์ •_ํ™œ์„ฑํ™”)))
return .send(.pokit(.delegate(.๋งํฌ์ถ”๊ฐ€_ํ™œ์„ฑํ™”)))
case .remind:
return .none
}
Expand Down
190 changes: 152 additions & 38 deletions Projects/App/Sources/MainTabSplit/Pokit/PokitSplitFeature.swift
Original file line number Diff line number Diff line change
Expand Up @@ -25,23 +25,25 @@ public struct PokitSplitFeature {

/// - State
@ObservableState
public struct State: Equatable {
public struct State {
var columnVisibility: NavigationSplitViewVisibility = Device.isPortrait ? .doubleColumn : .all

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

var path = StackState<Path.State>()

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

@Shared(.inMemory("SelectCategory"))
var categoryId: Int?
Expand All @@ -57,15 +59,16 @@ public struct PokitSplitFeature {
case inner(InnerAction)
case async(AsyncAction)
case scope(ScopeAction)
case path(StackActionOf<Path>)
case delegate(DelegateAction)
case ํฌํ‚ท(PokitRootFeature.Action)
case ์นดํ…Œ๊ณ ๋ฆฌ์ƒ์„ธ(CategoryDetailFeature.Action)
case ๋งํฌ์ถ”๊ฐ€๋ฐ์ˆ˜์ •(ContentSettingFeature.Action)
case ๋งํฌ์ถ”๊ฐ€(ContentSettingFeature.Action)
case ํฌํ‚ท์ถ”๊ฐ€๋ฐ์ˆ˜์ •(PresentationAction<PokitCategorySettingFeature.Action>)
case ๊ฒ€์ƒ‰(PresentationAction<PokitSearchFeature.Action>)
case ์„ค์ •(PresentationAction<PokitSettingFeature.Action>)
case ๋งํฌ์ƒ์„ธ(PresentationAction<ContentDetailFeature.Action>)
case ์•Œ๋žŒ(PresentationAction<PokitAlertBoxFeature.Action>)
case ์•Œ๋ฆผํ•จ(PresentationAction<PokitAlertBoxFeature.Action>)
case ๋งํฌ์ˆ˜์ •(PresentationAction<ContentSettingFeature.Action>)

@CasePathable
public enum View: Equatable, BindableAction {
Expand All @@ -80,23 +83,27 @@ public struct PokitSplitFeature {

public enum InnerAction: Equatable {
case ์นดํ…Œ๊ณ ๋ฆฌ_์ƒ์„ธ_ํ™œ์„ฑํ™”(BaseCategoryItem)
case ํฌํ‚ท์ถ”๊ฐ€๋ฐ์ˆ˜์ •_ํ™œ์„ฑํ™”(BaseCategoryItem?)
case ๋งํฌ์ˆ˜์ •_ํ™œ์„ฑํ™”(Int?)
case ๋งํฌ์ƒ์„ธ_ํ™œ์„ฑํ™”(Int)
}

public enum AsyncAction: Equatable { case doNothing }

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

public enum DelegateAction: Equatable {
case ๋งํฌ์ถ”๊ฐ€๋ฐ์ˆ˜์ •_ํ™œ์„ฑํ™”
case ๋งํฌ์ถ”๊ฐ€_ํ™œ์„ฑํ™”
}
}

Expand Down Expand Up @@ -125,22 +132,24 @@ public struct PokitSplitFeature {
/// - Delegate
case .delegate(let delegateAction):
return handleDelegateAction(delegateAction, state: &state)
case .path(let pathAction):
return handlePathAction(pathAction, 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 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)))
case .์•Œ๋žŒ(let alertAction):
return .send(.scope(.์•Œ๋žŒ(alertAction)))
case .์•Œ๋ฆผํ•จ(let alertAction):
return .send(.scope(.์•Œ๋ฆผํ•จ(alertAction)))
case .๋งํฌ์ˆ˜์ •(let contentSettingAction):
return .send(.scope(.๋งํฌ์ˆ˜์ •(contentSettingAction)))
}
}

Expand All @@ -151,29 +160,30 @@ public struct PokitSplitFeature {
Scope(state: \.ํฌํ‚ท, action: \.ํฌํ‚ท) {
PokitRootFeature()
}
Scope(state: \.๋งํฌ์ถ”๊ฐ€๋ฐ์ˆ˜์ •, action: \.๋งํฌ์ถ”๊ฐ€๋ฐ์ˆ˜์ •) {
Scope(state: \.๋งํฌ์ถ”๊ฐ€, action: \.๋งํฌ์ถ”๊ฐ€) {
ContentSettingFeature()
}

Reduce(self.core)
.forEach(\.path, action: \.path)
.ifLet(\.์นดํ…Œ๊ณ ๋ฆฌ์ƒ์„ธ, action: \.์นดํ…Œ๊ณ ๋ฆฌ์ƒ์„ธ) {
CategoryDetailFeature()
}
.ifLet(\.$ํฌํ‚ท์ถ”๊ฐ€๋ฐ์ˆ˜์ •, action: \.ํฌํ‚ท์ถ”๊ฐ€๋ฐ์ˆ˜์ •) {
PokitCategorySettingFeature()
}
.ifLet(\.$๊ฒ€์ƒ‰, action: \.๊ฒ€์ƒ‰) {
PokitSearchFeature()
}
.ifLet(\.$์„ค์ •, action: \.์„ค์ •) {
PokitSettingFeature()
}
.ifLet(\.$๋งํฌ์ƒ์„ธ, action: \.๋งํฌ์ƒ์„ธ) {
ContentDetailFeature()
}
.ifLet(\.$์•Œ๋žŒ, action: \.์•Œ๋žŒ) {
.ifLet(\.$์•Œ๋ฆผํ•จ, action: \.์•Œ๋ฆผํ•จ) {
PokitAlertBoxFeature()
}
.ifLet(\.$๋งํฌ์ˆ˜์ •, action: \.๋งํฌ์ˆ˜์ •) {
ContentSettingFeature()
}
}
}
//MARK: - FeatureAction Effect
Expand All @@ -186,13 +196,12 @@ private extension PokitSplitFeature {
case .๋ทฐ๊ฐ€_๋‚˜ํƒ€๋‚ฌ์„๋•Œ:
return .none
case .ํฌํ‚ท์ถ”๊ฐ€_๋ฒ„ํŠผ_๋ˆŒ๋ €์„๋•Œ:
state.ํฌํ‚ท์ถ”๊ฐ€๋ฐ์ˆ˜์ • = .init(type: .์ถ”๊ฐ€)
return .none
return .send(.inner(.ํฌํ‚ท์ถ”๊ฐ€๋ฐ์ˆ˜์ •_ํ™œ์„ฑํ™”(nil)))
case .๊ฒ€์ƒ‰_๋ฒ„ํŠผ_๋ˆŒ๋ €์„๋•Œ:
state.๊ฒ€์ƒ‰ = .init()
state.path.append(.๊ฒ€์ƒ‰(.init()))
return .none
case .์•Œ๋žŒ_๋ฒ„ํŠผ_๋ˆŒ๋ €์„๋•Œ:
state.์•Œ๋žŒ = .init()
state.์•Œ๋ฆผํ•จ = .init()
return .none
case .์„ค์ •_๋ฒ„ํŠผ_๋ˆŒ๋ €์„๋•Œ:
state.์„ค์ • = .init()
Expand All @@ -206,6 +215,24 @@ private extension PokitSplitFeature {
case let .์นดํ…Œ๊ณ ๋ฆฌ_์ƒ์„ธ_ํ™œ์„ฑํ™”(category):
state.์นดํ…Œ๊ณ ๋ฆฌ์ƒ์„ธ = .init(category: category)
return .send(.์นดํ…Œ๊ณ ๋ฆฌ์ƒ์„ธ(.delegate(.์นดํ…Œ๊ณ ๋ฆฌ_๋‚ด_์ปจํ…์ธ _๋ชฉ๋ก_์กฐํšŒ)))
case let .ํฌํ‚ท์ถ”๊ฐ€๋ฐ์ˆ˜์ •_ํ™œ์„ฑํ™”(category):
if let category {
state.ํฌํ‚ท์ถ”๊ฐ€๋ฐ์ˆ˜์ • = .init(
type: .์ˆ˜์ •,
categoryId: category.id,
categoryImage: category.categoryImage,
categoryName: category.categoryName
)
} else {
state.ํฌํ‚ท์ถ”๊ฐ€๋ฐ์ˆ˜์ • = .init(type: .์ถ”๊ฐ€)
}
return .none
case let .๋งํฌ์ˆ˜์ •_ํ™œ์„ฑํ™”(contentId):
state.๋งํฌ์ˆ˜์ • = .init(contentId: contentId)
return .none
case let .๋งํฌ์ƒ์„ธ_ํ™œ์„ฑํ™”(contentId):
state.๋งํฌ์ƒ์„ธ = .init(contentId: contentId)
return .none
}
}

Expand All @@ -217,57 +244,144 @@ private extension PokitSplitFeature {
/// - Scope Effect
func handleScopeAction(_ action: Action.ScopeAction, state: inout State) -> Effect<Action> {
switch action {
// - MARK: ํฌํ‚ท
case let .ํฌํ‚ท(.delegate(.categoryTapped(category))):
state.categoryId = category.id
if Device.isPortrait {
state.columnVisibility = .detailOnly
}
state.path.removeAll()
return .send(.inner(.์นดํ…Œ๊ณ ๋ฆฌ_์ƒ์„ธ_ํ™œ์„ฑํ™”(category)))
case .ํฌํ‚ท(.delegate(.์นดํ…Œ๊ณ ๋ฆฌ_์‚ญ์ œ)):
state.์นดํ…Œ๊ณ ๋ฆฌ์ƒ์„ธ = nil
return .none
case let .ํฌํ‚ท(.delegate(.์ˆ˜์ •ํ•˜๊ธฐ(category))):
return .send(.inner(.ํฌํ‚ท์ถ”๊ฐ€๋ฐ์ˆ˜์ •_ํ™œ์„ฑํ™”(category)))
case let .ํฌํ‚ท(.delegate(.๋งํฌ์ˆ˜์ •ํ•˜๊ธฐ(id: contentId))):
return .send(.inner(.๋งํฌ์ˆ˜์ •_ํ™œ์„ฑํ™”(contentId)))
case .ํฌํ‚ท(.delegate(.ํ•„ํ„ฐ_๋ฒ„ํŠผ_๋ˆŒ๋ €์„๋•Œ)):
state.categoryId = nil
state.์นดํ…Œ๊ณ ๋ฆฌ์ƒ์„ธ = nil
return .none
case .ํฌํ‚ท:
return .none

// - MARK: ์นดํ…Œ๊ณ ๋ฆฌ์ƒ์„ธ
case let .์นดํ…Œ๊ณ ๋ฆฌ์ƒ์„ธ(.delegate(.ํฌํ‚ท์ˆ˜์ •(category))):
return .send(.inner(.ํฌํ‚ท์ถ”๊ฐ€๋ฐ์ˆ˜์ •_ํ™œ์„ฑํ™”(category)))
case let .์นดํ…Œ๊ณ ๋ฆฌ์ƒ์„ธ(.delegate(.๋งํฌ์ˆ˜์ •(contentId: contentId))):
return .send(.inner(.๋งํฌ์ˆ˜์ •_ํ™œ์„ฑํ™”(contentId)))
case .์นดํ…Œ๊ณ ๋ฆฌ์ƒ์„ธ(.delegate(.ํฌํ‚ท์‚ญ์ œ)):
state.categoryId = nil
state.์นดํ…Œ๊ณ ๋ฆฌ์ƒ์„ธ = nil
return .send(.ํฌํ‚ท(.delegate(.๋ฏธ๋ถ„๋ฅ˜_์นดํ…Œ๊ณ ๋ฆฌ_์ปจํ…์ธ _์กฐํšŒ)))
case let .์นดํ…Œ๊ณ ๋ฆฌ์ƒ์„ธ(.delegate(.contentItemTapped(contentItem))):
return .send(.inner(.๋งํฌ์ƒ์„ธ_ํ™œ์„ฑํ™”(contentItem.id)))
case .์นดํ…Œ๊ณ ๋ฆฌ์ƒ์„ธ(.delegate(.์ปจํ…์ธ _์‚ญ์ œ)):
return .send(.ํฌํ‚ท(.delegate(.๋ฏธ๋ถ„๋ฅ˜_์นดํ…Œ๊ณ ๋ฆฌ_์ปจํ…์ธ _์กฐํšŒ)))
case .์นดํ…Œ๊ณ ๋ฆฌ์ƒ์„ธ:
return .none

case .๋งํฌ์ถ”๊ฐ€๋ฐ์ˆ˜์ •(.delegate(.dismiss)):
// - MARK: ๋งํฌ์ถ”๊ฐ€๋ฐ์ˆ˜์ •
case .๋งํฌ์ถ”๊ฐ€(.delegate(.dismiss)):
state.columnVisibility = .doubleColumn
return .none
case .๋งํฌ์ถ”๊ฐ€๋ฐ์ˆ˜์ •:
case .๋งํฌ์ถ”๊ฐ€:
return .none


// - MARK: ํฌํ‚ท์ถ”๊ฐ€๋ฐ์ˆ˜์ •
case .ํฌํ‚ท์ถ”๊ฐ€๋ฐ์ˆ˜์ •(.presented(.delegate(.settingSuccess))):
return .send(.ํฌํ‚ท(.delegate(.๋ฏธ๋ถ„๋ฅ˜_์นดํ…Œ๊ณ ๋ฆฌ_์ปจํ…์ธ _์กฐํšŒ)))
case .ํฌํ‚ท์ถ”๊ฐ€๋ฐ์ˆ˜์ •:
return .none


// - MARK: ๊ฒ€์ƒ‰
case let .๊ฒ€์ƒ‰(_, .delegate(.๋งํฌ์ˆ˜์ •(contentId: contentId))):
return .send(.inner(.๋งํฌ์ˆ˜์ •_ํ™œ์„ฑํ™”(contentId)))
case let .๊ฒ€์ƒ‰(_, .delegate(.linkCardTapped(content: content))):
return .send(.inner(.๋งํฌ์ƒ์„ธ_ํ™œ์„ฑํ™”(content.id)))
case .๊ฒ€์ƒ‰(_, .delegate(.์ปจํ…์ธ _์‚ญ์ œ)):
return .send(.ํฌํ‚ท(.delegate(.๋ฏธ๋ถ„๋ฅ˜_์นดํ…Œ๊ณ ๋ฆฌ_์ปจํ…์ธ _์กฐํšŒ)))
case .๊ฒ€์ƒ‰:
return .none


// - MARK: ์„ค์ •
case .์„ค์ •:
return .none


// - MARK: ๋งํฌ์ƒ์„ธ
case .๋งํฌ์ƒ์„ธ(.presented(.delegate(.์ฆ๊ฒจ์ฐพ๊ธฐ_๊ฐฑ์‹ _์™„๋ฃŒ))),
.๋งํฌ์ƒ์„ธ(.presented(.delegate(.์ปจํ…์ธ _์กฐํšŒ_์™„๋ฃŒ))),
.๋งํฌ์ƒ์„ธ(.presented(.delegate(.์ปจํ…์ธ _์‚ญ์ œ_์™„๋ฃŒ))):
var mergeEffect: [Effect<Action>] = [
.send(.ํฌํ‚ท(.delegate(.๋ฏธ๋ถ„๋ฅ˜_์นดํ…Œ๊ณ ๋ฆฌ_์ปจํ…์ธ _์กฐํšŒ)))
]
switch state.path.last {
case .๊ฒ€์ƒ‰:
guard let id = state.path.ids.last else { break }
mergeEffect.append(
.send(.path(.element(id: id, action: .๊ฒ€์ƒ‰(.delegate(.์ปจํ…์ธ _๊ฒ€์ƒ‰)))))
)
default:
mergeEffect.append(.send(.์นดํ…Œ๊ณ ๋ฆฌ์ƒ์„ธ(.delegate(.์นดํ…Œ๊ณ ๋ฆฌ_๋‚ด_์ปจํ…์ธ _๋ชฉ๋ก_์กฐํšŒ))))
}
return .merge(mergeEffect)
case let .๋งํฌ์ƒ์„ธ(.presented(.delegate(.editButtonTapped(contentId: contentId)))):
return .send(.inner(.๋งํฌ์ˆ˜์ •_ํ™œ์„ฑํ™”(contentId)))
case .๋งํฌ์ƒ์„ธ:
return .none

case .์•Œ๋žŒ:

// - MARK: ์•Œ๋žŒ
case let .์•Œ๋ฆผํ•จ(.presented(.delegate(.moveToContentEdit(id: contentId)))):
return .send(.inner(.๋งํฌ์ˆ˜์ •_ํ™œ์„ฑํ™”(contentId)))
case .์•Œ๋ฆผํ•จ(.presented(.delegate(.alertBoxDismiss))):
return .send(.์•Œ๋ฆผํ•จ(.dismiss))
case .์•Œ๋ฆผํ•จ:
return .none

// - MARK: ๋งํฌ์ˆ˜์ •
case .๋งํฌ์ˆ˜์ •(.presented(.delegate(.์ €์žฅํ•˜๊ธฐ_์™„๋ฃŒ))):
var mergeEffect: [Effect<Action>] = [
.send(.ํฌํ‚ท(.delegate(.๋ฏธ๋ถ„๋ฅ˜_์นดํ…Œ๊ณ ๋ฆฌ_์ปจํ…์ธ _์กฐํšŒ))),
.send(.๋งํฌ์ˆ˜์ •(.dismiss))
]
switch state.path.last {
case .๊ฒ€์ƒ‰:
guard let id = state.path.ids.last else { break }
mergeEffect.append(
.send(.path(.element(id: id, action: .๊ฒ€์ƒ‰(.delegate(.์ปจํ…์ธ _๊ฒ€์ƒ‰)))))
)
default:
mergeEffect.append(.send(.์นดํ…Œ๊ณ ๋ฆฌ์ƒ์„ธ(.delegate(.์นดํ…Œ๊ณ ๋ฆฌ_๋‚ด_์ปจํ…์ธ _๋ชฉ๋ก_์กฐํšŒ))))
}
return .merge(mergeEffect)
case .๋งํฌ์ˆ˜์ •:
return .none
}
}

/// - Delegate Effect
func handleDelegateAction(_ action: Action.DelegateAction, state: inout State) -> Effect<Action> {
switch action {
case .๋งํฌ์ถ”๊ฐ€๋ฐ์ˆ˜์ •_ํ™œ์„ฑํ™”:
case .๋งํฌ์ถ”๊ฐ€_ํ™œ์„ฑํ™”:
state.columnVisibility = .all
return .none
}
}

func handlePathAction(_ action: StackActionOf<Path>, state: inout State) -> Effect<Action> {
switch action {
case let .element(id: stackElementId, action: .๊ฒ€์ƒ‰(searchAction)):
return .send(.scope(.๊ฒ€์ƒ‰(stackElementId, searchAction)))
case .element, .popFrom, .push:
return .none
}
}
}

extension PokitSplitFeature {
@Reducer
enum Path {
case ์•Œ๋ฆผํ•จ(PokitAlertBoxFeature)
public enum Path {
case ๊ฒ€์ƒ‰(PokitSearchFeature)
}
}
Loading

0 comments on commit 7911cf0

Please sign in to comment.