Refactored MeetingsView

This commit is contained in:
Benoit Martins 2025-06-17 23:00:17 +02:00
parent 0d149c7b54
commit 8aa5b32787
10 changed files with 198 additions and 193 deletions

View file

@ -40,14 +40,11 @@ struct ContentView: View {
@State private var contactsListViewModel: ContactsListViewModel?
@State private var historyListViewModel: HistoryListViewModel?
@State private var conversationsListViewModel: ConversationsListViewModel?
@State private var meetingsListViewModel: MeetingsListViewModel?
//@ObservedObject var meetingWaitingRoomViewModel: MeetingWaitingRoomViewModel
//@ObservedObject var meetingsListViewModel: MeetingsListViewModel
//@ObservedObject var meetingViewModel: MeetingViewModel
//@Binding var index: Int
@State private var orientation = UIDevice.current.orientation
@State var sideMenuIsOpen: Bool = false
@ -513,9 +510,9 @@ struct ContentView: View {
historyListVM.resetFilterCallLogs()
} else if let conversationsListVM = conversationsListViewModel, sharedMainViewModel.indexView == 2 {
conversationsListVM.resetFilterConversations()
} else if sharedMainViewModel.indexView == 3 {
//meetingsListViewModel.currentFilter = ""
//meetingsListViewModel.computeMeetingsList()
} else if let meetingsListVM = meetingsListViewModel, sharedMainViewModel.indexView == 3 {
meetingsListVM.currentFilter = ""
meetingsListVM.computeMeetingsList()
}
} label: {
Image("caret-left")
@ -567,9 +564,9 @@ struct ContentView: View {
} else {
conversationsListVM.filterConversations(filter: text)
}
} else if sharedMainViewModel.indexView == 3 {
//meetingsListViewModel.currentFilter = text
//meetingsListViewModel.computeMeetingsList()
} else if let meetingsListVM = meetingsListViewModel, sharedMainViewModel.indexView == 3 {
meetingsListVM.currentFilter = text
meetingsListVM.computeMeetingsList()
}
}
} else {
@ -602,9 +599,9 @@ struct ContentView: View {
historyListVM.filterCallLogs(filter: text)
} else if let conversationsListVM = conversationsListViewModel, sharedMainViewModel.indexView == 2 {
conversationsListVM.filterConversations(filter: text)
} else if sharedMainViewModel.indexView == 3 {
//meetingsListViewModel.currentFilter = text
//meetingsListViewModel.computeMeetingsList()
} else if let meetingsListVM = meetingsListViewModel, sharedMainViewModel.indexView == 3 {
meetingsListVM.currentFilter = text
meetingsListVM.computeMeetingsList()
}
}
}
@ -726,31 +723,38 @@ struct ContentView: View {
}
}
} else if sharedMainViewModel.indexView == 3 {
//TODO a changer
NavigationView {
ZStack(alignment: .bottomTrailing) {
}
}
.navigationViewStyle(.stack)
/*
MeetingsView(
meetingsListViewModel: meetingsListViewModel,
meetingViewModel: meetingViewModel,
isShowScheduleMeetingFragment: $isShowScheduleMeetingFragment,
isShowSendCancelMeetingNotificationPopup: $isShowSendCancelMeetingNotificationPopup,
text: $text
)
.roundedCorner(25, corners: [.topRight, .topLeft])
.shadow(
color: (orientation == .landscapeLeft
|| orientation == .landscapeRight
|| UIScreen.main.bounds.size.width > UIScreen.main.bounds.size.height)
? .white.opacity(0.0)
: .black.opacity(0.2),
radius: 25
)
*/
}
if let meetingsListVM = meetingsListViewModel {
MeetingsView(
isShowScheduleMeetingFragment: $isShowScheduleMeetingFragment,
isShowSendCancelMeetingNotificationPopup: $isShowSendCancelMeetingNotificationPopup,
text: $text
)
.environmentObject(meetingsListVM)
.roundedCorner(25, corners: [.topRight, .topLeft])
.shadow(
color: (orientation == .landscapeLeft
|| orientation == .landscapeRight
|| UIScreen.main.bounds.size.width > UIScreen.main.bounds.size.height)
? .white.opacity(0.0)
: .black.opacity(0.2),
radius: 25
)
} else {
NavigationView {
VStack {
Spacer()
ProgressView()
.controlSize(.large)
Spacer()
}
.onAppear {
meetingsListViewModel = MeetingsListViewModel()
}
}
}
}
}
}
}
@ -976,7 +980,7 @@ struct ContentView: View {
.frame(maxWidth: .infinity)
.background(Color.gray100)
.ignoresSafeArea(.keyboard)
} else if let conversationsListVM = conversationsListViewModel, sharedMainViewModel.indexView == 2 {
} else if let conversationsListVM = conversationsListViewModel, let displayedConversation = sharedMainViewModel.displayedConversation, sharedMainViewModel.indexView == 2 {
ConversationFragment(
isShowConversationFragment: $isShowConversationFragment,
isShowStartCallGroupPopup: $isShowStartCallGroupPopup,
@ -989,13 +993,12 @@ struct ContentView: View {
.frame(maxWidth: .infinity)
.background(Color.gray100)
.ignoresSafeArea(.keyboard)
} else if sharedMainViewModel.indexView == 3 {
/*
MeetingFragment(meetingViewModel: meetingViewModel, meetingsListViewModel: meetingsListViewModel, isShowScheduleMeetingFragment: $isShowScheduleMeetingFragment, isShowSendCancelMeetingNotificationPopup: $isShowSendCancelMeetingNotificationPopup)
} else if let meetingsListVM = meetingsListViewModel, let displayedMeeting = sharedMainViewModel.displayedMeeting, sharedMainViewModel.indexView == 3 {
MeetingFragment(isShowScheduleMeetingFragment: $isShowScheduleMeetingFragment, isShowSendCancelMeetingNotificationPopup: $isShowSendCancelMeetingNotificationPopup)
.environmentObject(meetingsListVM)
.frame(maxWidth: .infinity)
.background(Color.gray100)
.ignoresSafeArea(.keyboard)
*/
}
}
@ -1235,19 +1238,14 @@ struct ContentView: View {
}
}
/*
if isShowScheduleMeetingFragment {
if let meetingsListVM = meetingsListViewModel, isShowScheduleMeetingFragment {
ScheduleMeetingFragment(
meetingViewModel: meetingViewModel,
meetingsListViewModel: meetingsListViewModel,
isShowScheduleMeetingFragment: $isShowScheduleMeetingFragment
)
.environmentObject(meetingsListVM)
.zIndex(3)
.transition(.move(edge: .bottom))
.onAppear {
}
}
*/
if isShowAccountProfileFragment {
AccountProfileFragment(
@ -1276,25 +1274,23 @@ struct ContentView: View {
.zIndex(3)
.transition(.move(edge: .trailing))
}
*/
if isShowSendCancelMeetingNotificationPopup {
if let meetingsListVM = meetingsListViewModel, isShowSendCancelMeetingNotificationPopup {
PopupView(isShowPopup: $isShowSendCancelMeetingNotificationPopup,
title: Text("meeting_schedule_cancel_dialog_title"),
content: Text("meeting_schedule_cancel_dialog_message"),
titleFirstButton: Text("dialog_cancel"),
actionFirstButton: {
sharedMainViewModel.displayedMeeting = nil
meetingsListViewModel.deleteSelectedMeeting()
meetingsListVM.deleteSelectedMeeting()
self.isShowSendCancelMeetingNotificationPopup.toggle(
) },
titleSecondButton: Text("dialog_ok"),
actionSecondButton: {
sharedMainViewModel.displayedMeeting = nil
if let meetingToDelete = self.meetingsListViewModel.selectedMeetingToDelete {
self.meetingViewModel.cancelMeetingWithNotifications(meeting: meetingToDelete)
meetingsListViewModel.deleteSelectedMeeting()
self.isShowSendCancelMeetingNotificationPopup.toggle()
}
meetingsListVM.cancelMeetingWithNotifications()
self.isShowSendCancelMeetingNotificationPopup.toggle()
})
.background(.black.opacity(0.65))
.zIndex(3)
@ -1302,7 +1298,6 @@ struct ContentView: View {
self.isShowSendCancelMeetingNotificationPopup.toggle()
}
}
*/
if isShowStartCallGroupPopup {
PopupView(
@ -1455,7 +1450,6 @@ class NavigationManager: ObservableObject {
//meetingViewModel: MeetingViewModel(),
//conversationForwardMessageViewModel: ConversationForwardMessageViewModel(),
//accountProfileViewModel: AccountProfileViewModel(),
//index: .constant(0)
)
}
// swiftlint:enable type_body_length

View file

@ -189,9 +189,10 @@ struct AddParticipantsFragment: View {
.padding(.trailing, 5)
}
if index < contactsManager.avatarListModel.count
&& contactsManager.avatarListModel[index].friend!.photo != nil
&& !contactsManager.avatarListModel[index].friend!.photo!.isEmpty {
if index < contactsManager.avatarListModel.count,
let friend = contactsManager.avatarListModel[index].friend,
let photo = friend.photo,
!photo.isEmpty {
Avatar(contactAvatarModel: contactsManager.avatarListModel[index], avatarSize: 50)
} else {
Image("profil-picture-default")
@ -199,7 +200,8 @@ struct AddParticipantsFragment: View {
.frame(width: 50, height: 50)
.clipShape(Circle())
}
Text((contactsManager.lastSearch[index].friend?.name)!)
Text((contactsManager.lastSearch[index].friend?.name ?? "")!)
.default_text_style(styleSize: 16)
.frame(maxWidth: .infinity, alignment: .leading)
.foregroundStyle(Color.orangeMain500)

View file

@ -28,8 +28,9 @@ struct MeetingFragment: View {
private var idiom: UIUserInterfaceIdiom { UIDevice.current.userInterfaceIdiom }
@State private var orientation = UIDevice.current.orientation
@ObservedObject var meetingViewModel: MeetingViewModel
@ObservedObject var meetingsListViewModel: MeetingsListViewModel
@EnvironmentObject var meetingsListViewModel: MeetingsListViewModel
@StateObject private var meetingViewModel = MeetingViewModel()
@State private var showDatePicker = false
@State private var showTimePicker = false
@ -63,21 +64,15 @@ struct MeetingFragment: View {
}
var body: some View {
let displayedMeetingUpdated = NotificationCenter.default
.publisher(for: NSNotification.Name("DisplayedMeetingUpdated"))
NavigationView {
ZStack(alignment: .bottomTrailing) {
VStack(spacing: 0) {
if #available(iOS 16.0, *) {
Rectangle()
.foregroundColor(Color.orangeMain500)
.edgesIgnoringSafeArea(.top)
.frame(height: 0)
} else if idiom != .pad && !(orientation == .landscapeLeft || orientation == .landscapeRight
|| UIScreen.main.bounds.size.width > UIScreen.main.bounds.size.height) {
Rectangle()
.foregroundColor(Color.orangeMain500)
.edgesIgnoringSafeArea(.top)
.frame(height: 1)
}
Rectangle()
.foregroundColor(Color.orangeMain500)
.edgesIgnoringSafeArea(.top)
.frame(height: 1)
HStack {
Image("caret-left")
@ -316,16 +311,10 @@ struct MeetingFragment: View {
})
}
.navigationViewStyle(StackNavigationViewStyle())
.onReceive(displayedMeetingUpdated) { _ in
if let displayedMeeting = SharedMainViewModel.shared.displayedMeeting {
meetingViewModel.loadExistingMeeting(meeting: displayedMeeting)
}
}
}
}
#Preview {
let model = MeetingViewModel()
model.subject = "Meeting subject"
model.conferenceUri = "linphone.com/lalalal.fr"
model.description = ""
return MeetingFragment(meetingViewModel: model
, meetingsListViewModel: MeetingsListViewModel()
, isShowScheduleMeetingFragment: .constant(true)
, isShowSendCancelMeetingNotificationPopup: .constant(false))
}

View file

@ -21,9 +21,8 @@ import SwiftUI
import linphonesw
struct MeetingsFragment: View {
@ObservedObject var meetingsListViewModel: MeetingsListViewModel
@ObservedObject var meetingViewModel: MeetingViewModel
@EnvironmentObject var meetingsListViewModel: MeetingsListViewModel
private var idiom: UIUserInterfaceIdiom { UIDevice.current.userInterfaceIdiom }
@ -86,7 +85,7 @@ struct MeetingsFragment: View {
.onTapGesture {
withAnimation {
if let meetingModel = model.model, meetingModel.confInfo.state != ConferenceInfo.State.Cancelled {
meetingViewModel.loadExistingMeeting(meeting: meetingModel)
SharedMainViewModel.shared.displayedMeeting = meetingModel
}
}
}
@ -191,7 +190,5 @@ struct MeetingsFragment: View {
}
#Preview {
MeetingsFragment(meetingsListViewModel: MeetingsListViewModel(),
meetingViewModel: MeetingViewModel(),
showingSheet: .constant(false), text: .constant(""))
MeetingsFragment(showingSheet: .constant(false), text: .constant(""))
}

View file

@ -28,7 +28,8 @@ struct MeetingsListBottomSheet: View {
private var idiom: UIUserInterfaceIdiom { UIDevice.current.userInterfaceIdiom }
@State private var orientation = UIDevice.current.orientation
@ObservedObject var meetingsListViewModel: MeetingsListViewModel
@EnvironmentObject var meetingsListViewModel: MeetingsListViewModel
@Binding var showingSheet: Bool
@Binding var isShowSendCancelMeetingNotificationPopup: Bool

View file

@ -27,8 +27,9 @@ struct ScheduleMeetingFragment: View {
private var idiom: UIUserInterfaceIdiom { UIDevice.current.userInterfaceIdiom }
@State private var orientation = UIDevice.current.orientation
@ObservedObject var meetingViewModel: MeetingViewModel
@ObservedObject var meetingsListViewModel: MeetingsListViewModel
@EnvironmentObject var meetingsListViewModel: MeetingsListViewModel
@StateObject private var meetingViewModel = MeetingViewModel()
@State private var delayedColor = Color.white
@State private var showDatePicker = false
@ -75,10 +76,6 @@ struct ScheduleMeetingFragment: View {
.padding(.leading, -10)
.onTapGesture {
withAnimation {
if let meeting = SharedMainViewModel.shared.displayedMeeting {
// reload meeting to cancel change from edit
meetingViewModel.loadExistingMeeting(meeting: meeting)
}
isShowScheduleMeetingFragment.toggle()
}
}
@ -506,9 +503,7 @@ struct ScheduleMeetingFragment: View {
}
#Preview {
ScheduleMeetingFragment(meetingViewModel: MeetingViewModel()
, meetingsListViewModel: MeetingsListViewModel()
, isShowScheduleMeetingFragment: .constant(true))
ScheduleMeetingFragment(isShowScheduleMeetingFragment: .constant(true))
}
// swiftlint:enable type_body_length

View file

@ -21,9 +21,8 @@ import SwiftUI
struct MeetingsView: View {
private var idiom: UIUserInterfaceIdiom { UIDevice.current.userInterfaceIdiom }
@ObservedObject var meetingsListViewModel: MeetingsListViewModel
@ObservedObject var meetingViewModel: MeetingViewModel
@EnvironmentObject var meetingsListViewModel: MeetingsListViewModel
@Binding var isShowScheduleMeetingFragment: Bool
@Binding var isShowSendCancelMeetingNotificationPopup: Bool
@ -36,29 +35,28 @@ struct MeetingsView: View {
ZStack(alignment: .bottomTrailing) {
if #available(iOS 16.0, *), idiom != .pad {
MeetingsFragment(meetingsListViewModel: meetingsListViewModel, meetingViewModel: meetingViewModel, showingSheet: $showingSheet, text: $text)
MeetingsFragment(showingSheet: $showingSheet, text: $text)
.sheet(isPresented: $showingSheet) {
MeetingsListBottomSheet(
meetingsListViewModel: meetingsListViewModel,
showingSheet: $showingSheet,
isShowSendCancelMeetingNotificationPopup: $isShowSendCancelMeetingNotificationPopup
)
.environmentObject(meetingsListViewModel)
.presentationDetents([.fraction(0.1)])
}
} else {
MeetingsFragment(meetingsListViewModel: meetingsListViewModel, meetingViewModel: meetingViewModel, showingSheet: $showingSheet, text: $text)
MeetingsFragment(showingSheet: $showingSheet, text: $text)
.halfSheet(showSheet: $showingSheet) {
MeetingsListBottomSheet(
meetingsListViewModel: meetingsListViewModel,
showingSheet: $showingSheet,
isShowSendCancelMeetingNotificationPopup: $isShowSendCancelMeetingNotificationPopup
)
.environmentObject(meetingsListViewModel)
} onDismiss: {}
}
Button {
withAnimation {
meetingViewModel.resetViewModelData()
isShowScheduleMeetingFragment.toggle()
}
} label: {
@ -80,8 +78,6 @@ struct MeetingsView: View {
#Preview {
MeetingsView(
meetingsListViewModel: MeetingsListViewModel(),
meetingViewModel: MeetingViewModel(),
isShowScheduleMeetingFragment: .constant(false),
isShowSendCancelMeetingNotificationPopup: .constant(false),
text: .constant("")

View file

@ -47,7 +47,6 @@ class MeetingViewModel: ObservableObject {
var conferenceScheduler: ConferenceScheduler?
private var mSchedulerDelegate: ConferenceSchedulerDelegate?
var conferenceInfoToEdit: ConferenceInfo?
@Published var myself: SelectedAddressModel?
@Published var fromDate: Date
@Published var toDate: Date
@ -71,6 +70,10 @@ class MeetingViewModel: ObservableObject {
selectedTimezoneIdx = knownTimezones.firstIndex(where: {$0 == selectedTimezone.identifier}) ?? 0
computeDateLabels()
computeTimeLabels()
if let displayedMeeting = SharedMainViewModel.shared.displayedMeeting {
self.loadExistingMeeting(meeting: displayedMeeting)
}
}
func resetViewModelData() {
@ -185,17 +188,18 @@ class MeetingViewModel: ObservableObject {
}
} else if state == ConferenceScheduler.State.Ready {
let conferenceAddress = self.conferenceScheduler?.info?.uri
if let confInfoToEdit = self.conferenceInfoToEdit {
Log.info("\(MeetingViewModel.TAG) Conference info \(confInfoToEdit.uri?.asStringUriOnly() ?? "'nil'") has been updated")
Log.info("\(MeetingViewModel.TAG) Conference info created, address will be \(conferenceAddress?.asStringUriOnly() ?? "'nil'")")
DispatchQueue.main.async {
ToastViewModel.shared.toastMessage = "Success_meeting_info_created_toast"
ToastViewModel.shared.displayToast = true
}
if SharedMainViewModel.shared.displayedMeeting != nil {
DispatchQueue.main.async {
ToastViewModel.shared.toastMessage = "Success_meeting_info_updated_toast"
ToastViewModel.shared.displayToast = true
}
} else {
Log.info("\(MeetingViewModel.TAG) Conference info created, address will be \(conferenceAddress?.asStringUriOnly() ?? "'nil'")")
DispatchQueue.main.async {
ToastViewModel.shared.toastMessage = "Success_meeting_info_created_toast"
ToastViewModel.shared.displayToast = true
NotificationCenter.default.post(
name: NSNotification.Name("DisplayedMeetingUpdated"),
object: nil
)
}
}
@ -210,9 +214,6 @@ class MeetingViewModel: ObservableObject {
}
}
} else if state == ConferenceScheduler.State.Updating {
DispatchQueue.main.async {
ToastViewModel.shared.displayToast = true
}
self.sendIcsInvitation(core: core)
}
}, onInvitationsSent: { (_: ConferenceScheduler, failedInvitations: [Address]) in
@ -295,73 +296,54 @@ class MeetingViewModel: ObservableObject {
}
}
func update() {
self.operationInProgress = true
CoreContext.shared.doOnCoreQueue { core in
Log.info("\(MeetingViewModel.TAG) Updating \(self.isBroadcastSelected ? "broadcast" : "meeting")")
if let conferenceInfo = self.conferenceInfoToEdit {
self.fillConferenceInfo(confInfo: conferenceInfo)
self.resetConferenceSchedulerAndListeners(core: core)
// Will trigger the conference update automatically
self.conferenceScheduler?.info = conferenceInfo
} else {
Log.error("No conference info to edit found!")
return
}
}
}
// Warning: must be called from core queue. Removed the dispatchQueue.main.async in order to have the animation properly trigger.
func loadExistingMeeting(meeting: MeetingModel) {
self.resetViewModelData()
self.subject = meeting.confInfo.subject ?? ""
self.description = meeting.confInfo.description ?? ""
self.fromDate = meeting.meetingDate
self.toDate = meeting.endDate
self.participants = []
CoreContext.shared.doOnCoreQueue { core in
let organizer = meeting.confInfo.organizer
var organizerFound = false
if let myAddr = core.defaultAccount?.contactAddress {
let isOrganizer = (organizer != nil) ? myAddr.weakEqual(address2: organizer!) : false
self.resetViewModelData()
self.subject = meeting.confInfo.subject ?? ""
self.description = meeting.confInfo.description ?? ""
self.fromDate = meeting.meetingDate
self.toDate = meeting.endDate
self.participants = []
CoreContext.shared.doOnCoreQueue { core in
let organizer = meeting.confInfo.organizer
var organizerFound = false
if let myAddr = core.defaultAccount?.contactAddress {
let isOrganizer = (organizer != nil) ? myAddr.weakEqual(address2: organizer!) : false
organizerFound = organizerFound || isOrganizer
ContactAvatarModel.getAvatarModelFromAddress(address: myAddr) { avatarResult in
DispatchQueue.main.async {
self.myself = SelectedAddressModel(addr: myAddr, avModel: avatarResult, isOrg: isOrganizer)
}
}
}
for pInfo in meeting.confInfo.participantInfos {
if let addr = pInfo.address {
let isOrganizer = (organizer != nil) ? addr.weakEqual(address2: organizer!) : false
organizerFound = organizerFound || isOrganizer
ContactAvatarModel.getAvatarModelFromAddress(address: myAddr) { avatarResult in
ContactAvatarModel.getAvatarModelFromAddress(address: addr) { avatarResult in
DispatchQueue.main.async {
self.myself = SelectedAddressModel(addr: myAddr, avModel: avatarResult, isOrg: isOrganizer)
}
}
}
for pInfo in meeting.confInfo.participantInfos {
if let addr = pInfo.address {
let isOrganizer = (organizer != nil) ? addr.weakEqual(address2: organizer!) : false
organizerFound = organizerFound || isOrganizer
ContactAvatarModel.getAvatarModelFromAddress(address: addr) { avatarResult in
DispatchQueue.main.async {
self.participants.append(SelectedAddressModel(addr: addr, avModel: avatarResult, isOrg: isOrganizer))
}
}
}
}
// if didn't find organizer, add him
if !organizerFound, let org = organizer {
ContactAvatarModel.getAvatarModelFromAddress(address: org) { avatarResult in
DispatchQueue.main.async {
self.participants.append(SelectedAddressModel(addr: org, avModel: avatarResult, isOrg: true))
self.participants.append(SelectedAddressModel(addr: addr, avModel: avatarResult, isOrg: isOrganizer))
}
}
}
}
self.conferenceUri = meeting.confInfo.uri?.asStringUriOnly() ?? ""
self.computeDateLabels()
self.computeTimeLabels()
SharedMainViewModel.shared.displayedMeeting = meeting
// if didn't find organizer, add him
if !organizerFound, let org = organizer {
ContactAvatarModel.getAvatarModelFromAddress(address: org) { avatarResult in
DispatchQueue.main.async {
self.participants.append(SelectedAddressModel(addr: org, avModel: avatarResult, isOrg: true))
}
}
}
}
self.conferenceUri = meeting.confInfo.uri?.asStringUriOnly() ?? ""
self.computeDateLabels()
self.computeTimeLabels()
}
func cancelMeetingWithNotifications(meeting: MeetingModel) {

View file

@ -141,8 +141,61 @@ class MeetingsListViewModel: ObservableObject {
// Only remaining meeting is the fake TodayMeeting, remove it too
meetingsList.removeAll()
}
ToastViewModel.shared.toastMessage = "Success_toast_meeting_deleted"
ToastViewModel.shared.displayToast = true
DispatchQueue.main.async {
ToastViewModel.shared.toastMessage = "Success_toast_meeting_deleted"
ToastViewModel.shared.displayToast = true
}
}
}
func cancelMeetingWithNotifications() {
CoreContext.shared.doOnCoreQueue { core in
if let meeting = self.selectedMeetingToDelete {
let conferenceScheduler = try? core.createConferenceScheduler()
//self.mSchedulerDelegate = ConferenceSchedulerDelegateStub(onStateChanged: { (_: ConferenceScheduler, state: ConferenceScheduler.State) in
let mSchedulerDelegate = ConferenceSchedulerDelegateStub(onStateChanged: { (_: ConferenceScheduler, state: ConferenceScheduler.State) in
Log.info("\(MeetingViewModel.TAG) Conference state changed \(state)")
if state == ConferenceScheduler.State.Ready {
self.sendIcsInvitation(core: core, conferenceScheduler: conferenceScheduler)
self.deleteSelectedMeeting()
}
}, onInvitationsSent: { (_: ConferenceScheduler, failedInvitations: [Address]) in
if failedInvitations.isEmpty {
Log.info("\(MeetingViewModel.TAG) All invitations have been sent")
} else {
var failInvList = ""
for failInv in failedInvitations {
if !failInvList.isEmpty {
failInvList += ", "
}
failInvList.append(failInv.asStringUriOnly())
}
Log.warn("\(MeetingViewModel.TAG) \(failedInvitations.count) invitations couldn't have been sent to: \(failInvList)")
DispatchQueue.main.async {
ToastViewModel.shared.toastMessage = "meeting_failed_to_send_part_of_invites_toast"
ToastViewModel.shared.displayToast = true
}
}
})
conferenceScheduler?.addDelegate(delegate: mSchedulerDelegate)
conferenceScheduler?.cancelConference(conferenceInfo: meeting.confInfo)
}
}
}
private func sendIcsInvitation(core: Core, conferenceScheduler: ConferenceScheduler?) {
if let chatRoomParams = try? core.createDefaultChatRoomParams() {
chatRoomParams.groupEnabled = false
chatRoomParams.backend = ChatRoom.Backend.FlexisipChat
chatRoomParams.encryptionEnabled = true
chatRoomParams.subject = "Meeting ics"
conferenceScheduler?.sendInvitations(chatRoomParams: chatRoomParams)
} else {
Log.error("\(MeetingViewModel.TAG) Failed to create default chatroom parameters. This should not happen")
}
}
}

View file

@ -10,7 +10,6 @@
660AAF7F2B839272004C0FA6 /* msgNotificationService.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = 660AAF7B2B839271004C0FA6 /* msgNotificationService.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
660D8A712B517D260092694D /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 660D8A702B517D260092694D /* GoogleService-Info.plist */; };
6613A0AE2BAEB7DF008923A4 /* MeetingFragment.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6613A0AD2BAEB7DF008923A4 /* MeetingFragment.swift */; };
6613A0B02BAEB7F4008923A4 /* MeetingsListFragment.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6613A0AF2BAEB7F4008923A4 /* MeetingsListFragment.swift */; };
6613A0B42BAEBE3F008923A4 /* MeetingViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6613A0B32BAEBE3F008923A4 /* MeetingViewModel.swift */; };
66162A202BDFC2F900DCE913 /* AddParticipantsViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66162A1F2BDFC2F900DCE913 /* AddParticipantsViewModel.swift */; };
66246C6A2C622AE900973E97 /* TimeZoneExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66246C692C622AE900973E97 /* TimeZoneExtension.swift */; };
@ -226,7 +225,6 @@
660AAF842B8392E0004C0FA6 /* msgNotificationService.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = msgNotificationService.entitlements; sourceTree = "<group>"; };
660D8A702B517D260092694D /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = "<group>"; };
6613A0AD2BAEB7DF008923A4 /* MeetingFragment.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MeetingFragment.swift; sourceTree = "<group>"; };
6613A0AF2BAEB7F4008923A4 /* MeetingsListFragment.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MeetingsListFragment.swift; sourceTree = "<group>"; };
6613A0B32BAEBE3F008923A4 /* MeetingViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MeetingViewModel.swift; sourceTree = "<group>"; };
66162A1F2BDFC2F900DCE913 /* AddParticipantsViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddParticipantsViewModel.swift; sourceTree = "<group>"; };
66246C692C622AE900973E97 /* TimeZoneExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimeZoneExtension.swift; sourceTree = "<group>"; };
@ -491,7 +489,6 @@
children = (
66E50A4A2BD12B7800AD61CA /* MeetingsFragment.swift */,
6613A0AD2BAEB7DF008923A4 /* MeetingFragment.swift */,
6613A0AF2BAEB7F4008923A4 /* MeetingsListFragment.swift */,
66F08C882C2AFEF700D9AE2F /* MeetingsListBottomSheet.swift */,
6646A7A22BB2E224006B842A /* ScheduleMeetingFragment.swift */,
66F626B12BCEBB86003E2DEC /* AddParticipantsFragment.swift */,
@ -1242,7 +1239,6 @@
66E56BC92BA4A6D7006CE56F /* MeetingsListViewModel.swift in Sources */,
D726E4392B16440C0083C415 /* ContactAvatarModel.swift in Sources */,
C67586AE2C09F23C002E77BF /* URLExtension.swift in Sources */,
6613A0B02BAEB7F4008923A4 /* MeetingsListFragment.swift in Sources */,
D76005F62B0798B00054B79A /* IntExtension.swift in Sources */,
D79F2D0A2C47F4BF0038FA07 /* TouchFeedback.swift in Sources */,
D78E06282BE3811D00CE3783 /* CallStatsModel.swift in Sources */,