From 168505af73008e3ce13b110da5a0af5aa638c7ce Mon Sep 17 00:00:00 2001 From: Vladislav Fitc Date: Tue, 30 May 2023 13:28:02 +0200 Subject: [PATCH] fix(dynamic facets): recalculate selections on facets order change (#289) --- ...namicFacetListInteractor+FilterState.swift | 41 +++++++++++++------ 1 file changed, 28 insertions(+), 13 deletions(-) diff --git a/Sources/InstantSearchCore/DynamicFacets/DynamicFacetListInteractor+FilterState.swift b/Sources/InstantSearchCore/DynamicFacets/DynamicFacetListInteractor+FilterState.swift index ff4aaea6..9626542a 100644 --- a/Sources/InstantSearchCore/DynamicFacets/DynamicFacetListInteractor+FilterState.swift +++ b/Sources/InstantSearchCore/DynamicFacets/DynamicFacetListInteractor+FilterState.swift @@ -46,11 +46,13 @@ public extension DynamicFacetListInteractor { public func connect() { whenSelectionsComputedThenUpdateFilterState() whenFilterStateChangedThenUpdateSelections() + whenFacetOrderChangedThenUpdateSelections() } public func disconnect() { filterState.onChange.cancelSubscription(for: interactor) interactor.onSelectionsChanged.cancelSubscription(for: filterState) + interactor.onFacetOrderChanged.cancelSubscription(for: filterState) } private func groupID(for attribute: Attribute) -> FilterGroup.ID { @@ -63,6 +65,21 @@ public extension DynamicFacetListInteractor { } } + private func calculateSelections(facets: [AttributedFacets], filterState: FilterState) -> [Attribute: Set] { + let selectionsPerAttribute: [(attribute: Attribute, values: Set)] = + facets + .map(\.attribute) + .map { attribute in + let values = filterState + .getFilters(forGroupWithID: groupID(for: attribute)) + .compactMap { $0.filter as? FacetFilter } + .filter { $0.attribute == attribute && !$0.isNegated } + .map(\.value.description) + return (attribute, Set(values)) + } + return Dictionary(uniqueKeysWithValues: selectionsPerAttribute) + } + private func whenSelectionsComputedThenUpdateFilterState() { interactor.onSelectionsComputed.subscribePast(with: filterState) { filterState, selectionsPerAttribute in selectionsPerAttribute.forEach { attribute, selections in @@ -75,20 +92,18 @@ public extension DynamicFacetListInteractor { } } + private func whenFacetOrderChangedThenUpdateSelections() { + interactor.onFacetOrderChanged.subscribePast(with: filterState) { filterState, orderedFacets in + interactor.selections = calculateSelections(facets: orderedFacets, + filterState: filterState) + } + } + private func whenFilterStateChangedThenUpdateSelections() { - filterState.onChange.subscribePast(with: interactor) { interactor, _ in - let selectionsPerAttribute: [(attribute: Attribute, values: Set)] = interactor - .orderedFacets - .map(\.attribute) - .map { attribute in - let values = filterState - .getFilters(forGroupWithID: groupID(for: attribute)) - .compactMap { $0.filter as? FacetFilter } - .filter { $0.attribute == attribute && !$0.isNegated } - .map(\.value.description) - return (attribute, Set(values)) - } - interactor.selections = Dictionary(uniqueKeysWithValues: selectionsPerAttribute) + filterState.onChange.subscribePast(with: interactor) { [weak filterState] interactor, _ in + guard let filterState else { return } + interactor.selections = calculateSelections(facets: interactor.orderedFacets, + filterState: filterState) } } }