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
+