diff --git a/Linphone/Core/CorePreferences.swift b/Linphone/Core/CorePreferences.swift
index 34288b7ac..e2bf29d00 100644
--- a/Linphone/Core/CorePreferences.swift
+++ b/Linphone/Core/CorePreferences.swift
@@ -330,6 +330,15 @@ class CorePreferences {
}
}
+ var showDeveloperSettings: Bool {
+ get {
+ config.getBool(section: "ui", key: "show_developer_settings", defaultValue: false)
+ }
+ set {
+ config.setBool(section: "ui", key: "show_developer_settings", value: newValue)
+ }
+ }
+
var showDialogWhenCallingDeviceUuidDirectly: Bool {
get {
config.getBool(section: "app", key: "show_confirmation_dialog_zrtp_trust_call", defaultValue: true)
diff --git a/Linphone/GeneratedGit.swift b/Linphone/GeneratedGit.swift
index 267e068c0..7cc9f4600 100644
--- a/Linphone/GeneratedGit.swift
+++ b/Linphone/GeneratedGit.swift
@@ -1,7 +1,7 @@
import Foundation
public enum AppGitInfo {
- public static let branch = "master"
- public static let commit = "fa9be23c2"
+ public static let branch = "feature/update_settings"
+ public static let commit = "5906c3449"
public static let tag = "6.1.0-alpha"
}
diff --git a/Linphone/Localizable/en.lproj/Localizable.strings b/Linphone/Localizable/en.lproj/Localizable.strings
index d234a0e94..7484b417c 100644
--- a/Linphone/Localizable/en.lproj/Localizable.strings
+++ b/Linphone/Localizable/en.lproj/Localizable.strings
@@ -475,10 +475,8 @@
"qr_code_validated" = "QR code validated";
"recordings_title" = "Recordings";
"recordings_list_empty" = "No recording for the moment…";
-"recordings_list_empty" = "No recording for the moment…";
-"recordings_list_empty" = "No recording for the moment…";
-"recordings_list_empty" = "No recording for the moment…";
"selected_participants_count" = "%@ selected participants";
+"settings_advanced_early_media_title" = "Early-media";
"settings_advanced_accept_early_media_title" = "Accept early media";
"settings_advanced_allow_outgoing_early_media_title" = "Allow outgoing early media";
"settings_advanced_audio_codecs_title" = "Audio codecs";
@@ -488,10 +486,13 @@
"settings_advanced_download_apply_remote_provisioning" = "Download & apply";
"settings_advanced_input_audio_device_title" = "Default input audio device";
"settings_advanced_media_encryption_mandatory_title" = "Media encryption mandatory";
+"settings_advanced_create_e2e_encrypted_conferences_title" = "Create end-to-end encrypted meetings & group calls";
"settings_advanced_output_audio_device_title" = "Default output audio device";
"settings_advanced_remote_provisioning_url" = "Remote provisioning URL";
"settings_advanced_title" = "Advanced settings";
"settings_advanced_upload_server_url" = "File sharing server URL";
+"settings_advanced_logs_upload_server_url" = "Logs sharing server URL";
+"settings_advanced_calls" = "Advanced calls settings";
"settings_advanced_video_codecs_title" = "Video codecs";
"settings_calls_adaptive_rate_control_title" = "Adaptive rate control";
"settings_calls_auto_record_title" = "Automatically start recording calls";
@@ -542,6 +543,21 @@
"settings_conversations_hide_message_content_in_notif_title" = "Do not show message content in iOS notification";
"settings_conversations_mark_as_read_when_dismissing_notif_title" = "Mark conversation as read when dismissing message notification";
"settings_conversations_title" = "Conversations";
+"settings_developer_title" = "Developer settings";
+"settings_developer_show_title" = "Show developer settings";
+"settings_developer_two_more_clicks_required_toast" = "Click 2 more times to enable developer settings";
+"settings_developer_one_more_click_required_toast" = "Click 1 more time to enable developer settings";
+"settings_developer_enabled_toast" = "Developer settings enabled";
+"settings_developer_already_enabled_toast" = "Developer settings already enabled";
+"settings_developer_enable_vu_meters_title" = "Enable record/playback volume vu meters while in call";
+"settings_developer_enable_advanced_call_stats_title" = "Show advanced call statistics";
+"settings_developer_push_compatible_domains_list_title" = "List of push notifications compatible domains (comma separated)";
+"settings_developer_clear_native_friends_in_database_title" = "Clear imported contacts from native address book";
+"settings_developer_clear_native_friends_in_database_subtitle" = "They will be imported again the next time the app starts unless you remove the contacts permission";
+"settings_developer_cleared_native_friends_in_database_toast" = "Imported contacts have been deleted";
+"settings_developer_clear_orphan_auth_info_title" = "Clear authentication info no longer associated to any account";
+"settings_developer_no_auth_info_removed_toast" = "No orphan authentication info found";
+"settings_developer_cleared_auth_info_toast" = "Orphaned authentication info removed";
"settings_meetings_default_layout_title" = "Default layout";
"settings_meetings_layout_active_speaker_label" = "Active speaker";
"settings_meetings_layout_mosaic_label" = "Mosaic";
diff --git a/Linphone/Localizable/fr.lproj/Localizable.strings b/Linphone/Localizable/fr.lproj/Localizable.strings
index 20d5d37a4..6fe138177 100644
--- a/Linphone/Localizable/fr.lproj/Localizable.strings
+++ b/Linphone/Localizable/fr.lproj/Localizable.strings
@@ -475,6 +475,7 @@
"recordings_title" = "Enregistrements";
"recordings_list_empty" = "Aucun appel enregistré…";
"selected_participants_count" = "%@ participants selectionnés";
+"settings_advanced_early_media_title" = "Early media";
"settings_advanced_accept_early_media_title" = "Accepter l'early media";
"settings_advanced_allow_outgoing_early_media_title" = "Autoriser l'early media pour les appels sortants";
"settings_advanced_audio_codecs_title" = "Codecs audio";
@@ -484,10 +485,13 @@
"settings_advanced_download_apply_remote_provisioning" = "Télécharger & appliquer";
"settings_advanced_input_audio_device_title" = "Périphérique de capture par défaut";
"settings_advanced_media_encryption_mandatory_title" = "Rendre le chiffrement du média obligatoire";
+"settings_advanced_create_e2e_encrypted_conferences_title" = "Créer en mode chiffré de bout en bout les réunions et les appels de groupe";
"settings_advanced_output_audio_device_title" = "Périphérique d'écoute par défaut";
"settings_advanced_remote_provisioning_url" = "URL de configuration distante";
"settings_advanced_title" = "Paramètres avancés";
"settings_advanced_upload_server_url" = "URL du serveur de partage de fichier";
+"settings_advanced_logs_upload_server_url" = "URL du serveur de partage des logs";
+"settings_advanced_calls" = "Paramètres d'appels avancés";
"settings_advanced_video_codecs_title" = "Codecs vidéo";
"settings_calls_adaptive_rate_control_title" = "Contrôle automatique de la qualité";
"settings_calls_auto_record_title" = "Enregistrement automatique des appels";
@@ -538,6 +542,22 @@
"settings_conversations_hide_message_content_in_notif_title" = "Masquer le contenu du message dans la notification iOS";
"settings_conversations_mark_as_read_when_dismissing_notif_title" = "Marquer la conversation comme lue lorsqu'une notification de message est supprimée";
"settings_conversations_title" = "Conversations";
+"settings_developer_title" = "Paramètres développeurs";
+"settings_developer_show_title" = "Afficher les paramètres développeurs";
+"settings_developer_two_more_clicks_required_toast" = "Encore 2 clicks pour activer les paramètres développeurs";
+"settings_developer_one_more_click_required_toast" = "Encore 1 click pour activer les paramètres développeurs";
+"settings_developer_enabled_toast" = "Paramètres développeurs activés";
+"settings_developer_already_enabled_toast" = "Paramètres développeurs déjà activés";
+"settings_developer_enable_vu_meters_title" = "Activer l'indicateur des volumes d'enregistrement et de lecture";
+"settings_developer_enable_advanced_call_stats_title" = "Afficher plus de statistiques d'appel";
+"settings_developer_push_compatible_domains_list_title" = "Liste des domaines qui supportent les notifications poussées (séparés par des virgules)";
+"settings_developer_clear_native_friends_in_database_title" = "Supprimer les contacts natifs importés";
+"settings_developer_clear_native_friends_in_database_subtitle" = "Ils seront synchronisés à nouveau au prochain démarrage de l'application sauf si vous retirez la permission de lire les contacts";
+"settings_developer_cleared_native_friends_in_database_toast" = "Contacts importés supprimés";
+"settings_developer_clear_orphan_auth_info_title" = "Supprimer les informations d'authentification orphelines";
+"settings_developer_no_auth_info_removed_toast" = "Aucune information d'authentification orpheline trouvée";
+"settings_developer_cleared_auth_info_toast_single" = "%@ information d'authentification supprimée";
+"settings_developer_cleared_auth_info_toast_multiple" = "%@ informations d'authentification supprimées";
"settings_meetings_default_layout_title" = "Disposition par défaut";
"settings_meetings_layout_active_speaker_label" = "Intervenant actif";
"settings_meetings_layout_mosaic_label" = "Mosaïque";
diff --git a/Linphone/UI/Main/Fragments/ToastView.swift b/Linphone/UI/Main/Fragments/ToastView.swift
index 8ffb2f1da..f7d18d540 100644
--- a/Linphone/UI/Main/Fragments/ToastView.swift
+++ b/Linphone/UI/Main/Fragments/ToastView.swift
@@ -198,6 +198,55 @@ struct ToastView: View {
.default_text_style(styleSize: 15)
.padding(8)
+ case "Success_cleared_native_friends_toast":
+ Text("settings_developer_cleared_native_friends_in_database_toast")
+ .multilineTextAlignment(.center)
+ .foregroundStyle(Color.greenSuccess500)
+ .default_text_style(styleSize: 15)
+ .padding(8)
+
+ case "Success_no_auth_info_removed_toast":
+ Text("settings_developer_no_auth_info_removed_toast")
+ .multilineTextAlignment(.center)
+ .foregroundStyle(Color.greenSuccess500)
+ .default_text_style(styleSize: 15)
+ .padding(8)
+
+ case "Success_cleared_auth_info_toast":
+ Text("settings_developer_cleared_auth_info_toast")
+ .multilineTextAlignment(.center)
+ .foregroundStyle(Color.greenSuccess500)
+ .default_text_style(styleSize: 15)
+ .padding(8)
+
+ case "Success_two_more_clicks_toast":
+ Text("settings_developer_two_more_clicks_required_toast")
+ .multilineTextAlignment(.center)
+ .foregroundStyle(Color.greenSuccess500)
+ .default_text_style(styleSize: 15)
+ .padding(8)
+
+ case "Success_one_more_click_toast":
+ Text("settings_developer_one_more_click_required_toast")
+ .multilineTextAlignment(.center)
+ .foregroundStyle(Color.greenSuccess500)
+ .default_text_style(styleSize: 15)
+ .padding(8)
+
+ case "Success_developer_enabled_toast":
+ Text("settings_developer_enabled_toast")
+ .multilineTextAlignment(.center)
+ .foregroundStyle(Color.greenSuccess500)
+ .default_text_style(styleSize: 15)
+ .padding(8)
+
+ case "Success_developer_already_enabled_toast":
+ Text("settings_developer_already_enabled_toast")
+ .multilineTextAlignment(.center)
+ .foregroundStyle(Color.greenSuccess500)
+ .default_text_style(styleSize: 15)
+ .padding(8)
+
case "Failed_toast_call_transfer_failed":
Text("call_transfer_failed_toast")
.multilineTextAlignment(.center)
diff --git a/Linphone/UI/Main/Help/Fragments/HelpFragment.swift b/Linphone/UI/Main/Help/Fragments/HelpFragment.swift
index 8a5b6fba9..f9f889636 100644
--- a/Linphone/UI/Main/Help/Fragments/HelpFragment.swift
+++ b/Linphone/UI/Main/Help/Fragments/HelpFragment.swift
@@ -25,6 +25,8 @@ struct HelpFragment: View {
@Binding var isShowHelpFragment: Bool
+ @State var clickCounter: Int = 0
+
var showAssistant: Bool {
(CoreContext.shared.coreIsStarted && CoreContext.shared.accounts.isEmpty)
|| SharedMainViewModel.shared.displayProfileMode
@@ -198,6 +200,29 @@ struct HelpFragment: View {
.background(Color.orangeMain100)
.cornerRadius(60)
}
+ .background(Color.gray100)
+ .onTapGesture {
+ if !AppServices.corePreferences.showDeveloperSettings {
+ clickCounter += 1
+
+ switch clickCounter {
+ case 1:
+ ToastViewModel.shared.show("Success_two_more_clicks_toast")
+
+ case 2:
+ ToastViewModel.shared.show("Success_one_more_click_toast")
+
+ case 3:
+ AppServices.corePreferences.showDeveloperSettings = true
+ ToastViewModel.shared.show("Success_developer_enabled_toast")
+
+ default:
+ ToastViewModel.shared.show("Success_developer_already_enabled_toast")
+ }
+ } else {
+ ToastViewModel.shared.show("Success_developer_already_enabled_toast")
+ }
+ }
Button {
if let url = URL(string: NSLocalizedString("website_open_source_licences_usage_url", comment: "")) {
diff --git a/Linphone/UI/Main/Help/ViewModel/HelpViewModel.swift b/Linphone/UI/Main/Help/ViewModel/HelpViewModel.swift
index ec987d8db..2cccdb401 100644
--- a/Linphone/UI/Main/Help/ViewModel/HelpViewModel.swift
+++ b/Linphone/UI/Main/Help/ViewModel/HelpViewModel.swift
@@ -172,19 +172,5 @@ class HelpViewModel: ObservableObject {
}
}
}
-
- func clearNativeFriendsDatabase() {
- CoreContext.shared.doOnCoreQueue { core in
- if let list = core.getFriendListByName(NATIVE_ADDRESS_BOOK_FRIEND_LIST) {
- let friends = list.friends
- Log.i("\(self.TAG) Friend list to remove found with [\(friends.count)] friends")
- for friend in friends {
- list.removeFriend(friend)
- }
- core.removeFriendList(list)
- Log.i("\(self.TAG) Friend list [\(NATIVE_ADDRESS_BOOK_FRIEND_LIST)] removed")
- }
- }
- }
*/
}
diff --git a/Linphone/UI/Main/Settings/Fragments/SettingsAdvancedCallFragment.swift b/Linphone/UI/Main/Settings/Fragments/SettingsAdvancedCallFragment.swift
new file mode 100644
index 000000000..2abcdcb7c
--- /dev/null
+++ b/Linphone/UI/Main/Settings/Fragments/SettingsAdvancedCallFragment.swift
@@ -0,0 +1,274 @@
+/*
+ * Copyright (c) 2010-2023 Belledonne Communications SARL.
+ *
+ * This file is part of linphone-iphone
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+import SwiftUI
+import UniformTypeIdentifiers
+
+struct SettingsAdvancedCallFragment: View {
+ @ObservedObject var settingsViewModel: SettingsViewModel
+
+ @Environment(\.dismiss) var dismiss
+
+ @State var earlyMediaIsOpen: Bool = false
+ @State var audioCodecsIsOpen: Bool = false
+ @State var videoCodecsIsOpen: Bool = false
+
+ var body: some View {
+ ZStack {
+ VStack(spacing: 1) {
+ Rectangle()
+ .foregroundColor(Color.orangeMain500)
+ .edgesIgnoringSafeArea(.top)
+ .frame(height: 0)
+
+ HStack {
+ Image("caret-left")
+ .renderingMode(.template)
+ .resizable()
+ .foregroundStyle(Color.orangeMain500)
+ .frame(width: 25, height: 25, alignment: .leading)
+ .padding(.all, 10)
+ .padding(.top, 4)
+ .padding(.leading, -10)
+ .onTapGesture {
+ dismiss()
+ }
+
+ Text("settings_advanced_calls")
+ .default_text_style_orange_800(styleSize: 16)
+ .frame(maxWidth: .infinity, alignment: .leading)
+ .padding(.top, 4)
+ .lineLimit(1)
+
+ Spacer()
+ }
+ .frame(maxWidth: .infinity)
+ .frame(height: 50)
+ .padding(.horizontal)
+ .padding(.bottom, 4)
+ .background(.white)
+
+ ScrollView {
+ VStack(spacing: 0) {
+ VStack(spacing: 0) {
+ VStack(spacing: 30) {
+ Toggle("settings_calls_enable_fec_title", isOn: $settingsViewModel.enableFec)
+ .default_text_style_700(styleSize: 15)
+
+ VStack(alignment: .leading) {
+ Text("call_stats_media_encryption_title")
+ .default_text_style_700(styleSize: 15)
+ .padding(.bottom, -5)
+
+ Menu {
+ Button("None") {
+ settingsViewModel.mediaEncryption = "None"
+ settingsViewModel.mediaEncryptionMandatory = false
+ }
+ Button("SRTP") {
+ settingsViewModel.mediaEncryption = "SRTP"
+ settingsViewModel.mediaEncryptionMandatory = true
+ }
+ Button("ZRTP") {
+ settingsViewModel.mediaEncryption = "ZRTP"
+ settingsViewModel.mediaEncryptionMandatory = true
+ }
+ Button("DTLS") {
+ settingsViewModel.mediaEncryption = "DTLS"
+ settingsViewModel.mediaEncryptionMandatory = true
+ }
+ } label: {
+ Text(settingsViewModel.mediaEncryption)
+ .default_text_style(styleSize: 15)
+ .frame(maxWidth: .infinity, alignment: .leading)
+ Image("caret-down")
+ .renderingMode(.template)
+ .resizable()
+ .foregroundStyle(Color.grayMain2c500)
+ .frame(width: 20, height: 20)
+ }
+ .frame(height: 25)
+ .padding(.horizontal, 20)
+ .padding(.vertical, 15)
+ .cornerRadius(60)
+ .overlay(
+ RoundedRectangle(cornerRadius: 60)
+ .inset(by: 0.5)
+ .stroke(Color.gray200, lineWidth: 1)
+ )
+ }
+
+ Toggle("settings_advanced_media_encryption_mandatory_title", isOn: $settingsViewModel.mediaEncryptionMandatory)
+ .default_text_style_700(styleSize: 15)
+ }
+ .padding(.vertical, 20)
+ .padding(.horizontal, 20)
+ .background(.white)
+ .cornerRadius(15)
+ .background(Color.gray100)
+ }
+ .padding(.vertical, 20)
+ .padding(.horizontal, 20)
+ .background(Color.gray100)
+
+ HStack(alignment: .center) {
+ Text("settings_advanced_early_media_title")
+ .default_text_style_800(styleSize: 18)
+ .frame(maxWidth: .infinity, alignment: .leading)
+
+ Spacer()
+
+ Image(earlyMediaIsOpen ? "caret-up" : "caret-down")
+ .renderingMode(.template)
+ .resizable()
+ .foregroundStyle(Color.grayMain2c600)
+ .frame(width: 25, height: 25, alignment: .leading)
+ .padding(.all, 10)
+ }
+ .padding(.vertical, 10)
+ .padding(.horizontal, 20)
+ .background(Color.gray100)
+ .onTapGesture {
+ withAnimation {
+ earlyMediaIsOpen.toggle()
+ }
+ }
+
+ if earlyMediaIsOpen {
+ VStack(spacing: 0) {
+ VStack(spacing: 30) {
+ Toggle("settings_advanced_accept_early_media_title", isOn: $settingsViewModel.acceptEarlyMedia)
+ .default_text_style_700(styleSize: 15)
+
+ Toggle("settings_advanced_allow_outgoing_early_media_title", isOn: $settingsViewModel.allowOutgoingEarlyMedia)
+ .default_text_style_700(styleSize: 15)
+ }
+ .padding(.vertical, 30)
+ .padding(.horizontal, 20)
+ }
+ .background(.white)
+ .cornerRadius(15)
+ .padding(.horizontal, 20)
+ .zIndex(-1)
+ .transition(.move(edge: .top))
+ .background(Color.gray100)
+ }
+
+ HStack(alignment: .center) {
+ Text("settings_advanced_audio_codecs_title")
+ .default_text_style_800(styleSize: 18)
+ .frame(maxWidth: .infinity, alignment: .leading)
+
+ Spacer()
+
+ Image(audioCodecsIsOpen ? "caret-up" : "caret-down")
+ .renderingMode(.template)
+ .resizable()
+ .foregroundStyle(Color.grayMain2c600)
+ .frame(width: 25, height: 25, alignment: .leading)
+ .padding(.all, 10)
+ }
+ .padding(.vertical, 10)
+ .padding(.horizontal, 20)
+ .background(Color.gray100)
+ .onTapGesture {
+ withAnimation {
+ audioCodecsIsOpen.toggle()
+ }
+ }
+
+ if audioCodecsIsOpen {
+ VStack(spacing: 0) {
+ VStack(spacing: 30) {
+ ForEach(settingsViewModel.audioCodecs) { audioCodec in
+ SettingsToggleWidget(title: audioCodec.mimeType, subtitle: audioCodec.subtitle, isOn: Binding(
+ get: { audioCodec.isEnabled },
+ set: { newValue in
+ audioCodec.toggleEnabled()
+ }
+ ))
+ }
+ }
+ .padding(.vertical, 30)
+ .padding(.horizontal, 20)
+ }
+ .background(.white)
+ .cornerRadius(15)
+ .padding(.horizontal, 20)
+ .zIndex(-2)
+ .transition(.move(edge: .top))
+ .background(Color.gray100)
+ }
+
+ HStack(alignment: .center) {
+ Text("settings_advanced_video_codecs_title")
+ .default_text_style_800(styleSize: 18)
+ .frame(maxWidth: .infinity, alignment: .leading)
+
+ Spacer()
+
+ Image(videoCodecsIsOpen ? "caret-up" : "caret-down")
+ .renderingMode(.template)
+ .resizable()
+ .foregroundStyle(Color.grayMain2c600)
+ .frame(width: 25, height: 25, alignment: .leading)
+ .padding(.all, 10)
+ }
+ .padding(.vertical, 10)
+ .padding(.horizontal, 20)
+ .background(Color.gray100)
+ .onTapGesture {
+ withAnimation {
+ videoCodecsIsOpen.toggle()
+ }
+ }
+
+ if videoCodecsIsOpen {
+ VStack(spacing: 0) {
+ VStack(spacing: 30) {
+ ForEach(settingsViewModel.videoCodecs) { videoCodec in
+ SettingsToggleWidget(title: videoCodec.mimeType, subtitle: videoCodec.subtitle, isOn: Binding(
+ get: { videoCodec.isEnabled },
+ set: { newValue in
+ videoCodec.toggleEnabled()
+ }
+ ))
+ }
+ }
+ .padding(.vertical, 30)
+ .padding(.horizontal, 20)
+ }
+ .background(.white)
+ .cornerRadius(15)
+ .padding(.horizontal, 20)
+ .zIndex(-3)
+ .transition(.move(edge: .top))
+ .background(Color.gray100)
+ }
+ }
+ .background(Color.gray100)
+ }
+ .background(Color.gray100)
+ }
+ .background(Color.gray100)
+ }
+ .navigationTitle("")
+ .navigationBarHidden(true)
+ }
+}
diff --git a/Linphone/UI/Main/Settings/Fragments/SettingsAdvancedFragment.swift b/Linphone/UI/Main/Settings/Fragments/SettingsAdvancedFragment.swift
index 2ed857377..37ecf7d1e 100644
--- a/Linphone/UI/Main/Settings/Fragments/SettingsAdvancedFragment.swift
+++ b/Linphone/UI/Main/Settings/Fragments/SettingsAdvancedFragment.swift
@@ -26,11 +26,8 @@ struct SettingsAdvancedFragment: View {
@Environment(\.dismiss) var dismiss
@State var audioDevicesIsOpen: Bool = false
- @State var audioCodecsIsOpen: Bool = false
- @State var videoCodecsIsOpen: Bool = false
@FocusState var isDeviceIdFocused: Bool
- @FocusState var isUploadServerUrlFocused: Bool
@FocusState var isRemoteProvisioningUrlFocused: Bool
var body: some View {
@@ -54,7 +51,7 @@ struct SettingsAdvancedFragment: View {
dismiss()
}
- Text("settings_title")
+ Text("settings_advanced_title")
.default_text_style_orange_800(styleSize: 16)
.frame(maxWidth: .infinity, alignment: .leading)
.padding(.top, 4)
@@ -71,61 +68,6 @@ struct SettingsAdvancedFragment: View {
ScrollView {
VStack(spacing: 0) {
VStack(spacing: 30) {
- Toggle("settings_calls_enable_fec_title", isOn: $settingsViewModel.enableFec)
- .default_text_style_700(styleSize: 15)
-
- VStack(alignment: .leading) {
- Text("call_stats_media_encryption_title")
- .default_text_style_700(styleSize: 15)
- .padding(.bottom, -5)
-
- Menu {
- Button("None") {
- settingsViewModel.mediaEncryption = "None"
- settingsViewModel.mediaEncryptionMandatory = false
- }
- Button("SRTP") {
- settingsViewModel.mediaEncryption = "SRTP"
- settingsViewModel.mediaEncryptionMandatory = true
- }
- Button("ZRTP") {
- settingsViewModel.mediaEncryption = "ZRTP"
- settingsViewModel.mediaEncryptionMandatory = true
- }
- Button("DTLS") {
- settingsViewModel.mediaEncryption = "DTLS"
- settingsViewModel.mediaEncryptionMandatory = true
- }
- } label: {
- Text(settingsViewModel.mediaEncryption)
- .default_text_style(styleSize: 15)
- .frame(maxWidth: .infinity, alignment: .leading)
- Image("caret-down")
- .renderingMode(.template)
- .resizable()
- .foregroundStyle(Color.grayMain2c500)
- .frame(width: 20, height: 20)
- }
- .frame(height: 25)
- .padding(.horizontal, 20)
- .padding(.vertical, 15)
- .cornerRadius(60)
- .overlay(
- RoundedRectangle(cornerRadius: 60)
- .inset(by: 0.5)
- .stroke(Color.gray200, lineWidth: 1)
- )
- }
-
- Toggle("settings_advanced_media_encryption_mandatory_title", isOn: $settingsViewModel.mediaEncryptionMandatory)
- .default_text_style_700(styleSize: 15)
-
- Toggle("settings_advanced_accept_early_media_title", isOn: $settingsViewModel.acceptEarlyMedia)
- .default_text_style_700(styleSize: 15)
-
- Toggle("settings_advanced_allow_outgoing_early_media_title", isOn: $settingsViewModel.allowOutgoingEarlyMedia)
- .default_text_style_700(styleSize: 15)
-
VStack(alignment: .leading) {
Text("settings_advanced_device_id")
.default_text_style_700(styleSize: 15)
@@ -145,25 +87,6 @@ struct SettingsAdvancedFragment: View {
.focused($isDeviceIdFocused)
}
- VStack(alignment: .leading) {
- Text("settings_advanced_upload_server_url")
- .default_text_style_700(styleSize: 15)
- .padding(.bottom, -5)
-
- TextField("settings_advanced_upload_server_url", text: $settingsViewModel.uploadServerUrl)
- .default_text_style(styleSize: 15)
- .frame(height: 25)
- .padding(.horizontal, 20)
- .padding(.vertical, 15)
- .cornerRadius(60)
- .overlay(
- RoundedRectangle(cornerRadius: 60)
- .inset(by: 0.5)
- .stroke(isUploadServerUrlFocused ? Color.orangeMain500 : Color.gray200, lineWidth: 1)
- )
- .focused($isUploadServerUrlFocused)
- }
-
VStack(alignment: .leading) {
Text("settings_advanced_remote_provisioning_url")
.default_text_style_700(styleSize: 15)
@@ -201,8 +124,10 @@ struct SettingsAdvancedFragment: View {
.disabled(settingsViewModel.remoteProvisioningUrl.isEmpty)
}
}
- .padding(.vertical, 30)
+ .padding(.vertical, 20)
.padding(.horizontal, 20)
+ .background(.white)
+ .cornerRadius(15)
.background(Color.gray100)
/*
@@ -307,102 +232,15 @@ struct SettingsAdvancedFragment: View {
}
.background(.white)
.cornerRadius(15)
- .padding(.horizontal)
+ .padding(.horizontal, 20)
.zIndex(-1)
.transition(.move(edge: .top))
+ .background(Color.gray100)
}
*/
-
- HStack(alignment: .center) {
- Text("settings_advanced_audio_codecs_title")
- .default_text_style_800(styleSize: 18)
- .frame(maxWidth: .infinity, alignment: .leading)
-
- Spacer()
-
- Image(audioCodecsIsOpen ? "caret-up" : "caret-down")
- .renderingMode(.template)
- .resizable()
- .foregroundStyle(Color.grayMain2c600)
- .frame(width: 25, height: 25, alignment: .leading)
- .padding(.all, 10)
- }
- .padding(.vertical, 10)
- .padding(.horizontal, 20)
- .background(Color.gray100)
- .onTapGesture {
- withAnimation {
- audioCodecsIsOpen.toggle()
- }
- }
-
- if audioCodecsIsOpen {
- VStack(spacing: 0) {
- VStack(spacing: 30) {
- ForEach(settingsViewModel.audioCodecs) { audioCodec in
- SettingsToggleWidget(title: audioCodec.mimeType, subtitle: audioCodec.subtitle, isOn: Binding(
- get: { audioCodec.isEnabled },
- set: { newValue in
- audioCodec.toggleEnabled()
- }
- ))
- }
- }
- .padding(.vertical, 30)
- .padding(.horizontal, 20)
- }
- .background(.white)
- .cornerRadius(15)
- .padding(.horizontal)
- .zIndex(-2)
- .transition(.move(edge: .top))
- }
-
- HStack(alignment: .center) {
- Text("settings_advanced_video_codecs_title")
- .default_text_style_800(styleSize: 18)
- .frame(maxWidth: .infinity, alignment: .leading)
-
- Spacer()
-
- Image(videoCodecsIsOpen ? "caret-up" : "caret-down")
- .renderingMode(.template)
- .resizable()
- .foregroundStyle(Color.grayMain2c600)
- .frame(width: 25, height: 25, alignment: .leading)
- .padding(.all, 10)
- }
- .padding(.vertical, 10)
- .padding(.horizontal, 20)
- .background(Color.gray100)
- .onTapGesture {
- withAnimation {
- videoCodecsIsOpen.toggle()
- }
- }
-
- if videoCodecsIsOpen {
- VStack(spacing: 0) {
- VStack(spacing: 30) {
- ForEach(settingsViewModel.videoCodecs) { videoCodec in
- SettingsToggleWidget(title: videoCodec.mimeType, subtitle: videoCodec.subtitle, isOn: Binding(
- get: { videoCodec.isEnabled },
- set: { newValue in
- videoCodec.toggleEnabled()
- }
- ))
- }
- }
- .padding(.vertical, 30)
- .padding(.horizontal, 20)
- }
- .background(.white)
- .cornerRadius(15)
- .padding(.horizontal)
- .zIndex(-3)
- .transition(.move(edge: .top))
- }
}
+ .padding(.vertical, 20)
+ .padding(.horizontal, 20)
}
.background(Color.gray100)
}
diff --git a/Linphone/UI/Main/Settings/Fragments/SettingsDeveloperFragment.swift b/Linphone/UI/Main/Settings/Fragments/SettingsDeveloperFragment.swift
new file mode 100644
index 000000000..cec5beff2
--- /dev/null
+++ b/Linphone/UI/Main/Settings/Fragments/SettingsDeveloperFragment.swift
@@ -0,0 +1,196 @@
+/*
+ * Copyright (c) 2010-2023 Belledonne Communications SARL.
+ *
+ * This file is part of linphone-iphone
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+import SwiftUI
+import UniformTypeIdentifiers
+
+struct SettingsDeveloperFragment: View {
+ @ObservedObject var settingsViewModel: SettingsViewModel
+
+ @Environment(\.dismiss) var dismiss
+
+ @FocusState var isUploadServerUrlFocused: Bool
+ @FocusState var isLogsUploadServerUrlFocused: Bool
+ @FocusState var isPushCompatibleDomainsListFocused: Bool
+
+ var body: some View {
+ ZStack {
+ VStack(spacing: 1) {
+ Rectangle()
+ .foregroundColor(Color.orangeMain500)
+ .edgesIgnoringSafeArea(.top)
+ .frame(height: 0)
+
+ HStack {
+ Image("caret-left")
+ .renderingMode(.template)
+ .resizable()
+ .foregroundStyle(Color.orangeMain500)
+ .frame(width: 25, height: 25, alignment: .leading)
+ .padding(.all, 10)
+ .padding(.top, 4)
+ .padding(.leading, -10)
+ .onTapGesture {
+ dismiss()
+ }
+
+ Text("settings_developer_title")
+ .default_text_style_orange_800(styleSize: 16)
+ .frame(maxWidth: .infinity, alignment: .leading)
+ .padding(.top, 4)
+ .lineLimit(1)
+
+ Spacer()
+ }
+ .frame(maxWidth: .infinity)
+ .frame(height: 50)
+ .padding(.horizontal)
+ .padding(.bottom, 4)
+ .background(.white)
+
+ ScrollView {
+ VStack(spacing: 0) {
+ VStack(spacing: 30) {
+ Toggle("settings_developer_show_title", isOn: $settingsViewModel.showDeveloperSettings)
+ .default_text_style_700(styleSize: 15)
+
+ Toggle("help_troubleshooting_print_logs_in_logcat", isOn: $settingsViewModel.printLogsInLogcat)
+ .default_text_style_700(styleSize: 15)
+
+ VStack(alignment: .leading) {
+ Text("settings_advanced_upload_server_url")
+ .default_text_style_700(styleSize: 15)
+ .padding(.bottom, -5)
+
+ TextField("settings_advanced_upload_server_url", text: $settingsViewModel.uploadServerUrl)
+ .default_text_style(styleSize: 15)
+ .frame(height: 25)
+ .padding(.horizontal, 20)
+ .padding(.vertical, 15)
+ .cornerRadius(60)
+ .overlay(
+ RoundedRectangle(cornerRadius: 60)
+ .inset(by: 0.5)
+ .stroke(isUploadServerUrlFocused ? Color.orangeMain500 : Color.gray200, lineWidth: 1)
+ )
+ .focused($isUploadServerUrlFocused)
+ }
+
+ VStack(alignment: .leading) {
+ Text("settings_advanced_logs_upload_server_url")
+ .default_text_style_700(styleSize: 15)
+ .padding(.bottom, -5)
+
+ TextField("settings_advanced_logs_upload_server_url", text: $settingsViewModel.logsUploadServerUrl)
+ .default_text_style(styleSize: 15)
+ .frame(height: 25)
+ .padding(.horizontal, 20)
+ .padding(.vertical, 15)
+ .cornerRadius(60)
+ .overlay(
+ RoundedRectangle(cornerRadius: 60)
+ .inset(by: 0.5)
+ .stroke(isLogsUploadServerUrlFocused ? Color.orangeMain500 : Color.gray200, lineWidth: 1)
+ )
+ .focused($isLogsUploadServerUrlFocused)
+ }
+
+ // TODO: Add these settings
+ /*
+ Toggle("settings_advanced_create_e2e_encrypted_conferences_title", isOn: $settingsViewModel.???)
+ .default_text_style_700(styleSize: 15)
+
+ Toggle("settings_developer_enable_vu_meters_title", isOn: $settingsViewModel.???)
+ .default_text_style_700(styleSize: 15)
+
+ Toggle("settings_developer_enable_advanced_call_stats_title", isOn: $settingsViewModel.???)
+ .default_text_style_700(styleSize: 15)
+
+ VStack(alignment: .leading) {
+ Text("settings_developer_push_compatible_domains_list_title")
+ .default_text_style_700(styleSize: 15)
+ .padding(.bottom, -5)
+
+ TextField("settings_developer_push_compatible_domains_list_title", text: $settingsViewModel.???)
+ .default_text_style(styleSize: 15)
+ .frame(height: 25)
+ .padding(.horizontal, 20)
+ .padding(.vertical, 15)
+ .cornerRadius(60)
+ .overlay(
+ RoundedRectangle(cornerRadius: 60)
+ .inset(by: 0.5)
+ .stroke(isPushCompatibleDomainsListFocused ? Color.orangeMain500 : Color.gray200, lineWidth: 1)
+ )
+ .focused($isPushCompatibleDomainsListFocused)
+ }
+ */
+
+ VStack(alignment: .leading) {
+ Button(
+ action: {
+ settingsViewModel.clearNativeFriendsDatabase()
+ }, label: {
+ Text("settings_developer_clear_native_friends_in_database_title")
+ .default_text_style_white_600(styleSize: 15)
+ .frame(maxWidth: .infinity, alignment: .center)
+ }
+ )
+ .padding(.horizontal, 20)
+ .padding(.vertical, 10)
+ .background(Color.redDanger500)
+ .cornerRadius(60)
+
+ Text("settings_developer_clear_native_friends_in_database_subtitle")
+ .default_text_style(styleSize: 14)
+ .frame(maxWidth: .infinity, alignment: .leading)
+ }
+
+ Button(
+ action: {
+ settingsViewModel.clearOrphanAuthInfo()
+ }, label: {
+ Text("settings_developer_clear_orphan_auth_info_title")
+ .default_text_style_white_600(styleSize: 15)
+ .frame(maxWidth: .infinity, alignment: .center)
+ }
+ )
+ .padding(.horizontal, 20)
+ .padding(.vertical, 10)
+ .background(Color.redDanger500)
+ .cornerRadius(60)
+
+ }
+ .padding(.vertical, 20)
+ .padding(.horizontal, 20)
+ .background(.white)
+ .cornerRadius(15)
+ .background(Color.gray100)
+ }
+ .padding(.vertical, 20)
+ .padding(.horizontal, 20)
+ }
+ .background(Color.gray100)
+ }
+ .background(Color.gray100)
+ }
+ .navigationTitle("")
+ .navigationBarHidden(true)
+ }
+}
diff --git a/Linphone/UI/Main/Settings/Fragments/SettingsFragment.swift b/Linphone/UI/Main/Settings/Fragments/SettingsFragment.swift
index 0c8d16257..33c79ab7a 100644
--- a/Linphone/UI/Main/Settings/Fragments/SettingsFragment.swift
+++ b/Linphone/UI/Main/Settings/Fragments/SettingsFragment.swift
@@ -132,7 +132,7 @@ struct SettingsFragment: View {
}
.background(.white)
.cornerRadius(15)
- .padding(.horizontal)
+ .padding(.horizontal, 20)
.zIndex(-1)
.transition(.move(edge: .top))
}
@@ -195,15 +195,36 @@ struct SettingsFragment: View {
}
}
*/
+
+ NavigationLink(destination: {
+ SettingsAdvancedCallFragment(settingsViewModel: settingsViewModel)
+ }, label: {
+ HStack(alignment: .center) {
+ Text("settings_advanced_calls")
+ .default_text_style_700(styleSize: 15)
+ .frame(maxWidth: .infinity, alignment: .leading)
+
+ Spacer()
+
+ Image("caret-right")
+ .renderingMode(.template)
+ .resizable()
+ .foregroundStyle(Color.grayMain2c600)
+ .frame(width: 25, height: 25, alignment: .leading)
+ }
+ .frame(maxWidth: .infinity)
+
+ })
}
.padding(.vertical, 30)
.padding(.horizontal, 20)
}
.background(.white)
.cornerRadius(15)
- .padding(.horizontal)
+ .padding(.horizontal, 20)
.zIndex(-2)
.transition(.move(edge: .top))
+ .background(Color.gray100)
}
HStack(alignment: .center) {
@@ -243,9 +264,10 @@ struct SettingsFragment: View {
}
.background(.white)
.cornerRadius(15)
- .padding(.horizontal)
+ .padding(.horizontal, 20)
.zIndex(-3)
.transition(.move(edge: .top))
+ .background(Color.gray100)
}
HStack(alignment: .center) {
@@ -373,9 +395,10 @@ struct SettingsFragment: View {
}
.background(.white)
.cornerRadius(15)
- .padding(.horizontal)
+ .padding(.horizontal, 20)
.zIndex(-4)
.transition(.move(edge: .top))
+ .background(Color.gray100)
}
HStack(alignment: .center) {
@@ -438,9 +461,10 @@ struct SettingsFragment: View {
}
.background(.white)
.cornerRadius(15)
- .padding(.horizontal)
+ .padding(.horizontal, 20)
.zIndex(-5)
.transition(.move(edge: .top))
+ .background(Color.gray100)
}
HStack(alignment: .center) {
@@ -480,9 +504,10 @@ struct SettingsFragment: View {
}
.background(.white)
.cornerRadius(15)
- .padding(.horizontal)
+ .padding(.horizontal, 20)
.zIndex(-6)
.transition(.move(edge: .top))
+ .background(Color.gray100)
}
/*
@@ -525,11 +550,13 @@ struct SettingsFragment: View {
}
.background(.white)
.cornerRadius(15)
- .padding(.horizontal)
+ .padding(.horizontal, 20)
.zIndex(-7)
.transition(.move(edge: .top))
+ .background(Color.gray100)
}
*/
+
NavigationLink(destination: {
SettingsAdvancedFragment(settingsViewModel: settingsViewModel)
}, label: {
@@ -553,6 +580,32 @@ struct SettingsFragment: View {
.padding(.vertical, 10)
.padding(.horizontal, 20)
.background(Color.gray100)
+
+ if AppServices.corePreferences.showDeveloperSettings {
+ NavigationLink(destination: {
+ SettingsDeveloperFragment(settingsViewModel: settingsViewModel)
+ }, label: {
+ HStack(alignment: .center) {
+ Text("settings_developer_title")
+ .default_text_style_800(styleSize: 18)
+ .frame(maxWidth: .infinity, alignment: .leading)
+
+ Spacer()
+
+ Image("caret-right")
+ .renderingMode(.template)
+ .resizable()
+ .foregroundStyle(Color.grayMain2c600)
+ .frame(width: 25, height: 25, alignment: .leading)
+ .padding(.all, 10)
+ }
+ .frame(maxWidth: .infinity)
+
+ })
+ .padding(.vertical, 10)
+ .padding(.horizontal, 20)
+ .background(Color.gray100)
+ }
}
}
.background(Color.gray100)
diff --git a/Linphone/UI/Main/Settings/ViewModel/SettingsViewModel.swift b/Linphone/UI/Main/Settings/ViewModel/SettingsViewModel.swift
index d000c4e13..4f9b7d880 100644
--- a/Linphone/UI/Main/Settings/ViewModel/SettingsViewModel.swift
+++ b/Linphone/UI/Main/Settings/ViewModel/SettingsViewModel.swift
@@ -57,7 +57,6 @@ class SettingsViewModel: ObservableObject {
@Published var acceptEarlyMedia: Bool = false
@Published var allowOutgoingEarlyMedia: Bool = false
@Published var deviceId: String = ""
- @Published var uploadServerUrl: String = ""
@Published var remoteProvisioningUrl: String = ""
@Published var inputAudioDeviceLabels: [String] = []
@@ -71,6 +70,13 @@ class SettingsViewModel: ObservableObject {
@Published var audioCodecs: [CodecModel] = []
@Published var videoCodecs: [CodecModel] = []
+
+ // Developer settings
+ @Published var showDeveloperSettings: Bool = false
+ @Published var printLogsInLogcat: Bool = false
+ @Published var uploadServerUrl: String = ""
+ @Published var logsUploadServerUrl: String = ""
+
init() {
CoreContext.shared.doOnCoreQueue { core in
@@ -105,9 +111,14 @@ class SettingsViewModel: ObservableObject {
let acceptEarlyMediaTmp = AppServices.corePreferences.acceptEarlyMedia
let allowOutgoingEarlyMediaTmp = AppServices.corePreferences.allowOutgoingEarlyMedia
let deviceIdTmp = AppServices.corePreferences.deviceName
- let fileSharingServerUrlTmp = core.fileTransferServer
let remoteProvisioningUrlTmp = core.provisioningUri
+ // Developer settings
+ let showDeveloperSettingsTmp = AppServices.corePreferences.showDeveloperSettings
+ let printLogsInLogcatTmp = AppServices.corePreferences.printLogsInLogcat
+ let fileSharingServerUrlTmp = core.fileTransferServer
+ let logsTransferServerTmp = core.logCollectionUploadServerUrl
+
DispatchQueue.main.async {
self.enableVfs = enableVfsTmp
@@ -131,9 +142,14 @@ class SettingsViewModel: ObservableObject {
self.allowOutgoingEarlyMedia = allowOutgoingEarlyMediaTmp
self.deviceId = deviceIdTmp
- self.uploadServerUrl = fileSharingServerUrlTmp ?? ""
self.remoteProvisioningUrl = remoteProvisioningUrlTmp ?? ""
+ // Developer settings
+ self.showDeveloperSettings = showDeveloperSettingsTmp
+ self.printLogsInLogcat = printLogsInLogcatTmp
+ self.uploadServerUrl = fileSharingServerUrlTmp ?? ""
+ self.logsUploadServerUrl = logsTransferServerTmp ?? ""
+
/*
self.setupAudioDevices()
@@ -421,9 +437,74 @@ class SettingsViewModel: ObservableObject {
AppServices.corePreferences.deviceName = self.deviceId
}
+ // Developer settings
+ if AppServices.corePreferences.showDeveloperSettings != self.showDeveloperSettings {
+ AppServices.corePreferences.showDeveloperSettings = self.showDeveloperSettings
+ }
+
+ if AppServices.corePreferences.printLogsInLogcat != self.printLogsInLogcat {
+ AppServices.corePreferences.printLogsInLogcat = self.printLogsInLogcat
+ }
+
if core.fileTransferServer != self.uploadServerUrl && !(core.fileTransferServer == nil && self.uploadServerUrl.isEmpty) {
core.fileTransferServer = self.uploadServerUrl
}
+
+ if core.logCollectionUploadServerUrl != self.logsUploadServerUrl && !(core.logCollectionUploadServerUrl == nil && self.logsUploadServerUrl.isEmpty) {
+ core.logCollectionUploadServerUrl = self.logsUploadServerUrl
+ }
+ }
+ }
+ func clearNativeFriendsDatabase() {
+ CoreContext.shared.doOnCoreQueue { core in
+ let nativeAddressBookFriendList = "Native address-book"
+ if let list = core.getFriendListByName(name: nativeAddressBookFriendList) {
+ let friends = list.friends
+ Log.info("\(SettingsViewModel.TAG) Friend list to remove found with \(friends.count) friends")
+ for friend in friends {
+ _ = list.removeFriend(linphoneFriend: friend)
+ }
+ core.removeFriendList(list: list)
+ Log.info("\(SettingsViewModel.TAG) Friend list \(nativeAddressBookFriendList) removed")
+ }
+
+ DispatchQueue.main.async {
+ ToastViewModel.shared.show("Success_cleared_native_friends_toast")
+ }
+ }
+ }
+
+ func clearOrphanAuthInfo() {
+ CoreContext.shared.doOnCoreQueue { core in
+ var count = 0
+
+ for authInfo in core.authInfoList {
+ if let username = authInfo.username {
+ let account = core.accountList.first {
+ $0.params?.identityAddress?.username == username
+ }
+
+ if account == nil {
+ Log.info("\(SettingsViewModel.TAG) Removing auth info \(authInfo) with username \(username) for which no account was found")
+ core.removeAuthInfo(info: authInfo)
+ count += 1
+ }
+ } else {
+ Log.info("\(SettingsViewModel.TAG) Removing auth info \(authInfo) without username")
+ core.removeAuthInfo(info: authInfo)
+ count += 1
+ }
+ }
+
+ if count == 0 {
+ DispatchQueue.main.async {
+ ToastViewModel.shared.show("Success_no_auth_info_removed_toast")
+ }
+ } else {
+ DispatchQueue.main.async {
+ ToastViewModel.shared.show("Success_cleared_auth_info_toast")
+ }
+ }
}
}
}
diff --git a/LinphoneApp.xcodeproj/project.pbxproj b/LinphoneApp.xcodeproj/project.pbxproj
index ad4d9f6d7..9e8cc70fc 100644
--- a/LinphoneApp.xcodeproj/project.pbxproj
+++ b/LinphoneApp.xcodeproj/project.pbxproj
@@ -205,6 +205,8 @@
D7D5AD872DD34F3C00016721 /* FirebaseCrashlytics in Frameworks */ = {isa = PBXBuildFile; productRef = D7D5AD862DD34F3C00016721 /* FirebaseCrashlytics */; };
D7D67B6A2F601F6100DD9976 /* AppIntentVocabulary.plist in Resources */ = {isa = PBXBuildFile; fileRef = D7D67B692F601F6100DD9976 /* AppIntentVocabulary.plist */; };
D7D67B6B2F601F6100DD9976 /* AppIntentVocabulary.plist in Resources */ = {isa = PBXBuildFile; fileRef = D7D67B692F601F6100DD9976 /* AppIntentVocabulary.plist */; };
+ D7D67B8B2F62B0DA00DD9976 /* SettingsAdvancedCallFragment.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7D67B8A2F62B07F00DD9976 /* SettingsAdvancedCallFragment.swift */; };
+ D7D67B8D2F62B0F100DD9976 /* SettingsDeveloperFragment.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7D67B8C2F62B0EF00DD9976 /* SettingsDeveloperFragment.swift */; };
D7DA67622ACCB2FA00E95002 /* LoginFragment.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7DA67612ACCB2FA00E95002 /* LoginFragment.swift */; };
D7DA67642ACCB31700E95002 /* ProfileModeFragment.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7DA67632ACCB31700E95002 /* ProfileModeFragment.swift */; };
D7DC096F2CFA1D7600A6D47C /* AccountProfileFragment.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7DC096E2CFA1D7400A6D47C /* AccountProfileFragment.swift */; };
@@ -487,6 +489,8 @@
D7D67B7A2F601F7400DD9976 /* sk */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = sk; path = sk.lproj/AppIntentVocabulary.plist; sourceTree = ""; };
D7D67B7B2F601F7400DD9976 /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = es; path = es.lproj/AppIntentVocabulary.plist; sourceTree = ""; };
D7D67B7C2F601F7500DD9976 /* uk */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = uk; path = uk.lproj/AppIntentVocabulary.plist; sourceTree = ""; };
+ D7D67B8A2F62B07F00DD9976 /* SettingsAdvancedCallFragment.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsAdvancedCallFragment.swift; sourceTree = ""; };
+ D7D67B8C2F62B0EF00DD9976 /* SettingsDeveloperFragment.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsDeveloperFragment.swift; sourceTree = ""; };
D7DA67612ACCB2FA00E95002 /* LoginFragment.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoginFragment.swift; sourceTree = ""; };
D7DA67632ACCB31700E95002 /* ProfileModeFragment.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProfileModeFragment.swift; sourceTree = ""; };
D7DC096E2CFA1D7400A6D47C /* AccountProfileFragment.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountProfileFragment.swift; sourceTree = ""; };
@@ -1191,12 +1195,14 @@
D7DC096B2CFA192F00A6D47C /* Fragments */ = {
isa = PBXGroup;
children = (
+ D7DC096E2CFA1D7400A6D47C /* AccountProfileFragment.swift */,
+ D7C5003F2D27F16900DD53EC /* AccountSettingsFragment.swift */,
D762102B2E97FDF8002E7999 /* CardDavAddressBookConfigurationFragment.swift */,
D711B1332E93F18300DF8C71 /* LdapServerConfigurationFragment.swift */,
- D78607702D36CB87009E6A7E /* SettingsAdvancedFragment.swift */,
D732C38B2D311D2100F78100 /* SettingsFragment.swift */,
- D7C5003F2D27F16900DD53EC /* AccountSettingsFragment.swift */,
- D7DC096E2CFA1D7400A6D47C /* AccountProfileFragment.swift */,
+ D78607702D36CB87009E6A7E /* SettingsAdvancedFragment.swift */,
+ D7D67B8C2F62B0EF00DD9976 /* SettingsDeveloperFragment.swift */,
+ D7D67B8A2F62B07F00DD9976 /* SettingsAdvancedCallFragment.swift */,
);
path = Fragments;
sourceTree = "";
@@ -1508,6 +1514,7 @@
D71A0E192B485ADF0002C6CD /* ViewExtension.swift in Sources */,
D759CB642C3FBD4200AC35E8 /* StartConversationFragment.swift in Sources */,
D7DF8BE92E2104EC003A3BC7 /* EmojiPickerView.swift in Sources */,
+ D7D67B8B2F62B0DA00DD9976 /* SettingsAdvancedCallFragment.swift in Sources */,
66FDB7812C7C689A00561566 /* EventEditViewController.swift in Sources */,
D750D3392AD3E6EE00EC99C5 /* PopupLoadingView.swift in Sources */,
D7E6D0492AE933AD00A57AAF /* FavoriteContactsListFragment.swift in Sources */,
@@ -1593,6 +1600,7 @@
D79F2D0A2C47F4BF0038FA07 /* TouchFeedback.swift in Sources */,
D78E06282BE3811D00CE3783 /* CallStatsModel.swift in Sources */,
D7E6D0512AEBDBD500A57AAF /* ContactsListBottomSheet.swift in Sources */,
+ D7D67B8D2F62B0F100DD9976 /* SettingsDeveloperFragment.swift in Sources */,
D75759322B56D40900E7AC10 /* ZRTPPopup.swift in Sources */,
D78E062E2BEA69F400CE3783 /* AudioRouteBottomSheet.swift in Sources */,
D7A0ACBB2C415D630043AE79 /* StartGroupConversationFragment.swift in Sources */,