【发布时间】:2021-06-11 02:16:30
【问题描述】:
TLDR:当NavigationLink 的userId 不再在数组中时,我如何关闭当前视图。
我正在尝试为所有者创建一个“踢出”功能来踢出其他用户。不过,在为 Space 文档的任何更改设置监听器后,我不确定如何为 ID 不在 Space 数组中的用户调用 presentationMode.wrappedValue.dismiss()。
空间视图
struct SpaceView: View {
@ObservedObject var spaceViewModel: SpaceViewModel
@Environment(\.presentationMode) var presentationMode: Binding<PresentationMode>
var body: some View {
ZStack {
VStack(spacing: 15) {
membersCollectionView
Spacer()
}
.padding(.bottom, 40)
moreActionSheetView
}
}
//MARK: - Views
var membersCollectionView: some View {
ScrollView {
LazyVGrid(
columns: spaceViewModel.memberColumns,
alignment: .leading,
spacing: 16,
pinnedViews: [.sectionHeaders, .sectionFooters]
) {
ForEach(spaceViewModel.space.members, id: \.self) { member in
SpaceMemberCell(member: member, action: spaceViewModel.spaceMemberCellTapped(_:))
}
}
.padding([.leading, .trailing], 20)
}
}
}
空间视图模型
class SpaceViewModel: ObservableObject {
@Published var space: Space
@Published var showAddFriendsActionSheet = false
@Published var showMoreButton: Bool = true
@Published var showMusicButton: Bool = false
@Published var showAddFriendsButton: Bool = true
@Published var showRaiseHandButton: Bool = false
@Published var showMuteButton: Bool = false
@Published var memberColumns: [GridItem] = []
@Published var selectedMember: SpaceMember?
@Published var accessType: SpaceAccessType = .member
@Published var memberActionSheetOffset: CGFloat = 0
@Published var moreActionSheetOffset: CGFloat = 0
@Published private(set) var isAllMuted: Bool
//@Published private(set) var roomStatus: Space.RoomStatus
private var spaceListener: ListenerRegistration!
@Published var isKickedOut = false
init(space: Space) {
self.space = space
self.isAllMuted = space.isAllMuted
self.roomStatus = space.roomStatus
self.memberColumns = Array(repeating: GridItem(.fixed(100), spacing: 16), count: space.members.count)
setAccessType()
}
deinit {
removeListeners()
}
///initializer for personal/solo space
init(personalSpace: Space) {
self.space = personalSpace
self.isAllMuted = personalSpace.isAllMuted
self.roomStatus = personalSpace.roomStatus
setAccessType()
self.showMuteButton = false
}
func removeListeners() {
if spaceListener != nil {
spaceListener.remove()
}
}
func setAccessType(){
guard let userId = Customer.current?.userId else { return }
if space.owner.memberInfo.userId == userId {
accessType = .owner
} else if space.speakerIds.contains(where: { $0 == userId }) { //check if current user is one of the speakerIds
accessType = .speaker
}
switch accessType {
case .owner:
showMusicButton = true
showRaiseHandButton = false
showMuteButton = true
case .speaker:
showRaiseHandButton = true
showMuteButton = true
showMusicButton = false
case .member:
showRaiseHandButton = true
showMuteButton = false
showMusicButton = false
}
}
func updateIsAllMuted(shouldMute: Bool) {
let newSpace = space
isAllMuted = shouldMute
SpaceService.updateIsAllMuted(isAllMuted: shouldMute, spaceId: space.spaceId)
newSpace.updateIsAllMuted(shouldMute)
space = newSpace
}
func startSpaceListener() {
spaceListener = db.collection(CollectionKeys.spaces)
.document(space.spaceId)
.addSnapshotListener({ (snapshot, error) in
if let error = error {
print("Error on space listener \(error.localizedDescription)")
self.handleError(title: "Error fetching space", message: error.localizedDescription)
return
}
guard let snapshot = snapshot,
let newSpace = Space(document: snapshot)
else {
print("Failed to create a space in listener")
return
}
self.space = newSpace
let memberIds = newSpace.members.map({$0.userId})
if !memberIds.contains(Customer.current!.userId) {
**//kick out user here or something**
}
})
}
func spaceMemberCellTapped(_ member: SpaceMember) {
selectedMember = member
memberActionSheetOffset = 0
}
func removeFromSpace() {
guard let member = selectedMember else { return }
SpaceService.removeMember(member: member, spaceId: space.spaceId) { (alertError) in
if let alertError = alertError {
print("Error toggling space status \(alertError)")
//self.handleAlertError(alertError: alertError)
return
}
self.space.removeMember(member: member)
}
selectedMember = nil
memberActionSheetOffset = UIScreen.main.bounds.height
}
}
在SpaceViewModel 的startSpaceListener() 中,如果用户的userId 不在空间列表中,我想关闭SpaceView。 Space、SpaceMember 和 SpaceOwner 只是一个没有任何装饰器的简单类。
我认为没有必要,但我可以根据要求提供模型的代码。
谢谢你:)
【问题讨论】:
标签: swift firebase google-cloud-firestore swiftui