Skip to content

Commit

Permalink
[Bug, Refactor] SSFilter 모듈 생성 및 Sent and Received Module 리팩토링 , Filt…
Browse files Browse the repository at this point in the history
…erLayout 버그 수정 (#622)

* prj: ssFilter생성

* feat: SSFilter Dependencies 추가,

* feat: SSFilterDateProperty 작성 SSFilterItemable 작성 Reducer 및 뷰 생성

* feat: dateWithFilter Reducer생성

* feat: sliderPropertyReducer 생성

* feat: sliderProperty와 연결 FilterReducer연결

* feat: sliderProperty 추가

* feat: filterView 완성

* feat: SSFilterView 연결

* feat: sent Module SSFilter적용

* Refactor: 필요 없는 파일 삭제

* feat: LedgerDetailFilterView and Reducer Refactor

* feat: Recived Filter 리팩토링

* feat: receivedFilter and RedciveFilterView 리팩토링

* feat: receivedFilter과 관련된 코드 리팩토링

* feat: receivedMainFilter 초기값 세팅 로직 생성

* feat: sliderProperty를 활용한 초기값 세팅 로직 작성

* feat: update filter initial State position

* feat: SentEnvelopeFilter initialPrev Value update
  • Loading branch information
MaraMincho authored Oct 14, 2024
1 parent a30a70d commit ebec0f0
Show file tree
Hide file tree
Showing 39 changed files with 1,418 additions and 875 deletions.
2 changes: 1 addition & 1 deletion Projects/App/Project.swift
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ let project = Project.makeModule(
"UILaunchStoryboardName": "LaunchScreen",
"BGTaskSchedulerPermittedIdentifiers": "com.oksusu.susu.app",
"CFBundleShortVersionString": "1.0.6",
"CFBundleVersion": "2024100436",
"CFBundleVersion": "2024101237",
"UIUserInterfaceStyle": "Light",
"ITSAppUsesNonExemptEncryption": "No",
"AppstoreAPPID": "6503701515",
Expand Down
1 change: 1 addition & 0 deletions Projects/Feature/Received/Project.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ let project = Project.makeModule(
.feature(.sSCreateEnvelope),
.feature(.sSEnvelope),
.feature(.sSEditSingleSelectButton),
.feature(.sSFilter),
],
testDependencies: []
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import ComposableArchitecture
import Designsystem
import FeatureAction
import Foundation
import SSFilter
import SSLayout

// MARK: - LedgerDetailFilter
Expand All @@ -25,27 +26,7 @@ struct LedgerDetailFilter: Sendable {
var header: HeaderViewFeature.State = .init(.init(title: "필터", type: .depth2Default))
var isLoading = true
var ledgerProperty = SharedContainer.getValue(LedgerDetailProperty.self)

var sliderProperty: CustomSlider = .init()
var sliderEndValue: Int64 = 100_000
var minimumTextValue: Int64 = 0
var maximumTextValue: Int64 = 0
var minimumTextValueString: String { CustomNumberFormatter.formattedByThreeZero(minimumTextValue) ?? "0" }
var maximumTextValueString: String { CustomNumberFormatter.formattedByThreeZero(maximumTextValue) ?? "0" }
var sliderRangeText: String {
"\(minimumTextValueString)원 ~ \(maximumTextValueString)"
}

var isInitialState: Bool {
return minimumTextValue == 0 && maximumTextValue == sliderEndValue
}

var filterByTextField: [LedgerFilterItemProperty] = []

mutating func updateSliderValueProperty() {
minimumTextValue = Int64(Double(sliderEndValue) * sliderProperty.currentLowHandlePercentage) / 10000 * 10000
maximumTextValue = Int64(Double(sliderEndValue) * sliderProperty.currentHighHandlePercentage) / 10000 * 10000
}
var filterState: SSFilterReducer<LedgerFilterItemProperty>.State = .init(type: .withSlider(titleLabel: "받은 봉투 금액"), isSearchSection: true)

init(_ property: Shared<LedgerDetailFilterProperty>) {
_property = property
Expand All @@ -64,19 +45,10 @@ struct LedgerDetailFilter: Sendable {
@CasePathable
enum ViewAction: Equatable, Sendable {
case onAppear(Bool)
case tappedItem(LedgerFilterItemProperty)
case changeTextField(String)
case closeButtonTapped
case tappedConfirmButton
case reset
case tappedSliderResetButton
}

enum InnerAction: Equatable, Sendable {
case isLoading(Bool)
case updateItems([LedgerFilterItemProperty])
case updateMaximumReceivedValue(Int64)
case updateSliderPropertyItems
}

enum AsyncAction: Equatable, Sendable {
Expand All @@ -88,9 +60,37 @@ struct LedgerDetailFilter: Sendable {
@CasePathable
enum ScopeAction: Equatable, Sendable {
case header(HeaderViewFeature.Action)
case filterAction(SSFilterReducer<LedgerFilterItemProperty>.Action)
}

enum DelegateAction: Equatable, Sendable {
case tappedConfirmButton
}

enum DelegateAction: Equatable, Sendable {}
func handleFilterAction(_ state: inout State, _ action: SSFilterReducer<LedgerFilterItemProperty>.Action) -> Effect<Action> {
switch action {
case let .delegate(.changeTextField(text)):
return .send(.async(.searchFriendsBy(name: text)))
.throttle(id: CancelID.searchTextField, for: 0.1, scheduler: mainQueue, latest: true)

case let .delegate(.tappedConfirmButtonWithSliderProperty(selectedItems, minimumValue, maximumValue)):
state.property.selectItems(selectedItems)
if let minimumValue, let maximumValue {
state.property.lowestAmount = minimumValue
state.property.highestAmount = maximumValue
}
return .run { send in
await send(.delegate(.tappedConfirmButton))
await dismiss()
}

case .delegate:
return .none

default:
return .none
}
}

@Dependency(\.dismiss) var dismiss
@Dependency(\.mainQueue) var mainQueue
Expand All @@ -106,84 +106,33 @@ struct LedgerDetailFilter: Sendable {
return .none
}
state.isOnAppear = isAppear
let prevSelectedItems = state.property.selectedItems
let prevMinimumValue = state.property.lowestAmount
let prevMaximumValue = state.property.highestAmount
return .merge(
.send(.scope(.filterAction(.inner(
.updatePrevSelectedFilteredItemsAndSlider(item: prevSelectedItems, minimumValue: prevMinimumValue, maximumValue: prevMaximumValue)))
)),
.send(.async(.searchInitialFriends)),
.send(.async(.getInitialMaxPriceValue)),
.publisher {
state
.sliderProperty
.objectWillChange
.map { _ in .inner(.updateSliderPropertyItems) }
}
.send(.async(.getInitialMaxPriceValue))
)

case let .tappedItem(item):
state.property.select(item.id)
return .none

case let .changeTextField(text):
state.textFieldText = text
return .send(.async(.searchFriendsBy(name: text)))
.throttle(id: CancelID.searchTextField, for: 0.1, scheduler: mainQueue, latest: true)

case .closeButtonTapped:
state.textFieldText = ""
return .none

case .tappedConfirmButton:
if !state.isInitialState {
state.property.lowestAmount = state.minimumTextValue
state.property.highestAmount = state.maximumTextValue
}
return .ssRun { _ in
await dismiss()
}

case .reset:
state.sliderProperty.reset()
state.property.reset()
return .none

case .tappedSliderResetButton:
state.sliderProperty.reset()
return .none
}
}

func scopeAction(_: inout State, _ action: Action.ScopeAction) -> Effect<Action> {
func scopeAction(_ state: inout State, _ action: Action.ScopeAction) -> Effect<Action> {
switch action {
case let .filterAction(currentAction):
return handleFilterAction(&state, currentAction)
case .header:
return .none
}
}

private func filterItems(_ state: inout State) {
guard let regex: Regex = try? .init("[\\w\\p{L}]*\(state.textFieldText)[\\w\\p{L}]*") else {
return
}
state.filterByTextField = state.property.selectableItems.filter { $0.title.contains(regex) }
}

func innerAction(_ state: inout State, _ action: Action.InnerAction) -> Effect<Action> {
switch action {
case let .isLoading(val):
state.isLoading = val
return .none

case let .updateItems(items):
let uniqueItem = (state.property.selectableItems + items).uniqued()
state.property.selectableItems = uniqueItem
filterItems(&state)
return .none

case let .updateMaximumReceivedValue(price):
state.sliderEndValue = price
state.updateSliderValueProperty()
return .none

case .updateSliderPropertyItems:
state.updateSliderValueProperty()
return .none
}
}

Expand All @@ -198,7 +147,7 @@ struct LedgerDetailFilter: Sendable {
await send(.inner(.isLoading(true)))
// 초기 친구 검색
let items = try await network.getInitialDataByLedgerID(id)
await send(.inner(.updateItems(items)))
await send(.scope(.filterAction(.inner(.updateItems(items)))))
await send(.inner(.isLoading(false)))
}

Expand All @@ -208,12 +157,13 @@ struct LedgerDetailFilter: Sendable {
}
return .ssRun { send in
let items = try await network.findFriendsBy(.init(name: name, ledgerID: id))
await send(.inner(.updateItems(items)))
await send(.scope(.filterAction(.inner(.updateItems(items)))))
}

case .getInitialMaxPriceValue:
return .ssRun { send in
let price = try await network.getMaximumSentValue()
await send(.inner(.updateMaximumReceivedValue(price)))
await send(.scope(.filterAction(.inner(.updateSliderMaximumValue(price)))))
}
}
}
Expand All @@ -223,6 +173,10 @@ struct LedgerDetailFilter: Sendable {
HeaderViewFeature()
}

Scope(state: \.filterState, action: \.scope.filterAction) {
SSFilterReducer()
}

Reduce { state, action in
switch action {
case let .view(currentAction):
Expand All @@ -233,6 +187,8 @@ struct LedgerDetailFilter: Sendable {
return asyncAction(&state, currentAction)
case let .scope(currentAction):
return scopeAction(&state, currentAction)
case .delegate:
return .none
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
//

import Foundation
import SSFilter

// MARK: - LedgerDetailFilterProperty

Expand All @@ -28,6 +29,10 @@ struct LedgerDetailFilterProperty: Equatable {
return "\(lowVal)~\(highVal)"
}

mutating func selectItems(_ items: [LedgerFilterItemProperty]) {
selectedItems = items
}

func isSelectedItems(id: Int64) -> Bool {
return selectedItems.first(where: { $0.id == id }) != nil
}
Expand Down Expand Up @@ -66,7 +71,7 @@ struct LedgerDetailFilterProperty: Equatable {

// MARK: - LedgerFilterItemProperty

struct LedgerFilterItemProperty: Equatable, Identifiable, Hashable {
struct LedgerFilterItemProperty: Equatable, Identifiable, Hashable, SSFilterItemable {
/// 친구 아이디
var id: Int64
/// 친구 이름
Expand Down
Loading

0 comments on commit ebec0f0

Please sign in to comment.