Use new core.createChatRoom() that replaces the older version

This commit is contained in:
Benoit Martins 2025-03-11 11:03:36 +01:00
parent 5c14429eda
commit b7ef60692d
13 changed files with 411 additions and 430 deletions

View file

@ -7,7 +7,7 @@
objects = {
/* Begin PBXBuildFile section */
4ED1F0A881A9ACB5977A8987 /* (null) in Frameworks */ = {isa = PBXBuildFile; };
4ED1F0A881A9ACB5977A8987 /* BuildFile in Frameworks */ = {isa = PBXBuildFile; };
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 */; };
@ -412,7 +412,7 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
4ED1F0A881A9ACB5977A8987 /* (null) in Frameworks */,
4ED1F0A881A9ACB5977A8987 /* BuildFile in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -1388,13 +1388,14 @@
CODE_SIGN_ENTITLEMENTS = msgNotificationService/msgNotificationService.entitlements;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 70;
CURRENT_PROJECT_VERSION = 72;
DEVELOPMENT_TEAM = Z2V957B3D6;
ENABLE_USER_SCRIPT_SANDBOXING = NO;
GCC_C_LANGUAGE_STANDARD = gnu17;
GCC_PREPROCESSOR_DEFINITIONS = (
"$(inherited)",
"DEBUG=1",
"USE_CRASHLYTICS=1",
);
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = msgNotificationService/Info.plist;
@ -1408,7 +1409,7 @@
);
LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
MARKETING_VERSION = 6.0.0;
OTHER_SWIFT_FLAGS = "$(inherited)";
OTHER_SWIFT_FLAGS = "$(inherited) -DUSE_CRASHLYTICS";
PRODUCT_BUNDLE_IDENTIFIER = org.linphone.phone.msgNotificationService;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
@ -1430,11 +1431,14 @@
CODE_SIGN_ENTITLEMENTS = msgNotificationService/msgNotificationService.entitlements;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 70;
CURRENT_PROJECT_VERSION = 72;
DEVELOPMENT_TEAM = Z2V957B3D6;
ENABLE_USER_SCRIPT_SANDBOXING = NO;
GCC_C_LANGUAGE_STANDARD = gnu17;
GCC_PREPROCESSOR_DEFINITIONS = "$(inherited)";
GCC_PREPROCESSOR_DEFINITIONS = (
"$(inherited)",
"USE_CRASHLYTICS=1",
);
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = msgNotificationService/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = msgNotificationService;
@ -1447,7 +1451,7 @@
);
LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
MARKETING_VERSION = 6.0.0;
OTHER_SWIFT_FLAGS = "$(inherited)";
OTHER_SWIFT_FLAGS = "$(inherited) -DUSE_CRASHLYTICS";
PRODUCT_BUNDLE_IDENTIFIER = org.linphone.phone.msgNotificationService;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
@ -1584,7 +1588,7 @@
ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = NO;
CODE_SIGN_ENTITLEMENTS = Linphone/Linphone.entitlements;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 70;
CURRENT_PROJECT_VERSION = 72;
DEAD_CODE_STRIPPING = YES;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DEVELOPMENT_ASSET_PATHS = "\"Linphone/Preview Content\"";
@ -1594,6 +1598,7 @@
GCC_PREPROCESSOR_DEFINITIONS = (
"$(inherited)",
"DEBUG=1",
"USE_CRASHLYTICS=1",
);
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = Linphone/Info.plist;
@ -1623,7 +1628,7 @@
"LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = "@executable_path/../Frameworks";
MACOSX_DEPLOYMENT_TARGET = 13.3;
MARKETING_VERSION = 6.0.0;
OTHER_SWIFT_FLAGS = "$(inherited)";
OTHER_SWIFT_FLAGS = "$(inherited) -DUSE_CRASHLYTICS";
PRODUCT_BUNDLE_IDENTIFIER = org.linphone.phone;
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = iphoneos;
@ -1643,13 +1648,16 @@
ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = NO;
CODE_SIGN_ENTITLEMENTS = Linphone/Linphone.entitlements;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 70;
CURRENT_PROJECT_VERSION = 72;
DEAD_CODE_STRIPPING = YES;
DEVELOPMENT_ASSET_PATHS = "\"Linphone/Preview Content\"";
DEVELOPMENT_TEAM = Z2V957B3D6;
ENABLE_HARDENED_RUNTIME = YES;
ENABLE_PREVIEWS = YES;
GCC_PREPROCESSOR_DEFINITIONS = "$(inherited)";
GCC_PREPROCESSOR_DEFINITIONS = (
"$(inherited)",
"USE_CRASHLYTICS=1",
);
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = Linphone/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = Linphone;
@ -1678,7 +1686,7 @@
"LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = "@executable_path/../Frameworks";
MACOSX_DEPLOYMENT_TARGET = 13.3;
MARKETING_VERSION = 6.0.0;
OTHER_SWIFT_FLAGS = "$(inherited)";
OTHER_SWIFT_FLAGS = "$(inherited) -DUSE_CRASHLYTICS";
PRODUCT_BUNDLE_IDENTIFIER = org.linphone.phone;
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = iphoneos;

View file

@ -43,7 +43,7 @@ final class CoreContext: ObservableObject {
@Published var coreIsStarted: Bool = false
@Published var accounts: [AccountModel] = []
@Published var shortcuts: [ShortcutModel] = []
private var mCore: Core!
var mCore: Core!
private var mIterateSuscription: AnyCancellable?
var bearerAuthInfoPendingPasswordUpdate: AuthInfo?

View file

@ -242,6 +242,15 @@ class CorePreferences {
}
}
static var defaultDomain: String {
get {
return Config.get().getString(section: "app", key: "default_domain", defaultString: "sip.linphone.org")
}
set {
Config.get().setString(section: "app", key: "default_domain", value: newValue)
}
}
private func copy(from: String, to: String, overrideIfExists: Bool = false) {
let fileManager = FileManager.default
if fileManager.fileExists(atPath: to), !overrideIfExists {

View file

@ -3486,6 +3486,17 @@
}
}
},
"conversation_one_to_one_hidden_subject" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Dummy subject"
}
}
}
},
"conversation_reply_to_message_title" : {
"extractionState" : "manual",
"localizations" : {

View file

@ -2262,16 +2262,14 @@ struct CallView: View {
HStack(spacing: 0) {
VStack {
Button {
if callViewModel.isOneOneCall && callViewModel.remoteAddress != nil {
callViewModel.createOneToOneChatRoomWith(remote: callViewModel.remoteAddress!)
}
callViewModel.createConversation()
} label: {
HStack {
if !callViewModel.operationInProgress {
Image("chat-teardrop-text")
.renderingMode(.template)
.resizable()
.foregroundStyle(callViewModel.isOneOneCall ? .white : Color.gray500)
.foregroundStyle(.white)
.frame(width: 32, height: 32)
} else {
ProgressView()
@ -2279,8 +2277,13 @@ struct CallView: View {
.progressViewStyle(CircularProgressViewStyle(tint: .white))
.frame(width: 32, height: 32, alignment: .center)
.onDisappear {
if callViewModel.isOneOneCall && callViewModel.displayedConversation != nil {
conversationViewModel.changeDisplayedChatRoom(conversationModel: callViewModel.displayedConversation!)
if callViewModel.displayedConversation != nil {
indexPage = 2
self.conversationViewModel.changeDisplayedChatRoom(conversationModel: callViewModel.displayedConversation!)
callViewModel.displayedConversation = nil
withAnimation {
telecomManager.callDisplayed = false
}
}
}
}
@ -2288,9 +2291,8 @@ struct CallView: View {
}
.buttonStyle(PressedButtonStyle(buttonSize: buttonSize))
.frame(width: buttonSize, height: buttonSize)
.background(callViewModel.isOneOneCall ? Color.gray500 : .white)
.background(Color.gray500)
.cornerRadius(40)
.disabled(!callViewModel.isOneOneCall)
Text("call_action_show_messages")
.foregroundStyle(.white)
@ -2631,16 +2633,14 @@ struct CallView: View {
VStack {
Button {
if callViewModel.isOneOneCall && callViewModel.remoteAddress != nil {
callViewModel.createOneToOneChatRoomWith(remote: callViewModel.remoteAddress!)
}
callViewModel.createConversation()
} label: {
HStack {
if !callViewModel.operationInProgress {
Image("chat-teardrop-text")
.renderingMode(.template)
.resizable()
.foregroundStyle(callViewModel.isOneOneCall ? .white : Color.gray500)
.foregroundStyle(.white)
.frame(width: 32, height: 32)
} else {
ProgressView()
@ -2648,7 +2648,7 @@ struct CallView: View {
.progressViewStyle(CircularProgressViewStyle(tint: .white))
.frame(width: 32, height: 32, alignment: .center)
.onDisappear {
if callViewModel.isOneOneCall && callViewModel.displayedConversation != nil {
if callViewModel.displayedConversation != nil {
conversationViewModel.changeDisplayedChatRoom(conversationModel: callViewModel.displayedConversation!)
}
}
@ -2657,9 +2657,8 @@ struct CallView: View {
}
.buttonStyle(PressedButtonStyle(buttonSize: buttonSize))
.frame(width: buttonSize, height: buttonSize)
.background(callViewModel.isOneOneCall ? Color.gray500 : .white)
.background(Color.gray500)
.cornerRadius(40)
.disabled(!callViewModel.isOneOneCall)
Text("call_action_show_messages")
.foregroundStyle(.white)

View file

@ -1162,141 +1162,179 @@ class CallViewModel: ObservableObject {
Log.info("\(CallViewModel.TAG) \(list.count) participants added to conference")
}
func createOneToOneChatRoomWith(remote: Address) {
CoreContext.shared.doOnCoreQueue { core in
let account = core.defaultAccount
if account == nil {
Log.error(
"\(StartConversationViewModel.TAG) No default account found, can't create conversation with \(remote.asStringUriOnly())!"
)
return
func createConversation() {
if currentCall != nil {
self.operationInProgress = true
CoreContext.shared.doOnCoreQueue { _ in
let existingConversation = self.lookupCurrentCallConversation(call: self.currentCall!)
if existingConversation != nil {
Log.info("\(CallViewModel.TAG) Found existing conversation \(LinphoneUtils.getConversationId(chatRoom: existingConversation!)), going to it")
let model = ConversationModel(chatRoom: existingConversation!)
DispatchQueue.main.async {
self.displayedConversation = model
self.operationInProgress = false
}
} else {
Log.info("\(CallViewModel.TAG) No existing conversation was found, let's create it")
self.createCurrentCallConversation(call: self.currentCall!)
}
}
}
}
func lookupCurrentCallConversation(call: Call) -> ChatRoom? {
let localAddress = call.callLog?.localAddress
let remoteAddress = call.remoteAddress
let params: ConferenceParams? = nil
let existingConversation: ChatRoom?
if call.conference != nil {
existingConversation = call.core?.searchChatRoom(
params: params,
localAddr: localAddress,
remoteAddr: remoteAddress,
participants: []
)
} else {
let participants = [remoteAddress!]
existingConversation = call.core?.searchChatRoom(
params: params,
localAddr: localAddress,
remoteAddr: nil,
participants: participants
)
}
if existingConversation != nil {
Log.info("\(CallViewModel.TAG) Found existing conversation \(existingConversation!.peerAddress?.asStringUriOnly() ?? "") found for current call with local address \(localAddress?.asStringUriOnly() ?? "") and remote address \(remoteAddress?.asStringUriOnly() ?? "")")
} else {
Log.warn("\(CallViewModel.TAG) No existing conversation found for current call with local address \(localAddress?.asStringUriOnly() ?? "") and remote address \(remoteAddress?.asStringUriOnly() ?? "")")
}
return existingConversation
}
func createCurrentCallConversation(call: Call) {
if let remoteAddress = call.remoteAddress {
let participants = [remoteAddress]
let core = call.core
DispatchQueue.main.async {
self.operationInProgress = true
}
do {
let params: ChatRoomParams = try core.createDefaultChatRoomParams()
params.groupEnabled = false
params.subject = "Dummy subject"
params.ephemeralLifetime = 0 // Make sure ephemeral is disabled by default
let sameDomain = remote.domain == account?.params?.domain ?? ""
if StartConversationViewModel.isEndToEndEncryptionMandatory() && sameDomain {
Log.info("\(StartConversationViewModel.TAG) Account is in secure mode & domain matches, creating a E2E conversation")
params.backend = ChatRoom.Backend.FlexisipChat
params.encryptionEnabled = true
} else if !StartConversationViewModel.isEndToEndEncryptionMandatory() {
if LinphoneUtils.isEndToEndEncryptedChatAvailable(core: core) {
Log.info(
"\(StartConversationViewModel.TAG) Account is in interop mode but LIME is available, creating a E2E conversation"
)
params.backend = ChatRoom.Backend.FlexisipChat
params.encryptionEnabled = true
} else {
Log.info(
"\(StartConversationViewModel.TAG) Account is in interop mode but LIME isn't available, creating a SIP simple conversation"
)
params.backend = ChatRoom.Backend.Basic
params.encryptionEnabled = false
if let params = getChatRoomParams(call: call) {
do {
if core != nil {
let chatRoom = try core!.createChatRoom(params: params, participants: participants)
if params.chatParams?.backend == ChatRoom.Backend.FlexisipChat {
if chatRoom.state == ChatRoom.State.Created {
let chatRoomId = LinphoneUtils.getConversationId(chatRoom: chatRoom)
Log.info("\(CallViewModel.TAG) 1-1 conversation \(chatRoomId) has been created")
let model = ConversationModel(chatRoom: chatRoom)
DispatchQueue.main.async {
self.displayedConversation = model
self.operationInProgress = false
}
} else {
Log.info("\(CallViewModel.TAG) Conversation isn't in Created state yet, wait for it")
self.chatRoomAddDelegate(core: core!, chatRoom: chatRoom)
}
} else {
let id = LinphoneUtils.getConversationId(chatRoom: chatRoom)
Log.info("\(CallViewModel.TAG) Conversation successfully created \(id)")
let model = ConversationModel(chatRoom: chatRoom)
DispatchQueue.main.async {
self.displayedConversation = model
self.operationInProgress = false
}
}
}
} else {
} catch {
Log.error(
"\(StartConversationViewModel.TAG) Account is in secure mode, can't chat with SIP address of different domain \(remote.asStringUriOnly())"
"\(CallViewModel.TAG) Failed to create 1-1 conversation with \(remoteAddress.asStringUriOnly())"
)
DispatchQueue.main.async {
self.operationInProgress = false
ToastViewModel.shared.toastMessage = "Failed_to_create_conversation_invalid_participant_error"
ToastViewModel.shared.toastMessage = "Failed_to_create_conversation_error"
ToastViewModel.shared.displayToast = true
}
return
}
}
}
}
func getChatRoomParams(call: Call) -> ConferenceParams? {
let localAddress = call.callLog?.localAddress
let remoteAddress = call.remoteAddress
let core = call.core
if let account = LinphoneUtils.getAccountForAddress(address: localAddress!) ?? LinphoneUtils.getDefaultAccount() {
do {
let params = try coreContext.mCore.createConferenceParams(conference: call.conference)
params.chatEnabled = true
params.groupEnabled = false
params.subject = NSLocalizedString("conversation_one_to_one_hidden_subject", comment: "")
params.account = account
let participants = [remote]
let localAddress = account?.params?.identityAddress
let existingChatRoom = core.searchChatRoom(params: params, localAddr: localAddress, remoteAddr: nil, participants: participants)
if existingChatRoom == nil {
Log.info(
"\(StartConversationViewModel.TAG) No existing 1-1 conversation between local account "
+ "\(localAddress?.asStringUriOnly() ?? "") and remote \(remote.asStringUriOnly()) was found for given parameters, let's create it"
)
let chatRoom = try core.createChatRoom(params: params, localAddr: localAddress, participants: participants)
if params.backend == ChatRoom.Backend.FlexisipChat {
if chatRoom.state == ChatRoom.State.Created {
let id = LinphoneUtils.getChatRoomId(room: chatRoom)
Log.info("\(StartConversationViewModel.TAG) 1-1 conversation \(id) 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 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)")
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.warn(
"\(StartConversationViewModel.TAG) A 1-1 conversation between local account \(localAddress?.asStringUriOnly() ?? "") and remote \(remote.asStringUriOnly()) for given parameters already exists!"
)
if let chatParams = params.chatParams {
chatParams.ephemeralLifetime = 0 // Make sure ephemeral is disabled by default
let model = ConversationModel(chatRoom: existingChatRoom!)
if self.operationInProgress == false {
DispatchQueue.main.async {
self.operationInProgress = true
}
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
self.operationInProgress = false
self.displayedConversation = model
let sameDomain = remoteAddress?.domain == CorePreferences.defaultDomain && remoteAddress?.domain == account.params?.domain
if account.params != nil && (account.params!.instantMessagingEncryptionMandatory && sameDomain) {
Log.info(
"\(CallViewModel.TAG) Account is in secure mode & domain matches, requesting E2E encryption"
)
chatParams.backend = ChatRoom.Backend.FlexisipChat
params.securityLevel = Conference.SecurityLevel.EndToEnd
} else if account.params != nil && !account.params!.instantMessagingEncryptionMandatory {
if core != nil && LinphoneUtils.isEndToEndEncryptedChatAvailable(core: core!) {
Log.info(
"\(CallViewModel.TAG) Account is in interop mode but LIME is available, requesting E2E encryption"
)
chatParams.backend = ChatRoom.Backend.FlexisipChat
params.securityLevel = Conference.SecurityLevel.EndToEnd
} else {
Log.info(
"\(CallViewModel.TAG) Account is in interop mode but LIME isn't available, disabling E2E encryption"
)
chatParams.backend = ChatRoom.Backend.Basic
params.securityLevel = Conference.SecurityLevel.None
}
} else {
DispatchQueue.main.async {
self.operationInProgress = false
self.displayedConversation = model
}
Log.error(
"\(CallViewModel.TAG) Account is in secure mode, can't chat with SIP address of different domain \(remoteAddress?.asStringUriOnly() ?? "")"
)
return nil
}
return params
} else {
return nil
}
} 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())!")
Log.error("\(CallViewModel.TAG) Can't create ConferenceParams \(remoteAddress?.asStringUriOnly() ?? "")")
return nil
}
} else {
return nil
}
}
func goToConversation(model: ConversationModel) {
if self.operationInProgress == false {
DispatchQueue.main.async {
self.operationInProgress = true
}
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
self.displayedConversation = model
self.operationInProgress = false
}
} else {
DispatchQueue.main.async {
self.displayedConversation = model
self.operationInProgress = false
}
}
}
@ -1331,13 +1369,13 @@ class CallViewModel: ObservableObject {
}
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
self.operationInProgress = false
self.displayedConversation = model
self.operationInProgress = false
}
} else {
DispatchQueue.main.async {
self.operationInProgress = false
self.displayedConversation = model
self.operationInProgress = false
}
}
} else if state == ChatRoom.State.CreationFailed {

View file

@ -43,7 +43,7 @@ class ContactViewModel: ObservableObject {
let account = core.defaultAccount
if account == nil {
Log.error(
"\(StartConversationViewModel.TAG) No default account found, can't create conversation with \(remote.asStringUriOnly())!"
"\(ConversationForwardMessageViewModel.TAG) No default account found, can't create conversation with \(remote.asStringUriOnly())"
)
return
}
@ -53,37 +53,42 @@ class ContactViewModel: ObservableObject {
}
do {
let params: ChatRoomParams = try core.createDefaultChatRoomParams()
let params = try core.createConferenceParams(conference: nil)
params.chatEnabled = true
params.groupEnabled = false
params.subject = "Dummy subject"
params.ephemeralLifetime = 0 // Make sure ephemeral is disabled by default
params.subject = NSLocalizedString("conversation_one_to_one_hidden_subject", comment: "")
params.account = account
let sameDomain = remote.domain == account?.params?.domain ?? ""
if StartConversationViewModel.isEndToEndEncryptionMandatory() && sameDomain {
Log.info("\(StartConversationViewModel.TAG) Account is in secure mode & domain matches, creating a E2E conversation")
params.backend = ChatRoom.Backend.FlexisipChat
params.encryptionEnabled = true
} else if !StartConversationViewModel.isEndToEndEncryptionMandatory() {
guard let chatParams = params.chatParams else { return }
chatParams.ephemeralLifetime = 0 // Make sure ephemeral is disabled by default
let sameDomain = remote.domain == CorePreferences.defaultDomain && remote.domain == account!.params?.domain
if account!.params != nil && (account!.params!.instantMessagingEncryptionMandatory && sameDomain) {
Log.info("\(ConversationForwardMessageViewModel.TAG) Account is in secure mode & domain matches, creating an E2E encrypted conversation")
chatParams.backend = ChatRoom.Backend.FlexisipChat
params.securityLevel = Conference.SecurityLevel.EndToEnd
} else if account!.params != nil && (!account!.params!.instantMessagingEncryptionMandatory) {
if LinphoneUtils.isEndToEndEncryptedChatAvailable(core: core) {
Log.info(
"\(StartConversationViewModel.TAG) Account is in interop mode but LIME is available, creating a E2E conversation"
"\(ConversationForwardMessageViewModel.TAG) Account is in interop mode but LIME is available, creating an E2E encrypted conversation"
)
params.backend = ChatRoom.Backend.FlexisipChat
params.encryptionEnabled = true
chatParams.backend = ChatRoom.Backend.FlexisipChat
params.securityLevel = Conference.SecurityLevel.EndToEnd
} else {
Log.info(
"\(StartConversationViewModel.TAG) Account is in interop mode but LIME isn't available, creating a SIP simple conversation"
"\(ConversationForwardMessageViewModel.TAG) Account is in interop mode but LIME isn't available, creating a SIP simple conversation"
)
params.backend = ChatRoom.Backend.Basic
params.encryptionEnabled = false
chatParams.backend = ChatRoom.Backend.Basic
params.securityLevel = Conference.SecurityLevel.None
}
} else {
Log.error(
"\(StartConversationViewModel.TAG) Account is in secure mode, can't chat with SIP address of different domain \(remote.asStringUriOnly())"
"\(ConversationForwardMessageViewModel.TAG) Account is in secure mode, can't chat with SIP address of different domain \(remote.asStringUriOnly())"
)
DispatchQueue.main.async {
self.operationInProgress = false
ToastViewModel.shared.toastMessage = "Failed_to_create_conversation_invalid_participant_error"
ToastViewModel.shared.toastMessage = "Failed_to_create_conversation_error"
ToastViewModel.shared.displayToast = true
}
return
@ -94,85 +99,56 @@ class ContactViewModel: ObservableObject {
let existingChatRoom = core.searchChatRoom(params: params, localAddr: localAddress, remoteAddr: nil, participants: participants)
if existingChatRoom == nil {
Log.info(
"\(StartConversationViewModel.TAG) No existing 1-1 conversation between local account "
+ "\(localAddress?.asStringUriOnly() ?? "") and remote \(remote.asStringUriOnly()) was found for given parameters, let's create it"
"\(ConversationForwardMessageViewModel.TAG) No existing 1-1 conversation between local account \(localAddress?.asStringUriOnly() ?? "") and remote \(remote.asStringUriOnly()) was found for given parameters, let's create it"
)
let chatRoom = try core.createChatRoom(params: params, localAddr: localAddress, participants: participants)
if params.backend == ChatRoom.Backend.FlexisipChat {
if chatRoom.state == ChatRoom.State.Created {
let id = LinphoneUtils.getChatRoomId(room: chatRoom)
Log.info("\(StartConversationViewModel.TAG) 1-1 conversation \(id) has been created")
let model = ConversationModel(chatRoom: chatRoom)
if self.operationInProgress == false {
DispatchQueue.main.async {
self.operationInProgress = true
}
do {
let chatRoom = try core.createChatRoom(params: params, participants: participants)
if chatParams.backend == ChatRoom.Backend.FlexisipChat {
let state = chatRoom.state
if state == ChatRoom.State.Created {
let chatRoomId = LinphoneUtils.getConversationId(chatRoom: chatRoom)
Log.info("\(ConversationForwardMessageViewModel.TAG) 1-1 conversation \(chatRoomId) has been created")
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
self.operationInProgress = false
let model = ConversationModel(chatRoom: chatRoom)
DispatchQueue.main.async {
self.displayedConversation = model
self.operationInProgress = false
}
} else {
DispatchQueue.main.async {
self.operationInProgress = false
self.displayedConversation = model
}
Log.info("\(ConversationForwardMessageViewModel.TAG) Conversation isn't in Created state yet (state is \(state)), wait for it")
self.chatRoomAddDelegate(core: core, chatRoom: chatRoom)
}
} else {
Log.info("\(StartConversationViewModel.TAG) Conversation 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)")
let model = ConversationModel(chatRoom: chatRoom)
if self.operationInProgress == false {
DispatchQueue.main.async {
self.operationInProgress = true
}
let chatRoomId = LinphoneUtils.getConversationId(chatRoom: chatRoom)
Log.info("\(ConversationForwardMessageViewModel.TAG) Conversation successfully created \(chatRoomId)")
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
self.operationInProgress = false
self.displayedConversation = model
}
} else {
let model = ConversationModel(chatRoom: chatRoom)
DispatchQueue.main.async {
self.operationInProgress = false
self.displayedConversation = model
self.operationInProgress = false
}
}
} catch {
Log.error("\(ConversationForwardMessageViewModel.TAG) Failed to create 1-1 conversation with \(remote.asStringUriOnly())")
DispatchQueue.main.async {
self.operationInProgress = false
ToastViewModel.shared.toastMessage = "Failed_to_create_conversation_error"
ToastViewModel.shared.displayToast = true
}
}
} else {
Log.warn(
"\(StartConversationViewModel.TAG) A 1-1 conversation between local account \(localAddress?.asStringUriOnly() ?? "") and remote \(remote.asStringUriOnly()) for given parameters already exists!"
"\(ConversationForwardMessageViewModel.TAG) A 1-1 conversation between local account \(localAddress?.asStringUriOnly() ?? "") and remote \(remote.asStringUriOnly()) for given parameters already exists!"
)
let model = ConversationModel(chatRoom: existingChatRoom!)
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
}
DispatchQueue.main.async {
self.displayedConversation = model
self.operationInProgress = false
}
}
} 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())!")
}
}
}

View file

@ -223,6 +223,11 @@ struct ConversationForwardMessageFragment: View {
}
.navigationTitle("")
.navigationBarHidden(true)
.onAppear {
DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) {
MagicSearchSingleton.shared.searchForSuggestions()
}
}
.onDisappear {
DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) {
magicSearch.searchForContacts(

View file

@ -187,9 +187,7 @@ struct StartConversationFragment: View {
ContactsListFragment(contactViewModel: ContactViewModel(), contactsListViewModel: ContactsListViewModel(), showingSheet: .constant(false)
, startCallFunc: { addr in
withAnimation {
startConversationViewModel.createOneToOneChatRoomWith(remote: addr)
}
})
.padding(.horizontal, 16)
@ -266,10 +264,8 @@ struct StartConversationFragment: View {
var suggestionsList: some View {
ForEach(0..<contactsManager.lastSearchSuggestions.count, id: \.self) { index in
Button {
withAnimation {
if contactsManager.lastSearchSuggestions[index].address != nil {
startConversationViewModel.createOneToOneChatRoomWith(remote: contactsManager.lastSearchSuggestions[index].address!)
}
if let address = contactsManager.lastSearchSuggestions[index].address {
startConversationViewModel.createOneToOneChatRoomWith(remote: address)
}
} label: {
HStack {
@ -394,6 +390,9 @@ struct StartConversationFragment: View {
.shadow(color: Color.orangeMain500, radius: 0, x: 0, y: 2)
.frame(maxWidth: sharedMainViewModel.maxWidth)
.position(x: geometry.size.width / 2, y: geometry.size.height / 2)
.onDisappear {
startConversationViewModel.messageText = ""
}
}
}
}

View file

@ -84,7 +84,7 @@ class ConversationForwardMessageViewModel: ObservableObject {
let account = core.defaultAccount
if account == nil {
Log.error(
"\(StartConversationViewModel.TAG) No default account found, can't create conversation with \(remote.asStringUriOnly())!"
"\(ConversationForwardMessageViewModel.TAG) No default account found, can't create conversation with \(remote.asStringUriOnly())"
)
return
}
@ -94,37 +94,42 @@ class ConversationForwardMessageViewModel: ObservableObject {
}
do {
let params: ChatRoomParams = try core.createDefaultChatRoomParams()
let params = try core.createConferenceParams(conference: nil)
params.chatEnabled = true
params.groupEnabled = false
params.subject = "Dummy subject"
params.ephemeralLifetime = 0 // Make sure ephemeral is disabled by default
params.subject = NSLocalizedString("conversation_one_to_one_hidden_subject", comment: "")
params.account = account
let sameDomain = remote.domain == account?.params?.domain ?? ""
if StartConversationViewModel.isEndToEndEncryptionMandatory() && sameDomain {
Log.info("\(StartConversationViewModel.TAG) Account is in secure mode & domain matches, creating a E2E conversation")
params.backend = ChatRoom.Backend.FlexisipChat
params.encryptionEnabled = true
} else if !StartConversationViewModel.isEndToEndEncryptionMandatory() {
guard let chatParams = params.chatParams else { return }
chatParams.ephemeralLifetime = 0 // Make sure ephemeral is disabled by default
let sameDomain = remote.domain == CorePreferences.defaultDomain && remote.domain == account!.params?.domain
if account!.params != nil && (account!.params!.instantMessagingEncryptionMandatory && sameDomain) {
Log.info("\(ConversationForwardMessageViewModel.TAG) Account is in secure mode & domain matches, creating an E2E encrypted conversation")
chatParams.backend = ChatRoom.Backend.FlexisipChat
params.securityLevel = Conference.SecurityLevel.EndToEnd
} else if account!.params != nil && (!account!.params!.instantMessagingEncryptionMandatory) {
if LinphoneUtils.isEndToEndEncryptedChatAvailable(core: core) {
Log.info(
"\(StartConversationViewModel.TAG) Account is in interop mode but LIME is available, creating a E2E conversation"
"\(ConversationForwardMessageViewModel.TAG) Account is in interop mode but LIME is available, creating an E2E encrypted conversation"
)
params.backend = ChatRoom.Backend.FlexisipChat
params.encryptionEnabled = true
chatParams.backend = ChatRoom.Backend.FlexisipChat
params.securityLevel = Conference.SecurityLevel.EndToEnd
} else {
Log.info(
"\(StartConversationViewModel.TAG) Account is in interop mode but LIME isn't available, creating a SIP simple conversation"
"\(ConversationForwardMessageViewModel.TAG) Account is in interop mode but LIME isn't available, creating a SIP simple conversation"
)
params.backend = ChatRoom.Backend.Basic
params.encryptionEnabled = false
chatParams.backend = ChatRoom.Backend.Basic
params.securityLevel = Conference.SecurityLevel.None
}
} else {
Log.error(
"\(StartConversationViewModel.TAG) Account is in secure mode, can't chat with SIP address of different domain \(remote.asStringUriOnly())"
"\(ConversationForwardMessageViewModel.TAG) Account is in secure mode, can't chat with SIP address of different domain \(remote.asStringUriOnly())"
)
DispatchQueue.main.async {
self.operationInProgress = false
ToastViewModel.shared.toastMessage = "Failed_to_create_conversation_invalid_participant_error"
ToastViewModel.shared.toastMessage = "Failed_to_create_conversation_error"
ToastViewModel.shared.displayToast = true
}
return
@ -135,85 +140,56 @@ class ConversationForwardMessageViewModel: ObservableObject {
let existingChatRoom = core.searchChatRoom(params: params, localAddr: localAddress, remoteAddr: nil, participants: participants)
if existingChatRoom == nil {
Log.info(
"\(StartConversationViewModel.TAG) No existing 1-1 conversation between local account "
+ "\(localAddress?.asStringUriOnly() ?? "") and remote \(remote.asStringUriOnly()) was found for given parameters, let's create it"
"\(ConversationForwardMessageViewModel.TAG) No existing 1-1 conversation between local account \(localAddress?.asStringUriOnly() ?? "") and remote \(remote.asStringUriOnly()) was found for given parameters, let's create it"
)
let chatRoom = try core.createChatRoom(params: params, localAddr: localAddress, participants: participants)
if params.backend == ChatRoom.Backend.FlexisipChat {
if chatRoom.state == ChatRoom.State.Created {
let id = LinphoneUtils.getChatRoomId(room: chatRoom)
Log.info("\(StartConversationViewModel.TAG) 1-1 conversation \(id) has been created")
let model = ConversationModel(chatRoom: chatRoom)
if self.operationInProgress == false {
DispatchQueue.main.async {
self.operationInProgress = true
}
do {
let chatRoom = try core.createChatRoom(params: params, participants: participants)
if chatParams.backend == ChatRoom.Backend.FlexisipChat {
let state = chatRoom.state
if state == ChatRoom.State.Created {
let chatRoomId = LinphoneUtils.getConversationId(chatRoom: chatRoom)
Log.info("\(ConversationForwardMessageViewModel.TAG) 1-1 conversation \(chatRoomId) has been created")
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
self.operationInProgress = false
let model = ConversationModel(chatRoom: chatRoom)
DispatchQueue.main.async {
self.displayedConversation = model
self.operationInProgress = false
}
} else {
DispatchQueue.main.async {
self.operationInProgress = false
self.displayedConversation = model
}
Log.info("\(ConversationForwardMessageViewModel.TAG) Conversation isn't in Created state yet (state is \(state)), wait for it")
self.chatRoomAddDelegate(core: core, chatRoom: chatRoom)
}
} else {
Log.info("\(StartConversationViewModel.TAG) Conversation 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)")
let model = ConversationModel(chatRoom: chatRoom)
if self.operationInProgress == false {
DispatchQueue.main.async {
self.operationInProgress = true
}
let chatRoomId = LinphoneUtils.getConversationId(chatRoom: chatRoom)
Log.info("\(ConversationForwardMessageViewModel.TAG) Conversation successfully created \(chatRoomId)")
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
self.operationInProgress = false
self.displayedConversation = model
}
} else {
let model = ConversationModel(chatRoom: chatRoom)
DispatchQueue.main.async {
self.operationInProgress = false
self.displayedConversation = model
self.operationInProgress = false
}
}
} catch {
Log.error("\(ConversationForwardMessageViewModel.TAG) Failed to create 1-1 conversation with \(remote.asStringUriOnly())")
DispatchQueue.main.async {
self.operationInProgress = false
ToastViewModel.shared.toastMessage = "Failed_to_create_conversation_error"
ToastViewModel.shared.displayToast = true
}
}
} else {
Log.warn(
"\(StartConversationViewModel.TAG) A 1-1 conversation between local account \(localAddress?.asStringUriOnly() ?? "") and remote \(remote.asStringUriOnly()) for given parameters already exists!"
"\(ConversationForwardMessageViewModel.TAG) A 1-1 conversation between local account \(localAddress?.asStringUriOnly() ?? "") and remote \(remote.asStringUriOnly()) for given parameters already exists!"
)
let model = ConversationModel(chatRoom: existingChatRoom!)
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
}
DispatchQueue.main.async {
self.displayedConversation = model
self.operationInProgress = false
}
}
} 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())!")
}
}
}
@ -223,7 +199,7 @@ class ConversationForwardMessageViewModel: ObservableObject {
let state = chatRoom.state
let id = LinphoneUtils.getChatRoomId(room: chatRoom)
if state == ChatRoom.State.CreationFailed {
Log.error("\(StartConversationViewModel.TAG) Conversation \(id) creation has failed!")
Log.error("\(ConversationForwardMessageViewModel.TAG) Conversation \(id) creation has failed!")
if let chatRoomDelegate = self.chatRoomDelegate {
chatRoom.removeDelegate(delegate: chatRoomDelegate)
}
@ -237,9 +213,9 @@ class ConversationForwardMessageViewModel: ObservableObject {
}, onConferenceJoined: { (chatRoom: ChatRoom, _: EventLog) in
let state = chatRoom.state
let id = LinphoneUtils.getChatRoomId(room: chatRoom)
Log.info("\(StartConversationViewModel.TAG) Conversation \(id) \(chatRoom.subject ?? "") state changed: \(state)")
Log.info("\(ConversationForwardMessageViewModel.TAG) Conversation \(id) \(chatRoom.subject ?? "") state changed: \(state)")
if state == ChatRoom.State.Created {
Log.info("\(StartConversationViewModel.TAG) Conversation \(id) successfully created")
Log.info("\(ConversationForwardMessageViewModel.TAG) Conversation \(id) successfully created")
if let chatRoomDelegate = self.chatRoomDelegate {
chatRoom.removeDelegate(delegate: chatRoomDelegate)
}
@ -262,7 +238,7 @@ class ConversationForwardMessageViewModel: ObservableObject {
}
}
} else if state == ChatRoom.State.CreationFailed {
Log.error("\(StartConversationViewModel.TAG) Conversation \(id) creation has failed!")
Log.error("\(ConversationForwardMessageViewModel.TAG) Conversation \(id) creation has failed!")
if let chatRoomDelegate = self.chatRoomDelegate {
chatRoom.removeDelegate(delegate: chatRoomDelegate)
}

View file

@ -357,10 +357,10 @@ class ConversationViewModel: ObservableObject {
let indexMessage = self.conversationMessagesSection[0].rows.firstIndex(where: {$0.eventModel.eventLogId == message.messageId})
DispatchQueue.main.async {
if let indexMessageEventLogId = indexMessageEventLogId {
if let indexMessageEventLogId = indexMessageEventLogId, !self.conversationMessagesSection.isEmpty, !self.conversationMessagesSection[0].rows.isEmpty, self.conversationMessagesSection[0].rows.count > indexMessageEventLogId {
self.conversationMessagesSection[0].rows[indexMessageEventLogId].eventModel.eventLogId = message.messageId
}
if let indexMessage = indexMessage {
if let indexMessage = indexMessage, !self.conversationMessagesSection.isEmpty, !self.conversationMessagesSection[0].rows.isEmpty, self.conversationMessagesSection[0].rows.count > indexMessage {
self.conversationMessagesSection[0].rows[indexMessage].message.status = statusTmp ?? .error
}
}

View file

@ -95,6 +95,10 @@ class StartConversationViewModel: ObservableObject {
participantsTmp.append(participant.address)
}
DispatchQueue.main.async {
self.participants.removeAll()
}
if account!.params != nil {
let chatRoom = try core.createChatRoom(params: chatRoomParams, participants: participantsTmp)
@ -106,20 +110,9 @@ class StartConversationViewModel: ObservableObject {
)
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
}
DispatchQueue.main.async {
self.displayedConversation = model
self.operationInProgress = false
}
} else {
Log.info(
@ -132,20 +125,9 @@ class StartConversationViewModel: ObservableObject {
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
}
DispatchQueue.main.async {
self.displayedConversation = model
self.operationInProgress = false
}
}
}
@ -163,11 +145,11 @@ class StartConversationViewModel: ObservableObject {
}
func createOneToOneChatRoomWith(remote: Address) {
coreContext.doOnCoreQueue { core in
CoreContext.shared.doOnCoreQueue { core in
let account = core.defaultAccount
if account == nil {
Log.error(
"\(StartConversationViewModel.TAG) No default account found, can't create conversation with \(remote.asStringUriOnly())!"
"\(StartConversationViewModel.TAG) No default account found, can't create conversation with \(remote.asStringUriOnly())"
)
return
}
@ -177,37 +159,42 @@ class StartConversationViewModel: ObservableObject {
}
do {
let params: ChatRoomParams = try core.createDefaultChatRoomParams()
let params = try core.createConferenceParams(conference: nil)
params.chatEnabled = true
params.groupEnabled = false
params.subject = "Dummy subject"
params.ephemeralLifetime = 0 // Make sure ephemeral is disabled by default
params.subject = NSLocalizedString("conversation_one_to_one_hidden_subject", comment: "")
params.account = account
let sameDomain = remote.domain == account?.params?.domain ?? ""
if StartConversationViewModel.isEndToEndEncryptionMandatory() && sameDomain {
Log.info("\(StartConversationViewModel.TAG) Account is in secure mode & domain matches, creating a E2E conversation")
params.backend = ChatRoom.Backend.FlexisipChat
params.encryptionEnabled = true
} else if !StartConversationViewModel.isEndToEndEncryptionMandatory() {
guard let chatParams = params.chatParams else { return }
chatParams.ephemeralLifetime = 0 // Make sure ephemeral is disabled by default
let sameDomain = remote.domain == CorePreferences.defaultDomain && remote.domain == account!.params?.domain
if account!.params != nil && (account!.params!.instantMessagingEncryptionMandatory && sameDomain) {
Log.info("\(StartConversationViewModel.TAG) Account is in secure mode & domain matches, creating an E2E encrypted conversation")
chatParams.backend = ChatRoom.Backend.FlexisipChat
params.securityLevel = Conference.SecurityLevel.EndToEnd
} else if account!.params != nil && (!account!.params!.instantMessagingEncryptionMandatory) {
if LinphoneUtils.isEndToEndEncryptedChatAvailable(core: core) {
Log.info(
"\(StartConversationViewModel.TAG) Account is in interop mode but LIME is available, creating a E2E conversation"
"\(StartConversationViewModel.TAG) Account is in interop mode but LIME is available, creating an E2E encrypted conversation"
)
params.backend = ChatRoom.Backend.FlexisipChat
params.encryptionEnabled = true
chatParams.backend = ChatRoom.Backend.FlexisipChat
params.securityLevel = Conference.SecurityLevel.EndToEnd
} else {
Log.info(
"\(StartConversationViewModel.TAG) Account is in interop mode but LIME isn't available, creating a SIP simple conversation"
)
params.backend = ChatRoom.Backend.Basic
params.encryptionEnabled = false
chatParams.backend = ChatRoom.Backend.Basic
params.securityLevel = Conference.SecurityLevel.None
}
} else {
Log.error(
"\(StartConversationViewModel.TAG) Account is in secure mode, can't chat with SIP address of different domain \(remote.asStringUriOnly())"
)
DispatchQueue.main.async {
self.operationInProgress = false
ToastViewModel.shared.toastMessage = "Failed_to_create_conversation_invalid_participant_error"
ToastViewModel.shared.toastMessage = "Failed_to_create_conversation_error"
ToastViewModel.shared.displayToast = true
}
return
@ -218,85 +205,56 @@ class StartConversationViewModel: ObservableObject {
let existingChatRoom = core.searchChatRoom(params: params, localAddr: localAddress, remoteAddr: nil, participants: participants)
if existingChatRoom == nil {
Log.info(
"\(StartConversationViewModel.TAG) No existing 1-1 conversation between local account "
+ "\(localAddress?.asStringUriOnly() ?? "") and remote \(remote.asStringUriOnly()) was found for given parameters, let's create it"
"\(StartConversationViewModel.TAG) No existing 1-1 conversation between local account \(localAddress?.asStringUriOnly() ?? "") and remote \(remote.asStringUriOnly()) was found for given parameters, let's create it"
)
let chatRoom = try core.createChatRoom(params: params, localAddr: localAddress, participants: participants)
if params.backend == ChatRoom.Backend.FlexisipChat {
if chatRoom.state == ChatRoom.State.Created {
let id = LinphoneUtils.getChatRoomId(room: chatRoom)
Log.info("\(StartConversationViewModel.TAG) 1-1 conversation \(id) has been created")
let model = ConversationModel(chatRoom: chatRoom)
if self.operationInProgress == false {
DispatchQueue.main.async {
self.operationInProgress = true
}
do {
let chatRoom = try core.createChatRoom(params: params, participants: participants)
if chatParams.backend == ChatRoom.Backend.FlexisipChat {
let state = chatRoom.state
if state == ChatRoom.State.Created {
let chatRoomId = LinphoneUtils.getConversationId(chatRoom: chatRoom)
Log.info("\(StartConversationViewModel.TAG) 1-1 conversation \(chatRoomId) has been created")
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
self.operationInProgress = false
let model = ConversationModel(chatRoom: chatRoom)
DispatchQueue.main.async {
self.displayedConversation = model
self.operationInProgress = false
}
} else {
DispatchQueue.main.async {
self.operationInProgress = false
self.displayedConversation = model
}
Log.info("\(StartConversationViewModel.TAG) Conversation isn't in Created state yet (state is \(state)), wait for it")
self.chatRoomAddDelegate(core: core, chatRoom: chatRoom)
}
} else {
Log.info("\(StartConversationViewModel.TAG) Conversation 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)")
let model = ConversationModel(chatRoom: chatRoom)
if self.operationInProgress == false {
DispatchQueue.main.async {
self.operationInProgress = true
}
let chatRoomId = LinphoneUtils.getConversationId(chatRoom: chatRoom)
Log.info("\(StartConversationViewModel.TAG) Conversation successfully created \(chatRoomId)")
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
self.operationInProgress = false
self.displayedConversation = model
}
} else {
let model = ConversationModel(chatRoom: chatRoom)
DispatchQueue.main.async {
self.operationInProgress = false
self.displayedConversation = model
self.operationInProgress = false
}
}
} catch {
Log.error("\(StartConversationViewModel.TAG) Failed to create 1-1 conversation with \(remote.asStringUriOnly())")
DispatchQueue.main.async {
self.operationInProgress = false
ToastViewModel.shared.toastMessage = "Failed_to_create_conversation_error"
ToastViewModel.shared.displayToast = true
}
}
} else {
Log.warn(
"\(StartConversationViewModel.TAG) A 1-1 conversation between local account \(localAddress?.asStringUriOnly() ?? "") and remote \(remote.asStringUriOnly()) for given parameters already exists!"
)
let model = ConversationModel(chatRoom: existingChatRoom!)
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
}
DispatchQueue.main.async {
self.displayedConversation = model
self.operationInProgress = false
}
}
} 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())!")
}
}
}
@ -304,9 +262,9 @@ class StartConversationViewModel: ObservableObject {
func chatRoomAddDelegate(core: Core, chatRoom: ChatRoom) {
self.chatRoomDelegate = ChatRoomDelegateStub(onStateChanged: { (chatRoom: ChatRoom, state: ChatRoom.State) in
let state = chatRoom.state
let id = LinphoneUtils.getChatRoomId(room: chatRoom)
let chatRoomId = LinphoneUtils.getChatRoomId(room: chatRoom)
if state == ChatRoom.State.CreationFailed {
Log.error("\(StartConversationViewModel.TAG) Conversation \(id) creation has failed!")
Log.error("\(StartConversationViewModel.TAG) Conversation \(chatRoomId) creation has failed!")
if let chatRoomDelegate = self.chatRoomDelegate {
chatRoom.removeDelegate(delegate: chatRoomDelegate)
}
@ -329,20 +287,9 @@ class StartConversationViewModel: ObservableObject {
self.chatRoomDelegate = nil
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
}
DispatchQueue.main.async {
self.displayedConversation = model
self.operationInProgress = false
}
} else if state == ChatRoom.State.CreationFailed {
Log.error("\(StartConversationViewModel.TAG) Conversation \(id) creation has failed!")

View file

@ -100,4 +100,17 @@ class LinphoneUtils: NSObject {
return nil
}
}
public class func getConversationId(chatRoom: ChatRoom) -> String {
return chatRoom.identifier ?? ""
}
public class func getDefaultAccount() -> Account? {
return CoreContext.shared.mCore.defaultAccount ?? (CoreContext.shared.mCore.accountList.first ?? nil)
}
public class func getAccountForAddress(address: Address) -> Account? {
return CoreContext.shared.mCore.accountList.first { $0.params?.identityAddress?.weakEqual(address2: address) == true }
}
}