diff --git a/Ring/Ring.xcodeproj/project.pbxproj b/Ring/Ring.xcodeproj/project.pbxproj index 02ed5f93ac51f01e121e93e3ff461024c2b3596b..9e90a6728b9aa68c492a492cc6e823ccdadb99a0 100644 --- a/Ring/Ring.xcodeproj/project.pbxproj +++ b/Ring/Ring.xcodeproj/project.pbxproj @@ -122,8 +122,6 @@ 0EF49AA123828CBC0064CD98 /* ConferenceParticipantViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EF49AA023828CBC0064CD98 /* ConferenceParticipantViewModel.swift */; }; 0EF49AA323828CD00064CD98 /* ConferenceParticipantView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 0EF49AA223828CD00064CD98 /* ConferenceParticipantView.xib */; }; 0EF78DE31FD0AE3000FC6966 /* ConversationsManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EF78DE21FD0AE3000FC6966 /* ConversationsManager.swift */; }; - 1A0C4EDA1F1D4B1B00550433 /* WelcomeViewController.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 1A0C4ED91F1D4B1B00550433 /* WelcomeViewController.storyboard */; }; - 1A0C4EDC1F1D4B7E00550433 /* WelcomeViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A0C4EDB1F1D4B7E00550433 /* WelcomeViewController.swift */; }; 1A0C4EE31F1D673600550433 /* InjectionBag.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A0C4EE21F1D673600550433 /* InjectionBag.swift */; }; 1A0C4EE51F1D67DF00550433 /* WalkthroughCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A0C4EE41F1D67DF00550433 /* WalkthroughCoordinator.swift */; }; 1A20417A1F1E547F00C08435 /* Stateable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A2041791F1E547F00C08435 /* Stateable.swift */; }; @@ -471,6 +469,7 @@ BB06BD8129D491F80064F0FC /* CustomAnnotationModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB06BD8029D491F80064F0FC /* CustomAnnotationModel.swift */; }; BB06BD8329D492AA0064F0FC /* LocationSharingVM.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB06BD8229D492AA0064F0FC /* LocationSharingVM.swift */; }; BB06BD8529D4C1210064F0FC /* DurationPicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB06BD8429D4C1210064F0FC /* DurationPicker.swift */; }; + BB0AB9932A8FC4340033061F /* Colors.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = BB0AB9922A8FC4340033061F /* Colors.xcassets */; }; BB1E8C7329159DFC005AE1D6 /* MembersList.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB1E8C6E29159DF6005AE1D6 /* MembersList.swift */; }; BB1E8C7529159DFC005AE1D6 /* SettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB1E8C7029159DFC005AE1D6 /* SettingsView.swift */; }; BB1E8C7729159E1F005AE1D6 /* SwarmInfoViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB1E8C7629159E1F005AE1D6 /* SwarmInfoViewController.swift */; }; @@ -479,6 +478,9 @@ BB3B0A412971AEE30083CAD8 /* LocationSharingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB3B0A402971AEE30083CAD8 /* LocationSharingView.swift */; }; BB3E5815291C138600E85BEA /* SwarmInfoViewController.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = BB3E5814291C138600E85BEA /* SwarmInfoViewController.storyboard */; }; BB4C6E2629229131001C901A /* ColorExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB4C6E2529229131001C901A /* ColorExtension.swift */; }; + BB6690042A99043200875848 /* AppInfoHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB6690032A99043200875848 /* AppInfoHelper.swift */; }; + BB6690072A99069900875848 /* WelcomeViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB6690052A99069200875848 /* WelcomeViewController.swift */; }; + BB6690082A99069900875848 /* WelcomeViewController.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = BB6690062A99069400875848 /* WelcomeViewController.storyboard */; }; BB8BBCA329F04DA1007228BA /* LocationSharingServiceTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB8BBCA229F04DA1007228BA /* LocationSharingServiceTests.swift */; }; BB90263528F0918700B85859 /* PaddingTextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB90263428F0918700B85859 /* PaddingTextField.swift */; }; BB91FAAD292EA36200BB41C1 /* EventData.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB91FAA9292EA26900BB41C1 /* EventData.swift */; }; @@ -721,8 +723,6 @@ 0EF49AA023828CBC0064CD98 /* ConferenceParticipantViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConferenceParticipantViewModel.swift; sourceTree = "<group>"; }; 0EF49AA223828CD00064CD98 /* ConferenceParticipantView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = ConferenceParticipantView.xib; sourceTree = "<group>"; }; 0EF78DE21FD0AE3000FC6966 /* ConversationsManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConversationsManager.swift; sourceTree = "<group>"; }; - 1A0C4ED91F1D4B1B00550433 /* WelcomeViewController.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; name = WelcomeViewController.storyboard; path = Welcome/WelcomeViewController.storyboard; sourceTree = "<group>"; }; - 1A0C4EDB1F1D4B7E00550433 /* WelcomeViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = WelcomeViewController.swift; path = Welcome/WelcomeViewController.swift; sourceTree = "<group>"; }; 1A0C4EE21F1D673600550433 /* InjectionBag.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = InjectionBag.swift; sourceTree = "<group>"; }; 1A0C4EE41F1D67DF00550433 /* WalkthroughCoordinator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WalkthroughCoordinator.swift; sourceTree = "<group>"; }; 1A1E476C1F0E808500EA9A36 /* Reusable.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Reusable.framework; path = Carthage/Build/iOS/Reusable.framework; sourceTree = "<group>"; }; @@ -1101,6 +1101,7 @@ BB06BD8029D491F80064F0FC /* CustomAnnotationModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomAnnotationModel.swift; sourceTree = "<group>"; }; BB06BD8229D492AA0064F0FC /* LocationSharingVM.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocationSharingVM.swift; sourceTree = "<group>"; }; BB06BD8429D4C1210064F0FC /* DurationPicker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DurationPicker.swift; sourceTree = "<group>"; }; + BB0AB9922A8FC4340033061F /* Colors.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Colors.xcassets; sourceTree = "<group>"; }; BB1E8C6E29159DF6005AE1D6 /* MembersList.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MembersList.swift; sourceTree = "<group>"; }; BB1E8C7029159DFC005AE1D6 /* SettingsView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SettingsView.swift; sourceTree = "<group>"; }; BB1E8C7629159E1F005AE1D6 /* SwarmInfoViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SwarmInfoViewController.swift; sourceTree = "<group>"; }; @@ -1109,6 +1110,9 @@ BB3B0A402971AEE30083CAD8 /* LocationSharingView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocationSharingView.swift; sourceTree = "<group>"; }; BB3E5814291C138600E85BEA /* SwarmInfoViewController.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = SwarmInfoViewController.storyboard; sourceTree = "<group>"; }; BB4C6E2529229131001C901A /* ColorExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ColorExtension.swift; sourceTree = "<group>"; }; + BB6690032A99043200875848 /* AppInfoHelper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppInfoHelper.swift; sourceTree = "<group>"; }; + BB6690052A99069200875848 /* WelcomeViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WelcomeViewController.swift; sourceTree = "<group>"; }; + BB6690062A99069400875848 /* WelcomeViewController.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = WelcomeViewController.storyboard; sourceTree = "<group>"; }; BB8BBCA229F04DA1007228BA /* LocationSharingServiceTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocationSharingServiceTests.swift; sourceTree = "<group>"; }; BB90263428F0918700B85859 /* PaddingTextField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PaddingTextField.swift; sourceTree = "<group>"; }; BB91FAA9292EA26900BB41C1 /* EventData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EventData.swift; sourceTree = "<group>"; }; @@ -1742,6 +1746,7 @@ isa = PBXGroup; children = ( 627F11F020348FBF006560B5 /* AvatarView.swift */, + BB6690032A99043200875848 /* AppInfoHelper.swift */, 0EE1B54F1F75AD4700BA98EE /* VCardUtils.swift */, 0E44B62E202B9DE40060F71B /* LocalNotificationsHelper.swift */, 0E99F19F22417A0400CF8BD6 /* JamiURI.swift */, @@ -1909,8 +1914,8 @@ 1A0C4ED51F1D49D800550433 /* Welcome */ = { isa = PBXGroup; children = ( - 1A0C4ED91F1D4B1B00550433 /* WelcomeViewController.storyboard */, - 1A0C4EDB1F1D4B7E00550433 /* WelcomeViewController.swift */, + BB6690062A99069400875848 /* WelcomeViewController.storyboard */, + BB6690052A99069200875848 /* WelcomeViewController.swift */, 1A20417B1F1E56FF00C08435 /* WelcomeViewModel.swift */, ); name = Welcome; @@ -2114,6 +2119,7 @@ 0EABD3842303600B00DE7ACF /* default.wav */, 1ABE07DA1F0D915100D36361 /* Localizable.strings */, 04399A021D1C2D9D00E99CD9 /* Images.xcassets */, + BB0AB9922A8FC4340033061F /* Colors.xcassets */, ); path = Resources; sourceTree = "<group>"; @@ -2629,11 +2635,11 @@ 26D08AB12693474300E37574 /* InvitationViewController.storyboard in Resources */, 6613A612214AFF4700B497D1 /* ScanViewController.storyboard in Resources */, 1A20417E1F1E8DDA00C08435 /* CreateProfileViewController.storyboard in Resources */, + BB6690082A99069900875848 /* WelcomeViewController.storyboard in Resources */, 1ABE07DF1F0D91A800D36361 /* LaunchScreen.storyboard in Resources */, 2662FC81246B793500FA7782 /* IncognitoSmartListViewController.storyboard in Resources */, 1A5DC0381F35675E0075E8EF /* ContactRequestCell.xib in Resources */, 0ECA56812433948E0055D31E /* MigrateAccountViewController.storyboard in Resources */, - 1A0C4EDA1F1D4B1B00550433 /* WelcomeViewController.storyboard in Resources */, 5CE66F751FBF769B00EE9291 /* InitialLoadingViewController.storyboard in Resources */, 1A5DC03E1F35678D0075E8EF /* ContactRequestsViewController.storyboard in Resources */, 446FAF192373424700519C4F /* SendFileViewController.storyboard in Resources */, @@ -2642,6 +2648,7 @@ 0E72374A20460320006B0C7D /* ProfileHeaderView.xib in Resources */, 4430A66D236CBC5900747177 /* ContactPickerViewController.storyboard in Resources */, 0E96ED75225D06250016C07D /* GeneralSettingsViewController.storyboard in Resources */, + BB0AB9932A8FC4340033061F /* Colors.xcassets in Resources */, 0EB1A5CF1F8EBE03009923E2 /* DeviceCell.xib in Resources */, 1A2D18B31F2915C500B2C785 /* ConversationViewController.storyboard in Resources */, 0E7CF4DF2017918300CD967D /* ButtonsContainerView.xib in Resources */, @@ -2764,7 +2771,6 @@ 1A2D18A11F27A6D600B2C785 /* LinkDeviceViewController.swift in Sources */, 0E5806F523BE4307007D1F5D /* PlayerViewModel.swift in Sources */, 1DF75AC2296E09240055EA87 /* Button+Helpers.swift in Sources */, - 1A0C4EDC1F1D4B7E00550433 /* WelcomeViewController.swift in Sources */, 26AF9F3F29771C8E00C7069A /* GeneralSettingsCoordinator.swift in Sources */, 02B22E091DF7585F000358C9 /* DaemonService.swift in Sources */, 5CE66F761FBF769B00EE9291 /* InitialLoadingViewController.swift in Sources */, @@ -2880,6 +2886,7 @@ BBB76E412966062C00A42DF5 /* MapView.swift in Sources */, 62A88D391F6C323500F8AB18 /* PresenceAdapter.mm in Sources */, 1DF75AC6296E0C2A0055EA87 /* AddMoreParticipantsInSwarm.swift in Sources */, + BB6690072A99069900875848 /* WelcomeViewController.swift in Sources */, 1A2D18B71F29164700B2C785 /* SmartlistViewModel.swift in Sources */, 62AA15C31FFC39C80064A063 /* VideoAdapterDelegate.swift in Sources */, 04399AAE1D1C304300E99CD9 /* Utils.mm in Sources */, @@ -2957,6 +2964,7 @@ 0EE1B5501F75AD4700BA98EE /* VCardUtils.swift in Sources */, 2682CC6D25110E36003E65E1 /* ContactPickerDelegate.swift in Sources */, 0E320D52224ADF930070B515 /* DialpadViewController.swift in Sources */, + BB6690042A99043200875848 /* AppInfoHelper.swift in Sources */, 0E49096E1FEAC0DE005CAA50 /* CallsService.swift in Sources */, 0273C2FF1E0C438F00CF00BA /* AccountAdapterDelegate.swift in Sources */, 1A2D18A41F27EF5200B2C785 /* AppCoordinator.swift in Sources */, diff --git a/Ring/Ring/Constants/Generated/Images.swift b/Ring/Ring/Constants/Generated/Images.swift index 2112ab84d5633ff070123fd969fd6c17148df926..4c523ea637922e63c966c060b5af4ad2a4df6754 100644 --- a/Ring/Ring/Constants/Generated/Images.swift +++ b/Ring/Ring/Constants/Generated/Images.swift @@ -35,6 +35,7 @@ internal enum Asset { internal static let audioRunning = ImageAsset(name: "audio_running") internal static let backButton = ImageAsset(name: "back_button") internal static let backgroundInputText = ColorAsset(name: "background_input_text") + internal static let backgroundLogin = ImageAsset(name: "background_login") internal static let backgroundMsgReceived = ColorAsset(name: "background_msg_received") internal static let blockIcon = ImageAsset(name: "block_icon") internal static let callButton = ImageAsset(name: "call_button") diff --git a/Ring/Ring/Constants/Generated/Strings.swift b/Ring/Ring/Constants/Generated/Strings.swift index 288e1db862116080d7b3336cce5d82840eb5691d..3246f7ad412558f21ab4a2387b5d15cafd84d1e7 100644 --- a/Ring/Ring/Constants/Generated/Strings.swift +++ b/Ring/Ring/Constants/Generated/Strings.swift @@ -13,8 +13,10 @@ internal enum L10n { internal enum Account { /// Account Status internal static let accountStatus = L10n.tr("Localizable", "account.accountStatus", fallback: "Account Status") - /// Create a SIP Account - internal static let createSipAccount = L10n.tr("Localizable", "account.createSipAccount", fallback: "Create a SIP Account") + /// Advanced Features + internal static let advancedFeatures = L10n.tr("Localizable", "account.advancedFeatures", fallback: "Advanced Features") + /// Configure a SIP Account + internal static let createSipAccount = L10n.tr("Localizable", "account.createSipAccount", fallback: "Configure a SIP Account") /// Enable Account internal static let enableAccount = L10n.tr("Localizable", "account.enableAccount", fallback: "Enable Account") /// Me @@ -87,8 +89,8 @@ internal enum L10n { internal static let devicesListHeader = L10n.tr("Localizable", "accountPage.devicesListHeader", fallback: "Devices") /// Disable Booth Mode internal static let disableBoothMode = L10n.tr("Localizable", "accountPage.disableBoothMode", fallback: "Disable Booth Mode") - /// Pleace provide your account password - internal static let disableBoothModeExplanation = L10n.tr("Localizable", "accountPage.disableBoothModeExplanation", fallback: "Pleace provide your account password") + /// Please provide your account password + internal static let disableBoothModeExplanation = L10n.tr("Localizable", "accountPage.disableBoothModeExplanation", fallback: "Please provide your account password") /// Enable Booth Mode internal static let enableBoothMode = L10n.tr("Localizable", "accountPage.enableBoothMode", fallback: "Enable Booth Mode") /// Enable Notifications @@ -119,8 +121,8 @@ internal enum L10n { internal static let proxyDisabledAlertTitle = L10n.tr("Localizable", "accountPage.proxyDisabledAlertTitle", fallback: "Proxy Server Disabled") /// Proxy address internal static let proxyPaceholder = L10n.tr("Localizable", "accountPage.proxyPaceholder", fallback: "Proxy address") - /// Choosen username is not available - internal static let registerNameErrorMessage = L10n.tr("Localizable", "accountPage.registerNameErrorMessage", fallback: "Choosen username is not available") + /// Chosen username is not available + internal static let registerNameErrorMessage = L10n.tr("Localizable", "accountPage.registerNameErrorMessage", fallback: "Chosen username is not available") /// Remove internal static let removeAccountButton = L10n.tr("Localizable", "accountPage.removeAccountButton", fallback: "Remove") /// By clicking "Remove" you will remove this account on this device! This action can not be undone. Also, your registered name can be lost. @@ -129,8 +131,8 @@ internal enum L10n { internal static let revokeDeviceButton = L10n.tr("Localizable", "accountPage.revokeDeviceButton", fallback: "Revoke") /// Are you sure you want to revoke this device? This action could not be undone. internal static let revokeDeviceMessage = L10n.tr("Localizable", "accountPage.revokeDeviceMessage", fallback: "Are you sure you want to revoke this device? This action could not be undone.") - /// Enter your passord - internal static let revokeDevicePlaceholder = L10n.tr("Localizable", "accountPage.revokeDevicePlaceholder", fallback: "Enter your passord") + /// Enter your password + internal static let revokeDevicePlaceholder = L10n.tr("Localizable", "accountPage.revokeDevicePlaceholder", fallback: "Enter your password") /// Revoke device internal static let revokeDeviceTitle = L10n.tr("Localizable", "accountPage.revokeDeviceTitle", fallback: "Revoke device") /// Settings @@ -211,8 +213,8 @@ internal enum L10n { internal static let confirmDeleteConversationTitle = L10n.tr("Localizable", "alerts.confirmDeleteConversationTitle", fallback: "Delete Conversation") /// Please close application and try to open it again internal static let dbFailedMessage = L10n.tr("Localizable", "alerts.dbFailedMessage", fallback: "Please close application and try to open it again") - /// An error happned when launching Jami - internal static let dbFailedTitle = L10n.tr("Localizable", "alerts.dbFailedTitle", fallback: "An error happned when launching Jami") + /// An error happened when launching Jami + internal static let dbFailedTitle = L10n.tr("Localizable", "alerts.dbFailedTitle", fallback: "An error happened when launching Jami") /// Cannot connect to provided account manager. Please check your credentials internal static let errorWrongCredentials = L10n.tr("Localizable", "alerts.errorWrongCredentials", fallback: "Cannot connect to provided account manager. Please check your credentials") /// Incoming call from @@ -301,8 +303,8 @@ internal enum L10n { internal static let startVideoCall = L10n.tr("Localizable", "contactPage.startVideoCall", fallback: "Start Video Call") } internal enum Conversation { - /// Failed to save image to galery - internal static let errorSavingImage = L10n.tr("Localizable", "conversation.errorSavingImage", fallback: "Failed to save image to galery") + /// Failed to save image to gallery + internal static let errorSavingImage = L10n.tr("Localizable", "conversation.errorSavingImage", fallback: "Failed to save image to gallery") /// You are currently receiving a live location from internal static let explanationReceivingLocationFrom = L10n.tr("Localizable", "conversation.explanationReceivingLocationFrom", fallback: "You are currently receiving a live location from ") /// You are currently sharing your location with @@ -386,8 +388,8 @@ internal enum L10n { internal static let skipCreateProfile = L10n.tr("Localizable", "createProfile.skipCreateProfile", fallback: "Skip") /// Your profile will be shared with your contacts. You can change it at any time. internal static let subtitle = L10n.tr("Localizable", "createProfile.subtitle", fallback: "Your profile will be shared with your contacts. You can change it at any time.") - /// Personalise your profile - internal static let title = L10n.tr("Localizable", "createProfile.title", fallback: "Personalise your profile") + /// Personalize your profile + internal static let title = L10n.tr("Localizable", "createProfile.title", fallback: "Personalize your profile") } internal enum DataTransfer { /// Press to start recording @@ -436,8 +438,8 @@ internal enum L10n { internal static let videoSettings = L10n.tr("Localizable", "generalSettings.videoSettings", fallback: "Video Settings") } internal enum GeneratedMessage { - /// You received inviation - internal static let contactAdded = L10n.tr("Localizable", "generatedMessage.contactAdded", fallback: "You received inviation") + /// You received invitation + internal static let contactAdded = L10n.tr("Localizable", "generatedMessage.contactAdded", fallback: "You received invitation") /// was kicked internal static let contactBanned = L10n.tr("Localizable", "generatedMessage.contactBanned", fallback: "was kicked") /// left @@ -464,7 +466,7 @@ internal enum L10n { internal enum Global { /// Accept internal static let accept = L10n.tr("Localizable", "global.accept", fallback: "Accept") - /// * Copyright (C) 2017-2019 Savoir-faire Linux Inc. + /// * Copyright (C) 2017-2023 Savoir-faire Linux Inc. /// * /// * Author: Silbino Gonçalves Matado <silbino.gmatado@savoirfairelinux.com> /// * @@ -534,22 +536,22 @@ internal enum L10n { internal static let noInvitations = L10n.tr("Localizable", "invitations.noInvitations", fallback: "No invitations") } internal enum LinkDevice { - /// An error occured during the export - internal static let defaultError = L10n.tr("Localizable", "linkDevice.defaultError", fallback: "An error occured during the export") + /// An error occurred during the export + internal static let defaultError = L10n.tr("Localizable", "linkDevice.defaultError", fallback: "An error occurred during the export") /// To complete the process, you need to open Jami on the new device and choose the option "Link this device to an account." Your pin is valid for 10 minutes internal static let explanationMessage = L10n.tr("Localizable", "linkDevice.explanationMessage", fallback: "To complete the process, you need to open Jami on the new device and choose the option \"Link this device to an account.\" Your pin is valid for 10 minutes") /// Verifying internal static let hudMessage = L10n.tr("Localizable", "linkDevice.hudMessage", fallback: "Verifying") - /// A network error occured during the export - internal static let networkError = L10n.tr("Localizable", "linkDevice.networkError", fallback: "A network error occured during the export") + /// A network error occurred during the export + internal static let networkError = L10n.tr("Localizable", "linkDevice.networkError", fallback: "A network error occurred during the export") /// The password you entered does not unlock this account internal static let passwordError = L10n.tr("Localizable", "linkDevice.passwordError", fallback: "The password you entered does not unlock this account") /// Link a new device internal static let title = L10n.tr("Localizable", "linkDevice.title", fallback: "Link a new device") } internal enum LinkToAccount { - /// To generate the PIN code, go to the account managment settings on device that contain account you want to use. In devices settings Select "Link another device to this account". You will get the necessary PIN to complete this form. The PIN is only valid for 10 minutes. - internal static let explanationPinMessage = L10n.tr("Localizable", "linkToAccount.explanationPinMessage", fallback: "To generate the PIN code, go to the account managment settings on device that contain account you want to use. In devices settings Select \"Link another device to this account\". You will get the necessary PIN to complete this form. The PIN is only valid for 10 minutes.") + /// To generate the PIN code, go to the account management settings on device that contain account you want to use. In devices settings Select "Link another device to this account". You will get the necessary PIN to complete this form. The PIN is only valid for 10 minutes. + internal static let explanationPinMessage = L10n.tr("Localizable", "linkToAccount.explanationPinMessage", fallback: "To generate the PIN code, go to the account management settings on device that contain account you want to use. In devices settings Select \"Link another device to this account\". You will get the necessary PIN to complete this form. The PIN is only valid for 10 minutes.") /// Link device internal static let linkButtonTitle = L10n.tr("Localizable", "linkToAccount.linkButtonTitle", fallback: "Link device") /// Enter PIN @@ -704,16 +706,20 @@ internal enum L10n { internal static let searchBar = L10n.tr("Localizable", "swarmcreation.searchBar", fallback: "Search for contact...") } internal enum Welcome { - /// Connect to a JAMS server - internal static let connectToManager = L10n.tr("Localizable", "welcome.connectToManager", fallback: "Connect to a JAMS server") - /// Create a Jami account - internal static let createAccount = L10n.tr("Localizable", "welcome.createAccount", fallback: "Create a Jami account") - /// Link this device to an account - internal static let linkDevice = L10n.tr("Localizable", "welcome.linkDevice", fallback: "Link this device to an account") + /// Connect to a Jami Account Manager Server + internal static let connectToManager = L10n.tr("Localizable", "welcome.connectToManager", fallback: "Connect to a Jami Account Manager Server") + /// Join Jami + internal static let createAccount = L10n.tr("Localizable", "welcome.createAccount", fallback: "Join Jami") + /// I already have an account + internal static let haveAccount = L10n.tr("Localizable", "welcome.haveAccount", fallback: "I already have an account") + /// Import from archive backup + internal static let linkBackup = L10n.tr("Localizable", "welcome.linkBackup", fallback: "Import from archive backup") + /// Import from another device + internal static let linkDevice = L10n.tr("Localizable", "welcome.linkDevice", fallback: "Import from another device") /// Jami is a free and universal communication platform which preserves the users' privacy and freedoms internal static let text = L10n.tr("Localizable", "welcome.text", fallback: "Jami is a free and universal communication platform which preserves the users' privacy and freedoms") - /// Welcome to Jami ! - internal static let title = L10n.tr("Localizable", "welcome.title", fallback: "Welcome to Jami !") + /// Share, freely and privately with Jami + internal static let title = L10n.tr("Localizable", "welcome.title", fallback: "Share, freely and privately with Jami") } } // swiftlint:enable explicit_type_interface function_parameter_count identifier_name line_length diff --git a/Ring/Ring/Extensions/UIColor+Ring.swift b/Ring/Ring/Extensions/UIColor+Ring.swift index d794c85a41d1c9797ad4fe4c242cf7e054a64b7f..7715f511c13a169045c7062dd32e737612ab97b8 100644 --- a/Ring/Ring/Extensions/UIColor+Ring.swift +++ b/Ring/Ring/Extensions/UIColor+Ring.swift @@ -90,8 +90,9 @@ extension UIColor { static let jamiMain = UIColor(hex: 0x3F6DA7, alpha: 1.0) static let conferenceRaiseHand = UIColor(red: 0, green: 184, blue: 255, alpha: 1.0) static let jamiSecondary = UIColor(hex: 0x1F4971, alpha: 1.0) - static let jamiButtonLight = UIColor(hex: 0x285F97, alpha: 1.0) - static let jamiButtonDark = UIColor(hex: 0x0F2643, alpha: 1.0) + static let jamiButtonLight = UIColor(named: "jamiButtonLight")! + static let jamiButtonDark = UIColor(named: "jamiButtonDark")! + static let jamiButtonWithOpacity = UIColor(named: "jamiButtonWithOpacity")! static let jamiMsgCellSent = UIColor(hex: 0x367BC1, alpha: 1.0) static var jamiMsgCellReceived: UIColor { return UIColor(named: "background_msg_received") ?? UIColor(red: 231, green: 235, blue: 235, alpha: 1.0) diff --git a/Ring/Ring/Features/Conversations/SmartList/SmartlistViewController.swift b/Ring/Ring/Features/Conversations/SmartList/SmartlistViewController.swift index 8c6aef38a70776137e80baf5ddfb7d4f44353f88..627822396555cc68867d4ee634b61e14e67e88e8 100644 --- a/Ring/Ring/Features/Conversations/SmartList/SmartlistViewController.swift +++ b/Ring/Ring/Features/Conversations/SmartList/SmartlistViewController.swift @@ -504,8 +504,9 @@ class SmartlistViewController: UIViewController, StoryboardBased, ViewModelBased aboutButton.rx.tap .throttle(Durations.halfSecond.toTimeInterval(), scheduler: MainScheduler.instance) .subscribe(onNext: { [weak self] in - self?.infoItemTapped() - self?.menu.removeFromSuperview() + guard let self else { return } + AppInfoHelper.showAboutJamiAlert(onViewController: self) + self.menu.removeFromSuperview() }) .disposed(by: self.disposeBag) aboutView.addSubview(aboutButton) @@ -532,35 +533,6 @@ class SmartlistViewController: UIViewController, StoryboardBased, ViewModelBased self.navigationController?.view.addSubview(menu) } - private func infoItemTapped() { - var compileDate: String { - let dateDefault = "" - let dateFormatter = DateFormatter() - dateFormatter.dateFormat = "YYYYMMdd" - let bundleName = Bundle.main.infoDictionary!["CFBundleName"] as? String ?? "Info.plist" - if let infoPath = Bundle.main.path(forResource: bundleName, ofType: nil), - let infoAttr = try? FileManager.default.attributesOfItem(atPath: infoPath), - let infoDate = infoAttr[FileAttributeKey.creationDate] as? Date { - return dateFormatter.string(from: infoDate) - } - return dateDefault - } - - let appVersion = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String ?? "" - - let versionName = "Világfa" - let alert = UIAlertController(title: "\nJami\nversion: \(appVersion)(\(compileDate))\n\(versionName)", message: "", preferredStyle: .alert) - alert.addAction(UIAlertAction(title: L10n.Global.ok, style: .default, handler: nil)) - let image = UIImageView(image: UIImage(asset: Asset.jamiIcon)) - alert.view.addSubview(image) - image.translatesAutoresizingMaskIntoConstraints = false - alert.view.addConstraint(NSLayoutConstraint(item: image, attribute: .centerX, relatedBy: .equal, toItem: alert.view, attribute: .centerX, multiplier: 1, constant: 0)) - alert.view.addConstraint(NSLayoutConstraint(item: image, attribute: .centerY, relatedBy: .equal, toItem: alert.view, attribute: .top, multiplier: 1, constant: 0.0)) - alert.view.addConstraint(NSLayoutConstraint(item: image, attribute: .width, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1.0, constant: 64.0)) - alert.view.addConstraint(NSLayoutConstraint(item: image, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1.0, constant: 64.0)) - self.present(alert, animated: true, completion: nil) - } - private func updateAccountItemSize() { let screenRect = UIScreen.main.bounds let screenWidth = screenRect.size.width diff --git a/Ring/Ring/Features/Walkthrough/LinkDevice/LinkDeviceViewController.storyboard b/Ring/Ring/Features/Walkthrough/LinkDevice/LinkDeviceViewController.storyboard index 7b1d9c0fa5bb18858357be2fbb7e44c953ebc71a..b523188bb2f67b02047bacd3ebc8f2fa4eb12c8e 100644 --- a/Ring/Ring/Features/Walkthrough/LinkDevice/LinkDeviceViewController.storyboard +++ b/Ring/Ring/Features/Walkthrough/LinkDevice/LinkDeviceViewController.storyboard @@ -1,9 +1,9 @@ <?xml version="1.0" encoding="UTF-8"?> -<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="16096" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="1yn-Mj-8Ek"> +<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="21701" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="1yn-Mj-8Ek"> <device id="retina4_7" orientation="portrait" appearance="light"/> <dependencies> <deployment identifier="iOS"/> - <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="16087"/> + <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="21678"/> <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/> </dependencies> <scenes> @@ -19,7 +19,7 @@ <rect key="frame" x="0.0" y="0.0" width="375" height="667"/> <subviews> <scrollView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" showsHorizontalScrollIndicator="NO" showsVerticalScrollIndicator="NO" keyboardDismissMode="interactive" translatesAutoresizingMaskIntoConstraints="NO" id="2ZO-zp-5uC"> - <rect key="frame" x="0.0" y="0.0" width="375" height="667"/> + <rect key="frame" x="0.0" y="20" width="375" height="647"/> <subviews> <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="HlM-9Z-7gA" userLabel="Container View" customClass="DesignableView" customModule="Ring" customModuleProvider="target"> <rect key="frame" x="0.0" y="0.0" width="375" height="343"/> @@ -28,7 +28,7 @@ <rect key="frame" x="20" y="20" width="335" height="323"/> <subviews> <stackView opaque="NO" contentMode="scaleToFill" spacing="8" translatesAutoresizingMaskIntoConstraints="NO" id="edM-LD-fKX"> - <rect key="frame" x="0.0" y="0.0" width="102" height="22"/> + <rect key="frame" x="0.0" y="0.0" width="103" height="22"/> <subviews> <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Enter pin" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="VN2-rO-YYy"> <rect key="frame" x="0.0" y="0.0" width="69" height="22"/> @@ -37,7 +37,7 @@ <nil key="highlightedColor"/> </label> <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="infoLight" showsTouchWhenHighlighted="YES" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="rtk-w4-zfQ" customClass="ButtonTransparentBackground" customModule="Ring" customModuleProvider="target"> - <rect key="frame" x="77" y="0.0" width="25" height="22"/> + <rect key="frame" x="77" y="0.0" width="26" height="22"/> <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/> <constraints> <constraint firstAttribute="height" constant="22" id="dIk-SQ-ZCf"/> @@ -72,7 +72,7 @@ </constraints> </view> <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Enter password" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="9AD-b5-bun"> - <rect key="frame" x="0.0" y="107" width="122" height="25"/> + <rect key="frame" x="0.0" y="107" width="121" height="25"/> <constraints> <constraint firstAttribute="height" constant="25" id="g3B-PW-uya"/> </constraints> @@ -130,7 +130,7 @@ <constraint firstAttribute="height" constant="5" id="O9x-AI-cnI"/> </constraints> </view> - <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="BLV-X1-oI7" customClass="DesignableButton" customModule="Ring" customModuleProvider="target"> + <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="BLV-X1-oI7" customClass="DesignableButton" customModule="Ring" customModuleProvider="target"> <rect key="frame" x="0.0" y="273" width="335" height="50"/> <constraints> <constraint firstAttribute="width" relation="lessThanOrEqual" constant="500" id="3lO-u5-XKW"/> @@ -203,4 +203,15 @@ <point key="canvasLocation" x="1103.2" y="365.66716641679164"/> </scene> </scenes> + <designables> + <designable name="3CA-fY-2S2"> + <size key="intrinsicContentSize" width="26.5" height="22"/> + </designable> + <designable name="BLV-X1-oI7"> + <size key="intrinsicContentSize" width="90" height="34"/> + </designable> + <designable name="FyJ-Ke-ba3"> + <size key="intrinsicContentSize" width="75.5" height="22"/> + </designable> + </designables> </document> diff --git a/Ring/Ring/Features/Walkthrough/Welcome/WelcomeViewController.storyboard b/Ring/Ring/Features/Walkthrough/Welcome/WelcomeViewController.storyboard deleted file mode 100644 index 0b9d766a35b835976511dcb6f94f5da0a6219d7e..0000000000000000000000000000000000000000 --- a/Ring/Ring/Features/Walkthrough/Welcome/WelcomeViewController.storyboard +++ /dev/null @@ -1,180 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="17701" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="ILs-xb-iKr"> - <device id="ipad12_9rounded" orientation="portrait" layout="fullscreen" appearance="light"/> - <dependencies> - <deployment identifier="iOS"/> - <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="17703"/> - <capability name="Safe area layout guides" minToolsVersion="9.0"/> - <capability name="System colors in document resources" minToolsVersion="11.0"/> - <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/> - </dependencies> - <scenes> - <!--Welcome View Controller--> - <scene sceneID="4AN-bE-bMJ"> - <objects> - <viewController id="ILs-xb-iKr" customClass="WelcomeViewController" customModule="Ring" customModuleProvider="target" sceneMemberID="viewController"> - <view key="view" clipsSubviews="YES" contentMode="scaleToFill" id="Dg0-kS-rT7"> - <rect key="frame" x="0.0" y="0.0" width="1024" height="1366"/> - <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> - <subviews> - <scrollView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" showsHorizontalScrollIndicator="NO" showsVerticalScrollIndicator="NO" translatesAutoresizingMaskIntoConstraints="NO" id="X8i-r8-BbF"> - <rect key="frame" x="0.0" y="0.0" width="1024" height="1346"/> - <subviews> - <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="djg-zh-qNA"> - <rect key="frame" x="0.0" y="0.0" width="1024" height="650"/> - <subviews> - <imageView userInteractionEnabled="NO" contentMode="scaleAspectFit" verticalHuggingPriority="251" image="jamiIcon" translatesAutoresizingMaskIntoConstraints="NO" id="2Pc-uJ-SAI"> - <rect key="frame" x="462" y="96" width="100" height="95"/> - <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/> - <constraints> - <constraint firstAttribute="width" secondItem="2Pc-uJ-SAI" secondAttribute="height" multiplier="20:19" id="5fN-uH-uSi"/> - <constraint firstAttribute="width" constant="100" id="TaY-2a-CCG"/> - </constraints> - </imageView> - <label opaque="NO" userInteractionEnabled="NO" alpha="0.0" contentMode="left" verticalHuggingPriority="251" verticalCompressionResistancePriority="751" text="Welcome to jami !" textAlignment="center" lineBreakMode="wordWrap" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontForContentSizeCategory="YES" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="E4b-Zv-unB"> - <rect key="frame" x="383.5" y="221" width="257" height="43"/> - <fontDescription key="fontDescription" type="system" weight="thin" pointSize="36"/> - <color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="0.5" colorSpace="custom" customColorSpace="sRGB"/> - <nil key="highlightedColor"/> - </label> - <button opaque="NO" alpha="0.0" contentMode="scaleToFill" verticalHuggingPriority="251" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="bu0-90-MB5" customClass="DesignableButton" customModule="Ring" customModuleProvider="target"> - <rect key="frame" x="362" y="304" width="300" height="50"/> - <constraints> - <constraint firstAttribute="height" relation="greaterThanOrEqual" constant="50" id="FEf-kf-jCs"/> - </constraints> - <fontDescription key="fontDescription" type="system" weight="thin" pointSize="18"/> - <inset key="titleEdgeInsets" minX="5" minY="0.0" maxX="5" maxY="0.0"/> - <state key="normal" title="Create a Ring account"> - <color key="titleColor" white="1" alpha="1" colorSpace="calibratedWhite"/> - </state> - <userDefinedRuntimeAttributes> - <userDefinedRuntimeAttribute type="boolean" keyPath="roundedCorners" value="YES"/> - </userDefinedRuntimeAttributes> - </button> - <button opaque="NO" alpha="0.0" contentMode="scaleToFill" verticalHuggingPriority="251" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="QLK-gs-fOJ" customClass="DesignableButton" customModule="Ring" customModuleProvider="target"> - <rect key="frame" x="362" y="374" width="300" height="50"/> - <constraints> - <constraint firstAttribute="height" relation="greaterThanOrEqual" constant="50" id="YW4-Sc-61P"/> - </constraints> - <fontDescription key="fontDescription" type="system" weight="thin" pointSize="18"/> - <inset key="titleEdgeInsets" minX="5" minY="0.0" maxX="5" maxY="0.0"/> - <state key="normal" title="Link this device to an account"> - <color key="titleColor" white="1" alpha="1" colorSpace="calibratedWhite"/> - </state> - <userDefinedRuntimeAttributes> - <userDefinedRuntimeAttribute type="boolean" keyPath="roundedCorners" value="YES"/> - </userDefinedRuntimeAttributes> - </button> - <button opaque="NO" alpha="0.0" contentMode="scaleToFill" verticalHuggingPriority="251" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Wd6-vQ-gaH" customClass="DesignableButton" customModule="Ring" customModuleProvider="target"> - <rect key="frame" x="362" y="444" width="300" height="50"/> - <constraints> - <constraint firstAttribute="width" relation="greaterThanOrEqual" constant="300" id="dWY-2h-Jo8"/> - <constraint firstAttribute="height" relation="greaterThanOrEqual" constant="50" id="xto-yX-yFM"/> - </constraints> - <fontDescription key="fontDescription" type="system" weight="thin" pointSize="18"/> - <inset key="titleEdgeInsets" minX="5" minY="0.0" maxX="5" maxY="0.0"/> - <state key="normal" title="Connect to a JAMS server"> - <color key="titleColor" white="1" alpha="1" colorSpace="calibratedWhite"/> - </state> - <userDefinedRuntimeAttributes> - <userDefinedRuntimeAttribute type="boolean" keyPath="roundedCorners" value="YES"/> - </userDefinedRuntimeAttributes> - </button> - <button opaque="NO" alpha="0.0" contentMode="scaleToFill" verticalHuggingPriority="251" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="kHN-iS-Mdb" customClass="DesignableButton" customModule="Ring" customModuleProvider="target"> - <rect key="frame" x="362" y="514" width="300" height="50"/> - <constraints> - <constraint firstAttribute="height" relation="greaterThanOrEqual" constant="50" id="o1x-x5-0z2"/> - </constraints> - <fontDescription key="fontDescription" type="system" weight="thin" pointSize="22"/> - <state key="normal" title="create Sip account"> - <color key="titleColor" red="0.1215686275" green="0.28627450980000002" blue="0.4431372549" alpha="1" colorSpace="custom" customColorSpace="sRGB"/> - </state> - <userDefinedRuntimeAttributes> - <userDefinedRuntimeAttribute type="boolean" keyPath="roundedCorners" value="YES"/> - </userDefinedRuntimeAttributes> - </button> - </subviews> - <color key="backgroundColor" systemColor="systemBackgroundColor"/> - <constraints> - <constraint firstItem="E4b-Zv-unB" firstAttribute="centerX" secondItem="djg-zh-qNA" secondAttribute="centerX" id="2I1-0R-aRl"/> - <constraint firstItem="E4b-Zv-unB" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="djg-zh-qNA" secondAttribute="leading" constant="20" id="5VL-fW-ruk"/> - <constraint firstItem="kHN-iS-Mdb" firstAttribute="leading" secondItem="bu0-90-MB5" secondAttribute="leading" id="7r4-TP-Df9"/> - <constraint firstItem="Wd6-vQ-gaH" firstAttribute="trailing" secondItem="bu0-90-MB5" secondAttribute="trailing" id="9XM-f1-twm"/> - <constraint firstItem="QLK-gs-fOJ" firstAttribute="top" secondItem="bu0-90-MB5" secondAttribute="bottom" constant="20" id="Edo-KX-6sz"/> - <constraint firstItem="2Pc-uJ-SAI" firstAttribute="centerY" secondItem="djg-zh-qNA" secondAttribute="centerY" constant="-181.5" id="OH8-EL-DdN"/> - <constraint firstItem="Wd6-vQ-gaH" firstAttribute="top" secondItem="QLK-gs-fOJ" secondAttribute="bottom" constant="20" id="Rpw-PU-14b"/> - <constraint firstItem="kHN-iS-Mdb" firstAttribute="top" secondItem="Wd6-vQ-gaH" secondAttribute="bottom" constant="20" id="eKk-yN-Id4"/> - <constraint firstItem="bu0-90-MB5" firstAttribute="centerX" secondItem="djg-zh-qNA" secondAttribute="centerX" id="fuH-3p-ssn"/> - <constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="E4b-Zv-unB" secondAttribute="trailing" constant="20" id="kyK-k1-xsg"/> - <constraint firstItem="QLK-gs-fOJ" firstAttribute="centerX" secondItem="djg-zh-qNA" secondAttribute="centerX" id="lwf-Rd-3hc"/> - <constraint firstItem="QLK-gs-fOJ" firstAttribute="trailing" secondItem="bu0-90-MB5" secondAttribute="trailing" id="lzM-cm-1nj"/> - <constraint firstItem="QLK-gs-fOJ" firstAttribute="leading" secondItem="bu0-90-MB5" secondAttribute="leading" id="mt4-7Z-eR3"/> - <constraint firstItem="2Pc-uJ-SAI" firstAttribute="centerX" secondItem="djg-zh-qNA" secondAttribute="centerX" id="oJD-7p-Zee"/> - <constraint firstItem="Wd6-vQ-gaH" firstAttribute="leading" secondItem="bu0-90-MB5" secondAttribute="leading" id="qQF-mv-aU4"/> - <constraint firstItem="kHN-iS-Mdb" firstAttribute="trailing" secondItem="bu0-90-MB5" secondAttribute="trailing" id="r8u-YI-WpC"/> - <constraint firstItem="bu0-90-MB5" firstAttribute="top" secondItem="E4b-Zv-unB" secondAttribute="bottom" constant="40" id="rNa-Lz-fF2"/> - <constraint firstItem="E4b-Zv-unB" firstAttribute="top" secondItem="2Pc-uJ-SAI" secondAttribute="bottom" constant="30" id="uqF-tz-TA3"/> - <constraint firstAttribute="bottom" relation="greaterThanOrEqual" secondItem="kHN-iS-Mdb" secondAttribute="bottom" constant="20" id="wAX-eY-8Cc"/> - <constraint firstItem="kHN-iS-Mdb" firstAttribute="centerX" secondItem="djg-zh-qNA" secondAttribute="centerX" id="xCk-wd-xlo"/> - <constraint firstAttribute="height" constant="650" id="yed-0d-kKi"/> - </constraints> - </view> - </subviews> - <constraints> - <constraint firstItem="djg-zh-qNA" firstAttribute="leading" secondItem="WOA-YS-hhU" secondAttribute="leading" id="NVB-Mh-6Mh"/> - <constraint firstItem="djg-zh-qNA" firstAttribute="trailing" secondItem="WOA-YS-hhU" secondAttribute="trailing" id="a3A-d3-Q1D"/> - <constraint firstItem="djg-zh-qNA" firstAttribute="bottom" secondItem="WOA-YS-hhU" secondAttribute="bottom" id="iPL-YC-e44"/> - <constraint firstItem="djg-zh-qNA" firstAttribute="centerX" secondItem="X8i-r8-BbF" secondAttribute="centerX" id="qJX-a9-Ihb"/> - <constraint firstItem="djg-zh-qNA" firstAttribute="top" secondItem="WOA-YS-hhU" secondAttribute="top" id="zes-gc-CwJ"/> - </constraints> - <viewLayoutGuide key="contentLayoutGuide" id="WOA-YS-hhU"/> - <viewLayoutGuide key="frameLayoutGuide" id="ahR-LE-Or6"/> - </scrollView> - </subviews> - <viewLayoutGuide key="safeArea" id="hvJ-fJ-PMc"/> - <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> - <constraints> - <constraint firstItem="X8i-r8-BbF" firstAttribute="top" secondItem="Dg0-kS-rT7" secondAttribute="top" id="4Eh-OM-QvP"/> - <constraint firstItem="X8i-r8-BbF" firstAttribute="trailing" secondItem="hvJ-fJ-PMc" secondAttribute="trailing" id="InM-7Y-w4b"/> - <constraint firstItem="X8i-r8-BbF" firstAttribute="leading" secondItem="hvJ-fJ-PMc" secondAttribute="leading" id="Mxh-zn-bSX"/> - <constraint firstItem="X8i-r8-BbF" firstAttribute="bottom" secondItem="hvJ-fJ-PMc" secondAttribute="bottom" id="bnM-Bf-Zwh"/> - <constraint firstItem="hvJ-fJ-PMc" firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="bu0-90-MB5" secondAttribute="trailing" constant="20" id="h6u-zb-Bvk"/> - <constraint firstItem="bu0-90-MB5" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="hvJ-fJ-PMc" secondAttribute="leading" constant="20" id="pf3-7r-uP4"/> - </constraints> - </view> - <navigationItem key="navigationItem" id="SVR-Ry-7d7"/> - <connections> - <outlet property="connectToAccountManagerButton" destination="Wd6-vQ-gaH" id="cNX-WT-aPP"/> - <outlet property="createAccountButton" destination="bu0-90-MB5" id="YNt-Tc-Snc"/> - <outlet property="createSipAccountButton" destination="kHN-iS-Mdb" id="eJ4-Qz-agr"/> - <outlet property="linkDeviceButton" destination="QLK-gs-fOJ" id="AXP-0r-10g"/> - <outlet property="ringLogoBottomConstraint" destination="OH8-EL-DdN" id="CIb-Qh-H7u"/> - <outlet property="welcomeTextLabel" destination="E4b-Zv-unB" id="ygV-A3-EZD"/> - </connections> - </viewController> - <placeholder placeholderIdentifier="IBFirstResponder" id="Yc1-qm-cpP" userLabel="First Responder" sceneMemberID="firstResponder"/> - </objects> - <point key="canvasLocation" x="-333.60000000000002" y="29.55665024630542"/> - </scene> - </scenes> - <designables> - <designable name="QLK-gs-fOJ"> - <size key="intrinsicContentSize" width="231" height="34"/> - </designable> - <designable name="Wd6-vQ-gaH"> - <size key="intrinsicContentSize" width="203" height="34"/> - </designable> - <designable name="bu0-90-MB5"> - <size key="intrinsicContentSize" width="173" height="34"/> - </designable> - <designable name="kHN-iS-Mdb"> - <size key="intrinsicContentSize" width="171" height="39"/> - </designable> - </designables> - <resources> - <image name="jamiIcon" width="100" height="95"/> - <systemColor name="systemBackgroundColor"> - <color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> - </systemColor> - </resources> -</document> diff --git a/Ring/Ring/Features/Walkthrough/Welcome/WelcomeViewController.swift b/Ring/Ring/Features/Walkthrough/Welcome/WelcomeViewController.swift deleted file mode 100644 index dd9468cbe5f61bbac516e9758ccc010246ab25b8..0000000000000000000000000000000000000000 --- a/Ring/Ring/Features/Walkthrough/Welcome/WelcomeViewController.swift +++ /dev/null @@ -1,167 +0,0 @@ -/* - * Copyright (C) 2017-2019 Savoir-faire Linux Inc. - * - * Author: Thibault Wittemberg <thibault.wittemberg@savoirfairelinux.com> - * Author: Quentin Muret <quentin.muret@savoirfairelinux.com> - * - * 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, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -import UIKit -import RxSwift -import RxCocoa -import Reusable - -class WelcomeViewController: UIViewController, StoryboardBased, ViewModelBased { - var viewModel: WelcomeViewModel! - - typealias VMType = WelcomeViewModel - // MARK: outlets - @IBOutlet weak var welcomeTextLabel: UILabel! - @IBOutlet weak var linkDeviceButton: DesignableButton! - @IBOutlet weak var createAccountButton: DesignableButton! - @IBOutlet weak var createSipAccountButton: DesignableButton! - @IBOutlet weak var connectToAccountManagerButton: DesignableButton! - - // MARK: constraints - @IBOutlet weak var ringLogoBottomConstraint: NSLayoutConstraint! - - // MARK: members - private let disposeBag = DisposeBag() - - // MARK: functions - override func viewDidLoad() { - super.viewDidLoad() - self.view.layoutIfNeeded() - self.applyL10n() - if self.viewModel.isAnimatable { - self.initialAnimation() - } else { - self.ringLogoBottomConstraint.constant = -220 - self.welcomeTextLabel.alpha = 1 - self.createAccountButton.alpha = 1 - self.linkDeviceButton.alpha = 1 - self.createSipAccountButton.alpha = 1 - self.connectToAccountManagerButton.alpha = 1 - } - createAccountButton.titleLabel?.ajustToTextSize() - linkDeviceButton.titleLabel?.ajustToTextSize() - connectToAccountManagerButton.titleLabel?.ajustToTextSize() - createSipAccountButton.titleLabel?.ajustToTextSize() - self.createAccountButton.applyGradient(with: [UIColor.jamiButtonLight, UIColor.jamiButtonDark], gradient: .horizontal) - self.linkDeviceButton.applyGradient(with: [UIColor.jamiButtonLight, UIColor.jamiButtonDark], gradient: .horizontal) - self.connectToAccountManagerButton.applyGradient(with: [UIColor.jamiButtonLight, UIColor.jamiButtonDark], gradient: .horizontal) - // Bind ViewModel to View - self.viewModel.welcomeText.bind(to: self.welcomeTextLabel.rx.text).disposed(by: self.disposeBag) - self.viewModel.createAccount.bind(to: self.createAccountButton.rx.title(for: .normal)).disposed(by: self.disposeBag) - self.viewModel.linkDevice.bind(to: self.linkDeviceButton.rx.title(for: .normal)).disposed(by: self.disposeBag) - createSipAccountButton.setTitle(L10n.Account.createSipAccount, for: .normal) - if !self.viewModel.notCancelable { - let cancelButton = UIButton(type: .custom) - cancelButton.setTitleColor(.jamiMain, for: .normal) - cancelButton.titleLabel?.font = UIFont(name: "HelveticaNeue-Light", size: 25) - cancelButton.setTitle(L10n.Global.cancel, for: .normal) - cancelButton.frame = CGRect(x: 0, y: 0, width: 100, height: 40) - let buttonItem = UIBarButtonItem(customView: cancelButton) - cancelButton.rx.tap.throttle(Durations.halfSecond.toTimeInterval(), scheduler: MainScheduler.instance) - .subscribe(onNext: { [weak self] in - self?.viewModel.cancelWalkthrough() - }) - .disposed(by: self.disposeBag) - self.navigationItem.leftBarButtonItem = buttonItem - } - Observable.just(self.viewModel.notCancelable).bind(to: self.createSipAccountButton.rx.isHidden).disposed(by: self.disposeBag) - Observable.just(!self.viewModel.notCancelable).bind(to: self.createSipAccountButton.rx.isEnabled).disposed(by: self.disposeBag) - // Bind View Actions to ViewModel - self.createAccountButton.rx.tap - .subscribe(onNext: { [weak self] in - self?.viewModel.proceedWithAccountCreation() - }) - .disposed(by: self.disposeBag) - - self.linkDeviceButton.rx.tap - .subscribe(onNext: { [weak self] in - self?.viewModel.proceedWithLinkDevice() - }) - .disposed(by: self.disposeBag) - - self.createSipAccountButton.rx.tap - .subscribe(onNext: { [weak self] in - self?.viewModel.createSipAccount() - }) - .disposed(by: self.disposeBag) - - self.connectToAccountManagerButton.rx.tap - .subscribe(onNext: { [weak self] in - self?.viewModel.linkToAccountManager() - }) - .disposed(by: self.disposeBag) - view.backgroundColor = UIColor.jamiBackgroundColor - self.welcomeTextLabel.textColor = UIColor.jamiLabelColor - self.createSipAccountButton.setTitleColor(UIColor.jamiTextBlue, for: .normal) - NotificationCenter.default.rx - .notification(UIDevice.orientationDidChangeNotification) - .observe(on: MainScheduler.instance) - .subscribe(onNext: { [weak self] (_) in - guard UIDevice.current.portraitOrLandscape else { return } - self?.configureWalkrhroughNavigationBar() - self?.updateButtonsSize() - }) - .disposed(by: self.disposeBag) - } - - func applyL10n() { - createSipAccountButton.setTitle(L10n.Account.createSipAccount, for: .normal) - linkDeviceButton.setTitle(L10n.Welcome.linkDevice, for: .normal) - connectToAccountManagerButton - .setTitle(L10n.Welcome.connectToManager, for: .normal) - createAccountButton.setTitle(L10n.Welcome.createAccount, for: .normal) - welcomeTextLabel.text = L10n.Welcome.title - } - - func initialAnimation() { - DispatchQueue.global(qos: .background).async { - sleep(1) - DispatchQueue.main.async { [weak self] in - self?.ringLogoBottomConstraint.constant = -72 - UIView.animate(withDuration: 0.5, animations: { - self?.ringLogoBottomConstraint.constant = -220 - self?.welcomeTextLabel.alpha = 1 - self?.createAccountButton.alpha = 1 - self?.linkDeviceButton.alpha = 1 - self?.connectToAccountManagerButton.alpha = 1 - self?.view.layoutIfNeeded() - }) - } - } - } - - func updateButtonsSize() { - self.createAccountButton.updateGradientFrame() - self.linkDeviceButton.updateGradientFrame() - self.connectToAccountManagerButton.updateGradientFrame() - self.view.layoutIfNeeded() - } - override func viewWillAppear(_ animated: Bool) { - super.viewWillAppear(animated) - self.navigationController?.navigationBar.tintColor = UIColor.jamiSecondary - self.navigationItem.backBarButtonItem = UIBarButtonItem(title: "", style: .plain, target: nil, action: nil) - self.navigationController?.navigationBar.setBackgroundImage(UIImage(), for: UIBarMetrics.default) - self.navigationController?.navigationBar.shadowImage = UIImage() - self.navigationController?.navigationBar.isTranslucent = true - self.view.layoutIfNeeded() - updateButtonsSize() - } -} diff --git a/Ring/Ring/Features/Walkthrough/WelcomeViewController.storyboard b/Ring/Ring/Features/Walkthrough/WelcomeViewController.storyboard new file mode 100644 index 0000000000000000000000000000000000000000..eb8f030b58142f4d626bd42173a065a672c934c1 --- /dev/null +++ b/Ring/Ring/Features/Walkthrough/WelcomeViewController.storyboard @@ -0,0 +1,279 @@ +<?xml version="1.0" encoding="UTF-8"?> +<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="21701" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="a7M-11-Me2"> + <device id="retina5_9" orientation="portrait" appearance="light"/> + <dependencies> + <deployment identifier="iOS"/> + <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="21678"/> + <capability name="Safe area layout guides" minToolsVersion="9.0"/> + <capability name="System colors in document resources" minToolsVersion="11.0"/> + <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/> + </dependencies> + <scenes> + <!--Welcome View Controller--> + <scene sceneID="Rk0-Pb-xfs"> + <objects> + <viewController id="a7M-11-Me2" customClass="WelcomeViewController" customModule="Ring" customModuleProvider="target" sceneMemberID="viewController"> + <view key="view" contentMode="scaleToFill" id="Ev1-K9-ko3"> + <rect key="frame" x="0.0" y="0.0" width="375" height="812"/> + <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> + <subviews> + <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="background_login" translatesAutoresizingMaskIntoConstraints="NO" id="WKh-ia-14i"> + <rect key="frame" x="0.0" y="0.0" width="375" height="812"/> + <color key="tintColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> + </imageView> + <scrollView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" showsHorizontalScrollIndicator="NO" showsVerticalScrollIndicator="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Vbh-6j-wmS"> + <rect key="frame" x="0.0" y="50" width="375" height="658"/> + <subviews> + <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="ka9-wr-QQv"> + <rect key="frame" x="0.0" y="0.0" width="375" height="471"/> + <subviews> + <imageView userInteractionEnabled="NO" contentMode="scaleAspectFit" verticalHuggingPriority="251" image="jamiIcon" translatesAutoresizingMaskIntoConstraints="NO" id="2Pc-uJ-SAI"> + <rect key="frame" x="137.66666666666666" y="20" width="100" height="95"/> + <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/> + <constraints> + <constraint firstAttribute="width" secondItem="2Pc-uJ-SAI" secondAttribute="height" multiplier="20:19" id="5fN-uH-uSi"/> + <constraint firstAttribute="height" constant="95" id="Mlo-yj-dOM"/> + </constraints> + </imageView> + <label opaque="NO" userInteractionEnabled="NO" alpha="0.0" contentMode="left" verticalHuggingPriority="251" verticalCompressionResistancePriority="751" text="Welcome to jami !" textAlignment="center" lineBreakMode="wordWrap" numberOfLines="2" baselineAdjustment="alignBaselines" adjustsFontForContentSizeCategory="YES" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="E4b-Zv-unB"> + <rect key="frame" x="110.33333333333333" y="165" width="154.66666666666669" height="76"/> + <constraints> + <constraint firstAttribute="height" constant="76" id="TB2-Qc-8kW"/> + </constraints> + <fontDescription key="fontDescription" type="system" pointSize="20"/> + <color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="0.5" colorSpace="custom" customColorSpace="sRGB"/> + <nil key="highlightedColor"/> + </label> + <stackView opaque="NO" contentMode="scaleToFill" axis="vertical" distribution="fillEqually" spacing="20" translatesAutoresizingMaskIntoConstraints="NO" id="CTB-bR-Knj"> + <rect key="frame" x="37.666666666666657" y="271" width="300" height="190"/> + <subviews> + <button opaque="NO" alpha="0.0" contentMode="scaleToFill" verticalHuggingPriority="251" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="bu0-90-MB5" customClass="DesignableButton" customModule="Ring" customModuleProvider="target"> + <rect key="frame" x="0.0" y="0.0" width="300" height="50"/> + <constraints> + <constraint firstAttribute="height" constant="50" id="FEf-kf-jCs"/> + </constraints> + <fontDescription key="fontDescription" type="system" pointSize="17"/> + <inset key="titleEdgeInsets" minX="5" minY="0.0" maxX="5" maxY="0.0"/> + <state key="normal" title="Create a Ring account"> + <color key="titleColor" white="1" alpha="1" colorSpace="calibratedWhite"/> + </state> + <userDefinedRuntimeAttributes> + <userDefinedRuntimeAttribute type="boolean" keyPath="roundedCorners" value="YES"/> + <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius"> + <real key="value" value="12"/> + </userDefinedRuntimeAttribute> + </userDefinedRuntimeAttributes> + </button> + <button opaque="NO" alpha="0.0" contentMode="scaleToFill" verticalHuggingPriority="251" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="QLK-gs-fOJ" customClass="DesignableButton" customModule="Ring" customModuleProvider="target"> + <rect key="frame" x="0.0" y="70" width="300" height="50"/> + <constraints> + <constraint firstAttribute="height" constant="50" id="YW4-Sc-61P"/> + </constraints> + <fontDescription key="fontDescription" type="system" pointSize="17"/> + <inset key="titleEdgeInsets" minX="5" minY="0.0" maxX="5" maxY="0.0"/> + <state key="normal" title="Link this device to an account"> + <color key="titleColor" white="1" alpha="1" colorSpace="calibratedWhite"/> + </state> + <userDefinedRuntimeAttributes> + <userDefinedRuntimeAttribute type="boolean" keyPath="roundedCorners" value="YES"/> + <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius"> + <real key="value" value="12"/> + </userDefinedRuntimeAttribute> + </userDefinedRuntimeAttributes> + </button> + <button hidden="YES" opaque="NO" contentMode="scaleToFill" verticalHuggingPriority="251" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Wd6-vQ-gaH" customClass="DesignableButton" customModule="Ring" customModuleProvider="target"> + <rect key="frame" x="0.0" y="130" width="300" height="50"/> + <constraints> + <constraint firstAttribute="height" constant="50" id="xto-yX-yFM"/> + </constraints> + <fontDescription key="fontDescription" type="system" pointSize="17"/> + <inset key="titleEdgeInsets" minX="5" minY="0.0" maxX="5" maxY="0.0"/> + <state key="normal" title="Connect to a JAMS server"> + <color key="titleColor" white="1" alpha="1" colorSpace="calibratedWhite"/> + </state> + <userDefinedRuntimeAttributes> + <userDefinedRuntimeAttribute type="boolean" keyPath="roundedCorners" value="YES"/> + <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius"> + <real key="value" value="12"/> + </userDefinedRuntimeAttribute> + </userDefinedRuntimeAttributes> + </button> + <button hidden="YES" opaque="NO" contentMode="scaleToFill" verticalHuggingPriority="251" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="py3-Pp-IIC" customClass="DesignableButton" customModule="Ring" customModuleProvider="target"> + <rect key="frame" x="0.0" y="130" width="300" height="50"/> + <constraints> + <constraint firstAttribute="height" constant="50" id="GuU-S6-A6D"/> + </constraints> + <fontDescription key="fontDescription" type="system" pointSize="17"/> + <inset key="titleEdgeInsets" minX="5" minY="0.0" maxX="5" maxY="0.0"/> + <state key="normal" title="Connect to a JAMS server"> + <color key="titleColor" white="1" alpha="1" colorSpace="calibratedWhite"/> + </state> + <userDefinedRuntimeAttributes> + <userDefinedRuntimeAttribute type="boolean" keyPath="roundedCorners" value="YES"/> + <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius"> + <real key="value" value="12"/> + </userDefinedRuntimeAttribute> + </userDefinedRuntimeAttributes> + </button> + <button opaque="NO" alpha="0.0" contentMode="scaleToFill" verticalHuggingPriority="251" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="kHN-iS-Mdb" customClass="DesignableButton" customModule="Ring" customModuleProvider="target"> + <rect key="frame" x="0.0" y="140" width="300" height="50"/> + <constraints> + <constraint firstAttribute="height" constant="50" id="o1x-x5-0z2"/> + </constraints> + <fontDescription key="fontDescription" type="system" pointSize="17"/> + <state key="normal" title="create Sip account"> + <color key="titleColor" red="0.1215686275" green="0.28627450980000002" blue="0.4431372549" alpha="1" colorSpace="custom" customColorSpace="sRGB"/> + </state> + <userDefinedRuntimeAttributes> + <userDefinedRuntimeAttribute type="boolean" keyPath="roundedCorners" value="YES"/> + <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius"> + <real key="value" value="12"/> + </userDefinedRuntimeAttribute> + </userDefinedRuntimeAttributes> + </button> + <button hidden="YES" opaque="NO" contentMode="scaleToFill" verticalHuggingPriority="251" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="S02-sh-I3j" customClass="DesignableButton" customModule="Ring" customModuleProvider="target"> + <rect key="frame" x="0.0" y="190" width="300" height="50"/> + <constraints> + <constraint firstAttribute="height" constant="50" id="sAy-MH-owv"/> + </constraints> + <fontDescription key="fontDescription" type="system" pointSize="17"/> + <state key="normal" title="create Sip account"> + <color key="titleColor" red="0.1215686275" green="0.28627450980000002" blue="0.4431372549" alpha="1" colorSpace="custom" customColorSpace="sRGB"/> + </state> + <userDefinedRuntimeAttributes> + <userDefinedRuntimeAttribute type="boolean" keyPath="roundedCorners" value="YES"/> + <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius"> + <real key="value" value="12"/> + </userDefinedRuntimeAttribute> + </userDefinedRuntimeAttributes> + </button> + <button hidden="YES" opaque="NO" contentMode="scaleToFill" verticalHuggingPriority="251" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="ki3-CT-J1m" customClass="DesignableButton" customModule="Ring" customModuleProvider="target"> + <rect key="frame" x="0.0" y="190" width="300" height="50"/> + <constraints> + <constraint firstAttribute="height" constant="50" id="xdN-0S-pdc"/> + </constraints> + <fontDescription key="fontDescription" type="system" pointSize="17"/> + <state key="normal" title="create Sip account"> + <color key="titleColor" red="0.1215686275" green="0.28627450980000002" blue="0.4431372549" alpha="1" colorSpace="custom" customColorSpace="sRGB"/> + </state> + <userDefinedRuntimeAttributes> + <userDefinedRuntimeAttribute type="boolean" keyPath="roundedCorners" value="YES"/> + <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius"> + <real key="value" value="12"/> + </userDefinedRuntimeAttribute> + </userDefinedRuntimeAttributes> + </button> + </subviews> + <constraints> + <constraint firstAttribute="width" relation="greaterThanOrEqual" constant="300" id="lFX-dh-3CE"/> + </constraints> + </stackView> + </subviews> + <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> + <constraints> + <constraint firstItem="2Pc-uJ-SAI" firstAttribute="top" secondItem="ka9-wr-QQv" secondAttribute="top" constant="20" id="2hZ-9k-9aa"/> + <constraint firstItem="E4b-Zv-unB" firstAttribute="centerX" secondItem="2Pc-uJ-SAI" secondAttribute="centerX" id="BrK-Ku-djd"/> + <constraint firstItem="CTB-bR-Knj" firstAttribute="centerX" secondItem="ka9-wr-QQv" secondAttribute="centerX" id="EN2-7d-QMm"/> + <constraint firstItem="2Pc-uJ-SAI" firstAttribute="centerX" secondItem="ka9-wr-QQv" secondAttribute="centerX" id="FLm-J1-PSJ"/> + <constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="CTB-bR-Knj" secondAttribute="trailing" constant="30" id="HMv-8n-gxi"/> + <constraint firstAttribute="bottom" secondItem="CTB-bR-Knj" secondAttribute="bottom" constant="10" id="Lju-1b-sgn"/> + <constraint firstItem="E4b-Zv-unB" firstAttribute="top" secondItem="2Pc-uJ-SAI" secondAttribute="bottom" constant="50" id="jYr-kA-NLP"/> + <constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="E4b-Zv-unB" secondAttribute="trailing" constant="15" id="lwR-AZ-cXx"/> + <constraint firstItem="CTB-bR-Knj" firstAttribute="top" secondItem="E4b-Zv-unB" secondAttribute="bottom" constant="30" id="mPU-JJ-xSF"/> + <constraint firstItem="E4b-Zv-unB" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="ka9-wr-QQv" secondAttribute="leading" constant="15" id="xBc-Kv-P49"/> + </constraints> + </view> + </subviews> + <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> + <constraints> + <constraint firstAttribute="trailing" secondItem="ka9-wr-QQv" secondAttribute="trailing" id="Lu6-4V-r6O"/> + <constraint firstAttribute="bottom" secondItem="ka9-wr-QQv" secondAttribute="bottom" id="O4F-Jr-R5F"/> + <constraint firstItem="ka9-wr-QQv" firstAttribute="width" secondItem="Vbh-6j-wmS" secondAttribute="width" id="Rcw-rb-QZM"/> + <constraint firstItem="ka9-wr-QQv" firstAttribute="leading" secondItem="Vbh-6j-wmS" secondAttribute="leading" id="dle-bH-uby"/> + <constraint firstItem="ka9-wr-QQv" firstAttribute="top" secondItem="Vbh-6j-wmS" secondAttribute="top" id="vZ7-kW-y3N"/> + </constraints> + </scrollView> + <button opaque="NO" contentMode="scaleToFill" verticalHuggingPriority="251" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="IWW-3h-vlx" customClass="DesignableButton" customModule="Ring" customModuleProvider="target"> + <rect key="frame" x="116" y="718" width="143" height="50"/> + <constraints> + <constraint firstAttribute="height" constant="50" id="b69-oL-WqW"/> + </constraints> + <fontDescription key="fontDescription" type="system" pointSize="17"/> + <state key="normal" title="create Sip account"> + <color key="titleColor" red="0.1215686275" green="0.28627450980000002" blue="0.4431372549" alpha="1" colorSpace="custom" customColorSpace="sRGB"/> + </state> + <userDefinedRuntimeAttributes> + <userDefinedRuntimeAttribute type="boolean" keyPath="roundedCorners" value="YES"/> + <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius"> + <real key="value" value="12"/> + </userDefinedRuntimeAttribute> + </userDefinedRuntimeAttributes> + </button> + </subviews> + <viewLayoutGuide key="safeArea" id="1aJ-6z-De7"/> + <color key="backgroundColor" systemColor="systemBackgroundColor"/> + <constraints> + <constraint firstItem="WKh-ia-14i" firstAttribute="top" secondItem="Ev1-K9-ko3" secondAttribute="top" id="5vk-rm-tgp"/> + <constraint firstItem="Vbh-6j-wmS" firstAttribute="trailing" secondItem="Ev1-K9-ko3" secondAttribute="trailing" id="7Oc-Ym-9Hs"/> + <constraint firstItem="1aJ-6z-De7" firstAttribute="bottom" secondItem="IWW-3h-vlx" secondAttribute="bottom" constant="10" id="CPo-7T-PUo"/> + <constraint firstItem="IWW-3h-vlx" firstAttribute="centerX" secondItem="1aJ-6z-De7" secondAttribute="centerX" id="DSc-Tr-BZc"/> + <constraint firstAttribute="bottom" secondItem="WKh-ia-14i" secondAttribute="bottom" id="FIY-ya-kOW"/> + <constraint firstItem="IWW-3h-vlx" firstAttribute="top" secondItem="Vbh-6j-wmS" secondAttribute="bottom" constant="10" id="MNp-Gc-3RR"/> + <constraint firstItem="Vbh-6j-wmS" firstAttribute="top" secondItem="1aJ-6z-De7" secondAttribute="top" id="OVd-qb-k4N"/> + <constraint firstItem="CTB-bR-Knj" firstAttribute="centerY" secondItem="1aJ-6z-De7" secondAttribute="centerY" priority="100" id="Vey-an-e0p"/> + <constraint firstItem="WKh-ia-14i" firstAttribute="leading" secondItem="Ev1-K9-ko3" secondAttribute="leading" id="fJs-yL-UfK"/> + <constraint firstAttribute="trailing" secondItem="WKh-ia-14i" secondAttribute="trailing" id="fV4-nX-zRz"/> + <constraint firstItem="Vbh-6j-wmS" firstAttribute="leading" secondItem="1aJ-6z-De7" secondAttribute="leading" id="kAl-nu-6CQ"/> + </constraints> + </view> + <connections> + <outlet property="aboutJamiButton" destination="IWW-3h-vlx" id="sSJ-Rq-YzZ"/> + <outlet property="advancedFeaturesButton" destination="kHN-iS-Mdb" id="Zil-kV-3gy"/> + <outlet property="configureSIPButton" destination="ki3-CT-J1m" id="aVq-rF-U7h"/> + <outlet property="connectJamiAcountManagerButton" destination="S02-sh-I3j" id="ual-XS-H9Z"/> + <outlet property="importBackupButton" destination="py3-Pp-IIC" id="bWR-Tw-165"/> + <outlet property="importDeviceButton" destination="Wd6-vQ-gaH" id="TfO-Xg-8Yk"/> + <outlet property="joinJamiButton" destination="bu0-90-MB5" id="8ed-UA-GJh"/> + <outlet property="linkAccountButton" destination="QLK-gs-fOJ" id="RYz-cf-ypx"/> + <outlet property="welcomeTextLabel" destination="E4b-Zv-unB" id="wD6-ix-018"/> + </connections> + </viewController> + <placeholder placeholderIdentifier="IBFirstResponder" id="c0E-9z-Cxj" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/> + </objects> + <point key="canvasLocation" x="536.79999999999995" y="28.817733990147783"/> + </scene> + </scenes> + <designables> + <designable name="IWW-3h-vlx"> + <size key="intrinsicContentSize" width="143" height="33"/> + </designable> + <designable name="QLK-gs-fOJ"> + <size key="intrinsicContentSize" width="226" height="33"/> + </designable> + <designable name="S02-sh-I3j"> + <size key="intrinsicContentSize" width="143" height="33"/> + </designable> + <designable name="Wd6-vQ-gaH"> + <size key="intrinsicContentSize" width="199" height="33"/> + </designable> + <designable name="bu0-90-MB5"> + <size key="intrinsicContentSize" width="168" height="33"/> + </designable> + <designable name="kHN-iS-Mdb"> + <size key="intrinsicContentSize" width="143" height="33"/> + </designable> + <designable name="ki3-CT-J1m"> + <size key="intrinsicContentSize" width="143" height="33"/> + </designable> + <designable name="py3-Pp-IIC"> + <size key="intrinsicContentSize" width="199" height="33"/> + </designable> + </designables> + <resources> + <image name="background_login" width="2940" height="2189"/> + <image name="jamiIcon" width="66.666664123535156" height="63.333332061767578"/> + <systemColor name="systemBackgroundColor"> + <color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> + </systemColor> + </resources> +</document> diff --git a/Ring/Ring/Features/Walkthrough/WelcomeViewController.swift b/Ring/Ring/Features/Walkthrough/WelcomeViewController.swift new file mode 100644 index 0000000000000000000000000000000000000000..c72007670f92fc566ccb3711436ea029c7586a8b --- /dev/null +++ b/Ring/Ring/Features/Walkthrough/WelcomeViewController.swift @@ -0,0 +1,233 @@ +/* + * Copyright (C) 2017-2023 Savoir-faire Linux Inc. + * + * Author: Thibault Wittemberg <thibault.wittemberg@savoirfairelinux.com> + * Author: Quentin Muret <quentin.muret@savoirfairelinux.com> + * Author: Alireza Toghiani Khorasgani alireza.toghiani@savoirfairelinux.com * + * + * 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +import UIKit +import RxSwift +import RxCocoa +import Reusable + +class WelcomeViewController: UIViewController, StoryboardBased, ViewModelBased { + var viewModel: WelcomeViewModel! + + typealias VMType = WelcomeViewModel + // MARK: outlets + @IBOutlet weak var welcomeTextLabel: UILabel! + @IBOutlet weak var joinJamiButton: DesignableButton! + @IBOutlet weak var linkAccountButton: DesignableButton! + @IBOutlet weak var importDeviceButton: DesignableButton! + @IBOutlet weak var importBackupButton: DesignableButton! + @IBOutlet weak var advancedFeaturesButton: DesignableButton! + @IBOutlet weak var connectJamiAcountManagerButton: DesignableButton! + @IBOutlet weak var configureSIPButton: DesignableButton! + + @IBOutlet weak var aboutJamiButton: DesignableButton! + + // MARK: members + private let disposeBag = DisposeBag() + + // MARK: functions + override func viewDidLoad() { + super.viewDidLoad() + self.view.layoutIfNeeded() + self.applyL10n() + if self.viewModel.isAnimatable { + self.initialAnimation() + } else { + self.welcomeTextLabel.alpha = 1 + self.joinJamiButton.alpha = 1 + self.linkAccountButton.alpha = 1 + self.advancedFeaturesButton.alpha = 1 + } + for button in [joinJamiButton, linkAccountButton, importDeviceButton, importBackupButton, advancedFeaturesButton, connectJamiAcountManagerButton, configureSIPButton] { + button?.titleLabel?.ajustToTextSize() + } + self.joinJamiButton.backgroundColor = .jamiButtonDark + self.linkAccountButton.backgroundColor = .jamiButtonDark + + for button in [importDeviceButton, importBackupButton, connectJamiAcountManagerButton, configureSIPButton] { + button?.borderWidth = 1 + button?.borderColor = .jamiButtonDark + button?.backgroundColor = .jamiButtonWithOpacity + button?.setTitleColor(UIColor.jamiButtonDark, for: []) + } + advancedFeaturesButton.setTitleColor(UIColor.jamiButtonDark, for: []) + + // Bind ViewModel to View + self.viewModel.welcomeText.bind(to: self.welcomeTextLabel.rx.text).disposed(by: self.disposeBag) + self.viewModel.createAccount.bind(to: self.joinJamiButton.rx.title(for: .normal)).disposed(by: self.disposeBag) + self.viewModel.linkDevice.bind(to: self.importDeviceButton.rx.title(for: .normal)).disposed(by: self.disposeBag) + configureSIPButton.setTitle(L10n.Account.createSipAccount, for: .normal) + if !self.viewModel.notCancelable { + let cancelButton = UIButton(type: .custom) + cancelButton.setTitleColor(.jamiMain, for: .normal) + cancelButton.titleLabel?.font = UIFont(name: "HelveticaNeue-Light", size: 25) + cancelButton.setTitle(L10n.Global.cancel, for: .normal) + cancelButton.frame = CGRect(x: 0, y: 0, width: 100, height: 40) + let buttonItem = UIBarButtonItem(customView: cancelButton) + cancelButton.rx.tap.throttle(Durations.halfSecond.toTimeInterval(), scheduler: MainScheduler.instance) + .subscribe(onNext: { [weak self] in + self?.viewModel.cancelWalkthrough() + }) + .disposed(by: self.disposeBag) + self.navigationItem.leftBarButtonItem = buttonItem + } + // Bind View Actions to ViewModel + setupButtonActions() + + view.backgroundColor = UIColor.jamiBackgroundColor + self.welcomeTextLabel.textColor = UIColor.jamiLabelColor + NotificationCenter.default.rx + .notification(UIDevice.orientationDidChangeNotification) + .observe(on: MainScheduler.instance) + .subscribe(onNext: { [weak self] (_) in + guard UIDevice.current.portraitOrLandscape else { return } + self?.configureWalkrhroughNavigationBar() + }) + .disposed(by: self.disposeBag) + } + + func applyL10n() { + joinJamiButton.setTitle(L10n.Welcome.createAccount, for: .normal) + linkAccountButton.setTitle(L10n.Welcome.haveAccount, for: .normal) + importDeviceButton.setTitle(L10n.Welcome.linkDevice, for: .normal) + importBackupButton.setTitle(L10n.Welcome.linkBackup, for: .normal) + + advancedFeaturesButton.setTitle(L10n.Account.advancedFeatures, for: .normal) + connectJamiAcountManagerButton.setTitle(L10n.Welcome.connectToManager, for: .normal) + configureSIPButton.setTitle(L10n.Account.createSipAccount, for: .normal) + welcomeTextLabel.text = L10n.Welcome.title + + aboutJamiButton.setTitle(L10n.Smartlist.aboutJami, for: []) + } + + private func aboutJamiButtonDidTap() { + var compileDate: String { + let dateDefault = "" + let dateFormatter = DateFormatter() + dateFormatter.dateFormat = "YYYYMMdd" + let bundleName = Bundle.main.infoDictionary!["CFBundleName"] as? String ?? "Info.plist" + if let infoPath = Bundle.main.path(forResource: bundleName, ofType: nil), + let infoAttr = try? FileManager.default.attributesOfItem(atPath: infoPath), + let infoDate = infoAttr[FileAttributeKey.creationDate] as? Date { + return dateFormatter.string(from: infoDate) + } + return dateDefault + } + + let appVersion = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String ?? "" + + let versionName = "Világfa" + let alert = UIAlertController(title: "\nJami\nversion: \(appVersion)(\(compileDate))\n\(versionName)", message: "", preferredStyle: .alert) + alert.addAction(UIAlertAction(title: L10n.Global.ok, style: .default, handler: nil)) + let image = UIImageView(image: UIImage(asset: Asset.jamiIcon)) + alert.view.addSubview(image) + image.translatesAutoresizingMaskIntoConstraints = false + alert.view.addConstraint(NSLayoutConstraint(item: image, attribute: .centerX, relatedBy: .equal, toItem: alert.view, attribute: .centerX, multiplier: 1, constant: 0)) + alert.view.addConstraint(NSLayoutConstraint(item: image, attribute: .centerY, relatedBy: .equal, toItem: alert.view, attribute: .top, multiplier: 1, constant: 0.0)) + alert.view.addConstraint(NSLayoutConstraint(item: image, attribute: .width, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1.0, constant: 64.0)) + alert.view.addConstraint(NSLayoutConstraint(item: image, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1.0, constant: 64.0)) + self.present(alert, animated: true, completion: nil) + } + + func setupButtonActions() { + self.joinJamiButton.rx.tap + .subscribe(onNext: { [weak self] in + self?.viewModel.proceedWithAccountCreation() + }) + .disposed(by: self.disposeBag) + + self.importDeviceButton.rx.tap + .subscribe(onNext: { [weak self] in + self?.viewModel.proceedWithLinkDevice() + }) + .disposed(by: self.disposeBag) + + self.aboutJamiButton.rx.tap + .subscribe(onNext: { [weak self] in + self?.aboutJamiButtonDidTap() + }) + .disposed(by: self.disposeBag) + + self.linkAccountButton.rx.tap + .subscribe(onNext: { [weak self] in + guard let self else { return } + if self.importDeviceButton.isHidden { + self.importDeviceButton.isHidden = false + self.linkAccountButton.backgroundColor = .jamiButtonLight + } else { + self.importDeviceButton.isHidden = true + self.linkAccountButton.backgroundColor = .jamiButtonDark + } + }) + .disposed(by: self.disposeBag) + + self.advancedFeaturesButton.rx.tap + .subscribe(onNext: { [weak self] in + guard let self else { return } + if self.connectJamiAcountManagerButton.isHidden { + self.connectJamiAcountManagerButton.isHidden = false + self.configureSIPButton.isHidden = false + } else { + self.connectJamiAcountManagerButton.isHidden = true + self.configureSIPButton.isHidden = true + } + }) + .disposed(by: self.disposeBag) + + self.connectJamiAcountManagerButton.rx.tap + .subscribe(onNext: { [weak self] in + self?.viewModel.linkToAccountManager() + }) + .disposed(by: self.disposeBag) + + self.configureSIPButton.rx.tap + .subscribe(onNext: { [weak self] in + self?.viewModel.createSipAccount() + }) + .disposed(by: self.disposeBag) + } + + func initialAnimation() { + DispatchQueue.global(qos: .background).async { + sleep(1) + DispatchQueue.main.async { [weak self] in + UIView.animate(withDuration: 0.5, animations: { + self?.welcomeTextLabel.alpha = 1 + self?.joinJamiButton.alpha = 1 + self?.linkAccountButton.alpha = 1 + self?.advancedFeaturesButton.alpha = 1 + self?.view.layoutIfNeeded() + }) + } + } + } + + override func viewWillAppear(_ animated: Bool) { + super.viewWillAppear(animated) + self.navigationController?.navigationBar.tintColor = UIColor.jamiSecondary + self.navigationItem.backBarButtonItem = UIBarButtonItem(title: "", style: .plain, target: nil, action: nil) + self.navigationController?.navigationBar.setBackgroundImage(UIImage(), for: UIBarMetrics.default) + self.navigationController?.navigationBar.shadowImage = UIImage() + self.navigationController?.navigationBar.isTranslucent = true + self.view.layoutIfNeeded() + } +} diff --git a/Ring/Ring/Helpers/AppInfoHelper.swift b/Ring/Ring/Helpers/AppInfoHelper.swift new file mode 100644 index 0000000000000000000000000000000000000000..a3225a6f2408aa6b09652765bcb7a0603f0b3de2 --- /dev/null +++ b/Ring/Ring/Helpers/AppInfoHelper.swift @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2023 Savoir-faire Linux Inc. + * + * Author: Alireza Toghiani Khorasgani alireza.toghiani@savoirfairelinux.com * + * + * 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +import Foundation + +class AppInfoHelper { + + class func showAboutJamiAlert(onViewController viewController: UIViewController) { + var compileDate: String { + let dateDefault = "" + let dateFormatter = DateFormatter() + dateFormatter.dateFormat = "YYYYMMdd" + let bundleName = Bundle.main.infoDictionary!["CFBundleName"] as? String ?? "Info.plist" + if let infoPath = Bundle.main.path(forResource: bundleName, ofType: nil), + let infoAttr = try? FileManager.default.attributesOfItem(atPath: infoPath), + let infoDate = infoAttr[FileAttributeKey.creationDate] as? Date { + return dateFormatter.string(from: infoDate) + } + return dateDefault + } + + let appVersion = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String ?? "" + + let versionName = "Világfa" + let alert = UIAlertController(title: "\nJami\nversion: \(appVersion)(\(compileDate))\n\(versionName)", message: "", preferredStyle: .alert) + alert.addAction(UIAlertAction(title: L10n.Global.ok, style: .default, handler: nil)) + let image = UIImageView(image: UIImage(asset: Asset.jamiIcon)) + alert.view.addSubview(image) + image.translatesAutoresizingMaskIntoConstraints = false + alert.view.addConstraint(NSLayoutConstraint(item: image, attribute: .centerX, relatedBy: .equal, toItem: alert.view, attribute: .centerX, multiplier: 1, constant: 0)) + alert.view.addConstraint(NSLayoutConstraint(item: image, attribute: .centerY, relatedBy: .equal, toItem: alert.view, attribute: .top, multiplier: 1, constant: 0.0)) + alert.view.addConstraint(NSLayoutConstraint(item: image, attribute: .width, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1.0, constant: 64.0)) + alert.view.addConstraint(NSLayoutConstraint(item: image, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1.0, constant: 64.0)) + viewController.present(alert, animated: true, completion: nil) + } +} diff --git a/Ring/Ring/Resources/Colors.xcassets/Contents.json b/Ring/Ring/Resources/Colors.xcassets/Contents.json new file mode 100644 index 0000000000000000000000000000000000000000..73c00596a7fca3f3d4bdd64053b69d86745f9e10 --- /dev/null +++ b/Ring/Ring/Resources/Colors.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Ring/Ring/Resources/Colors.xcassets/jamiButtonDark.colorset/Contents.json b/Ring/Ring/Resources/Colors.xcassets/jamiButtonDark.colorset/Contents.json new file mode 100644 index 0000000000000000000000000000000000000000..91035b5f7ce6597e84acf9f17a077c4ca5903fed --- /dev/null +++ b/Ring/Ring/Resources/Colors.xcassets/jamiButtonDark.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0.600", + "green" : "0.337", + "red" : "0.000" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0.914", + "green" : "0.725", + "red" : "0.012" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Ring/Ring/Resources/Colors.xcassets/jamiButtonLight.colorset/Contents.json b/Ring/Ring/Resources/Colors.xcassets/jamiButtonLight.colorset/Contents.json new file mode 100644 index 0000000000000000000000000000000000000000..9d46483e93fc776644f1bdf2eeb9e151995ede08 --- /dev/null +++ b/Ring/Ring/Resources/Colors.xcassets/jamiButtonLight.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0.788", + "green" : "0.443", + "red" : "0.000" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0.769", + "green" : "0.612", + "red" : "0.012" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Ring/Ring/Resources/Colors.xcassets/jamiButtonWithOpacity.colorset/Contents.json b/Ring/Ring/Resources/Colors.xcassets/jamiButtonWithOpacity.colorset/Contents.json new file mode 100644 index 0000000000000000000000000000000000000000..273c0cfc52441e9119ca007d8c2209018ebd1d6a --- /dev/null +++ b/Ring/Ring/Resources/Colors.xcassets/jamiButtonWithOpacity.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "0.330", + "blue" : "0.600", + "green" : "0.337", + "red" : "0.000" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "0.330", + "blue" : "0.914", + "green" : "0.725", + "red" : "0.008" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Ring/Ring/Resources/Images.xcassets/background_login.imageset/BG-DarkMode-ID_Jami.png b/Ring/Ring/Resources/Images.xcassets/background_login.imageset/BG-DarkMode-ID_Jami.png new file mode 100644 index 0000000000000000000000000000000000000000..55c13d725f6a57854b89e8e0580e21c1c11c4175 Binary files /dev/null and b/Ring/Ring/Resources/Images.xcassets/background_login.imageset/BG-DarkMode-ID_Jami.png differ diff --git a/Ring/Ring/Resources/Images.xcassets/background_login.imageset/BG-LightMode-ID_Jami.png b/Ring/Ring/Resources/Images.xcassets/background_login.imageset/BG-LightMode-ID_Jami.png new file mode 100644 index 0000000000000000000000000000000000000000..f6bb1d3956f986a065894a47593b5937416e752f Binary files /dev/null and b/Ring/Ring/Resources/Images.xcassets/background_login.imageset/BG-LightMode-ID_Jami.png differ diff --git a/Ring/Ring/Resources/Images.xcassets/background_login.imageset/Contents.json b/Ring/Ring/Resources/Images.xcassets/background_login.imageset/Contents.json new file mode 100644 index 0000000000000000000000000000000000000000..39cae70032cd97eae2003657551275cfd08650c5 --- /dev/null +++ b/Ring/Ring/Resources/Images.xcassets/background_login.imageset/Contents.json @@ -0,0 +1,25 @@ +{ + "images" : [ + { + "filename" : "BG-LightMode-ID_Jami.png", + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "filename" : "BG-DarkMode-ID_Jami.png", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "template-rendering-intent" : "original" + } +} diff --git a/Ring/Ring/Resources/en.lproj/Localizable.strings b/Ring/Ring/Resources/en.lproj/Localizable.strings index 18d253f2e7f3eecc73634e757cc2afed1cdbedeb..d5f3c3682edd96c7ff3f9e661433d7ed3aa89aca 100644 --- a/Ring/Ring/Resources/en.lproj/Localizable.strings +++ b/Ring/Ring/Resources/en.lproj/Localizable.strings @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017-2019 Savoir-faire Linux Inc. + * Copyright (C) 2017-2023 Savoir-faire Linux Inc. * * Author: Silbino Gonçalves Matado <silbino.gmatado@savoirfairelinux.com> * @@ -97,7 +97,7 @@ "conversation.messagePlaceholder" = "Write message to "; "conversation.explanationSendingLocationTo" = "You are currently sharing your location with "; "conversation.explanationReceivingLocationFrom" = "You are currently receiving a live location from "; -"conversation.errorSavingImage" = "Failed to save image to galery"; +"conversation.errorSavingImage" = "Failed to save image to gallery"; "conversation.receivedRequest" = "%@ sent you a request for a conversation."; "conversation.incomingRequest" = "Sent you a request for a conversation."; "conversation.requestMessage" = "Hello,\nWould you like to join the conversation?"; @@ -113,16 +113,18 @@ // Walkthrough //Welcome Screen -"welcome.title" = "Welcome to Jami !"; +"welcome.title" = "Share, freely and privately with Jami"; "welcome.text" = "Jami is a free and universal communication platform which preserves the users' privacy and freedoms"; -"welcome.linkDevice" = "Link this device to an account"; -"welcome.createAccount" = "Create a Jami account"; -"welcome.connectToManager" = "Connect to a JAMS server"; +"welcome.haveAccount" = "I already have an account"; +"welcome.linkDevice" = "Import from another device"; +"welcome.linkBackup" = "Import from archive backup"; +"welcome.createAccount" = "Join Jami"; +"welcome.connectToManager" = "Connect to a Jami Account Manager Server"; //Creation Profile Screen "createProfile.skipCreateProfile" = "Skip"; "createProfile.profileCreated" = "Next"; -"createProfile.title" = "Personalise your profile"; +"createProfile.title" = "Personalize your profile"; "createProfile.enterNameLabel" = "Enter a display name"; "createProfile.enterNamePlaceholder" = "Enter name"; "createProfile.subtitle" = "Your profile will be shared with your contacts. You can change it at any time."; @@ -154,7 +156,7 @@ "linkToAccount.linkButtonTitle" = "Link device"; "linkToAccount.pinPlaceholder" = "PIN"; "linkToAccount.pinLabel" = "Enter PIN"; -"linkToAccount.explanationPinMessage" = "To generate the PIN code, go to the account managment settings on device that contain account you want to use. In devices settings Select \"Link another device to this account\". You will get the necessary PIN to complete this form. The PIN is only valid for 10 minutes."; +"linkToAccount.explanationPinMessage" = "To generate the PIN code, go to the account management settings on device that contain account you want to use. In devices settings Select \"Link another device to this account\". You will get the necessary PIN to complete this form. The PIN is only valid for 10 minutes."; //Link To Account Manager form "linkToAccountManager.signIn" = "Sign In"; @@ -172,7 +174,7 @@ "alerts.profileTakePhoto" = "Take photo"; "alerts.profileUploadPhoto" = "Upload photo"; "alerts.accountLinkedTitle" = "Linking account"; -"alerts.dbFailedTitle" = "An error happned when launching Jami"; +"alerts.dbFailedTitle" = "An error happened when launching Jami"; "alerts.dbFailedMessage" = "Please close application and try to open it again"; "alerts.confirmBlockContact" = "Are you sure you want to block this contact? The conversation history with this contact will also be deleted permanently."; "alerts.confirmDeleteConversation" = "Are you sure you want to delete this conversation permanently?"; @@ -242,7 +244,7 @@ "accountPage.revokeDeviceTitle" = "Revoke device"; "accountPage.revokeDeviceMessage" = "Are you sure you want to revoke this device? This action could not be undone."; "accountPage.revokeDeviceButton" = "Revoke"; -"accountPage.revokeDevicePlaceholder" = "Enter your passord"; +"accountPage.revokeDevicePlaceholder" = "Enter your password"; "accountPage.deviceRevoked" = "Device revocation completed"; "accountPage.deviceRevocationProgress" = "Revoking..."; "accountPage.deviceRevocationSuccess" = "Device was revoked"; @@ -259,7 +261,7 @@ "accountPage.contactMeOnJamiContant" = "Contact me using \"%s\" on the Jami distributed communication platform: https://jami.net"; "accountPage.passwordPlaceholder" = "Enter account password"; "accountPage.usernamePlaceholder" = "Enter desired username"; -"accountPage.registerNameErrorMessage" = "Choosen username is not available"; +"accountPage.registerNameErrorMessage" = "Chosen username is not available"; "accountPage.usernameRegistering" = "Registering"; "accountPage.usernameRegisterAction" = "Register"; "accountPage.usernameRegistrationFailed" = "Registration failed. Please check password."; @@ -271,7 +273,7 @@ "accountPage.changePasswordError" = "Password incorrect"; "accountPage.enableBoothMode" = "Enable Booth Mode"; "accountPage.disableBoothMode" = "Disable Booth Mode"; -"accountPage.disableBoothModeExplanation" = "Pleace provide your account password"; +"accountPage.disableBoothModeExplanation" = "Please provide your account password"; "accountPage.boothModeExplanation" = "In booth mode conversation history not saved and jami functionality limited by making outgoing calls. When you enable booth mode all your conversations will be removed."; "accountPage.noBoothMode" = "To enable Booth mode you need to create account password first."; "accountPage.boothModeAlertMessage" = "After enabling booth mode all your conversations will be removed."; @@ -289,7 +291,8 @@ "account.sipServer" = "SIP Server"; "account.port" = "Port"; "account.proxyServer" = "Proxy"; -"account.createSipAccount" = "Create a SIP Account"; +"account.createSipAccount" = "Configure a SIP Account"; +"account.advancedFeatures" = "Advanced Features"; "account.serverLabel" = "Enter Address"; "account.portLabel" = "Enter Port Number"; "account.accountStatus" = "Account Status"; @@ -308,8 +311,8 @@ //Link New Device "linkDevice.title" = "Link a new device"; "linkDevice.passwordError" = "The password you entered does not unlock this account"; -"linkDevice.networkError" = "A network error occured during the export"; -"linkDevice.defaultError" = "An error occured during the export"; +"linkDevice.networkError" = "A network error occurred during the export"; +"linkDevice.defaultError" = "An error occurred during the export"; "linkDevice.explanationMessage" = "To complete the process, you need to open Jami on the new device and choose the option \"Link this device to an account.\" Your pin is valid for 10 minutes"; "linkDevice.hudMessage" = "Verifying"; @@ -342,7 +345,7 @@ //Generated Message -"generatedMessage.contactAdded" = "You received inviation"; +"generatedMessage.contactAdded" = "You received invitation"; "generatedMessage.swarmCreated" = "Swarm created"; "generatedMessage.invitationReceived" = "was invited to join"; "generatedMessage.invitationAccepted" = "joined the conversation";