From ac0e70f719305fc2a53e956d369e75aed132636d Mon Sep 17 00:00:00 2001 From: Benoit Martins Date: Wed, 22 Jan 2025 09:49:38 +0100 Subject: [PATCH] Add help view --- Linphone.xcodeproj/project.pbxproj | 36 ++ .../app-store-logo.imageset/Contents.json | 21 + .../app-store-logo.svg | 1 + .../fire.imageset/Contents.json | 21 + .../Assets.xcassets/fire.imageset/fire.svg | 1 + .../package.imageset/Contents.json | 21 + .../package.imageset/package.svg | 1 + Linphone/Core/CoreContext.swift | 1 + Linphone/Localizable.xcstrings | 534 ++++++++++++++++++ Linphone/Ressources/linphonerc-default | 2 +- Linphone/UI/Main/ContentView.swift | 13 +- Linphone/UI/Main/Fragments/SideMenu.swift | 19 +- Linphone/UI/Main/Fragments/ToastView.swift | 14 + .../Main/Help/Fragments/DebugFragment.swift | 239 ++++++++ .../UI/Main/Help/Fragments/HelpFragment.swift | 275 +++++++++ .../Main/Help/ViewModel/HelpViewModel.swift | 185 ++++++ 16 files changed, 1370 insertions(+), 14 deletions(-) create mode 100644 Linphone/Assets.xcassets/app-store-logo.imageset/Contents.json create mode 100644 Linphone/Assets.xcassets/app-store-logo.imageset/app-store-logo.svg create mode 100644 Linphone/Assets.xcassets/fire.imageset/Contents.json create mode 100644 Linphone/Assets.xcassets/fire.imageset/fire.svg create mode 100644 Linphone/Assets.xcassets/package.imageset/Contents.json create mode 100644 Linphone/Assets.xcassets/package.imageset/package.svg create mode 100644 Linphone/UI/Main/Help/Fragments/DebugFragment.swift create mode 100644 Linphone/UI/Main/Help/Fragments/HelpFragment.swift create mode 100644 Linphone/UI/Main/Help/ViewModel/HelpViewModel.swift diff --git a/Linphone.xcodeproj/project.pbxproj b/Linphone.xcodeproj/project.pbxproj index fd81ddda0..39574aad9 100644 --- a/Linphone.xcodeproj/project.pbxproj +++ b/Linphone.xcodeproj/project.pbxproj @@ -106,6 +106,8 @@ D732A91B2B061BD900DB42BA /* HistoryListBottomSheet.swift in Sources */ = {isa = PBXBuildFile; fileRef = D732A91A2B061BD900DB42BA /* HistoryListBottomSheet.swift */; }; D732C38C2D311D2500F78100 /* SettingsFragment.swift in Sources */ = {isa = PBXBuildFile; fileRef = D732C38B2D311D2100F78100 /* SettingsFragment.swift */; }; D7343FE82D3FA2000059D784 /* CodecModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7343FE72D3FA1F40059D784 /* CodecModel.swift */; }; + D7343FED2D3FE1560059D784 /* HelpFragment.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7343FEC2D3FE1550059D784 /* HelpFragment.swift */; }; + D7343FEF2D3FE16C0059D784 /* HelpViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7343FEE2D3FE16B0059D784 /* HelpViewModel.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 */; }; @@ -129,6 +131,7 @@ D77A080E2CB6BCAF0095D589 /* MessageConferenceInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = D77A080D2CB6BCA10095D589 /* MessageConferenceInfo.swift */; }; D78290B82ADD3910004AA85C /* ContactsFragment.swift in Sources */ = {isa = PBXBuildFile; fileRef = D78290B72ADD3910004AA85C /* ContactsFragment.swift */; }; D78290BB2ADD40B2004AA85C /* ContactViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D78290BA2ADD40B2004AA85C /* ContactViewModel.swift */; }; + D783028F2D414847009CCB60 /* DebugFragment.swift in Sources */ = {isa = PBXBuildFile; fileRef = D783028E2D414845009CCB60 /* DebugFragment.swift */; }; D783C77C2B1089B200622CC2 /* assistant_linphone_default_values in Resources */ = {isa = PBXBuildFile; fileRef = D783C77A2B1089B200622CC2 /* assistant_linphone_default_values */; }; D783C77D2B1089B200622CC2 /* assistant_third_party_default_values in Resources */ = {isa = PBXBuildFile; fileRef = D783C77B2B1089B200622CC2 /* assistant_third_party_default_values */; }; D78607712D36CB8A009E6A7E /* SettingsAdvancedFragment.swift in Sources */ = {isa = PBXBuildFile; fileRef = D78607702D36CB87009E6A7E /* SettingsAdvancedFragment.swift */; }; @@ -310,6 +313,8 @@ D732A91A2B061BD900DB42BA /* HistoryListBottomSheet.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HistoryListBottomSheet.swift; sourceTree = ""; }; D732C38B2D311D2100F78100 /* SettingsFragment.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsFragment.swift; sourceTree = ""; }; D7343FE72D3FA1F40059D784 /* CodecModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CodecModel.swift; sourceTree = ""; }; + D7343FEC2D3FE1550059D784 /* HelpFragment.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HelpFragment.swift; sourceTree = ""; }; + D7343FEE2D3FE16B0059D784 /* HelpViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HelpViewModel.swift; sourceTree = ""; }; D73449982BC6932A00778C56 /* MeetingWaitingRoomFragment.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MeetingWaitingRoomFragment.swift; sourceTree = ""; }; D734499A2BC694C900778C56 /* MeetingWaitingRoomViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MeetingWaitingRoomViewModel.swift; sourceTree = ""; }; D748BF2B2ACD82D2004844EB /* ThirdPartySipAccountLoginFragment.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThirdPartySipAccountLoginFragment.swift; sourceTree = ""; }; @@ -332,6 +337,7 @@ D77A080D2CB6BCA10095D589 /* MessageConferenceInfo.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageConferenceInfo.swift; sourceTree = ""; }; D78290B72ADD3910004AA85C /* ContactsFragment.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContactsFragment.swift; sourceTree = ""; }; D78290BA2ADD40B2004AA85C /* ContactViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContactViewModel.swift; sourceTree = ""; }; + D783028E2D414845009CCB60 /* DebugFragment.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DebugFragment.swift; sourceTree = ""; }; D783C77A2B1089B200622CC2 /* assistant_linphone_default_values */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = assistant_linphone_default_values; sourceTree = ""; }; D783C77B2B1089B200622CC2 /* assistant_third_party_default_values */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = assistant_third_party_default_values; sourceTree = ""; }; D78607702D36CB87009E6A7E /* SettingsAdvancedFragment.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsAdvancedFragment.swift; sourceTree = ""; }; @@ -620,6 +626,7 @@ D7CEE0332B7A20A400FD79B7 /* Conversations */, D7A03FBB2ACC2D850081A588 /* Contacts */, D74C9CFD2ACAEC150021626A /* Fragments */, + D7343FE92D3FE0830059D784 /* Help */, D7A03FBE2ACC2E010081A588 /* History */, 66E56BC52BA45E49006CE56F /* Meetings */, 66D382032CEB7DB80063E1C5 /* Models */, @@ -703,6 +710,32 @@ path = Fragments; sourceTree = ""; }; + D7343FE92D3FE0830059D784 /* Help */ = { + isa = PBXGroup; + children = ( + D7343FEA2D3FE1080059D784 /* Fragments */, + D7343FEB2D3FE1150059D784 /* ViewModel */, + ); + path = Help; + sourceTree = ""; + }; + D7343FEA2D3FE1080059D784 /* Fragments */ = { + isa = PBXGroup; + children = ( + D783028E2D414845009CCB60 /* DebugFragment.swift */, + D7343FEC2D3FE1550059D784 /* HelpFragment.swift */, + ); + path = Fragments; + sourceTree = ""; + }; + D7343FEB2D3FE1150059D784 /* ViewModel */ = { + isa = PBXGroup; + children = ( + D7343FEE2D3FE16B0059D784 /* HelpViewModel.swift */, + ); + path = ViewModel; + sourceTree = ""; + }; D74C9CF62ACACEB70021626A /* Fragments */ = { isa = PBXGroup; children = ( @@ -1201,6 +1234,7 @@ 66C491FD2B24D36500CEA16D /* AudioRouteUtils.swift in Sources */, D70959F12B8DF3EC0014AC0B /* ConversationModel.swift in Sources */, C6DC4E3D2C199C4E009096FD /* BundleExtenion.swift in Sources */, + D7343FEF2D3FE16C0059D784 /* HelpViewModel.swift in Sources */, D7EAACCF2AD6ED8000AA6A8A /* PermissionsFragment.swift in Sources */, D759CB662C3FBE1D00AC35E8 /* StartConversationViewModel.swift in Sources */, D777DBB32AE12C5900565A99 /* ContactsManager.swift in Sources */, @@ -1234,6 +1268,7 @@ C62817302C1C3DCC00DBA646 /* AccountModel.swift in Sources */, D73449992BC6932A00778C56 /* MeetingWaitingRoomFragment.swift in Sources */, D7C48DF42AFA66F900D938CB /* EditContactController.swift in Sources */, + D7343FED2D3FE1560059D784 /* HelpFragment.swift in Sources */, C628172E2C1C3A3600DBA646 /* AccountExtension.swift in Sources */, 66C491FF2B24D4AC00CEA16D /* FileUtils.swift in Sources */, C62817322C1C400A00DBA646 /* StringExtension.swift in Sources */, @@ -1248,6 +1283,7 @@ D734499B2BC694C900778C56 /* MeetingWaitingRoomViewModel.swift in Sources */, D719ABB72ABC67BF00B41C10 /* LinphoneApp.swift in Sources */, 66E50A4B2BD12B7800AD61CA /* MeetingsFragment.swift in Sources */, + D783028F2D414847009CCB60 /* DebugFragment.swift in Sources */, 66162A202BDFC2F900DCE913 /* AddParticipantsViewModel.swift in Sources */, D732A91B2B061BD900DB42BA /* HistoryListBottomSheet.swift in Sources */, D72250632ADE9615008FB426 /* HistoryViewModel.swift in Sources */, diff --git a/Linphone/Assets.xcassets/app-store-logo.imageset/Contents.json b/Linphone/Assets.xcassets/app-store-logo.imageset/Contents.json new file mode 100644 index 000000000..2b6f5c597 --- /dev/null +++ b/Linphone/Assets.xcassets/app-store-logo.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "app-store-logo.svg", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Linphone/Assets.xcassets/app-store-logo.imageset/app-store-logo.svg b/Linphone/Assets.xcassets/app-store-logo.imageset/app-store-logo.svg new file mode 100644 index 000000000..5b7588a4e --- /dev/null +++ b/Linphone/Assets.xcassets/app-store-logo.imageset/app-store-logo.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/Linphone/Assets.xcassets/fire.imageset/Contents.json b/Linphone/Assets.xcassets/fire.imageset/Contents.json new file mode 100644 index 000000000..22c6560a7 --- /dev/null +++ b/Linphone/Assets.xcassets/fire.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "fire.svg", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Linphone/Assets.xcassets/fire.imageset/fire.svg b/Linphone/Assets.xcassets/fire.imageset/fire.svg new file mode 100644 index 000000000..8f744c3fc --- /dev/null +++ b/Linphone/Assets.xcassets/fire.imageset/fire.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/Linphone/Assets.xcassets/package.imageset/Contents.json b/Linphone/Assets.xcassets/package.imageset/Contents.json new file mode 100644 index 000000000..e7f4c7143 --- /dev/null +++ b/Linphone/Assets.xcassets/package.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "package.svg", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Linphone/Assets.xcassets/package.imageset/package.svg b/Linphone/Assets.xcassets/package.imageset/package.svg new file mode 100644 index 000000000..b682ceb2e --- /dev/null +++ b/Linphone/Assets.xcassets/package.imageset/package.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/Linphone/Core/CoreContext.swift b/Linphone/Core/CoreContext.swift index a98f92c82..1d8adeafa 100644 --- a/Linphone/Core/CoreContext.swift +++ b/Linphone/Core/CoreContext.swift @@ -153,6 +153,7 @@ final class CoreContext: ObservableObject { self.mCore.config!.setBool(section: "sip", key: "deliver_imdn", value: false) self.mCore.config!.setString(section: "misc", key: "log_collection_upload_server_url", value: "https://files.linphone.org:443/http-file-transfer-server/hft.php") self.mCore.config!.setString(section: "misc", key: "file_transfer_server_url", value: "https://files.linphone.org:443/http-file-transfer-server/hft.php") + self.mCore.config!.setString(section: "misc", key: "version_check_url_root", value: "https://download.linphone.org/releases") let shortcutsCount = self.mCore.config!.getInt(section: "ui", key: "shortcut_count", defaultValue: 0) if shortcutsCount > 0 { diff --git a/Linphone/Localizable.xcstrings b/Linphone/Localizable.xcstrings index 0703260be..f07797c31 100644 --- a/Linphone/Localizable.xcstrings +++ b/Linphone/Localizable.xcstrings @@ -2801,6 +2801,17 @@ } } }, + "conversation_end_to_end_encrypted_bottom_sheet_link" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "https://linphone.org/en/features/#security" + } + } + } + }, "conversation_ephemeral_messages_duration_disabled" : { "localizations" : { "en" : { @@ -3643,6 +3654,23 @@ } } }, + "dialog_install" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Install" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Installer" + } + } + } + }, "dialog_no" : { "localizations" : { "en" : { @@ -3895,6 +3923,227 @@ } } }, + "help_about_advanced_title" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Advanced" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Avancé" + } + } + } + }, + "help_about_check_for_update" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Check update" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Vérifier les mises à jour" + } + } + } + }, + "help_about_contribute_translations_title" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Contribute on Linphone translation" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Aider à traduire Linphone" + } + } + } + }, + "help_about_open_source_licenses_subtitle" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "© Belledonne Communications 2010-2024" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "© Belledonne Communications 2010-2024" + } + } + } + }, + "help_about_open_source_licenses_title" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "GNU General Public License v3.0" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "GNU General Public License v3.0" + } + } + } + }, + "help_about_privacy_policy_subtitle" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "What information Linphone collects and uses" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Quelles informations Linphone collecte et utilise" + } + } + } + }, + "help_about_privacy_policy_title" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Privacy policy" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Politique de confidentialité" + } + } + } + }, + "help_about_title" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "About Linphone" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "À propos de Linphone" + } + } + } + }, + "help_about_version_title" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Version" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Version" + } + } + } + }, + "help_dialog_update_available_message" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "A new version %@ is available. Do you want to update?" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Une nouvelle version %@ est disponible. Voulez-vous mettre à jour ?" + } + } + } + }, + "help_dialog_update_available_title" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Update available" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Mise à jour disponible" + } + } + } + }, + "help_error_checking_version_toast_message" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "An error occurred while checking for update" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Une erreur est survenue" + } + } + } + }, + "help_quit_title" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Quit app" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Quitter l'application" + } + } + } + }, "help_title" : { "extractionState" : "manual", "localizations" : { @@ -3912,7 +4161,25 @@ } } }, + "help_troubleshooting_app_version_title" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "App version" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Version de l'application" + } + } + } + }, "help_troubleshooting_clean_logs" : { + "extractionState" : "manual", "localizations" : { "en" : { "stringUnit" : { @@ -3928,7 +4195,25 @@ } } }, + "help_troubleshooting_clear_native_friends_in_database" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Clear imported contacts from native address book" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Supprimer les contacts natifs importés" + } + } + } + }, "help_troubleshooting_debug_logs_cleaned_toast_message" : { + "extractionState" : "manual", "localizations" : { "en" : { "stringUnit" : { @@ -3944,7 +4229,76 @@ } } }, + "help_troubleshooting_debug_logs_upload_error_toast_message" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Failed to upload debug logs" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Echec à l'envoi des journaux" + } + } + } + }, + "help_troubleshooting_firebase_project_title" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Firebase project ID" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "ID du projet Firebase" + } + } + } + }, + "help_troubleshooting_print_logs_in_logcat" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Print logs in logcat" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Imprimer les journaux dans logcat" + } + } + } + }, + "help_troubleshooting_sdk_version_title" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "SDK version" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Version du SDK" + } + } + } + }, "help_troubleshooting_share_logs" : { + "extractionState" : "manual", "localizations" : { "en" : { "stringUnit" : { @@ -3960,6 +4314,74 @@ } } }, + "help_troubleshooting_share_logs_dialog_title" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Share debug logs link using…" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Partager le lien vers journaux avec…" + } + } + } + }, + "help_troubleshooting_show_config_file" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Show configuration" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Afficher la configuration" + } + } + } + }, + "help_troubleshooting_title" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Troubleshooting" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Dépannage" + } + } + } + }, + "help_version_up_to_date_toast_message" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Your version is up-to-date" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Votre version est à jour" + } + } + } + }, "history_call_start_create_group_call" : { "localizations" : { "en" : { @@ -6978,6 +7400,7 @@ "shouldTranslate" : false }, "Temp Help" : { + "extractionState" : "stale", "localizations" : { "en" : { "stringUnit" : { @@ -6987,6 +7410,23 @@ } } }, + "text_copied_to_clipboard_toast" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Text copied into clipboard" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Texte copié dans le presse-papier" + } + } + } + }, "TLS" : { "shouldTranslate" : false }, @@ -7106,6 +7546,100 @@ } } }, + "web_platform_forgotten_password_url" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "https://subscribe.linphone.org/" + } + } + } + }, + "web_platform_register_email_url" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "https://subscribe.linphone.org/register/email" + } + } + } + }, + "website_contact_url" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "https://linphone.org/contact" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "https://linphone.org/contact" + } + } + } + }, + "website_download_url" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "https://linphone.org/linphone-softphone" + } + } + } + }, + "website_open_source_licences_usage_url" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "https://wiki.linphone.org/xwiki/wiki/public/view/Linphone/Third%20party%20components%20/" + } + } + } + }, + "website_privacy_policy_url" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "https://linphone.org/en/privacy-policy" + } + } + } + }, + "website_terms_and_conditions_url" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "https://www.linphone.org/en/terms-of-use" + } + } + } + }, + "website_translate_weblate_url" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "https://weblate.linphone.org/" + } + } + } + }, "welcome_carousel_skip" : { "localizations" : { "en" : { diff --git a/Linphone/Ressources/linphonerc-default b/Linphone/Ressources/linphonerc-default index 686a5f4ff..bf0cadf9a 100644 --- a/Linphone/Ressources/linphonerc-default +++ b/Linphone/Ressources/linphonerc-default @@ -36,7 +36,7 @@ port=443 [misc] log_collection_upload_server_url=https://files.linphone.org:443/http-file-transfer-server/hft.php file_transfer_server_url=https://files.linphone.org:443/http-file-transfer-server/hft.php -version_check_url_root=https://www.linphone.org/releases +version_check_url_root=https://download.linphone.org/releases max_calls=10 conference_layout=1 diff --git a/Linphone/UI/Main/ContentView.swift b/Linphone/UI/Main/ContentView.swift index b22ee302f..f954aa4ec 100644 --- a/Linphone/UI/Main/ContentView.swift +++ b/Linphone/UI/Main/ContentView.swift @@ -73,6 +73,7 @@ struct ContentView: View { @State var isShowConversationFragment = false @State var isShowAccountProfileFragment = false @State var isShowSettingsFragment = false + @State var isShowHelpFragment = false @State var fullscreenVideo = false @@ -951,7 +952,8 @@ struct ContentView: View { safeAreaInsets: geometry.safeAreaInsets, isShowLoginFragment: $isShowLoginFragment, isShowAccountProfileFragment: $isShowAccountProfileFragment, - isShowSettingsFragment: $isShowSettingsFragment + isShowSettingsFragment: $isShowSettingsFragment, + isShowHelpFragment: $isShowHelpFragment ) .ignoresSafeArea(.all) .zIndex(2) @@ -1199,6 +1201,15 @@ struct ContentView: View { .transition(.move(edge: .trailing)) } + if isShowHelpFragment { + HelpFragment( + helpViewModel: HelpViewModel(), + isShowHelpFragment: $isShowHelpFragment + ) + .zIndex(3) + .transition(.move(edge: .trailing)) + } + if isShowSendCancelMeetingNotificationPopup { PopupView(isShowPopup: $isShowSendCancelMeetingNotificationPopup, title: Text("meeting_schedule_cancel_dialog_title"), diff --git a/Linphone/UI/Main/Fragments/SideMenu.swift b/Linphone/UI/Main/Fragments/SideMenu.swift index c04e4ec7a..0f1b27cdf 100644 --- a/Linphone/UI/Main/Fragments/SideMenu.swift +++ b/Linphone/UI/Main/Fragments/SideMenu.swift @@ -32,6 +32,7 @@ struct SideMenu: View { @Binding var isShowLoginFragment: Bool @Binding var isShowAccountProfileFragment: Bool @Binding var isShowSettingsFragment: Bool + @Binding var isShowHelpFragment: Bool @State private var showHelp = false var body: some View { @@ -147,18 +148,11 @@ struct SideMenu: View { iconName: "question", title: "help_title" ).onTapGesture { - showHelp = true - } - .confirmationDialog("Temp Help", isPresented: $showHelp, titleVisibility: .visible) { - Button("help_troubleshooting_share_logs") { - HelpView.sendLogs() - } - Button("help_troubleshooting_clean_logs") { - HelpView.clearLogs() - } - Button("manage_account_delete") { - HelpView.logout() + self.menuClose() + withAnimation { + isShowHelpFragment = true } + } } .padding(.bottom, safeAreaInsets.bottom + 13) @@ -191,7 +185,8 @@ struct SideMenu: View { safeAreaInsets: geometry.safeAreaInsets, isShowLoginFragment: $triggerNavigateToLogin, isShowAccountProfileFragment: .constant(false), - isShowSettingsFragment: .constant(false) + isShowSettingsFragment: .constant(false), + isShowHelpFragment: .constant(false) ) .ignoresSafeArea(.all) .zIndex(2) diff --git a/Linphone/UI/Main/Fragments/ToastView.swift b/Linphone/UI/Main/Fragments/ToastView.swift index 4d8da1ea7..d61e77c97 100644 --- a/Linphone/UI/Main/Fragments/ToastView.swift +++ b/Linphone/UI/Main/Fragments/ToastView.swift @@ -59,6 +59,13 @@ struct ToastView: View { .default_text_style(styleSize: 15) .padding(8) + case "Success_version_up_to_date": + Text("help_version_up_to_date_toast_message") + .multilineTextAlignment(.center) + .foregroundStyle(Color.greenSuccess500) + .default_text_style(styleSize: 15) + .padding(8) + case "Success_remove_call_logs": Text("call_history_deleted_toast") .multilineTextAlignment(.center) @@ -94,6 +101,13 @@ struct ToastView: View { .default_text_style(styleSize: 15) .padding(8) + case "Success_text_copied_into_clipboard": + Text("text_copied_to_clipboard_toast") + .multilineTextAlignment(.center) + .foregroundStyle(Color.greenSuccess500) + .default_text_style(styleSize: 15) + .padding(8) + case "Info_call_securised": Text("call_can_be_trusted_toast") .multilineTextAlignment(.center) diff --git a/Linphone/UI/Main/Help/Fragments/DebugFragment.swift b/Linphone/UI/Main/Help/Fragments/DebugFragment.swift new file mode 100644 index 000000000..4acacf8bb --- /dev/null +++ b/Linphone/UI/Main/Help/Fragments/DebugFragment.swift @@ -0,0 +1,239 @@ +/* + * 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 DebugFragment: View { + @ObservedObject var helpViewModel: HelpViewModel + + @Environment(\.dismiss) var dismiss + + @State private var showShareSheet: 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("help_troubleshooting_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: 20) { + /* + Toggle("help_troubleshooting_print_logs_in_logcat", isOn: $helpViewModel.logcat) + .default_text_style_700(styleSize: 15) + */ + + HStack { + Spacer() + + Button( + action: { + helpViewModel.cleanLogs() + }, label: { + Text("help_troubleshooting_clean_logs") + .default_text_style_orange_500(styleSize: 14) + .lineLimit(1) + } + ) + .padding(.horizontal, 15) + .padding(.vertical, 10) + .background(Color.orangeMain100) + .cornerRadius(60) + + Spacer() + + Button( + action: { + helpViewModel.shareLogs() + }, label: { + Text("help_troubleshooting_share_logs") + .default_text_style_orange_500(styleSize: 14) + .lineLimit(1) + } + ) + .padding(.horizontal, 15) + .padding(.vertical, 10) + .background(Color.orangeMain100) + .cornerRadius(60) + + Spacer() + } + + Button { + UIPasteboard.general.setValue( + helpViewModel.version, + forPasteboardType: UTType.plainText.identifier + ) + ToastViewModel.shared.toastMessage = "Success_text_copied_into_clipboard" + ToastViewModel.shared.displayToast = true + } label: { + HStack { + Image("app-store-logo") + .renderingMode(.template) + .resizable() + .foregroundStyle(Color.orangeMain500) + .frame(width: 30, height: 30) + + VStack { + Text("help_troubleshooting_app_version_title") + .default_text_style_700(styleSize: 14) + .frame(maxWidth: .infinity, alignment: .leading) + .multilineTextAlignment(.leading) + + Text(helpViewModel.version) + .default_text_style(styleSize: 14) + .frame(maxWidth: .infinity, alignment: .leading) + .multilineTextAlignment(.leading) + } + .padding(.horizontal, 5) + + Image("copy") + .renderingMode(.template) + .resizable() + .foregroundStyle(Color.grayMain2c600) + .frame(width: 25, height: 25) + } + } + Button { + UIPasteboard.general.setValue( + helpViewModel.sdkVersion, + forPasteboardType: UTType.plainText.identifier + ) + ToastViewModel.shared.toastMessage = "Success_text_copied_into_clipboard" + ToastViewModel.shared.displayToast = true + } label: { + HStack { + Image("package") + .renderingMode(.template) + .resizable() + .foregroundStyle(Color.orangeMain500) + .frame(width: 30, height: 30) + + VStack { + Text("help_troubleshooting_sdk_version_title") + .default_text_style_700(styleSize: 14) + .frame(maxWidth: .infinity, alignment: .leading) + .multilineTextAlignment(.leading) + + Text(helpViewModel.sdkVersion) + .default_text_style(styleSize: 14) + .frame(maxWidth: .infinity, alignment: .leading) + .multilineTextAlignment(.leading) + } + .padding(.horizontal, 5) + + Image("copy") + .renderingMode(.template) + .resizable() + .foregroundStyle(Color.grayMain2c600) + .frame(width: 25, height: 25) + } + } + Button { + } label: { + HStack { + Image("fire") + .renderingMode(.template) + .resizable() + .foregroundStyle(Color.orangeMain500) + .frame(width: 30, height: 30) + + VStack { + Text("help_troubleshooting_firebase_project_title") + .default_text_style_700(styleSize: 14) + .frame(maxWidth: .infinity, alignment: .leading) + .multilineTextAlignment(.leading) + + Text(helpViewModel.firebaseProjectId) + .default_text_style(styleSize: 14) + .frame(maxWidth: .infinity, alignment: .leading) + .multilineTextAlignment(.leading) + } + .padding(.horizontal, 5) + } + } + } + .padding(.vertical, 20) + .padding(.horizontal, 20) + .background(Color.gray100) + } + } + .background(Color.gray100) + } + .background(Color.gray100) + + if helpViewModel.logsUploadInProgress { + PopupLoadingView() + .background(.black.opacity(0.65)) + } + } + .navigationTitle("") + .navigationBarHidden(true) + .onChange(of: helpViewModel.logText) { _ in + showShareSheet = true + } + .sheet(isPresented: $showShareSheet) { + ShareAnySheet(items: [helpViewModel.logText]) + .edgesIgnoringSafeArea(.bottom) + } + } +} + +struct ShareAnySheet: UIViewControllerRepresentable { + var items: [Any] // The content to share + + func makeUIViewController(context: Context) -> UIActivityViewController { + UIActivityViewController(activityItems: items, applicationActivities: nil) + } + + func updateUIViewController(_ uiViewController: UIActivityViewController, context: Context) { + // No updates needed + } +} diff --git a/Linphone/UI/Main/Help/Fragments/HelpFragment.swift b/Linphone/UI/Main/Help/Fragments/HelpFragment.swift new file mode 100644 index 000000000..5d0cfea1a --- /dev/null +++ b/Linphone/UI/Main/Help/Fragments/HelpFragment.swift @@ -0,0 +1,275 @@ +/* + * 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 + +struct HelpFragment: View { + + @ObservedObject private var sharedMainViewModel = SharedMainViewModel.shared + + @ObservedObject var helpViewModel: HelpViewModel + + @Binding var isShowHelpFragment: Bool + + @State var advancedSettingsIsOpen: Bool = false + + @FocusState var isVoicemailUriFocused: Bool + + 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 { + withAnimation { + isShowHelpFragment = false + } + } + + Text("help_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: 20) { + Text("help_about_title") + .default_text_style_800(styleSize: 16) + .frame(maxWidth: .infinity, alignment: .leading) + .padding(.bottom, 5) + + Button { + if let url = URL(string: NSLocalizedString("website_privacy_policy_url", comment: "")) { + UIApplication.shared.open(url) + } + } label: { + HStack { + Image("detective") + .renderingMode(.template) + .resizable() + .foregroundStyle(Color.orangeMain500) + .frame(width: 30, height: 30) + + VStack { + Text("help_about_privacy_policy_title") + .default_text_style_700(styleSize: 14) + .frame(maxWidth: .infinity, alignment: .leading) + .multilineTextAlignment(.leading) + + Text("help_about_privacy_policy_subtitle") + .default_text_style(styleSize: 14) + .frame(maxWidth: .infinity, alignment: .leading) + .multilineTextAlignment(.leading) + } + .padding(.horizontal, 5) + + Image("arrow-square-out") + .renderingMode(.template) + .resizable() + .foregroundStyle(Color.grayMain2c600) + .frame(width: 25, height: 25) + } + } + + HStack { + Image("info") + .renderingMode(.template) + .resizable() + .foregroundStyle(Color.orangeMain500) + .frame(width: 30, height: 30) + + VStack { + Text("help_about_version_title") + .default_text_style_700(styleSize: 14) + .frame(maxWidth: .infinity, alignment: .leading) + .multilineTextAlignment(.leading) + + Text(helpViewModel.version) + .default_text_style(styleSize: 14) + .frame(maxWidth: .infinity, alignment: .leading) + .multilineTextAlignment(.leading) + } + .padding(.horizontal, 5) + + Button( + action: { + helpViewModel.checkForUpdate() + }, label: { + Text("help_about_check_for_update") + .default_text_style_orange_500(styleSize: 14) + .lineLimit(1) + } + ) + .padding(.horizontal, 15) + .padding(.vertical, 10) + .background(Color.orangeMain100) + .cornerRadius(60) + } + + Button { + if let url = URL(string: NSLocalizedString("website_open_source_licences_usage_url", comment: "")) { + UIApplication.shared.open(url) + } + } label: { + HStack { + Image("check-square-offset") + .renderingMode(.template) + .resizable() + .foregroundStyle(Color.orangeMain500) + .frame(width: 30, height: 30) + + VStack { + Text("help_about_open_source_licenses_title") + .default_text_style_700(styleSize: 14) + .frame(maxWidth: .infinity, alignment: .leading) + .multilineTextAlignment(.leading) + + Text("help_about_open_source_licenses_subtitle") + .default_text_style(styleSize: 14) + .frame(maxWidth: .infinity, alignment: .leading) + .multilineTextAlignment(.leading) + } + .padding(.horizontal, 5) + + Image("arrow-square-out") + .renderingMode(.template) + .resizable() + .foregroundStyle(Color.grayMain2c600) + .frame(width: 25, height: 25) + } + } + + Button { + if let url = URL(string: NSLocalizedString("website_translate_weblate_url", comment: "")) { + UIApplication.shared.open(url) + } + } label: { + HStack { + Image("earth") + .renderingMode(.template) + .resizable() + .foregroundStyle(Color.orangeMain500) + .frame(width: 30, height: 30) + + Text("help_about_contribute_translations_title") + .default_text_style_700(styleSize: 14) + .frame(maxWidth: .infinity, alignment: .leading) + .multilineTextAlignment(.leading) + .padding(.horizontal, 5) + + Image("arrow-square-out") + .renderingMode(.template) + .resizable() + .foregroundStyle(Color.grayMain2c600) + .frame(width: 25, height: 25) + } + } + + Text("help_about_advanced_title") + .default_text_style_800(styleSize: 16) + .frame(maxWidth: .infinity, alignment: .leading) + .padding(.top, 20) + .padding(.bottom, 5) + + NavigationLink(destination: { + DebugFragment(helpViewModel: helpViewModel) + }, label: { + HStack { + Image("wrench") + .renderingMode(.template) + .resizable() + .foregroundStyle(Color.orangeMain500) + .frame(width: 30, height: 30) + + Text("help_troubleshooting_title") + .default_text_style_700(styleSize: 14) + .frame(maxWidth: .infinity, alignment: .leading) + .multilineTextAlignment(.leading) + .padding(.horizontal, 5) + + Image("caret-right") + .renderingMode(.template) + .resizable() + .foregroundStyle(Color.grayMain2c600) + .frame(width: 25, height: 25) + } + }) + } + .frame(maxWidth: sharedMainViewModel.maxWidth) + .padding(.all, 20) + } + .frame(maxWidth: .infinity) + } + .background(Color.gray100) + } + .background(Color.gray100) + + if helpViewModel.checkUpdateAvailable { + PopupView( + isShowPopup: $helpViewModel.checkUpdateAvailable, + title: Text("help_dialog_update_available_title"), + content: Text(String(format: String(localized: "help_dialog_update_available_message"), helpViewModel.versionAvailable)), + titleFirstButton: Text("dialog_cancel"), + actionFirstButton: { + helpViewModel.checkUpdateAvailable = false + }, + titleSecondButton: Text("dialog_install"), + actionSecondButton: { + helpViewModel.checkUpdateAvailable = false + if let url = URL(string: helpViewModel.urlVersionAvailable) { + UIApplication.shared.open(url) + } + } + ) + .background(.black.opacity(0.65)) + .zIndex(3) + .onTapGesture { + helpViewModel.checkUpdateAvailable = false + } + } + } + .navigationTitle("") + .navigationBarHidden(true) + } + .navigationViewStyle(StackNavigationViewStyle()) + } +} diff --git a/Linphone/UI/Main/Help/ViewModel/HelpViewModel.swift b/Linphone/UI/Main/Help/ViewModel/HelpViewModel.swift new file mode 100644 index 000000000..282314d62 --- /dev/null +++ b/Linphone/UI/Main/Help/ViewModel/HelpViewModel.swift @@ -0,0 +1,185 @@ +/* + * 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 linphonesw + +class HelpViewModel: ObservableObject { + private let TAG = "[HelpViewModel]" + + @Published var logcat: Bool = false + @Published var logText: String = "" + @Published var version: String = "" + @Published var appVersion: String = "" + @Published var sdkVersion: String = "" + @Published var firebaseProjectId: String = "" + @Published var checkUpdateAvailable: Bool = false + @Published var uploadLogsAvailable: Bool = false + @Published var logsUploadInProgress: Bool = false + @Published var versionAvailable: String = "" + @Published var urlVersionAvailable: String = "" + + private var coreDelegate: CoreDelegate? + + init() { + let appName = Bundle.main.infoDictionary?["CFBundleName"] as? String + let versionTmp = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String + let build = Bundle.main.infoDictionary?["CFBundleVersion"] as? String + + self.version = (versionTmp ?? "6.0.0") + "-beta-" + (build ?? "0") + + self.sdkVersion = Core.getVersion + + if let path = Bundle.main.path(forResource: "GoogleService-Info", ofType: "plist"), + let plist = NSDictionary(contentsOfFile: path) as? [String: Any], + let projectID = plist["PROJECT_ID"] as? String { + firebaseProjectId = projectID + } + + CoreContext.shared.doOnCoreQueue { core in + self.coreDelegate = CoreDelegateStub( + onLogCollectionUploadStateChanged: {( + core: Core, + state: Core.LogCollectionUploadState, + info: String + ) in + if info.starts(with: "https") { + DispatchQueue.main.async { + self.logsUploadInProgress = false + self.logText = info + } + } + }, + onVersionUpdateCheckResultReceived: {( + core: Core, + result: VersionUpdateCheckResult, + version: String?, + url: String? + ) in + switch result { + case .NewVersionAvailable: + if let version = version, let url = url { + Log.info("\(self.TAG): Update available, version [\(version)], url [\(url)]") + DispatchQueue.main.async { + self.versionAvailable = version + self.urlVersionAvailable = url + self.checkUpdateAvailable = true + } + } + case .UpToDate: + Log.info("\(self.TAG): This version is up-to-date") + DispatchQueue.main.async { + ToastViewModel.shared.toastMessage = "Success_version_up_to_date" + ToastViewModel.shared.displayToast = true + } + default: + Log.info("\(self.TAG): Can't check for update, an error happened [\(result)]") + DispatchQueue.main.async { + ToastViewModel.shared.toastMessage = "Error" + ToastViewModel.shared.displayToast = true + } + } + } + ) + core.addDelegate(delegate: self.coreDelegate!) + } + } + + deinit { + if let delegate = coreDelegate { + CoreContext.shared.doOnCoreQueue { core in + core.removeDelegate(delegate: delegate) + } + } + } + + /* + func toggleLogcat() { + let newValue = !self.logcat + CoreContext.shared.doOnCoreQueue { core in + CorePreferences.printLogsInLogcat = newValue + Factory.Instance.enableLogcatLogs(newValue) + self.logcat = newValue + } + } + */ + + func shareLogs() { + CoreContext.shared.doOnCoreQueue { core in + Log.info("\(self.TAG) Uploading debug logs for sharing") + core.uploadLogCollection() + DispatchQueue.main.async { + self.logsUploadInProgress = true + } + } + } + + func cleanLogs() { + CoreContext.shared.doOnCoreQueue { _ in + Core.resetLogCollection() + Log.info("\(self.TAG) Debug logs have been cleaned") + DispatchQueue.main.async { + ToastViewModel.shared.toastMessage = "Success_clear_logs" + ToastViewModel.shared.displayToast = true + } + } + } + + func checkForUpdate() { + let currentVersion = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String + CoreContext.shared.doOnCoreQueue { core in + Log.info("\(self.TAG) Checking for update using current version \(currentVersion ?? "6.0.0")") + core.checkForUpdate(currentVersion: currentVersion ?? "6.0.0") + } + } + + /* + func showConfigFile() { + CoreContext.shared.doOnCoreQueue { core in + Log.i("\(self.TAG) Dumping & displaying Core's config") + let config = core.config.dump() + let file = FileUtils.getFileStorageCacheDir( + "linphonerc.txt", + overrideExisting: true + ) + DispatchQueue.main.async { + if FileUtils.dumpStringToFile(config, file: file) { + Log.i("\(self.TAG) .linphonerc string saved as file in cache folder") + self.showConfigFileEvent = Event(value: file.absolutePath) + } else { + Log.e("\(self.TAG) Failed to save .linphonerc string as file in cache folder") + } + } + } + } + + 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") + } + } + } + */ +}