Add settings view

This commit is contained in:
Benoit Martins 2025-01-10 16:08:14 +01:00
parent fe0d0f166c
commit eb68b50a43
7 changed files with 1767 additions and 3 deletions

View file

@ -103,6 +103,7 @@
D732A9132B04C7A300DB42BA /* HistoryListFragment.swift in Sources */ = {isa = PBXBuildFile; fileRef = D732A9122B04C7A300DB42BA /* HistoryListFragment.swift */; };
D732A9152B04C7FE00DB42BA /* HistoryListViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D732A9142B04C7FE00DB42BA /* HistoryListViewModel.swift */; };
D732A91B2B061BD900DB42BA /* HistoryListBottomSheet.swift in Sources */ = {isa = PBXBuildFile; fileRef = D732A91A2B061BD900DB42BA /* HistoryListBottomSheet.swift */; };
D732C38C2D311D2500F78100 /* SettingsFragment.swift in Sources */ = {isa = PBXBuildFile; fileRef = D732C38B2D311D2100F78100 /* SettingsFragment.swift */; };
D73449992BC6932A00778C56 /* MeetingWaitingRoomFragment.swift in Sources */ = {isa = PBXBuildFile; fileRef = D73449982BC6932A00778C56 /* MeetingWaitingRoomFragment.swift */; };
D734499B2BC694C900778C56 /* MeetingWaitingRoomViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D734499A2BC694C900778C56 /* MeetingWaitingRoomViewModel.swift */; };
D748BF2C2ACD82D2004844EB /* ThirdPartySipAccountLoginFragment.swift in Sources */ = {isa = PBXBuildFile; fileRef = D748BF2B2ACD82D2004844EB /* ThirdPartySipAccountLoginFragment.swift */; };
@ -114,6 +115,9 @@
D74C9D012ACB098C0021626A /* PermissionManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = D74C9D002ACB098C0021626A /* PermissionManager.swift */; };
D74DA0122C047F0700A8561D /* HistoryModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D74DA0112C047F0700A8561D /* HistoryModel.swift */; };
D750D3392AD3E6EE00EC99C5 /* PopupLoadingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D750D3382AD3E6EE00EC99C5 /* PopupLoadingView.swift */; };
D756C8152D34FF9200A58F2F /* SettingsViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D756C8142D34FF8900A58F2F /* SettingsViewModel.swift */; };
D756C8172D352C5F00A58F2F /* CorePreferences.swift in Sources */ = {isa = PBXBuildFile; fileRef = D756C8162D352C5600A58F2F /* CorePreferences.swift */; };
D756C8182D352C5F00A58F2F /* CorePreferences.swift in Sources */ = {isa = PBXBuildFile; fileRef = D756C8162D352C5600A58F2F /* CorePreferences.swift */; };
D75759322B56D40900E7AC10 /* ZRTPPopup.swift in Sources */ = {isa = PBXBuildFile; fileRef = D75759312B56D40900E7AC10 /* ZRTPPopup.swift */; };
D759CB642C3FBD4200AC35E8 /* StartConversationFragment.swift in Sources */ = {isa = PBXBuildFile; fileRef = D759CB632C3FBD4200AC35E8 /* StartConversationFragment.swift */; };
D759CB662C3FBE1D00AC35E8 /* StartConversationViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D759CB652C3FBE1D00AC35E8 /* StartConversationViewModel.swift */; };
@ -300,6 +304,7 @@
D732A9122B04C7A300DB42BA /* HistoryListFragment.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HistoryListFragment.swift; sourceTree = "<group>"; };
D732A9142B04C7FE00DB42BA /* HistoryListViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HistoryListViewModel.swift; sourceTree = "<group>"; };
D732A91A2B061BD900DB42BA /* HistoryListBottomSheet.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HistoryListBottomSheet.swift; sourceTree = "<group>"; };
D732C38B2D311D2100F78100 /* SettingsFragment.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsFragment.swift; sourceTree = "<group>"; };
D73449982BC6932A00778C56 /* MeetingWaitingRoomFragment.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MeetingWaitingRoomFragment.swift; sourceTree = "<group>"; };
D734499A2BC694C900778C56 /* MeetingWaitingRoomViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MeetingWaitingRoomViewModel.swift; sourceTree = "<group>"; };
D748BF2B2ACD82D2004844EB /* ThirdPartySipAccountLoginFragment.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThirdPartySipAccountLoginFragment.swift; sourceTree = "<group>"; };
@ -311,6 +316,8 @@
D74C9D002ACB098C0021626A /* PermissionManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PermissionManager.swift; sourceTree = "<group>"; };
D74DA0112C047F0700A8561D /* HistoryModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HistoryModel.swift; sourceTree = "<group>"; };
D750D3382AD3E6EE00EC99C5 /* PopupLoadingView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PopupLoadingView.swift; sourceTree = "<group>"; };
D756C8142D34FF8900A58F2F /* SettingsViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsViewModel.swift; sourceTree = "<group>"; };
D756C8162D352C5600A58F2F /* CorePreferences.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CorePreferences.swift; sourceTree = "<group>"; };
D75759312B56D40900E7AC10 /* ZRTPPopup.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ZRTPPopup.swift; sourceTree = "<group>"; };
D759CB632C3FBD4200AC35E8 /* StartConversationFragment.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StartConversationFragment.swift; sourceTree = "<group>"; };
D759CB652C3FBE1D00AC35E8 /* StartConversationViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StartConversationViewModel.swift; sourceTree = "<group>"; };
@ -620,6 +627,7 @@
D719ABC72ABC6FB200B41C10 /* Core */ = {
isa = PBXGroup;
children = (
D756C8162D352C5600A58F2F /* CorePreferences.swift */,
D719ABC82ABC6FD700B41C10 /* CoreContext.swift */,
66C491FA2B24D32600CEA16D /* CoreExtension.swift */,
);
@ -931,6 +939,7 @@
D7DC096B2CFA192F00A6D47C /* Fragments */ = {
isa = PBXGroup;
children = (
D732C38B2D311D2100F78100 /* SettingsFragment.swift */,
D7C5003F2D27F16900DD53EC /* AccountSettingsFragment.swift */,
D7DC096E2CFA1D7400A6D47C /* AccountProfileFragment.swift */,
);
@ -947,6 +956,7 @@
D7DC096D2CFA194600A6D47C /* ViewModel */ = {
isa = PBXGroup;
children = (
D756C8142D34FF8900A58F2F /* SettingsViewModel.swift */,
D7C500412D2BE96E00DD53EC /* AccountSettingsViewModel.swift */,
D7DC09702CFDBF8300A6D47C /* AccountProfileViewModel.swift */,
);
@ -1147,6 +1157,7 @@
66FBFC492B83BD2400BC6AB1 /* ConfigExtension.swift in Sources */,
66FBFC4A2B83BD3300BC6AB1 /* FileUtils.swift in Sources */,
66FBFC4B2B83BD7B00BC6AB1 /* CoreExtension.swift in Sources */,
D756C8172D352C5F00A58F2F /* CorePreferences.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -1252,6 +1263,7 @@
6613A0B42BAEBE3F008923A4 /* MeetingViewModel.swift in Sources */,
D7173EBE2B7A5C0A00BCC481 /* LinphoneUtils.swift in Sources */,
66C492012B24DB6900CEA16D /* Log.swift in Sources */,
D756C8182D352C5F00A58F2F /* CorePreferences.swift in Sources */,
C6A5A9432C10B5ED0070FEA4 /* DecodableExtension.swift in Sources */,
D714035B2BE11E00004BD8CA /* CallMediaEncryptionModel.swift in Sources */,
D748BF2C2ACD82D2004844EB /* ThirdPartySipAccountLoginFragment.swift in Sources */,
@ -1273,6 +1285,7 @@
D72A9A052B9750A1000DC093 /* UIList.swift in Sources */,
D726E43D2B19E4FE0083C415 /* StartCallFragment.swift in Sources */,
66E56BCC2BA9A1E0006CE56F /* MeetingsListItemModel.swift in Sources */,
D756C8152D34FF9200A58F2F /* SettingsViewModel.swift in Sources */,
D7B99E9B2B29F7C300BE7BF2 /* ActivityIndicator.swift in Sources */,
66F626B22BCEBB86003E2DEC /* AddParticipantsFragment.swift in Sources */,
D72343302ACEFEF8009AA24E /* QrCodeScannerFragment.swift in Sources */,
@ -1290,6 +1303,7 @@
D7CEE0352B7A210300FD79B7 /* ConversationsView.swift in Sources */,
D717071E2AC5922E0037746F /* ColorExtension.swift in Sources */,
D71968922B86369D00DF4459 /* ChatBubbleView.swift in Sources */,
D732C38C2D311D2500F78100 /* SettingsFragment.swift in Sources */,
D78290B82ADD3910004AA85C /* ContactsFragment.swift in Sources */,
D7DA67642ACCB31700E95002 /* ProfileModeFragment.swift in Sources */,
D7CEE03D2B7A23B200FD79B7 /* ConversationsListFragment.swift in Sources */,

View file

@ -0,0 +1,241 @@
/*
* 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 <http://www.gnu.org/licenses/>.
*/
import Foundation
import linphonesw
class CorePreferences {
static var printLogsInLogcat: Bool {
get {
return Config.get().getBool(section: "app", key: "debug", defaultValue: true)
}
set {
Config.get().setBool(section: "app", key: "debug", value: newValue)
}
}
static var firstLaunch: Bool {
get {
return Config.get().getBool(section: "app", key: "first_6.0_launch", defaultValue: true)
}
set {
Config.get().setBool(section: "app", key: "first_6.0_launch", value: newValue)
}
}
static var linphoneConfigurationVersion: Int {
get {
return Config.get().getInt(section: "app", key: "config_version", defaultValue: 52005)
}
set {
Config.get().setInt(section: "app", key: "config_version", value: newValue)
}
}
static var checkForUpdateServerUrl: String {
get {
return Config.get().getString(section: "misc", key: "version_check_url_root", defaultString: "")
}
set {
Config.get().setString(section: "misc", key: "version_check_url_root", value: newValue)
}
}
static var conditionsAndPrivacyPolicyAccepted: Bool {
get {
return Config.get().getBool(section: "app", key: "read_and_agree_terms_and_privacy", defaultValue: false)
}
set {
Config.get().setBool(section: "app", key: "read_and_agree_terms_and_privacy", value: newValue)
}
}
static var publishPresence: Bool {
get {
return Config.get().getBool(section: "app", key: "publish_presence", defaultValue: true)
}
set {
Config.get().setBool(section: "app", key: "publish_presence", value: newValue)
}
}
static var keepServiceAlive: Bool {
get {
return Config.get().getBool(section: "app", key: "keep_service_alive", defaultValue: false)
}
set {
Config.get().setBool(section: "app", key: "keep_service_alive", value: newValue)
}
}
static var deviceName: String {
get {
return Config.get().getString(section: "app", key: "device", defaultString: "").trimmingCharacters(in: .whitespaces)
}
set {
Config.get().setString(section: "app", key: "device", value: newValue.trimmingCharacters(in: .whitespaces))
}
}
static var routeAudioToSpeakerWhenVideoIsEnabled: Bool {
get {
return Config.get().getBool(section: "app", key: "route_audio_to_speaker_when_video_enabled", defaultValue: true)
}
set {
Config.get().setBool(section: "app", key: "route_audio_to_speaker_when_video_enabled", value: newValue)
}
}
static var automaticallyStartCallRecording: Bool {
get {
return Config.get().getBool(section: "app", key: "auto_start_call_record", defaultValue: false)
}
set {
Config.get().setBool(section: "app", key: "auto_start_call_record", value: newValue)
}
}
static var showDialogWhenCallingDeviceUuidDirectly: Bool {
get {
return Config.get().getBool(section: "app", key: "show_confirmation_dialog_zrtp_trust_call", defaultValue: true)
}
set {
Config.get().setBool(section: "app", key: "show_confirmation_dialog_zrtp_trust_call", value: newValue)
}
}
static var markConversationAsReadWhenDismissingMessageNotification: Bool {
get {
return Config.get().getBool(section: "app", key: "mark_as_read_notif_dismissal", defaultValue: false)
}
set {
Config.get().setBool(section: "app", key: "mark_as_read_notif_dismissal", value: newValue)
}
}
static var contactsFilter: String {
get {
return Config.get().getString(section: "ui", key: "contacts_filter", defaultString: "")
}
set {
Config.get().setString(section: "ui", key: "contacts_filter", value: newValue)
}
}
static var showFavoriteContacts: Bool {
get {
return Config.get().getBool(section: "ui", key: "show_favorites_contacts", defaultValue: true)
}
set {
Config.get().setBool(section: "ui", key: "show_favorites_contacts", value: newValue)
}
}
static var voiceRecordingMaxDuration: Int {
get {
return Config.get().getInt(section: "app", key: "voice_recording_max_duration", defaultValue: 600000)
}
set {
Config.get().setInt(section: "app", key: "voice_recording_max_duration", value: newValue)
}
}
static var darkMode: Int {
get {
if !darkModeAllowed { return 0 }
return Config.get().getInt(section: "app", key: "dark_mode", defaultValue: -1)
}
set {
Config.get().setInt(section: "app", key: "dark_mode", value: newValue)
}
}
static var enableSecureMode: Bool {
get {
return Config.get().getBool(section: "ui", key: "enable_secure_mode", defaultValue: true)
}
set {
Config.get().setBool(section: "ui", key: "enable_secure_mode", value: newValue)
}
}
static var themeMainColor: String {
get {
return Config.get().getString(section: "ui", key: "theme_main_color", defaultString: "orange")
}
set {
Config.get().setString(section: "ui", key: "theme_main_color", value: newValue)
}
}
static var darkModeAllowed: Bool {
return Config.get().getBool(section: "ui", key: "dark_mode_allowed", defaultValue: true)
}
static var changeMainColorAllowed: Bool {
return Config.get().getBool(section: "ui", key: "change_main_color_allowed", defaultValue: false)
}
static var hideSettings: Bool {
return Config.get().getBool(section: "ui", key: "hide_settings", defaultValue: false)
}
static var maxAccountsCount: Int {
return Config.get().getInt(section: "ui", key: "max_account", defaultValue: 0)
}
/*
static var configPath: String {
return context.view.window?.rootViewController?.view.frame.origin.x ?? "" + "/.linphonerc"
}
static var factoryConfigPath: String {
return context.view.window?.rootViewController?.view.frame.origin.x ?? "" + "/linphonerc"
}
func copyAssetsFromPackage() {
copy(from: "linphonerc_default", to: configPath)
copy(from: "linphonerc_factory", to: factoryConfigPath, overrideIfExists: true)
}
*/
static var vfsEnabled: Bool {
get {
return Config.get().getBool(section: "app", key: "vfs_enabled", defaultValue: false)
}
set {
Config.get().setBool(section: "app", key: "vfs_enabled", value: newValue)
}
}
private func copy(from: String, to: String, overrideIfExists: Bool = false) {
let fileManager = FileManager.default
if fileManager.fileExists(atPath: to), !overrideIfExists {
return
}
if let assetPath = Bundle.main.path(forResource: from, ofType: "") {
do {
try fileManager.copyItem(atPath: assetPath, toPath: to)
} catch {
print("Error copying file: \(error)")
}
}
}
}

View file

@ -5668,6 +5668,885 @@
}
}
},
"settings_calls_adaptive_rate_control_title" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Adaptive rate control"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Contrôle qualité adaptatif"
}
}
}
},
"settings_calls_auto_record_title" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Automatically start recording calls"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Démarrer l'enregistrement des appels automatiquement"
}
}
}
},
"settings_calls_calibrate_echo_canceller_done" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "%@ ms"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "%@ ms"
}
}
}
},
"settings_calls_calibrate_echo_canceller_done_no_echo" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "no echo"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "pas d'écho"
}
}
}
},
"settings_calls_calibrate_echo_canceller_failed" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "failed"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "échec"
}
}
}
},
"settings_calls_calibrate_echo_canceller_in_progress" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "in progress"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "en cours"
}
}
}
},
"settings_calls_calibrate_echo_canceller_title" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Calibrate echo canceller"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Calibrer l'annulateur d'écho"
}
}
}
},
"settings_calls_change_ringtone_title" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Change ringtone"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Changer de sonnerie"
}
}
}
},
"settings_calls_echo_canceller_subtitle" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Prevents echo from being heard by remote end if no hardware echo canceller is available"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Évite que de l'écho soit entendu par votre correspondant si un annulateur matériel n'est pas disponible"
}
}
}
},
"settings_calls_echo_canceller_title" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Use software echo canceller"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Utiliser l'annulateur d'écho logiciel"
}
}
}
},
"settings_calls_enable_fec_title" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Enable video FEC"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Activer la FEC vidéo"
}
}
}
},
"settings_calls_enable_video_title" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Enable video"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Activer la vidéo"
}
}
}
},
"settings_calls_title" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Calls"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Appels"
}
}
}
},
"settings_calls_vibrate_while_ringing_title" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Vibrate while incoming call is ringing"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Vibrer lors de la réception d'un appel"
}
}
}
},
"settings_contacts_add_carddav_server_title" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Add CardDAV address book"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ajouter un carnet d'adresse CardDAV"
}
}
}
},
"settings_contacts_add_ldap_server_title" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Add LDAP server"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ajouter un serveur LDAP"
}
}
}
},
"settings_contacts_carddav_deleted_toast" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "CardDAV account deleted"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Compte CardDAV supprimé"
}
}
}
},
"settings_contacts_carddav_mandatory_field_not_filled_toast" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Please fill in at least the display name and server URL"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Veuillez remplir au moins le nom d'affichage et l'URL du serveur"
}
}
}
},
"settings_contacts_carddav_name_title" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Display name"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nom d'affichage"
}
}
}
},
"settings_contacts_carddav_password_title" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Password"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Mot de passe"
}
}
}
},
"settings_contacts_carddav_realm_title" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Authentication realm"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Domaine d'authentification"
}
}
}
},
"settings_contacts_carddav_server_url_title" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Server URL"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "URL du serveur"
}
}
}
},
"settings_contacts_carddav_sync_error_toast" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Synchronization error!"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Erreur de synchronization !"
}
}
}
},
"settings_contacts_carddav_sync_successful_toast" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Synchronization successful"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Synchronization réussie"
}
}
}
},
"settings_contacts_carddav_use_as_default_title" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Store newly created contacts here"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Stocker ici les contacts nouvellement crées"
}
}
}
},
"settings_contacts_carddav_username_title" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Username"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nom d'utilisateur"
}
}
}
},
"settings_contacts_edit_carddav_server_title" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Edit CardDAV address book"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Editer le carnet d'adresse CardDAV"
}
}
}
},
"settings_contacts_edit_ldap_server_title" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Edit LDAP server"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Editer le serveur LDAP"
}
}
}
},
"settings_contacts_ldap_bind_dn_title" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Bind DN"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Bind DN"
}
}
}
},
"settings_contacts_ldap_bind_user_password_title" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Bind user password"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Mot de passe de l'utilisateur Bind"
}
}
}
},
"settings_contacts_ldap_max_results_title" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Maximum results"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nombre de résultats maximum"
}
}
}
},
"settings_contacts_ldap_password_title" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Password"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Mot de passe"
}
}
}
},
"settings_contacts_ldap_request_timeout_title" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Request timeout"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Délai d'attente de la requête"
}
}
}
},
"settings_contacts_ldap_search_base_title" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Search base (can't be empty)"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Base de recherche (ne peut être vide)"
}
}
}
},
"settings_contacts_ldap_search_filter_title" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Filter"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Filtre"
}
}
}
},
"settings_contacts_ldap_server_url_title" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Server URL (can't be empty)"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "URL du serveur (ne peut être vide)"
}
}
}
},
"settings_contacts_ldap_use_tls_title" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Use TLS"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Utiliser TLS"
}
}
}
},
"settings_contacts_title" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Contacts"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Contacts"
}
}
}
},
"settings_conversations_auto_download_title" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Auto-download files"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Télécharger automatiquement les fichiers"
}
}
}
},
"settings_conversations_mark_as_read_when_dismissing_notif_title" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Mark conversation as read when dismissing message notification"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Marquer la conversation comme lue lorsqu'une notification de message est supprimée"
}
}
}
},
"settings_conversations_title" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Conversations"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Conversations"
}
}
}
},
"settings_meetings_default_layout_title" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Default layout"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Disposition par défaut"
}
}
}
},
"settings_meetings_layout_active_speaker_label" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Active speaker"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Intervenant actif"
}
}
}
},
"settings_meetings_layout_mosaic_label" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Mosaic"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Mosaïque"
}
}
}
},
"settings_meetings_title" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Meetings"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Réunions"
}
}
}
},
"settings_network_allow_ipv6" : {
"comment" : "Autoriser l'IPv6",
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Allow IPv6"
}
}
}
},
"settings_network_title" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Network"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Réseau"
}
}
}
},
"settings_network_use_wifi_only" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Use only Wi-Fi networks"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Se connecter uniquement via le Wi-Fi"
}
}
}
},
"settings_security_enable_vfs_subtitle" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Warning: once enabled it can't be disabled!"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Attention, vous ne pourrez pas revenir en arrière !"
}
}
}
},
"settings_security_enable_vfs_title" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Encrypt everything"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Chiffrer tous les fichiers"
}
}
}
},
"settings_security_prevent_screenshots_title" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Prevent interface from being recorded"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Empêcher l'interface d'être enregistrée"
}
}
}
},
"settings_security_title" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Security"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Securité"
}
}
}
},
"settings_title" : {
"extractionState" : "manual",
"localizations" : {

View file

@ -72,6 +72,7 @@ struct ContentView: View {
@State var isShowSipAddressesPopupType = 0 // 0 to call, 1 to message, 2 to video call
@State var isShowConversationFragment = false
@State var isShowAccountProfileFragment = false
@State var isShowSettingsFragment = false
@State var fullscreenVideo = false
@ -949,7 +950,8 @@ struct ContentView: View {
menuClose: self.openMenu,
safeAreaInsets: geometry.safeAreaInsets,
isShowLoginFragment: $isShowLoginFragment,
isShowAccountProfileFragment: $isShowAccountProfileFragment
isShowAccountProfileFragment: $isShowAccountProfileFragment,
isShowSettingsFragment: $isShowSettingsFragment
)
.ignoresSafeArea(.all)
.zIndex(2)
@ -1188,6 +1190,15 @@ struct ContentView: View {
.transition(.move(edge: .trailing))
}
if isShowSettingsFragment {
SettingsFragment(
settingsViewModel: SettingsViewModel(),
isShowSettingsFragment: $isShowSettingsFragment
)
.zIndex(3)
.transition(.move(edge: .trailing))
}
if isShowSendCancelMeetingNotificationPopup {
PopupView(isShowPopup: $isShowSendCancelMeetingNotificationPopup,
title: Text("meeting_schedule_cancel_dialog_title"),

View file

@ -31,6 +31,7 @@ struct SideMenu: View {
let safeAreaInsets: EdgeInsets
@Binding var isShowLoginFragment: Bool
@Binding var isShowAccountProfileFragment: Bool
@Binding var isShowSettingsFragment: Bool
@State private var showHelp = false
var body: some View {
@ -124,14 +125,21 @@ struct SideMenu: View {
ForEach(0..<CoreContext.shared.shortcuts.count, id: \.self) { index in
SideMenuShortcut(shortcutModel: CoreContext.shared.shortcuts[index])
}
SideMenuEntry(
iconName: "gear",
title: "settings_title"
)
).onTapGesture {
withAnimation {
isShowSettingsFragment = true
}
}
SideMenuEntry(
iconName: "record-fill",
title: "recordings_title"
)
SideMenuEntry(
iconName: "question",
title: "help_title"
@ -179,7 +187,8 @@ struct SideMenu: View {
menuClose: {},
safeAreaInsets: geometry.safeAreaInsets,
isShowLoginFragment: $triggerNavigateToLogin,
isShowAccountProfileFragment: .constant(false)
isShowAccountProfileFragment: .constant(false),
isShowSettingsFragment: .constant(false)
)
.ignoresSafeArea(.all)
.zIndex(2)

View file

@ -0,0 +1,476 @@
/*
* 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 <http://www.gnu.org/licenses/>.
*/
import SwiftUI
import UniformTypeIdentifiers
struct SettingsFragment: View {
@ObservedObject var settingsViewModel: SettingsViewModel
@Binding var isShowSettingsFragment: Bool
@State private var isOn: Bool = false
@State var securityIsOpen: Bool = false
@State var callsIsOpen: Bool = false
@State var conversationsIsOpen: Bool = false
@State var contactsIsOpen: Bool = false
@State var meetingsIsOpen: Bool = false
@State var networkIsOpen: Bool = false
@State var userInterfaceIsOpen: Bool = false
var body: some View {
NavigationView {
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 {
settingsViewModel.saveChangesWhenLeaving()
withAnimation {
if isShowSettingsFragment {
isShowSettingsFragment = false
}
}
}
Text("settings_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) {
HStack(alignment: .center) {
Text("settings_security_title")
.default_text_style_800(styleSize: 18)
.frame(maxWidth: .infinity, alignment: .leading)
Spacer()
Image(securityIsOpen ? "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 {
securityIsOpen.toggle()
}
}
if securityIsOpen {
VStack(spacing: 0) {
VStack(spacing: 30) {
HStack {
VStack(alignment: .leading, spacing: 2) {
Text("settings_security_enable_vfs_title")
.default_text_style_700(styleSize: 15)
Text("settings_security_enable_vfs_subtitle")
.foregroundColor(Color.grayMain2c500)
.default_text_style(styleSize: 14)
}
.layoutPriority(1)
Toggle(isOn: $settingsViewModel.enableVfs) {
EmptyView()
}
.toggleStyle(SwitchToggleStyle())
.disabled(settingsViewModel.enableVfs)
}
/*
Toggle("settings_security_prevent_screenshots_title", isOn: $isOn)
.default_text_style_700(styleSize: 15)
*/
}
.padding(.vertical, 30)
.padding(.horizontal, 20)
}
.background(.white)
.cornerRadius(15)
.padding(.horizontal)
.zIndex(-1)
.transition(.move(edge: .top))
}
HStack(alignment: .center) {
Text("settings_calls_title")
.default_text_style_800(styleSize: 18)
.frame(maxWidth: .infinity, alignment: .leading)
Spacer()
Image(callsIsOpen ? "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 {
callsIsOpen.toggle()
}
}
if callsIsOpen {
VStack(spacing: 0) {
VStack(spacing: 30) {
Toggle("settings_calls_adaptive_rate_control_title", isOn: $settingsViewModel.adaptiveRateControl)
.default_text_style_700(styleSize: 15)
Toggle("settings_calls_enable_video_title", isOn: $settingsViewModel.enableVideo)
.default_text_style_700(styleSize: 15)
/*
Toggle("settings_calls_vibrate_while_ringing_title", isOn: $isOn)
.default_text_style_700(styleSize: 15)
*/
Toggle("settings_calls_auto_record_title", isOn: $settingsViewModel.autoRecord)
.default_text_style_700(styleSize: 15)
/*
Button {
} label: {
HStack {
Text("settings_calls_change_ringtone_title")
.default_text_style_700(styleSize: 15)
.frame(maxWidth: .infinity, alignment: .leading)
Image("arrow-square-out")
.renderingMode(.template)
.resizable()
.foregroundStyle(Color.grayMain2c600)
.frame(width: 25, height: 25, alignment: .leading)
.padding(.trailing, 10)
}
}
*/
}
.padding(.vertical, 30)
.padding(.horizontal, 20)
}
.background(.white)
.cornerRadius(15)
.padding(.horizontal)
.zIndex(-2)
.transition(.move(edge: .top))
}
HStack(alignment: .center) {
Text("settings_conversations_title")
.default_text_style_800(styleSize: 18)
.frame(maxWidth: .infinity, alignment: .leading)
Spacer()
Image(conversationsIsOpen ? "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 {
conversationsIsOpen.toggle()
}
}
if conversationsIsOpen {
VStack(spacing: 0) {
VStack(spacing: 30) {
Toggle("settings_conversations_auto_download_title", isOn: $settingsViewModel.autoDownload)
.default_text_style_700(styleSize: 15)
}
.padding(.vertical, 30)
.padding(.horizontal, 20)
}
.background(.white)
.cornerRadius(15)
.padding(.horizontal)
.zIndex(-3)
.transition(.move(edge: .top))
}
/*
// Hide Contacts
HStack(alignment: .center) {
Text("settings_contacts_title")
.default_text_style_800(styleSize: 18)
.frame(maxWidth: .infinity, alignment: .leading)
Spacer()
Image(contactsIsOpen ? "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 {
contactsIsOpen.toggle()
}
}
if contactsIsOpen {
VStack(spacing: 0) {
VStack(spacing: 30) {
Toggle("account_settings_avpf_title", isOn: $isOn)
.default_text_style_700(styleSize: 15)
Toggle("account_settings_avpf_title", isOn: $isOn)
.default_text_style_700(styleSize: 15)
}
.padding(.vertical, 30)
.padding(.horizontal, 20)
}
.background(.white)
.cornerRadius(15)
.padding(.horizontal)
.zIndex(-4)
.transition(.move(edge: .top))
}
*/
HStack(alignment: .center) {
Text("settings_meetings_title")
.default_text_style_800(styleSize: 18)
.frame(maxWidth: .infinity, alignment: .leading)
Spacer()
Image(meetingsIsOpen ? "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 {
meetingsIsOpen.toggle()
}
}
if meetingsIsOpen {
VStack(spacing: 0) {
VStack(spacing: 30) {
VStack(alignment: .leading) {
Text("settings_meetings_default_layout_title")
.default_text_style_700(styleSize: 15)
.padding(.bottom, -5)
Menu {
Button("settings_meetings_layout_active_speaker_label") { settingsViewModel.defaultLayout = String(localized: "settings_meetings_layout_active_speaker_label") }
Button("settings_meetings_layout_mosaic_label") { settingsViewModel.defaultLayout = String(localized: "settings_meetings_layout_mosaic_label") }
} label: {
Text(settingsViewModel.defaultLayout)
.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)
)
}
}
.padding(.vertical, 30)
.padding(.horizontal, 20)
}
.background(.white)
.cornerRadius(15)
.padding(.horizontal)
.zIndex(-5)
.transition(.move(edge: .top))
}
HStack(alignment: .center) {
Text("settings_network_title")
.default_text_style_800(styleSize: 18)
.frame(maxWidth: .infinity, alignment: .leading)
Spacer()
Image(networkIsOpen ? "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 {
networkIsOpen.toggle()
}
}
if networkIsOpen {
VStack(spacing: 0) {
VStack(spacing: 30) {
Toggle("settings_network_use_wifi_only", isOn: $settingsViewModel.useWifiOnly)
.default_text_style_700(styleSize: 15)
Toggle("settings_network_allow_ipv6", isOn: $settingsViewModel.allowIpv6)
.default_text_style_700(styleSize: 15)
}
.padding(.vertical, 30)
.padding(.horizontal, 20)
}
.background(.white)
.cornerRadius(15)
.padding(.horizontal)
.zIndex(-6)
.transition(.move(edge: .top))
}
/*
// Hide User interface (Dark mode)
HStack(alignment: .center) {
Text("manage_account_details_title")
.default_text_style_800(styleSize: 18)
.frame(maxWidth: .infinity, alignment: .leading)
Spacer()
Image(userInterfaceIsOpen ? "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 {
userInterfaceIsOpen.toggle()
}
}
if userInterfaceIsOpen {
VStack(spacing: 0) {
VStack(spacing: 30) {
Toggle("account_settings_avpf_title", isOn: $isOn)
.default_text_style_700(styleSize: 15)
Toggle("account_settings_avpf_title", isOn: $isOn)
.default_text_style_700(styleSize: 15)
}
.padding(.vertical, 30)
.padding(.horizontal, 20)
}
.background(.white)
.cornerRadius(15)
.padding(.horizontal)
.zIndex(-7)
.transition(.move(edge: .top))
}
*/
HStack(alignment: .center) {
Text("settings_advanced_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)
}
.padding(.vertical, 10)
.padding(.horizontal, 20)
.background(Color.gray100)
.onTapGesture {
withAnimation {
//networkIsOpen.toggle()
}
}
}
}
.background(Color.gray100)
}
.background(Color.gray100)
}
.navigationTitle("")
.navigationBarHidden(true)
}
.navigationViewStyle(StackNavigationViewStyle())
}
}

View file

@ -0,0 +1,134 @@
/*
* 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 <http://www.gnu.org/licenses/>.
*/
import linphonesw
class SettingsViewModel: ObservableObject {
static let TAG = "[SettingsViewModel]"
private var coreDelegate: CoreDelegate?
// Security settings
@Published var enableVfs: Bool = false
//@Published var preventScreenshots: Bool = false
// Calls settings
@Published var adaptiveRateControl: Bool = false
@Published var enableVideo: Bool = false
@Published var autoRecord: Bool = false
// Conversations settings
@Published var autoDownload: Bool = false
// Meetings settings
@Published var defaultLayout: String = ""
// Network settings
@Published var useWifiOnly: Bool = false
@Published var allowIpv6: Bool = false
init() {
CoreContext.shared.doOnCoreQueue { core in
let enableVfsTmp = CorePreferences.vfsEnabled
let adaptiveRateControlTmp = core.adaptiveRateControlEnabled
let enableVideoTmp = core.videoEnabled
let autoRecordTmp = CorePreferences.automaticallyStartCallRecording
let autoDownloadTmp = core.maxSizeForAutoDownloadIncomingFiles == 0
let defaultLayoutTmp = core.defaultConferenceLayout.rawValue == 0 ? String(localized: "settings_meetings_layout_mosaic_label") : String(localized: "settings_meetings_layout_active_speaker_label")
let useWifiOnlyTmp = core.wifiOnlyEnabled
let allowIpv6Tmp = core.ipv6Enabled
DispatchQueue.main.async {
self.enableVfs = enableVfsTmp
self.adaptiveRateControl = adaptiveRateControlTmp
self.enableVideo = enableVideoTmp
self.autoRecord = autoRecordTmp
self.autoDownload = autoDownloadTmp
self.defaultLayout = defaultLayoutTmp
self.useWifiOnly = useWifiOnlyTmp
self.allowIpv6 = allowIpv6Tmp
self.coreDelegate = CoreDelegateStub(
onAudioDevicesListUpdated: { (_: Core) in
Log.info(
"\(SettingsViewModel.TAG) Audio devices list has changed, update available input/output audio devices list"
)
// setupAudioDevices()
}
)
core.addDelegate(delegate: self.coreDelegate!)
}
}
}
deinit {
if let delegate = coreDelegate {
CoreContext.shared.doOnCoreQueue { core in
core.removeDelegate(delegate: delegate)
}
}
}
func saveChangesWhenLeaving() {
CoreContext.shared.doOnCoreQueue { core in
if CorePreferences.vfsEnabled != self.enableVfs {
CorePreferences.vfsEnabled = self.enableVfs
}
if core.adaptiveRateControlEnabled != self.adaptiveRateControl {
core.adaptiveRateControlEnabled = self.adaptiveRateControl
}
if core.videoEnabled != self.enableVideo {
core.videoCaptureEnabled = self.enableVideo
core.videoDisplayEnabled = self.enableVideo
}
if CorePreferences.automaticallyStartCallRecording != self.autoRecord {
CorePreferences.automaticallyStartCallRecording = self.autoRecord
}
if (core.maxSizeForAutoDownloadIncomingFiles == 0) != self.autoDownload {
core.maxSizeForAutoDownloadIncomingFiles = self.autoDownload ? 0 : -1
}
if (core.defaultConferenceLayout.rawValue == 0) != (self.defaultLayout == String(localized: "settings_meetings_layout_mosaic_label")) {
core.defaultConferenceLayout = self.defaultLayout == String(localized: "settings_meetings_layout_mosaic_label") ? .Grid : .ActiveSpeaker
}
if core.wifiOnlyEnabled != self.useWifiOnly {
core.wifiOnlyEnabled = self.useWifiOnly
}
if core.ipv6Enabled != self.allowIpv6 {
core.ipv6Enabled = self.allowIpv6
}
}
}
}