diff --git a/GoogleService-Info.plist b/GoogleService-Info.plist new file mode 100644 index 000000000..f996be8f2 --- /dev/null +++ b/GoogleService-Info.plist @@ -0,0 +1,36 @@ + + + + + CLIENT_ID + 221368768663-0ufgu96cel0auk4v0me863lgm252b9n2.apps.googleusercontent.com + REVERSED_CLIENT_ID + com.googleusercontent.apps.221368768663-0ufgu96cel0auk4v0me863lgm252b9n2 + API_KEY + AIzaSyDJTtlRCM7IqdVUU2dSIYq2YIsTz6bqnkI + GCM_SENDER_ID + 221368768663 + PLIST_VERSION + 1 + BUNDLE_ID + org.linphone.phone + PROJECT_ID + linphone-iphone + STORAGE_BUCKET + linphone-iphone.appspot.com + IS_ADS_ENABLED + + IS_ANALYTICS_ENABLED + + IS_APPINVITE_ENABLED + + IS_GCM_ENABLED + + IS_SIGNIN_ENABLED + + GOOGLE_APP_ID + 1:221368768663:ios:a2c822bc087b5a219431d2 + DATABASE_URL + https://linphone-iphone.firebaseio.com + + diff --git a/Linphone.xcodeproj/project.pbxproj b/Linphone.xcodeproj/project.pbxproj index c49a03650..b4c229e18 100644 --- a/Linphone.xcodeproj/project.pbxproj +++ b/Linphone.xcodeproj/project.pbxproj @@ -7,6 +7,7 @@ objects = { /* Begin PBXBuildFile section */ + 660D8A712B517D260092694D /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 660D8A702B517D260092694D /* GoogleService-Info.plist */; }; 662B69D92B25DE18007118BF /* TelecomManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 662B69D82B25DE18007118BF /* TelecomManager.swift */; }; 662B69DB2B25DE25007118BF /* ProviderDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 662B69DA2B25DE25007118BF /* ProviderDelegate.swift */; }; 66C491F92B24D25B00CEA16D /* ConfigExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66C491F82B24D25A00CEA16D /* ConfigExtension.swift */; }; @@ -97,6 +98,7 @@ /* End PBXBuildFile section */ /* Begin PBXFileReference section */ + 660D8A702B517D260092694D /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = ""; }; 662B69D82B25DE18007118BF /* TelecomManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TelecomManager.swift; sourceTree = ""; }; 662B69DA2B25DE25007118BF /* ProviderDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProviderDelegate.swift; sourceTree = ""; }; 66C491F82B24D25A00CEA16D /* ConfigExtension.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConfigExtension.swift; sourceTree = ""; }; @@ -249,6 +251,7 @@ D719ABAA2ABC67BF00B41C10 = { isa = PBXGroup; children = ( + 660D8A702B517D260092694D /* GoogleService-Info.plist */, D719ABB52ABC67BF00B41C10 /* Linphone */, D719ABB42ABC67BF00B41C10 /* Products */, A31AF2AB8C6A3D7B7EA3B424 /* Pods */, @@ -600,6 +603,7 @@ D732A90D2B0376F500DB42BA /* linphonerc-factory in Resources */, D783C77C2B1089B200622CC2 /* assistant_linphone_default_values in Resources */, D70C93DE2AC2D0F60063CA3B /* Localizable.xcstrings in Resources */, + 660D8A712B517D260092694D /* GoogleService-Info.plist in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -835,16 +839,22 @@ ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = NO; CODE_SIGN_ENTITLEMENTS = Linphone/Linphone.entitlements; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1; + CURRENT_PROJECT_VERSION = 4; DEAD_CODE_STRIPPING = YES; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_ASSET_PATHS = "\"Linphone/Preview Content\""; DEVELOPMENT_TEAM = Z2V957B3D6; ENABLE_HARDENED_RUNTIME = YES; ENABLE_PREVIEWS = YES; + GCC_PREPROCESSOR_DEFINITIONS = ( + "$(inherited)", + "DEBUG=1", + ); GENERATE_INFOPLIST_FILE = YES; INFOPLIST_FILE = Linphone/Info.plist; - INFOPLIST_KEY_NSCameraUsageDescription = "Share photos with your friends and customize avatars"; + INFOPLIST_KEY_NSCameraUsageDescription = "Camera usage is required for video VOIP calls"; INFOPLIST_KEY_NSContactsUsageDescription = "Make calls with your friends"; + INFOPLIST_KEY_NSMicrophoneUsageDescription = "Microphone usage is required for VOIP calls"; INFOPLIST_KEY_NSPhotoLibraryUsageDescription = "Share photos with your friends and customize avatars"; "INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphoneos*]" = YES; "INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphonesimulator*]" = YES; @@ -856,15 +866,17 @@ "INFOPLIST_KEY_UIStatusBarStyle[sdk=iphonesimulator*]" = UIStatusBarStyleDefault; INFOPLIST_KEY_UISupportedInterfaceOrientations = "UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight UIInterfaceOrientationPortrait"; INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown"; + INFOPLIST_KEY_UIUserInterfaceStyle = Light; IPHONEOS_DEPLOYMENT_TARGET = 15.0; LD_RUNPATH_SEARCH_PATHS = "@executable_path/Frameworks"; "LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = "@executable_path/../Frameworks"; MACOSX_DEPLOYMENT_TARGET = 13.3; - MARKETING_VERSION = 1.0; + MARKETING_VERSION = 6.0; + OTHER_SWIFT_FLAGS = "$(inherited)"; PRODUCT_BUNDLE_IDENTIFIER = org.linphone.phone; PRODUCT_NAME = "$(TARGET_NAME)"; - SDKROOT = auto; - SUPPORTED_PLATFORMS = "iphoneos iphonesimulator macosx"; + SDKROOT = iphoneos; + SUPPORTED_PLATFORMS = "iphonesimulator iphoneos"; SWIFT_EMIT_LOC_STRINGS = YES; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; @@ -879,16 +891,18 @@ ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = NO; CODE_SIGN_ENTITLEMENTS = Linphone/Linphone.entitlements; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1; + CURRENT_PROJECT_VERSION = 4; DEAD_CODE_STRIPPING = YES; DEVELOPMENT_ASSET_PATHS = "\"Linphone/Preview Content\""; DEVELOPMENT_TEAM = Z2V957B3D6; ENABLE_HARDENED_RUNTIME = YES; ENABLE_PREVIEWS = YES; + GCC_PREPROCESSOR_DEFINITIONS = "$(inherited)"; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_FILE = Linphone/Info.plist; - INFOPLIST_KEY_NSCameraUsageDescription = "Share photos with your friends and customize avatars"; + INFOPLIST_KEY_NSCameraUsageDescription = "Camera usage is required for video VOIP calls"; INFOPLIST_KEY_NSContactsUsageDescription = "Make calls with your friends"; + INFOPLIST_KEY_NSMicrophoneUsageDescription = "Microphone usage is required for VOIP calls"; INFOPLIST_KEY_NSPhotoLibraryUsageDescription = "Share photos with your friends and customize avatars"; "INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphoneos*]" = YES; "INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphonesimulator*]" = YES; @@ -900,15 +914,17 @@ "INFOPLIST_KEY_UIStatusBarStyle[sdk=iphonesimulator*]" = UIStatusBarStyleDefault; INFOPLIST_KEY_UISupportedInterfaceOrientations = "UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight UIInterfaceOrientationPortrait"; INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown"; + INFOPLIST_KEY_UIUserInterfaceStyle = Light; IPHONEOS_DEPLOYMENT_TARGET = 15.0; LD_RUNPATH_SEARCH_PATHS = "@executable_path/Frameworks"; "LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = "@executable_path/../Frameworks"; MACOSX_DEPLOYMENT_TARGET = 13.3; - MARKETING_VERSION = 1.0; + MARKETING_VERSION = 6.0; + OTHER_SWIFT_FLAGS = "$(inherited)"; PRODUCT_BUNDLE_IDENTIFIER = org.linphone.phone; PRODUCT_NAME = "$(TARGET_NAME)"; - SDKROOT = auto; - SUPPORTED_PLATFORMS = "iphoneos iphonesimulator macosx"; + SDKROOT = iphoneos; + SUPPORTED_PLATFORMS = "iphonesimulator iphoneos"; SWIFT_EMIT_LOC_STRINGS = YES; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; diff --git a/Linphone/Core/CoreContext.swift b/Linphone/Core/CoreContext.swift index a7a0abb4a..593cea6b8 100644 --- a/Linphone/Core/CoreContext.swift +++ b/Linphone/Core/CoreContext.swift @@ -92,6 +92,8 @@ final class CoreContext: ObservableObject { self.mCore.callkitEnabled = true self.mCore.pushNotificationEnabled = true + self.mCore.setUserAgent(name: "Linphone iOS 6.0 Beta (\(UIDevice.current.localizedModel)) - Linphone SDK : \(self.coreVersion)", version: "6.0") + self.mCoreSuscriptions.insert(self.mCore.publisher?.onGlobalStateChanged?.postOnMainQueue { (cbVal: (core: Core, state: GlobalState, message: String)) in if cbVal.state == GlobalState.On { self.defaultAccount = self.mCore.defaultAccount @@ -102,6 +104,22 @@ final class CoreContext: ObservableObject { } }) + self.mCoreSuscriptions.insert(self.mCore.publisher?.onGlobalStateChanged?.postOnCoreQueue { (cbVal: (core: Core, state: GlobalState, message: String)) in + if cbVal.state == GlobalState.On { +#if DEBUG + let pushEnvironment = ".dev" +#else + let pushEnvironment = "" +#endif + for account in cbVal.core.accountList where account.params?.pushNotificationConfig?.provider != ("apns" + pushEnvironment) { + let newParams = account.params?.clone() + Log.info("Account \(String(describing: newParams?.identityAddress?.asStringUriOnly())) - updating apple push provider from \(String(describing: newParams?.pushNotificationConfig?.provider)) to apns\(pushEnvironment)") + newParams?.pushNotificationConfig?.provider = "apns" + pushEnvironment + account.params = newParams + } + } + }) + self.mCore.videoCaptureEnabled = true self.mCore.videoDisplayEnabled = true @@ -170,8 +188,10 @@ final class CoreContext: ObservableObject { forPasteboardType: UTType.plainText.identifier ) - ToastViewModel.shared.toastMessage = "Success_copied_into_clipboard" - ToastViewModel.shared.displayToast = true + DispatchQueue.main.async { + ToastViewModel.shared.toastMessage = "Success_send_logs" + ToastViewModel.shared.displayToast = true + } } }) @@ -182,6 +202,7 @@ final class CoreContext: ObservableObject { self.mCore.iterate() } + try? self.mCore.start() } } diff --git a/Linphone/LinphoneApp.swift b/Linphone/LinphoneApp.swift index 9596a76ce..0930db967 100644 --- a/Linphone/LinphoneApp.swift +++ b/Linphone/LinphoneApp.swift @@ -18,6 +18,9 @@ */ import SwiftUI +#if USE_CRASHLYTICS +import Firebase +#endif @main struct LinphoneApp: App { @@ -32,6 +35,12 @@ struct LinphoneApp: App { @State private var startCallViewModel: StartCallViewModel? @State private var callViewModel: CallViewModel? + init() { +#if USE_CRASHLYTICS + FirebaseApp.configure() +#endif + } + var body: some Scene { WindowGroup { if coreContext.coreIsStarted { diff --git a/Linphone/Localizable.xcstrings b/Linphone/Localizable.xcstrings index 8dc0dee51..ec823b015 100644 --- a/Linphone/Localizable.xcstrings +++ b/Linphone/Localizable.xcstrings @@ -371,7 +371,10 @@ "Log out" : { }, - "Logout" : { + "Logs cleared" : { + + }, + "Logs URL copied into clipboard" : { }, "Message" : { @@ -382,9 +385,6 @@ }, "Missed call" : { - }, - "My Profile" : { - }, "New call" : { diff --git a/Linphone/UI/Assistant/Viewmodel/AccountLoginViewModel.swift b/Linphone/UI/Assistant/Viewmodel/AccountLoginViewModel.swift index 8cf56625f..819931bd3 100644 --- a/Linphone/UI/Assistant/Viewmodel/AccountLoginViewModel.swift +++ b/Linphone/UI/Assistant/Viewmodel/AccountLoginViewModel.swift @@ -91,7 +91,12 @@ class AccountLoginViewModel: ObservableObject { accountParams.registerEnabled = true accountParams.pushNotificationAllowed = true accountParams.remotePushNotificationAllowed = false - accountParams.pushNotificationConfig?.provider = "apns.dev" +#if DEBUG + let pushEnvironment = ".dev" +#else + let pushEnvironment = "" +#endif + accountParams.pushNotificationConfig?.provider = "apns" + pushEnvironment // Now that our AccountParams is configured, we can create the Account object let account = try core.createAccount(params: accountParams) diff --git a/Linphone/UI/Call/CallView.swift b/Linphone/UI/Call/CallView.swift index 755575926..5de1d37d8 100644 --- a/Linphone/UI/Call/CallView.swift +++ b/Linphone/UI/Call/CallView.swift @@ -51,6 +51,280 @@ struct CallView: View { GeometryReader { geo in if #available(iOS 16.0, *), idiom != .pad { innerView(geometry: geo) + .sheet(isPresented: + .constant( + telecomManager.callStarted + && !fullscreenVideo + && !hideButtonsSheet + && idiom != .pad + && !(orientation == .landscapeLeft || orientation == .landscapeRight || UIScreen.main.bounds.size.width > UIScreen.main.bounds.size.height) + ) + ) { + GeometryReader { _ in + VStack(spacing: 0) { + HStack(spacing: 12) { + Button { + callViewModel.terminateCall() + } label: { + Image("phone-disconnect") + .renderingMode(.template) + .resizable() + .foregroundStyle(.white) + .frame(width: 32, height: 32) + + } + .frame(width: 90, height: 60) + .background(Color.redDanger500) + .cornerRadius(40) + + Spacer() + + Button { + callViewModel.toggleVideo() + } label: { + Image(telecomManager.remoteVideo ? "video-camera" : "video-camera-slash") + .renderingMode(.template) + .resizable() + .foregroundStyle((callViewModel.isPaused || telecomManager.isPausedByRemote) ? Color.gray500 : .white) + .frame(width: 32, height: 32) + + } + .frame(width: 60, height: 60) + .background((callViewModel.isPaused || telecomManager.isPausedByRemote) ? Color.gray600 : Color.gray500) + .cornerRadius(40) + .disabled(callViewModel.isPaused || telecomManager.isPausedByRemote) + + Button { + callViewModel.toggleMuteMicrophone() + } label: { + Image(callViewModel.micMutted ? "microphone-slash" : "microphone") + .renderingMode(.template) + .resizable() + .foregroundStyle(callViewModel.micMutted ? .black : .white) + .frame(width: 32, height: 32) + + } + .frame(width: 60, height: 60) + .background(callViewModel.micMutted ? .white : Color.gray500) + .cornerRadius(40) + + Button { + if AVAudioSession.sharedInstance().availableInputs != nil + && !AVAudioSession.sharedInstance().availableInputs!.filter({ $0.portType.rawValue.contains("Bluetooth") }).isEmpty { + + hideButtonsSheet = true + + DispatchQueue.global().asyncAfter(deadline: .now() + 0.5) { + audioRouteSheet = true + } + } else { + do { + try AVAudioSession.sharedInstance().overrideOutputAudioPort(AVAudioSession.sharedInstance().currentRoute.outputs.filter({ $0.portType.rawValue == "Speaker" }).isEmpty ? .speaker : .none) + } catch _ { + + } + } + + } label: { + Image(imageAudioRoute) + .renderingMode(.template) + .resizable() + .foregroundStyle(.white) + .frame(width: 32, height: 32) + .onAppear(perform: getAudioRouteImage) + .onReceive(pub) { _ in + self.getAudioRouteImage() + } + + } + .frame(width: 60, height: 60) + .background(Color.gray500) + .cornerRadius(40) + } + .frame(height: geo.size.height * 0.15) + .padding(.horizontal, 20) + .padding(.top, -6) + + HStack(spacing: 0) { + VStack { + Button { + } label: { + Image("phone-transfer") + .renderingMode(.template) + .resizable() + .foregroundStyle(Color.gray500) + .frame(width: 32, height: 32) + } + .frame(width: 60, height: 60) + .background(Color.gray600) + .cornerRadius(40) + .disabled(true) + + Text("Transfer") + .foregroundStyle(.white) + .default_text_style(styleSize: 15) + } + .frame(width: geo.size.width * 0.25, height: geo.size.width * 0.25) + + VStack { + Button { + } label: { + Image("phone-plus") + .renderingMode(.template) + .resizable() + .foregroundStyle(Color.gray500) + .frame(width: 32, height: 32) + } + .frame(width: 60, height: 60) + .background(Color.gray600) + .cornerRadius(40) + .disabled(true) + + Text("New call") + .foregroundStyle(.white) + .default_text_style(styleSize: 15) + } + .frame(width: geo.size.width * 0.25, height: geo.size.width * 0.25) + + VStack { + Button { + } label: { + Image("phone-list") + .renderingMode(.template) + .resizable() + .foregroundStyle(Color.gray500) + .frame(width: 32, height: 32) + } + .frame(width: 60, height: 60) + .background(Color.gray600) + .cornerRadius(40) + .disabled(true) + + Text("Call list") + .foregroundStyle(.white) + .default_text_style(styleSize: 15) + } + .frame(width: geo.size.width * 0.25, height: geo.size.width * 0.25) + + VStack { + Button { + } label: { + Image("dialer") + .renderingMode(.template) + .resizable() + .foregroundStyle(Color.gray500) + .frame(width: 32, height: 32) + } + .frame(width: 60, height: 60) + .background(Color.gray600) + .cornerRadius(40) + .disabled(true) + + Text("Dialer") + .foregroundStyle(.white) + .default_text_style(styleSize: 15) + } + .frame(width: geo.size.width * 0.25, height: geo.size.width * 0.25) + } + .frame(height: geo.size.height * 0.15) + + HStack(spacing: 0) { + VStack { + Button { + } label: { + Image("chat-teardrop-text") + .renderingMode(.template) + .resizable() + //.foregroundStyle((callViewModel.isPaused || telecomManager.isPausedByRemote) ? Color.gray500 : .white) + .foregroundStyle(Color.gray500) + .frame(width: 32, height: 32) + } + .frame(width: 60, height: 60) + //.background((callViewModel.isPaused || telecomManager.isPausedByRemote) ? Color.gray600 : Color.gray500) + .background(Color.gray600) + .cornerRadius(40) + //.disabled(callViewModel.isPaused || telecomManager.isPausedByRemote) + .disabled(true) + + Text("Messages") + .foregroundStyle(.white) + .default_text_style(styleSize: 15) + } + .frame(width: geo.size.width * 0.25, height: geo.size.width * 0.25) + + VStack { + Button { + callViewModel.togglePause() + } label: { + Image(callViewModel.isPaused ? "play" : "pause") + .renderingMode(.template) + .resizable() + .foregroundStyle(telecomManager.isPausedByRemote ? Color.gray500 : .white) + .frame(width: 32, height: 32) + } + .frame(width: 60, height: 60) + .background(telecomManager.isPausedByRemote ? Color.gray600 : (callViewModel.isPaused ? Color.greenSuccess500 : Color.gray500)) + .cornerRadius(40) + .disabled(telecomManager.isPausedByRemote) + + Text("Pause") + .foregroundStyle(.white) + .default_text_style(styleSize: 15) + } + .frame(width: geo.size.width * 0.25, height: geo.size.width * 0.25) + + VStack { + Button { + callViewModel.toggleRecording() + } label: { + Image("record-fill") + .renderingMode(.template) + .resizable() + .foregroundStyle((callViewModel.isPaused || telecomManager.isPausedByRemote) ? Color.gray500 : .white) + .frame(width: 32, height: 32) + } + .frame(width: 60, height: 60) + .background((callViewModel.isPaused || telecomManager.isPausedByRemote) ? Color.gray600 : (callViewModel.isRecording ? Color.redDanger500 : Color.gray500)) + .cornerRadius(40) + .disabled(callViewModel.isPaused || telecomManager.isPausedByRemote) + + Text("Record") + .foregroundStyle(.white) + .default_text_style(styleSize: 15) + } + .frame(width: geo.size.width * 0.25, height: geo.size.width * 0.25) + + VStack { + Button { + } label: { + Image("video-camera") + .renderingMode(.template) + .resizable() + .foregroundStyle(.white) + .frame(width: 32, height: 32) + } + .frame(width: 60, height: 60) + .background(Color.gray500) + .cornerRadius(40) + + Text("Disposition") + .foregroundStyle(.white) + .default_text_style(styleSize: 15) + } + .frame(width: geo.size.width * 0.25, height: geo.size.width * 0.25) + .hidden() + } + .frame(height: geo.size.height * 0.15) + + Spacer() + } + .frame(maxHeight: .infinity, alignment: .top) + .presentationBackground(.black) + .presentationDetents([.fraction(0.1), .fraction(0.45)]) + .interactiveDismissDisabled() + .presentationBackgroundInteraction(.enabled) + } + } .sheet(isPresented: $audioRouteSheet, onDismiss: { audioRouteSheet = false hideButtonsSheet = false @@ -237,7 +511,7 @@ struct CallView: View { Spacer() - if callViewModel.cameraDisplayed { + if telecomManager.remoteVideo { Button { callViewModel.switchCamera() } label: { @@ -331,10 +605,12 @@ struct CallView: View { .scaledToFill() .clipped() .onTapGesture { - fullscreenVideo.toggle() + if telecomManager.remoteVideo { + fullscreenVideo.toggle() + } } - if callViewModel.cameraDisplayed { + if telecomManager.remoteVideo { HStack { Spacer() VStack { diff --git a/Linphone/UI/Call/ViewModel/CallViewModel.swift b/Linphone/UI/Call/ViewModel/CallViewModel.swift index 26f9dd2ed..0764d41ec 100644 --- a/Linphone/UI/Call/ViewModel/CallViewModel.swift +++ b/Linphone/UI/Call/ViewModel/CallViewModel.swift @@ -139,8 +139,6 @@ class CallViewModel: ObservableObject { "[CallViewModel] Updating call with video enabled set to \(params.videoEnabled)" ) try self.currentCall!.update(params: params) - - self.cameraDisplayed = self.currentCall!.cameraEnabled == true } catch { } diff --git a/Linphone/UI/Main/ContentView.swift b/Linphone/UI/Main/ContentView.swift index a0a2a0899..92ec3fd72 100644 --- a/Linphone/UI/Main/ContentView.swift +++ b/Linphone/UI/Main/ContentView.swift @@ -681,12 +681,12 @@ struct ContentView: View { if newPhase == .active { coreContext.onForeground() /* - if !isShowStartCallFragment { - contactsManager.fetchContacts() - DispatchQueue.global().asyncAfter(deadline: .now() + 0.5) { - historyListViewModel.computeCallLogsList() - } - } + if !isShowStartCallFragment { + contactsManager.fetchContacts() + DispatchQueue.global().asyncAfter(deadline: .now() + 0.5) { + historyListViewModel.computeCallLogsList() + } + } */ print("Active") } else if newPhase == .inactive { diff --git a/Linphone/UI/Main/Fragments/SideMenu.swift b/Linphone/UI/Main/Fragments/SideMenu.swift index 029f90ff1..e9fdc8d70 100644 --- a/Linphone/UI/Main/Fragments/SideMenu.swift +++ b/Linphone/UI/Main/Fragments/SideMenu.swift @@ -43,19 +43,44 @@ struct SideMenu: View { HStack { List { - Text("My Profile").onTapGesture { - print("My Profile") - } - Text("Send logs").onTapGesture { - sendLogs() - } - Text("Clear logs").onTapGesture { - print("Clear logs") - Core.resetLogCollection() - } - Text("Logout").onTapGesture { - print("Logout") - } + /* + Text("My Profile") + .frame(height: 40) + .frame(maxWidth: .infinity, alignment: .leading) + .background(Color.white) + .onTapGesture { + print("My Profile") + self.menuClose() + } + */ + Text("Send logs") + .frame(height: 40) + .frame(maxWidth: .infinity, alignment: .leading) + .background(Color.white) + .onTapGesture { + print("Send logs") + sendLogs() + self.menuClose() + } + Text("Clear logs") + .frame(height: 40) + .frame(maxWidth: .infinity, alignment: .leading) + .background(Color.white) + .onTapGesture { + print("Clear logs") + clearLogs() + self.menuClose() + } + /* + Text("Logout") + .frame(height: 40) + .frame(maxWidth: .infinity, alignment: .leading) + .background(Color.white) + .onTapGesture { + print("Logout") + self.menuClose() + } + */ } .frame(width: self.width - safeAreaInsets.leading) .background(Color.white) @@ -75,4 +100,14 @@ struct SideMenu: View { core.uploadLogCollection() } } + + func clearLogs() { + coreContext.doOnCoreQueue { core in + Core.resetLogCollection() + DispatchQueue.main.async { + ToastViewModel.shared.toastMessage = "Success_clear_logs" + ToastViewModel.shared.displayToast = true + } + } + } } diff --git a/Linphone/UI/Main/Fragments/ToastView.swift b/Linphone/UI/Main/Fragments/ToastView.swift index 9f8dc277e..565128b7e 100644 --- a/Linphone/UI/Main/Fragments/ToastView.swift +++ b/Linphone/UI/Main/Fragments/ToastView.swift @@ -48,6 +48,20 @@ struct ToastView: View { .default_text_style(styleSize: 15) .padding(8) + case "Success_clear_logs": + Text("Logs cleared") + .multilineTextAlignment(.center) + .foregroundStyle(Color.greenSuccess500) + .default_text_style(styleSize: 15) + .padding(8) + + case "Success_send_logs": + Text("Logs URL copied into clipboard") + .multilineTextAlignment(.center) + .foregroundStyle(Color.greenSuccess500) + .default_text_style(styleSize: 15) + .padding(8) + case "Success_copied_into_clipboard": Text("SIP address copied into clipboard") .multilineTextAlignment(.center) diff --git a/Linphone/Utils/Log.swift b/Linphone/Utils/Log.swift index bb4e61cb1..a2351724c 100644 --- a/Linphone/Utils/Log.swift +++ b/Linphone/Utils/Log.swift @@ -24,6 +24,9 @@ import UIKit import os import linphonesw import linphone +#if USE_CRASHLYTICS +import Firebase +#endif class Log: LoggingServiceDelegate { @@ -88,6 +91,9 @@ class Log: LoggingServiceDelegate { } else { NSLog(log) } +#if USE_CRASHLYTICS + Crashlytics.crashlytics().log(log) +#endif } func onLogMessageWritten(logService: linphonesw.LoggingService, domain: String, level: linphonesw.LogLevel, message: String) { diff --git a/Podfile b/Podfile index 18951b82a..696a25e90 100644 --- a/Podfile +++ b/Podfile @@ -5,14 +5,20 @@ source "https://github.com/CocoaPods/Specs.git" def basic_pods if ENV['PODFILE_PATH'].nil? - pod 'linphone-sdk', '~> 5.3.0-alpha' + pod 'linphone-sdk', '~> 5.4.0-alpha' else pod 'linphone-sdk', :path => ENV['PODFILE_PATH'] # local sdk end - + + crashlytics end - +def crashlytics + if not ENV['USE_CRASHLYTICS'].nil? + pod 'Firebase/Analytics' + pod 'Firebase/Crashlytics' + end +end target 'Linphone' do # Comment the next line if you don't want to use dynamic frameworks @@ -25,9 +31,35 @@ target 'Linphone' do end post_install do |installer| - installer.pods_project.targets.each do |target| - target.build_configurations.each do |config| - config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '15.0' - end - end -end \ No newline at end of file + app_project = Xcodeproj::Project.open(Dir.glob("*.xcodeproj")[0]) + app_project.native_targets.each do |target| + target.build_configurations.each do |config| + if target.name == "Linphone" || target.name == 'msgNotificationService' || target.name == 'msgNotificationContent' + if ENV['USE_CRASHLYTICS'].nil? + if config.name == "Debug" then + config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] = '$(inherited) DEBUG=1' + else + config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] = '$(inherited)' + end + config.build_settings['OTHER_SWIFT_FLAGS'] = '$(inherited)' + else + # activate crashlytics + if config.name == "Debug" then + config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] = '$(inherited) DEBUG=1 USE_CRASHLYTICS=1' + else + config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] = '$(inherited) USE_CRASHLYTICS=1' + end + config.build_settings['OTHER_SWIFT_FLAGS'] = '$(inherited) -DUSE_CRASHLYTICS' + end + end + + app_project.save + end + end + installer.pods_project.targets.each do |target| + target.build_configurations.each do |config| + config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '15.0' + end + end +end +