Add participants during a conference call

This commit is contained in:
Benoit Martins 2024-07-09 14:05:40 +02:00
parent 39c7c6a4b1
commit 7bae9fd342
3 changed files with 114 additions and 77 deletions

View file

@ -34,6 +34,8 @@ struct CallView: View {
@ObservedObject var callViewModel: CallViewModel
@State private var addParticipantsViewModel: AddParticipantsViewModel?
private var idiom: UIUserInterfaceIdiom { UIDevice.current.userInterfaceIdiom }
@State private var orientation = UIDevice.current.orientation
@ -177,9 +179,12 @@ struct CallView: View {
}
if isShowParticipantsListFragment {
ParticipantsListFragment(callViewModel: callViewModel, isShowParticipantsListFragment: $isShowParticipantsListFragment)
ParticipantsListFragment(callViewModel: callViewModel, addParticipantsViewModel: addParticipantsViewModel ?? AddParticipantsViewModel(), isShowParticipantsListFragment: $isShowParticipantsListFragment)
.zIndex(4)
.transition(.move(edge: .bottom))
.onAppear {
addParticipantsViewModel = AddParticipantsViewModel()
}
}
if callViewModel.zrtpPopupDisplayed == true {

View file

@ -28,6 +28,8 @@ struct ParticipantsListFragment: View {
@ObservedObject var callViewModel: CallViewModel
@ObservedObject var addParticipantsViewModel: AddParticipantsViewModel
@State private var delayedColor = Color.white
@Binding var isShowParticipantsListFragment: Bool
@ -36,89 +38,96 @@ struct ParticipantsListFragment: View {
@State private var indexToRemove = -1
var body: some View {
ZStack {
VStack(spacing: 1) {
Rectangle()
.foregroundColor(delayedColor)
.edgesIgnoringSafeArea(.top)
.frame(height: 0)
.task(delayColor)
HStack {
Image("caret-left")
.renderingMode(.template)
.resizable()
.foregroundStyle(Color.orangeMain500)
.frame(width: 25, height: 25, alignment: .leading)
.padding(.all, 10)
.padding(.top, 2)
.padding(.leading, -10)
.onTapGesture {
delayColorDismiss()
withAnimation {
isShowParticipantsListFragment.toggle()
NavigationView {
ZStack {
VStack(spacing: 1) {
Rectangle()
.foregroundColor(delayedColor)
.edgesIgnoringSafeArea(.top)
.frame(height: 0)
.task(delayColor)
HStack {
Image("caret-left")
.renderingMode(.template)
.resizable()
.foregroundStyle(Color.orangeMain500)
.frame(width: 25, height: 25, alignment: .leading)
.padding(.all, 10)
.padding(.top, 2)
.padding(.leading, -10)
.onTapGesture {
delayColorDismiss()
withAnimation {
isShowParticipantsListFragment.toggle()
}
}
Text("\(callViewModel.participantList.count + 1) \(callViewModel.participantList.isEmpty ? "Participant" : "Participants")")
.multilineTextAlignment(.leading)
.default_text_style_orange_800(styleSize: 16)
Spacer()
}
.frame(maxWidth: .infinity)
.frame(height: 50)
.padding(.horizontal)
.padding(.bottom, 4)
.background(.white)
participantsList
HStack {
Spacer()
if callViewModel.myParticipantModel!.isAdmin {
NavigationLink(destination: {
AddParticipantsFragment(addParticipantsViewModel: addParticipantsViewModel, confirmAddParticipantsFunc: callViewModel.addParticipants)
.onAppear {
addParticipantsViewModel.participantsToAdd = []
}
}, label: {
Image("plus")
.resizable()
.renderingMode(.template)
.frame(width: 25, height: 25)
.foregroundStyle(.white)
.padding()
.background(Color.orangeMain500)
.clipShape(Circle())
.shadow(color: .black.opacity(0.2), radius: 4)
})
.padding()
}
Text("\(callViewModel.participantList.count + 1) \(callViewModel.participantList.isEmpty ? "Participant" : "Participants")")
.multilineTextAlignment(.leading)
.default_text_style_orange_800(styleSize: 16)
Spacer()
}
.padding(.trailing, 10)
}
.frame(maxWidth: .infinity)
.frame(height: 50)
.padding(.horizontal)
.padding(.bottom, 4)
.background(.white)
participantsList
HStack {
Spacer()
NavigationLink(destination: {
//AddParticipantsFragment()
}, label: {
Image("plus")
.resizable()
.renderingMode(.template)
.frame(width: 25, height: 25)
.foregroundStyle(.white)
.padding()
.background(Color.orangeMain500)
.clipShape(Circle())
.shadow(color: .black.opacity(0.2), radius: 4)
if self.isShowPopup {
let contentPopup = Text("Etes-vous sûr de vouloir supprimer \(callViewModel.participantList[indexToRemove].name) ?")
PopupView(isShowPopup: $isShowPopup,
title: Text("Supprimer un participant"),
content: contentPopup,
titleFirstButton: Text("Non"),
actionFirstButton: {self.isShowPopup.toggle()},
titleSecondButton: Text("Oui"),
actionSecondButton: {
callViewModel.removeParticipant(index: indexToRemove)
self.isShowPopup.toggle()
indexToRemove = -1
})
.padding()
}
.padding(.trailing, 10)
}
.background(.white)
if self.isShowPopup {
let contentPopup = Text("Etes-vous sûr de vouloir supprimer \(callViewModel.participantList[indexToRemove].name) ?")
PopupView(isShowPopup: $isShowPopup,
title: Text("Supprimer un participant"),
content: contentPopup,
titleFirstButton: Text("Non"),
actionFirstButton: {self.isShowPopup.toggle()},
titleSecondButton: Text("Oui"),
actionSecondButton: {
callViewModel.removeParticipant(index: indexToRemove)
self.isShowPopup.toggle()
indexToRemove = -1
})
.background(.black.opacity(0.65))
.onTapGesture {
self.isShowPopup.toggle()
indexToRemove = -1
.background(.black.opacity(0.65))
.onTapGesture {
self.isShowPopup.toggle()
indexToRemove = -1
}
}
}
.navigationBarHidden(true)
}
.navigationBarHidden(true)
}
@Sendable private func delayColor() async {
@ -256,5 +265,5 @@ struct ParticipantsListFragment: View {
}
#Preview {
ParticipantsListFragment(callViewModel: CallViewModel(), isShowParticipantsListFragment: .constant(true))
ParticipantsListFragment(callViewModel: CallViewModel(), addParticipantsViewModel: AddParticipantsViewModel(), isShowParticipantsListFragment: .constant(true))
}

View file

@ -25,6 +25,8 @@ import Combine
// swiftlint:disable type_body_length
class CallViewModel: ObservableObject {
static let TAG = "[CallViewModel]"
var coreContext = CoreContext.shared
var telecomManager = TelecomManager.shared
@ -1130,7 +1132,7 @@ class CallViewModel: ObservableObject {
let defaultAccount = core.defaultAccount
var subject = ""
if (defaultAccount != nil && defaultAccount!.params != nil && defaultAccount!.params!.audioVideoConferenceFactoryAddress != nil) {
if defaultAccount != nil && defaultAccount!.params != nil && defaultAccount!.params!.audioVideoConferenceFactoryAddress != nil {
Log.info("[CallViewModel] Merging \(callsCount) calls into a remotely hosted conference")
subject = "Remote group call"
} else {
@ -1150,5 +1152,26 @@ class CallViewModel: ObservableObject {
}
}
}
func addParticipants(participantsToAdd: [SelectedAddressModel]) {
var list: [SelectedAddressModel] = []
for selectedAddr in participantsToAdd {
if let found = list.first(where: { $0.address.weakEqual(address2: selectedAddr.address) }) {
Log.info("\(CallViewModel.TAG) Participant \(found.address.asStringUriOnly()) already in list, skipping")
continue
}
list.append(selectedAddr)
Log.info("\(CallViewModel.TAG) Added participant \(selectedAddr.address.asStringUriOnly())")
}
do {
try self.currentCall!.conference?.addParticipants(addresses: list.map { $0.address })
} catch {
}
Log.info("\(CallViewModel.TAG) \(list.count) participants added to conference")
}
}
// swiftlint:enable type_body_length