Filters UI Update and ordering (#2521)

This commit is contained in:
Mauro
2024-03-04 18:32:59 +01:00
committed by GitHub
parent 5427fbe129
commit 4320e5c9e0
11 changed files with 114 additions and 51 deletions
@@ -234,9 +234,9 @@ class HomeScreenViewModel: HomeScreenViewModelType, HomeScreenViewModelProtocol
} else {
if state.bindings.isSearchFieldFocused {
roomSummaryProvider?.setFilter(.include(.init(query: state.bindings.searchQuery,
filters: state.bindings.filtersState.activeFilters)))
filters: state.bindings.filtersState.activeFilters.set)))
} else {
roomSummaryProvider?.setFilter(.include(.init(filters: state.bindings.filtersState.activeFilters)))
roomSummaryProvider?.setFilter(.include(.init(filters: state.bindings.filtersState.activeFilters.set)))
}
}
}
@@ -18,15 +18,16 @@ import Combine
import Foundation
import MatrixRustSDK
import OrderedCollections
enum RoomListFilter: Int, CaseIterable, Identifiable {
var id: Int {
rawValue
}
case unreads
case people
case rooms
case unreads
case favourites
var localizedName: String {
@@ -71,25 +72,22 @@ enum RoomListFilter: Int, CaseIterable, Identifiable {
}
struct RoomListFiltersState {
private(set) var activeFilters: Set<RoomListFilter>
private(set) var activeFilters: OrderedSet<RoomListFilter>
private var inactiveFilters: OrderedSet<RoomListFilter>
init(activeFilters: Set<RoomListFilter> = []) {
self.activeFilters = activeFilters
}
var sortedActiveFilters: [RoomListFilter] {
activeFilters.sorted(by: { $0.rawValue < $1.rawValue })
init(activeFilters: OrderedSet<RoomListFilter> = []) {
self.activeFilters = .init(activeFilters)
inactiveFilters = OrderedSet(RoomListFilter.allCases).subtracting(activeFilters)
}
var availableFilters: [RoomListFilter] {
var availableFilters = Set(RoomListFilter.allCases)
var availableFilters = inactiveFilters
for filter in activeFilters {
availableFilters.remove(filter)
if let incompatibleFilter = filter.incompatibleFilter {
availableFilters.remove(incompatibleFilter)
}
}
return availableFilters.sorted(by: { $0.rawValue < $1.rawValue })
return availableFilters.elements
}
var isFiltering: Bool {
@@ -101,15 +99,22 @@ struct RoomListFiltersState {
activeFilters.contains(incompatibleFilter) {
fatalError("[RoomListFiltersState] adding mutually exclusive filters is not allowed")
}
activeFilters.insert(filter)
// We always want the most recently enabled filter to be at the bottom of the others.
activeFilters.append(filter)
inactiveFilters.remove(filter)
}
mutating func deactivateFilter(_ filter: RoomListFilter) {
activeFilters.remove(filter)
// We always want the most recently disabled filter to be on top of the others
inactiveFilters.insert(filter, at: 0)
}
mutating func clearFilters() {
activeFilters.removeAll()
// We iterate in reverse because filters should get disabled from the first to last that has been used.
for filter in activeFilters.reversed() {
deactivateFilter(filter)
}
}
func isFilterActive(_ filter: RoomListFilter) -> Bool {
@@ -37,21 +37,21 @@ struct RoomListFilterView_Previews: PreviewProvider, TestablePreview {
private struct FilterToggleStyle: ToggleStyle {
private func strokeColor(isOn: Bool) -> Color {
isOn ? .compound.bgActionPrimaryRest : .compound.borderInteractiveSecondary
isOn ? .compound.bgSubtleSecondary : .compound.borderInteractiveSecondary
}
private func backgroundColor(isOn: Bool) -> Color {
isOn ? .compound.bgActionPrimaryRest : .compound.bgCanvasDefault
isOn ? .compound.bgSubtleSecondary : .compound.bgCanvasDefault
}
private func foregroundColor(isOn: Bool) -> Color {
isOn ? .compound.textOnSolidPrimary : .compound.textPrimary
isOn ? .compound.textPrimary : .compound.textSecondary
}
func makeBody(configuration: Configuration) -> some View {
let shape = RoundedRectangle(cornerRadius: 20)
configuration.label
.font(.compound.bodyLG)
.font(.compound.bodyLGSemibold)
.foregroundColor(foregroundColor(isOn: configuration.isOn))
.padding(.horizontal, 16)
.padding(.vertical, 8)
@@ -27,7 +27,7 @@ struct RoomListFiltersView: View {
clearButton
}
ForEach(state.sortedActiveFilters) { filter in
ForEach(state.activeFilters) { filter in
RoomListFilterView(filter: filter,
isActive: getBinding(for: filter))
.matchedGeometryEffect(id: filter.id, in: namespace)