diff --git a/Linphone.xcodeproj/project.pbxproj b/Linphone.xcodeproj/project.pbxproj index ce886bd33..7915fe26b 100644 --- a/Linphone.xcodeproj/project.pbxproj +++ b/Linphone.xcodeproj/project.pbxproj @@ -128,6 +128,7 @@ D7A03FBD2ACC2DB60081A588 /* ContactsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7A03FBC2ACC2DB60081A588 /* ContactsView.swift */; }; D7A03FC02ACC2E390081A588 /* HistoryView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7A03FBF2ACC2E390081A588 /* HistoryView.swift */; }; D7A03FC62ACC458A0081A588 /* SplashScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7A03FC52ACC458A0081A588 /* SplashScreen.swift */; }; + D7A0ACBB2C415D630043AE79 /* StartGroupConversationFragment.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7A0ACBA2C415D630043AE79 /* StartGroupConversationFragment.swift */; }; D7A2EDD62AC18115005D90FC /* SharedMainViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7A2EDD52AC18115005D90FC /* SharedMainViewModel.swift */; }; D7ADF6002AFE356400212231 /* Avatar.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7ADF5FF2AFE356400212231 /* Avatar.swift */; }; D7B5066D2AEFA9B900CEB4E9 /* ContactInnerFragment.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7B5066C2AEFA9B900CEB4E9 /* ContactInnerFragment.swift */; }; @@ -309,6 +310,7 @@ D7A03FBC2ACC2DB60081A588 /* ContactsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContactsView.swift; sourceTree = ""; }; D7A03FBF2ACC2E390081A588 /* HistoryView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HistoryView.swift; sourceTree = ""; }; D7A03FC52ACC458A0081A588 /* SplashScreen.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SplashScreen.swift; sourceTree = ""; }; + D7A0ACBA2C415D630043AE79 /* StartGroupConversationFragment.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StartGroupConversationFragment.swift; sourceTree = ""; }; D7A2EDD52AC18115005D90FC /* SharedMainViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SharedMainViewModel.swift; sourceTree = ""; }; D7A2EDDA2AC19EEC005D90FC /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = Info.plist; sourceTree = ""; }; D7ADF5FF2AFE356400212231 /* Avatar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Avatar.swift; sourceTree = ""; }; @@ -832,6 +834,7 @@ D71968912B86369D00DF4459 /* ChatBubbleView.swift */, D72A9A042B9750A1000DC093 /* UIList.swift */, D759CB632C3FBD4200AC35E8 /* StartConversationFragment.swift */, + D7A0ACBA2C415D630043AE79 /* StartGroupConversationFragment.swift */, ); path = Fragments; sourceTree = ""; @@ -1115,6 +1118,7 @@ D7E6D0512AEBDBD500A57AAF /* ContactsListBottomSheet.swift in Sources */, D75759322B56D40900E7AC10 /* ZRTPPopup.swift in Sources */, D78E062E2BEA69F400CE3783 /* AudioRouteBottomSheet.swift in Sources */, + D7A0ACBB2C415D630043AE79 /* StartGroupConversationFragment.swift in Sources */, D7A2EDD62AC18115005D90FC /* SharedMainViewModel.swift in Sources */, D7A03FC62ACC458A0081A588 /* SplashScreen.swift in Sources */, D7E6ADF52B9876ED0009A2BC /* Attachment.swift in Sources */, @@ -1201,7 +1205,6 @@ GCC_PREPROCESSOR_DEFINITIONS = ( "$(inherited)", "DEBUG=1", - "USE_CRASHLYTICS=1", ); GENERATE_INFOPLIST_FILE = YES; INFOPLIST_FILE = msgNotificationService/Info.plist; @@ -1215,7 +1218,7 @@ ); LOCALIZATION_PREFERS_STRING_CATALOGS = YES; MARKETING_VERSION = 1.0; - OTHER_SWIFT_FLAGS = "$(inherited) -DUSE_CRASHLYTICS"; + OTHER_SWIFT_FLAGS = "$(inherited)"; PRODUCT_BUNDLE_IDENTIFIER = org.linphone.phone.msgNotificationService; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -1241,10 +1244,7 @@ DEVELOPMENT_TEAM = Z2V957B3D6; ENABLE_USER_SCRIPT_SANDBOXING = YES; GCC_C_LANGUAGE_STANDARD = gnu17; - GCC_PREPROCESSOR_DEFINITIONS = ( - "$(inherited)", - "USE_CRASHLYTICS=1", - ); + GCC_PREPROCESSOR_DEFINITIONS = "$(inherited)"; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_FILE = msgNotificationService/Info.plist; INFOPLIST_KEY_CFBundleDisplayName = msgNotificationService; @@ -1257,7 +1257,7 @@ ); LOCALIZATION_PREFERS_STRING_CATALOGS = YES; MARKETING_VERSION = 1.0; - OTHER_SWIFT_FLAGS = "$(inherited) -DUSE_CRASHLYTICS"; + OTHER_SWIFT_FLAGS = "$(inherited)"; PRODUCT_BUNDLE_IDENTIFIER = org.linphone.phone.msgNotificationService; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -1404,7 +1404,6 @@ GCC_PREPROCESSOR_DEFINITIONS = ( "$(inherited)", "DEBUG=1", - "USE_CRASHLYTICS=1", ); GENERATE_INFOPLIST_FILE = YES; INFOPLIST_FILE = Linphone/Info.plist; @@ -1431,7 +1430,7 @@ "LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = "@executable_path/../Frameworks"; MACOSX_DEPLOYMENT_TARGET = 13.3; MARKETING_VERSION = 6.0.0; - OTHER_SWIFT_FLAGS = "$(inherited) -DUSE_CRASHLYTICS"; + OTHER_SWIFT_FLAGS = "$(inherited)"; PRODUCT_BUNDLE_IDENTIFIER = org.linphone.phone; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = iphoneos; @@ -1457,10 +1456,7 @@ DEVELOPMENT_TEAM = Z2V957B3D6; ENABLE_HARDENED_RUNTIME = YES; ENABLE_PREVIEWS = YES; - GCC_PREPROCESSOR_DEFINITIONS = ( - "$(inherited)", - "USE_CRASHLYTICS=1", - ); + GCC_PREPROCESSOR_DEFINITIONS = "$(inherited)"; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_FILE = Linphone/Info.plist; INFOPLIST_KEY_NSCameraUsageDescription = "Camera usage is required for video VOIP calls"; @@ -1486,7 +1482,7 @@ "LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = "@executable_path/../Frameworks"; MACOSX_DEPLOYMENT_TARGET = 13.3; MARKETING_VERSION = 6.0.0; - OTHER_SWIFT_FLAGS = "$(inherited) -DUSE_CRASHLYTICS"; + OTHER_SWIFT_FLAGS = "$(inherited)"; PRODUCT_BUNDLE_IDENTIFIER = org.linphone.phone; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = iphoneos; diff --git a/Linphone/Assets.xcassets/conversation.imageset/Contents.json b/Linphone/Assets.xcassets/conversation.imageset/Contents.json new file mode 100644 index 000000000..949fb1205 --- /dev/null +++ b/Linphone/Assets.xcassets/conversation.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "conversation.svg", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Linphone/Assets.xcassets/conversation.imageset/conversation.svg b/Linphone/Assets.xcassets/conversation.imageset/conversation.svg new file mode 100644 index 000000000..1d534708b --- /dev/null +++ b/Linphone/Assets.xcassets/conversation.imageset/conversation.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/Linphone/Localizable.xcstrings b/Linphone/Localizable.xcstrings index e2bafb067..d887ef0c0 100644 --- a/Linphone/Localizable.xcstrings +++ b/Linphone/Localizable.xcstrings @@ -886,6 +886,74 @@ } } }, + "conversation_dialog_set_subject" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Set conversation subject" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Nommer la conversation" + } + } + } + }, + "conversation_dialog_subject_hint" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Conversation subject" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Nom de la conversation" + } + } + } + }, + "conversation_failed_to_create_toast" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Failed to create conversation!" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Échec de la création de la conversation !" + } + } + } + }, + "conversation_invalid_participant_due_to_security_mode_toast" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Can't create conversation with a participant not on the same domain due to security restrictions!" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Pour des raisons de sécurité, la création d'une conversation avec un participant d'un domaine tiers est désactivé." + } + } + } + }, "Conversations" : { }, @@ -1420,6 +1488,23 @@ }, "New contact" : { + }, + "new_conversation_create_group" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Create a group conversation" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Créer une conversation de groupe" + } + } + } }, "new_conversation_title" : { "extractionState" : "manual", diff --git a/Linphone/UI/Main/Contacts/Fragments/SipAddressesPopup.swift b/Linphone/UI/Main/Contacts/Fragments/SipAddressesPopup.swift index 8eadcb687..ffd1df3cb 100644 --- a/Linphone/UI/Main/Contacts/Fragments/SipAddressesPopup.swift +++ b/Linphone/UI/Main/Contacts/Fragments/SipAddressesPopup.swift @@ -1,9 +1,21 @@ -// -// SipAddressesPopup.swift -// Linphone -// -// Created by Benoît Martins on 03/07/2024. -// +/* + * Copyright (c) 2010-2023 Belledonne Communications SARL. + * + * This file is part of linphone-iphone + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ import SwiftUI import linphonesw diff --git a/Linphone/UI/Main/Conversations/ConversationsView.swift b/Linphone/UI/Main/Conversations/ConversationsView.swift index ea219b8a7..3918ed6c8 100644 --- a/Linphone/UI/Main/Conversations/ConversationsView.swift +++ b/Linphone/UI/Main/Conversations/ConversationsView.swift @@ -41,7 +41,7 @@ struct ConversationsView: View { MagicSearchSingleton.shared.searchForSuggestions() } } label: { - Image("plus-circle") + Image("conversation") .renderingMode(.template) .foregroundStyle(.white) .padding() diff --git a/Linphone/UI/Main/Conversations/Fragments/StartConversationFragment.swift b/Linphone/UI/Main/Conversations/Fragments/StartConversationFragment.swift index 1e4ee9e2a..25ae0ac87 100644 --- a/Linphone/UI/Main/Conversations/Fragments/StartConversationFragment.swift +++ b/Linphone/UI/Main/Conversations/Fragments/StartConversationFragment.swift @@ -136,7 +136,7 @@ struct StartConversationFragment: View { .padding(.horizontal) NavigationLink(destination: { - //StartGroupConversationFragment(startConversationViewModel: startConversationViewModel) + StartGroupConversationFragment(startConversationViewModel: startConversationViewModel) }, label: { HStack { HStack(alignment: .center) { @@ -150,9 +150,10 @@ struct StartConversationFragment: View { .background(Color.orangeMain500) .cornerRadius(40) - Text("history_call_start_create_group_call") + Text("new_conversation_create_group") .foregroundStyle(.black) .default_text_style_800(styleSize: 16) + .lineLimit(1) Spacer() @@ -184,16 +185,6 @@ struct StartConversationFragment: View { } ContactsListFragment(contactViewModel: ContactViewModel(), contactsListViewModel: ContactsListViewModel(), showingSheet: .constant(false), startCallFunc: { addr in - DispatchQueue.main.asyncAfter(deadline: .now() + 0.2) { - magicSearch.searchForContacts( - sourceFlags: MagicSearch.Source.Friends.rawValue | MagicSearch.Source.LdapServers.rawValue - ) - } - - startConversationViewModel.searchField = "" - magicSearch.currentFilterSuggestions = "" - delayColorDismiss() - withAnimation { startConversationViewModel.createOneToOneChatRoomWith(remote: addr) } @@ -232,6 +223,16 @@ struct StartConversationFragment: View { PopupLoadingView() .background(.black.opacity(0.65)) .onDisappear { + DispatchQueue.main.asyncAfter(deadline: .now() + 0.2) { + magicSearch.searchForContacts( + sourceFlags: MagicSearch.Source.Friends.rawValue | MagicSearch.Source.LdapServers.rawValue + ) + } + + startConversationViewModel.searchField = "" + magicSearch.currentFilterSuggestions = "" + delayColorDismiss() + isShowStartConversationFragment = false if startConversationViewModel.displayedConversation != nil { @@ -271,15 +272,6 @@ struct StartConversationFragment: View { var suggestionsList: some View { ForEach(0... + */ + +import SwiftUI + +struct StartGroupConversationFragment: View { + @ObservedObject var startConversationViewModel: StartConversationViewModel + @State var addParticipantsViewModel = AddParticipantsViewModel() + + var body: some View { + AddParticipantsFragment(addParticipantsViewModel: addParticipantsViewModel, confirmAddParticipantsFunc: startConversationViewModel.addParticipants) + .onAppear { + addParticipantsViewModel.participantsToAdd = startConversationViewModel.participants + } + } +} + +#Preview { + StartGroupConversationFragment(startConversationViewModel: StartConversationViewModel()) +} diff --git a/Linphone/UI/Main/Conversations/ViewModel/StartConversationViewModel.swift b/Linphone/UI/Main/Conversations/ViewModel/StartConversationViewModel.swift index 90f8754f5..5c60bb45c 100644 --- a/Linphone/UI/Main/Conversations/ViewModel/StartConversationViewModel.swift +++ b/Linphone/UI/Main/Conversations/ViewModel/StartConversationViewModel.swift @@ -61,83 +61,105 @@ class StartConversationViewModel: ObservableObject { participants = list } - /* func createGroupChatRoom() { coreContext.doOnCoreQueue { core in let account = core.defaultAccount - if (account == nil) { + if account == nil { Log.error( "\(StartConversationViewModel.TAG) No default account found, can't create group conversation!" ) return } - - operationInProgress = true - - let groupChatRoomSubject = subject - val params: ChatRoomParams = coreContext.core.createDefaultChatRoomParams() - params.isGroupEnabled = true - params.subject = groupChatRoomSubject - params.backend = ChatRoom.Backend.FlexisipChat - params.isEncryptionEnabled = true - - val participants = arrayListOf
() - for (participant in selection.value.orEmpty()) { - participants.add(participant.address) + + DispatchQueue.main.async { + self.operationInProgress = true } - val localAddress = account.params.identityAddress - - val participantsArray = arrayOf
() - val chatRoom = core.createChatRoom( - params, - localAddress, - participants.toArray(participantsArray) - ) - if (chatRoom != null) { - if (params.backend == ChatRoom.Backend.FlexisipChat) { - if (chatRoom.state == ChatRoom.State.Created) { - val id = LinphoneUtils.getChatRoomId(chatRoom) - Log.i( - "$TAG Group conversation [$id] ($groupChatRoomSubject) has been created" - ) - operationInProgress.postValue(false) - chatRoomCreatedEvent.postValue( - Event( - Pair( - chatRoom.localAddress.asStringUriOnly(), - chatRoom.peerAddress.asStringUriOnly() - ) - ) - ) - } else { - Log.i( - "$TAG Conversation [$groupChatRoomSubject] isn't in Created state yet, wait for it" - ) - chatRoom.addListener(chatRoomListener) - } - } else { - val id = LinphoneUtils.getChatRoomId(chatRoom) - Log.i("$TAG Conversation successfully created [$id] ($groupChatRoomSubject)") - operationInProgress.postValue(false) - chatRoomCreatedEvent.postValue( - Event( - Pair( - chatRoom.localAddress.asStringUriOnly(), - chatRoom.peerAddress.asStringUriOnly() - ) - ) - ) + + let groupChatRoomSubject = self.messageText + do { + let params: ChatRoomParams = try core.createDefaultChatRoomParams() + params.groupEnabled = true + params.subject = groupChatRoomSubject + params.backend = ChatRoom.Backend.FlexisipChat + params.encryptionEnabled = true + + var participantsTmp: [Address] = [] + self.participants.forEach { participant in + participantsTmp.append(participant.address) + } + + if account!.params != nil { + let localAddress = account!.params!.identityAddress + + let chatRoom = try core.createChatRoom( + params: params, + localAddr: localAddress, + participants: participantsTmp + ) + + if params.backend == ChatRoom.Backend.FlexisipChat { + if chatRoom.state == ChatRoom.State.Created { + let id = LinphoneUtils.getChatRoomId(room: chatRoom) + Log.info( + "\(StartConversationViewModel.TAG) Group conversation \(id) \(groupChatRoomSubject) has been created" + ) + + let model = ConversationModel(chatRoom: chatRoom) + if self.operationInProgress == false { + DispatchQueue.main.async { + self.operationInProgress = true + } + + DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) { + self.operationInProgress = false + self.displayedConversation = model + } + } else { + DispatchQueue.main.async { + self.operationInProgress = false + self.displayedConversation = model + } + } + } else { + Log.info( + "\(StartConversationViewModel.TAG) Conversation \(groupChatRoomSubject) isn't in Created state yet, wait for it" + ) + self.chatRoomAddDelegate(core: core, chatRoom: chatRoom) + } + } else { + let id = LinphoneUtils.getChatRoomId(room: chatRoom) + Log.info("\(StartConversationViewModel.TAG) Conversation successfully created \(id) \(groupChatRoomSubject)") + + let model = ConversationModel(chatRoom: chatRoom) + if self.operationInProgress == false { + DispatchQueue.main.async { + self.operationInProgress = true + } + + DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) { + self.operationInProgress = false + self.displayedConversation = model + } + } else { + DispatchQueue.main.async { + self.operationInProgress = false + self.displayedConversation = model + } + } + } + } + } catch let error { + Log.error("\(StartConversationViewModel.TAG) Failed to create group conversation \(groupChatRoomSubject)!") + Log.error("\(StartConversationViewModel.TAG) \(error)") + + DispatchQueue.main.async { + self.operationInProgress = false + ToastViewModel.shared.toastMessage = "Failed_to_create_conversation_error" + ToastViewModel.shared.displayToast = true } - } else { - Log.e("$TAG Failed to create group conversation [$groupChatRoomSubject]!") - operationInProgress.postValue(false) - chatRoomCreationErrorEvent.postValue( - Event(R.string.conversation_failed_to_create_toast) - ) } } } - */ func createOneToOneChatRoomWith(remote: Address) { coreContext.doOnCoreQueue { core in @@ -184,12 +206,9 @@ class StartConversationViewModel: ObservableObject { ) DispatchQueue.main.async { self.operationInProgress = false + ToastViewModel.shared.toastMessage = "Failed_to_create_conversation_invalid_participant_error" + ToastViewModel.shared.displayToast = true } - /* - chatRoomCreationErrorEvent.postValue( - Event(R.string.conversation_invalid_participant_due_to_security_mode_toast) - ) - */ return } @@ -207,16 +226,22 @@ class StartConversationViewModel: ObservableObject { let id = LinphoneUtils.getChatRoomId(room: chatRoom) Log.info("\(StartConversationViewModel.TAG) 1-1 conversation \(id) has been created") - /* - chatRoomCreatedEvent.postValue( - Event( - Pair( - chatRoom.localAddress.asStringUriOnly(), - chatRoom.peerAddress.asStringUriOnly() - ) - ) - ) - */ + let model = ConversationModel(chatRoom: chatRoom) + if self.operationInProgress == false { + DispatchQueue.main.async { + self.operationInProgress = true + } + + DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) { + self.operationInProgress = false + self.displayedConversation = model + } + } else { + DispatchQueue.main.async { + self.operationInProgress = false + self.displayedConversation = model + } + } } else { Log.info("\(StartConversationViewModel.TAG) Conversation isn't in Created state yet, wait for it") self.chatRoomAddDelegate(core: core, chatRoom: chatRoom) @@ -226,20 +251,21 @@ class StartConversationViewModel: ObservableObject { Log.info("\(StartConversationViewModel.TAG) Conversation successfully created \(id)") let model = ConversationModel(chatRoom: chatRoom) - DispatchQueue.main.async { - self.operationInProgress = false - self.displayedConversation = model + if self.operationInProgress == false { + DispatchQueue.main.async { + self.operationInProgress = true + } + + DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) { + self.operationInProgress = false + self.displayedConversation = model + } + } else { + DispatchQueue.main.async { + self.operationInProgress = false + self.displayedConversation = model + } } - /* - chatRoomCreatedEvent.postValue( - Event( - Pair( - chatRoom.localAddress.asStringUriOnly(), - chatRoom.peerAddress.asStringUriOnly() - ) - ) - ) - */ } } else { Log.warn( @@ -247,74 +273,87 @@ class StartConversationViewModel: ObservableObject { ) let model = ConversationModel(chatRoom: existingChatRoom!) - DispatchQueue.main.async { - self.operationInProgress = false - self.displayedConversation = model + if self.operationInProgress == false { + DispatchQueue.main.async { + self.operationInProgress = true + } + + DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) { + self.operationInProgress = false + self.displayedConversation = model + } + } else { + DispatchQueue.main.async { + self.operationInProgress = false + self.displayedConversation = model + } } - - - /* - chatRoomCreatedEvent.postValue( - Event( - Pair( - existingChatRoom.localAddress.asStringUriOnly(), - existingChatRoom.peerAddress.asStringUriOnly() - ) - ) - ) - */ } } catch { DispatchQueue.main.async { self.operationInProgress = false + ToastViewModel.shared.toastMessage = "Failed_to_create_conversation_error" + ToastViewModel.shared.displayToast = true } Log.error("\(StartConversationViewModel.TAG) Failed to create 1-1 conversation with \(remote.asStringUriOnly())!") } } } - func chatRoomAddDelegate(core: Core, chatRoom: ChatRoom) { - self.chatRoomSuscriptions.insert(chatRoom.publisher?.onConferenceJoined?.postOnCoreQueue { - (chatRoom: ChatRoom, eventLog: EventLog) in - let state = chatRoom.state - let id = LinphoneUtils.getChatRoomId(room: chatRoom) - Log.info("\(StartConversationViewModel.TAG) Conversation \(id) \(chatRoom.subject) state changed: \(state)") - if state == ChatRoom.State.Created { - Log.info("\(StartConversationViewModel.TAG) Conversation \(id) successfully created") - self.chatRoomSuscriptions.removeAll() - + func chatRoomAddDelegate(core: Core, chatRoom: ChatRoom) { + self.chatRoomSuscriptions.insert(chatRoom.publisher?.onConferenceJoined?.postOnCoreQueue { + (chatRoom: ChatRoom, eventLog: EventLog) in + let state = chatRoom.state + let id = LinphoneUtils.getChatRoomId(room: chatRoom) + Log.info("\(StartConversationViewModel.TAG) Conversation \(id) \(chatRoom.subject ?? "") state changed: \(state)") + if state == ChatRoom.State.Created { + Log.info("\(StartConversationViewModel.TAG) Conversation \(id) successfully created") + self.chatRoomSuscriptions.removeAll() + + let model = ConversationModel(chatRoom: chatRoom) + if self.operationInProgress == false { DispatchQueue.main.async { - let model = ConversationModel(chatRoom: chatRoom) + self.operationInProgress = true + } + + DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) { self.operationInProgress = false self.displayedConversation = model } - - /* - chatRoomCreatedEvent.postValue( - Event( - Pair( - chatRoom.localAddress.asStringUriOnly(), - chatRoom.peerAddress.asStringUriOnly() - ) - ) - ) - */ - } else if state == ChatRoom.State.CreationFailed { - Log.error("\(StartConversationViewModel.TAG) Conversation \(id) creation has failed!") - self.chatRoomSuscriptions.removeAll() + } else { DispatchQueue.main.async { self.operationInProgress = false + self.displayedConversation = model } - /* - chatRoomCreationErrorEvent.postValue( - Event(R.string.conversation_failed_to_create_toast) - ) - */ } - }) - } + } else if state == ChatRoom.State.CreationFailed { + Log.error("\(StartConversationViewModel.TAG) Conversation \(id) creation has failed!") + self.chatRoomSuscriptions.removeAll() + DispatchQueue.main.async { + self.operationInProgress = false + ToastViewModel.shared.toastMessage = "Failed_to_create_conversation_error" + ToastViewModel.shared.displayToast = true + } + } + }) - func isEndToEndEncryptionMandatory() -> Bool { - return false // TODO: Will be done later in SDK - } + self.chatRoomSuscriptions.insert(chatRoom.publisher?.onStateChanged?.postOnCoreQueue { + (chatRoom: ChatRoom, state: ChatRoom.State) in + let state = chatRoom.state + let id = LinphoneUtils.getChatRoomId(room: chatRoom) + if state == ChatRoom.State.CreationFailed { + Log.error("\(StartConversationViewModel.TAG) Conversation \(id) creation has failed!") + self.chatRoomSuscriptions.removeAll() + DispatchQueue.main.async { + self.operationInProgress = false + ToastViewModel.shared.toastMessage = "Failed_to_create_conversation_error" + ToastViewModel.shared.displayToast = true + } + } + }) + } + + func isEndToEndEncryptionMandatory() -> Bool { + return false // TODO: Will be done later in SDK + } } diff --git a/Linphone/UI/Main/Fragments/ToastView.swift b/Linphone/UI/Main/Fragments/ToastView.swift index 9ebbff919..d918e4140 100644 --- a/Linphone/UI/Main/Fragments/ToastView.swift +++ b/Linphone/UI/Main/Fragments/ToastView.swift @@ -206,7 +206,6 @@ struct ToastView: View { .default_text_style(styleSize: 15) .padding(8) - case "Failed_to_create_group_call_error": Text("conference_failed_to_create_group_call_toast") .multilineTextAlignment(.center) @@ -214,6 +213,20 @@ struct ToastView: View { .default_text_style(styleSize: 15) .padding(8) + case "Failed_to_create_conversation_error": + Text("conversation_failed_to_create_toast") + .multilineTextAlignment(.center) + .foregroundStyle(Color.redDanger500) + .default_text_style(styleSize: 15) + .padding(8) + + case "Failed_to_create_conversation_invalid_participant_error": + Text("conversation_invalid_participant_due_to_security_mode_toast") + .multilineTextAlignment(.center) + .foregroundStyle(Color.redDanger500) + .default_text_style(styleSize: 15) + .padding(8) + default: Text("Error") .multilineTextAlignment(.center) diff --git a/Linphone/UI/Main/History/Fragments/StartGroupCallFragment.swift b/Linphone/UI/Main/History/Fragments/StartGroupCallFragment.swift index 6e254127f..9e5386f4e 100644 --- a/Linphone/UI/Main/History/Fragments/StartGroupCallFragment.swift +++ b/Linphone/UI/Main/History/Fragments/StartGroupCallFragment.swift @@ -1,9 +1,21 @@ -// -// StartGroupCallFragment.swift -// Linphone -// -// Created by Benoît Martins on 24/06/2024. -// +/* + * Copyright (c) 2010-2023 Belledonne Communications SARL. + * + * This file is part of linphone-iphone + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ import SwiftUI diff --git a/Linphone/Utils/Extensions/DecodableExtension.swift b/Linphone/Utils/Extensions/DecodableExtension.swift index 71ccb81c5..5b6b7c93e 100644 --- a/Linphone/Utils/Extensions/DecodableExtension.swift +++ b/Linphone/Utils/Extensions/DecodableExtension.swift @@ -1,21 +1,21 @@ /* -* Copyright (c) 2010-2020 Belledonne Communications SARL. -* -* This file is part of linhome -* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -*/ + * Copyright (c) 2010-2023 Belledonne Communications SARL. + * + * This file is part of linphone-iphone + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ import Foundation diff --git a/Linphone/Utils/Extensions/EncodableExtension.swift b/Linphone/Utils/Extensions/EncodableExtension.swift index 8c0e75710..08eea64a4 100644 --- a/Linphone/Utils/Extensions/EncodableExtension.swift +++ b/Linphone/Utils/Extensions/EncodableExtension.swift @@ -1,21 +1,21 @@ /* -* Copyright (c) 2010-2020 Belledonne Communications SARL. -* -* This file is part of linhome -* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -*/ + * Copyright (c) 2010-2023 Belledonne Communications SARL. + * + * This file is part of linphone-iphone + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ import Foundation diff --git a/Linphone/Utils/Extensions/UIApplicationExtension.swift b/Linphone/Utils/Extensions/UIApplicationExtension.swift index 6ed48ae78..158b25515 100644 --- a/Linphone/Utils/Extensions/UIApplicationExtension.swift +++ b/Linphone/Utils/Extensions/UIApplicationExtension.swift @@ -1,21 +1,21 @@ /* -* Copyright (c) 2010-2020 Belledonne Communications SARL. -* -* This file is part of linhome -* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -*/ + * Copyright (c) 2010-2023 Belledonne Communications SARL. + * + * This file is part of linphone-iphone + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ import Foundation import UIKit diff --git a/Linphone/Utils/FileUtils.swift b/Linphone/Utils/FileUtils.swift index 97dc886e1..a7f8323d8 100644 --- a/Linphone/Utils/FileUtils.swift +++ b/Linphone/Utils/FileUtils.swift @@ -1,21 +1,21 @@ /* -* Copyright (c) 2010-2023 Belledonne Communications SARL. -* -* This file is part of linhome -* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -*/ + * Copyright (c) 2010-2023 Belledonne Communications SARL. + * + * This file is part of linphone-iphone + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ import UIKit import linphonesw diff --git a/Linphone/Utils/SingleSignOn/OIDAuthStateExtension.swift b/Linphone/Utils/SingleSignOn/OIDAuthStateExtension.swift index f9f541529..c68409782 100644 --- a/Linphone/Utils/SingleSignOn/OIDAuthStateExtension.swift +++ b/Linphone/Utils/SingleSignOn/OIDAuthStateExtension.swift @@ -1,21 +1,21 @@ /* -* Copyright (c) 2010-2020 Belledonne Communications SARL. -* -* This file is part of linhome -* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -*/ + * Copyright (c) 2010-2023 Belledonne Communications SARL. + * + * This file is part of linphone-iphone + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ import Foundation import AppAuth