mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-10-31 16:24:11 +00:00
108 lines
4.4 KiB
Swift
108 lines
4.4 KiB
Swift
//
|
|
// Copyright 2025 New Vector Ltd.
|
|
//
|
|
// SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
|
|
// Please see LICENSE files in the repository root for full details.
|
|
//
|
|
|
|
import Compound
|
|
import SwiftUI
|
|
|
|
struct SpaceScreen: View {
|
|
@Bindable var context: SpaceScreenViewModel.Context
|
|
|
|
var body: some View {
|
|
ScrollView {
|
|
LazyVStack(spacing: 0) {
|
|
SpaceHeaderView(spaceRoomProxy: context.viewState.space,
|
|
mediaProvider: context.mediaProvider)
|
|
rooms
|
|
}
|
|
}
|
|
.background(Color.compound.bgCanvasDefault.ignoresSafeArea())
|
|
.navigationTitle(context.viewState.spaceName)
|
|
.navigationBarTitleDisplayMode(.inline)
|
|
.toolbar { toolbar }
|
|
.sheet(item: $context.leaveHandle) { _ in
|
|
LeaveSpaceView(context: context)
|
|
}
|
|
}
|
|
|
|
@ViewBuilder
|
|
var rooms: some View {
|
|
ForEach(context.viewState.rooms, id: \.id) { spaceRoomProxy in
|
|
SpaceRoomCell(spaceRoomProxy: spaceRoomProxy,
|
|
isSelected: spaceRoomProxy.id == context.viewState.selectedSpaceRoomID,
|
|
isJoining: context.viewState.joiningRoomIDs.contains(spaceRoomProxy.id),
|
|
mediaProvider: context.mediaProvider) { action in
|
|
context.send(viewAction: .spaceAction(action))
|
|
}
|
|
}
|
|
|
|
if context.viewState.isPaginating {
|
|
ProgressView()
|
|
.padding()
|
|
}
|
|
}
|
|
|
|
@ToolbarContentBuilder
|
|
var toolbar: some ToolbarContent {
|
|
// 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,
|
|
roomAvatar: context.viewState.space.avatar,
|
|
mediaProvider: context.mediaProvider)
|
|
}
|
|
|
|
ToolbarItemGroup(placement: .secondaryAction) {
|
|
if let permalink = context.viewState.permalink {
|
|
Section {
|
|
ShareLink(item: permalink) {
|
|
Label(L10n.actionShare, icon: \.shareIos)
|
|
}
|
|
}
|
|
}
|
|
|
|
Section {
|
|
Button(role: .destructive) { context.send(viewAction: .leaveSpace) } label: {
|
|
Label(L10n.actionLeaveSpace, icon: \.leave)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// MARK: - Previews
|
|
|
|
struct SpaceScreen_Previews: PreviewProvider, TestablePreview {
|
|
static let viewModel = makeViewModel()
|
|
|
|
static var previews: some View {
|
|
NavigationStack {
|
|
SpaceScreen(context: viewModel.context)
|
|
}
|
|
}
|
|
|
|
static func makeViewModel() -> SpaceScreenViewModel {
|
|
let spaceRoomProxy = SpaceRoomProxyMock(.init(id: "!eng-space:matrix.org",
|
|
name: "Engineering Team",
|
|
isSpace: true,
|
|
parent: SpaceRoomProxyMock(.init(name: "MegaGroup", isSpace: true)),
|
|
childrenCount: 30,
|
|
joinedMembersCount: 76,
|
|
heroes: [.mockDan, .mockBob, .mockCharlie, .mockVerbose],
|
|
topic: "Description of the space goes right here. Lorem ipsum dolor sit amet consectetur. Leo viverra morbi habitant in.",
|
|
joinRule: .knockRestricted(rules: [.roomMembership(roomId: "")])))
|
|
let spaceRoomListProxy = SpaceRoomListProxyMock(.init(spaceRoomProxy: spaceRoomProxy,
|
|
initialSpaceRooms: .mockSpaceList))
|
|
|
|
let viewModel = SpaceScreenViewModel(spaceRoomListProxy: spaceRoomListProxy,
|
|
spaceServiceProxy: SpaceServiceProxyMock(.init()),
|
|
selectedSpaceRoomPublisher: .init(nil),
|
|
userSession: UserSessionMock(.init()),
|
|
userIndicatorController: UserIndicatorControllerMock())
|
|
return viewModel
|
|
}
|
|
}
|