Space filters (#4977)

* Add support for SpaceFilters on the SpaceServiceProxy level and a screen that renders them

* Add aliases to a couple of space room mocks

* Update translations and related snapshots

* Add a feature flag for space filters

* Add a new room summary provider filter that takes a list of room identifiers next to the normal state filters

This will take the SpaceFilter's descendants and combine it with the normal filters to reduce the rooms shown

* Add a new space filter button to the home screen and link it to the SpaceFiltersScreen and the actual RoomSummaryProvider room list filters

* Bump the RustSDK to v26.01.20-2 for SpaceFilter support.

* Add a cancellation button to the space filters screen

* Make the filter presentation mode liquidy, move the sheet to within the home screen.

* Address PR comments
This commit is contained in:
Stefan Ceriu
2026-01-21 22:19:39 +02:00
committed by GitHub
parent 0d34a28ec2
commit b4b9f6affa
41 changed files with 808 additions and 13 deletions
@@ -16,21 +16,39 @@ struct HomeScreen: View {
@State private var scrollViewAdapter = ScrollViewAdapter()
@Namespace private var navigationTransitionNamespace
private enum NavigationTransitionSourceID {
case spaceFilters
}
var body: some View {
HomeScreenContent(context: context, scrollViewAdapter: scrollViewAdapter)
.alert(item: $context.alertInfo)
.alert(item: $context.leaveRoomAlertItem,
actions: leaveRoomAlertActions,
message: leaveRoomAlertMessage)
.navigationTitle(L10n.screenRoomlistMainSpaceTitle)
.navigationTitle(title)
.toolbar { toolbar }
.background(Color.compound.bgCanvasDefault.ignoresSafeArea())
.track(screen: .Home)
.toolbarBloom(hasSearchBar: true)
.sentryTrace("\(Self.self)")
.sheet(item: $context.spaceFiltersViewModel) { vm in
ChatsSpaceFiltersScreen(context: vm.context)
.navigationTransition(.zoom(sourceID: NavigationTransitionSourceID.spaceFilters,
in: navigationTransitionNamespace))
}
}
// MARK: - Private
private var title: String {
if let selectedSpace = context.viewState.selectedSpaceFilter {
selectedSpace.room.name
} else {
L10n.screenRoomlistMainSpaceTitle
}
}
@ToolbarContentBuilder
private var toolbar: some ToolbarContent {
@@ -47,6 +65,20 @@ struct HomeScreen: View {
.buttonStyle(.compound(.super, size: .toolbarIcon))
}
}
if context.viewState.spaceFiltersEnabled {
if #available(iOS 26, *) {
ToolbarSpacer(.fixed, placement: .primaryAction)
}
ToolbarItem(placement: .primaryAction) {
SpaceFiltersButton(selected: context.viewState.selectedSpaceFilter != nil) {
context.send(viewAction: .spaceFilters)
}
.matchedTransitionSource(id: NavigationTransitionSourceID.spaceFilters,
in: navigationTransitionNamespace)
}
}
}
private var settingsButton: some View {
@@ -93,6 +125,42 @@ struct HomeScreen: View {
private func leaveRoomAlertMessage(_ item: LeaveRoomAlertItem) -> some View {
Text(item.subtitle)
}
private struct SpaceFiltersButton: View {
var selected = false
var action: () -> Void
var body: some View {
if #available(iOS 26, *) {
if selected {
content
.backportButtonStyleGlassProminent()
.tint(.compound.bgAccentRest)
} else {
content
}
} else {
if selected {
content
.buttonStyle(.compound(.primary, size: .toolbarIcon))
} else {
content
.buttonStyle(.compound(.tertiary, size: .toolbarIcon))
}
}
}
private var content: some View {
Button {
action()
} label: {
CompoundIcon(\.filter)
}
.accessibilityLabel(L10n.screenRoomlistYourSpaces)
.accessibilityAddTraits(selected ? .isSelected : [])
.accessibilityIdentifier(A11yIdentifiers.homeScreen.spaceFilters)
}
}
}
// MARK: - Previews