The space tweaks continue! (#4606)

* Update a string on the space announcement sheet.

* Don't show space rooms after using the join button in the space room list.

* Allow the Deselect All button to Select (almost) All as well.

* Fix the cells in the leave space sheet when there are only admin rooms.
This commit is contained in:
Doug
2025-10-09 16:56:54 +01:00
committed by GitHub
parent 40367eeec9
commit b496955f6b
15 changed files with 63 additions and 63 deletions
@@ -27,8 +27,6 @@ struct SpaceScreenViewState: BindableState {
var isSpaceManagementEnabled = false
var bindings = SpaceScreenViewStateBindings()
var spaceName: String { space.name ?? L10n.commonSpace }
}
struct SpaceScreenViewStateBindings {
@@ -39,6 +37,7 @@ enum SpaceScreenViewAction {
case spaceAction(SpaceRoomCell.Action)
case leaveSpace
case deselectAllLeaveRoomDetails
case selectAllLeaveRoomDetails
case toggleLeaveSpaceRoomDetails(id: String)
case confirmLeaveSpace
case spaceSettings
@@ -95,6 +95,11 @@ class SpaceScreenViewModel: SpaceScreenViewModelType, SpaceScreenViewModelProtoc
for room in leaveHandle.rooms {
room.isSelected = false
}
case .selectAllLeaveRoomDetails:
guard let leaveHandle = state.bindings.leaveHandle else { fatalError("The leave handle should be available.") }
for room in leaveHandle.rooms where !room.isLastAdmin {
room.isSelected = true
}
case .toggleLeaveSpaceRoomDetails(let spaceRoomID):
guard let room = state.bindings.leaveHandle?.rooms.first(where: { $0.spaceRoomProxy.id == spaceRoomID }) else {
fatalError("The space room to toggle is not in the list of rooms to leave.")
@@ -125,14 +130,7 @@ class SpaceScreenViewModel: SpaceScreenViewModelType, SpaceScreenViewModelProtoc
return
}
// If multiple join operations are running, then only show the last one.
guard state.joiningRoomIDs == [spaceRoomProxy.id] else { return }
if spaceRoomProxy.isSpace {
await selectSpace(spaceRoomProxy)
} else {
actionsSubject.send(.selectRoom(roomID: spaceRoomProxy.id))
}
// We don't want to show the space room after joining it this way 🤷‍♂️
}
private func selectSpace(_ spaceRoomProxy: SpaceRoomProxyProtocol) async {
@@ -12,6 +12,7 @@ struct LeaveSpaceRoomDetailsCell: View {
@Environment(\.dynamicTypeSize) private var dynamicTypeSize
let room: LeaveSpaceRoomDetails
var hideSelection = false
let mediaProvider: MediaProviderProtocol?
let action: () -> Void
@@ -53,7 +54,9 @@ struct LeaveSpaceRoomDetailsCell: View {
.frame(maxWidth: .infinity, alignment: .leading)
.padding(.vertical, 8)
ListRowAccessory.multiSelection(room.isSelected)
if !hideSelection {
ListRowAccessory.multiSelection(room.isSelected)
}
}
.padding(.horizontal, 16)
}
@@ -99,6 +102,13 @@ struct LeaveSpaceRoomDetailsCell_Previews: PreviewProvider, TestablePreview {
isLastAdmin: true,
isSelected: false),
mediaProvider: MediaProviderMock(configuration: .init())) { }
LeaveSpaceRoomDetailsCell(room: .init(spaceRoomProxy: SpaceRoomProxyMock(.init(id: "2",
name: "My Space",
isSpace: true)),
isLastAdmin: true,
isSelected: false),
hideSelection: true,
mediaProvider: MediaProviderMock(configuration: .init())) { }
LeaveSpaceRoomDetailsCell(room: .init(spaceRoomProxy: SpaceRoomProxyMock(.init(id: "3",
name: "Room",
isSpace: false)),
@@ -111,6 +121,13 @@ struct LeaveSpaceRoomDetailsCell_Previews: PreviewProvider, TestablePreview {
isLastAdmin: true,
isSelected: false),
mediaProvider: MediaProviderMock(configuration: .init())) { }
LeaveSpaceRoomDetailsCell(room: .init(spaceRoomProxy: SpaceRoomProxyMock(.init(id: "4",
name: "My Room",
isSpace: false)),
isLastAdmin: true,
isSelected: false),
hideSelection: true,
mediaProvider: MediaProviderMock(configuration: .init())) { }
}
}
}
@@ -42,7 +42,7 @@ struct LeaveSpaceView: View {
BigIcon(icon: \.errorSolid, style: .alertSolid)
VStack(spacing: 8) {
Text(leaveHandle.title(spaceName: context.viewState.spaceName))
Text(leaveHandle.title(spaceName: context.viewState.space.name))
.font(.compound.headingMDBold)
.foregroundStyle(.compound.textPrimary)
.multilineTextAlignment(.center)
@@ -64,20 +64,24 @@ struct LeaveSpaceView: View {
LazyVStack(spacing: 0, pinnedViews: .sectionHeaders) {
Section {
ForEach(leaveHandle.rooms, id: \.spaceRoomProxy.id) { room in
LeaveSpaceRoomDetailsCell(room: room, mediaProvider: context.mediaProvider) {
LeaveSpaceRoomDetailsCell(room: room,
hideSelection: leaveHandle.mode == .onlyAdminRooms,
mediaProvider: context.mediaProvider) {
context.send(viewAction: .toggleLeaveSpaceRoomDetails(id: room.spaceRoomProxy.id))
}
.disabled(room.isLastAdmin)
}
} header: {
Button(L10n.commonDeselectAll) {
context.send(viewAction: .deselectAllLeaveRoomDetails)
if leaveHandle.mode == .manyRooms {
Button(leaveHandle.selectedCount > 0 ? L10n.actionDeselectAll : L10n.actionSelectAll) {
context.send(viewAction: leaveHandle.selectedCount > 0 ? .deselectAllLeaveRoomDetails : .selectAllLeaveRoomDetails)
}
.buttonStyle(.compound(.textLink, size: .small))
.frame(maxWidth: .infinity, alignment: .trailing)
.padding(.horizontal, 16)
.padding(.bottom, 8)
.background(Color.compound.bgCanvasDefault.ignoresSafeArea())
}
.buttonStyle(.compound(.textLink, size: .small))
.frame(maxWidth: .infinity, alignment: .trailing)
.padding(.horizontal, 16)
.padding(.bottom, 8)
.background(Color.compound.bgCanvasDefault.ignoresSafeArea())
}
}
}
@@ -20,7 +20,7 @@ struct SpaceScreen: View {
}
}
.background(Color.compound.bgCanvasDefault.ignoresSafeArea())
.navigationTitle(context.viewState.spaceName)
.navigationTitle(context.viewState.space.name)
.navigationBarTitleDisplayMode(.inline)
.toolbar { toolbar }
.sheet(item: $context.leaveHandle) { leaveHandle in
@@ -50,7 +50,7 @@ struct SpaceScreen: View {
// Use the same trick as the RoomScreen for a leading title view that
// also hides the navigation title.
ToolbarItem(placement: .principal) {
RoomHeaderView(roomName: context.viewState.spaceName,
RoomHeaderView(roomName: context.viewState.space.name,
roomAvatar: context.viewState.space.avatar,
mediaProvider: context.mediaProvider)
}