diff options
| author | Andrej Mihajlov <and@mullvad.net> | 2019-03-19 15:30:13 +0100 |
|---|---|---|
| committer | Andrej Mihajlov <and@mullvad.net> | 2019-03-27 14:15:53 +0100 |
| commit | 1ec0e389301a11bc18426ce2bf1d81aa28792e97 (patch) | |
| tree | fa55ffdf7475abfc444813e58780724a4fc87dcc | |
| parent | 89b45be8f6159cfb23071c5fd241edb1ff41921c (diff) | |
| download | mullvadvpn-1ec0e389301a11bc18426ce2bf1d81aa28792e97.tar.xz mullvadvpn-1ec0e389301a11bc18426ce2bf1d81aa28792e97.zip | |
Bootstrap iOS app
133 files changed, 2513 insertions, 0 deletions
diff --git a/ios/.gitignore b/ios/.gitignore new file mode 100644 index 0000000000..bc91965ae3 --- /dev/null +++ b/ios/.gitignore @@ -0,0 +1,41 @@ +# Xcode +# +# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore + +## Build generated +build/ +DerivedData/ + +## Various settings +*.pbxuser +!default.pbxuser +*.mode1v3 +!default.mode1v3 +*.mode2v3 +!default.mode2v3 +*.perspectivev3 +!default.perspectivev3 +xcuserdata/ + +## Other +*.moved-aside +*.xccheckout +*.xcscmblueprint + +## Obj-C/Swift specific +*.hmap +*.ipa +*.dSYM.zip +*.dSYM + +## Playgrounds +timeline.xctimeline +playground.xcworkspace + +# Swift Package Manager +# +# Add this line if you want to avoid checking in source code from Swift Package Manager dependencies. +# Packages/ +# Package.pins +# Package.resolved +.build/ diff --git a/ios/AdditionalAssets/DefaultButton.svg b/ios/AdditionalAssets/DefaultButton.svg new file mode 100644 index 0000000000..67727ae05b --- /dev/null +++ b/ios/AdditionalAssets/DefaultButton.svg @@ -0,0 +1,3 @@ +<svg viewBox="0 0 44 44" xmlns="http://www.w3.org/2000/svg"> + <rect x="0" y="0" width="44" height="44" rx="4" ry="4" fill="rgb(41, 77, 115)" /> +</svg> diff --git a/ios/AdditionalAssets/SuccessButton.svg b/ios/AdditionalAssets/SuccessButton.svg new file mode 100644 index 0000000000..3aae17f24d --- /dev/null +++ b/ios/AdditionalAssets/SuccessButton.svg @@ -0,0 +1,3 @@ +<svg viewBox="0 0 44 44" xmlns="http://www.w3.org/2000/svg"> + <rect x="0" y="0" width="44" height="44" rx="4" ry="4" fill="rgb(68, 173, 77)" /> +</svg> diff --git a/ios/AdditionalAssets/TranslucentDangerButton.svg b/ios/AdditionalAssets/TranslucentDangerButton.svg new file mode 100644 index 0000000000..9ad8a9171b --- /dev/null +++ b/ios/AdditionalAssets/TranslucentDangerButton.svg @@ -0,0 +1,3 @@ +<svg viewBox="0 0 44 44" xmlns="http://www.w3.org/2000/svg"> + <rect x="0" y="0" width="44" height="44" rx="4" ry="4" fill="rgba(208, 2, 27, 0.40)" /> +</svg> diff --git a/ios/AdditionalAssets/TranslucentNeutralButton.svg b/ios/AdditionalAssets/TranslucentNeutralButton.svg new file mode 100644 index 0000000000..77d3ae8071 --- /dev/null +++ b/ios/AdditionalAssets/TranslucentNeutralButton.svg @@ -0,0 +1,3 @@ +<svg viewBox="0 0 44 44" xmlns="http://www.w3.org/2000/svg"> + <rect x="0" y="0" width="44" height="44" rx="4" ry="4" fill="rgba(200, 200, 200, 0.3)" /> +</svg> diff --git a/ios/MullvadVPN.xcodeproj/project.pbxproj b/ios/MullvadVPN.xcodeproj/project.pbxproj new file mode 100644 index 0000000000..7b1bf02158 --- /dev/null +++ b/ios/MullvadVPN.xcodeproj/project.pbxproj @@ -0,0 +1,536 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 50; + objects = { + +/* Begin PBXBuildFile section */ + 5862805422428EF100F5A6E1 /* TranslucentButtonBlurView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5862805322428EF100F5A6E1 /* TranslucentButtonBlurView.swift */; }; + 5867A51C2248F26A005513C0 /* SegueIdentifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5867A51B2248F26A005513C0 /* SegueIdentifier.swift */; }; + 58C3A4B222456F1B00340BDB /* AccountInputGroupView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58C3A4B122456F1A00340BDB /* AccountInputGroupView.swift */; }; + 58CCA010224249A1004F3011 /* ConnectViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58CCA00F224249A1004F3011 /* ConnectViewController.swift */; }; + 58CCA01222424D11004F3011 /* SettingsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58CCA01122424D11004F3011 /* SettingsViewController.swift */; }; + 58CCA0162242560B004F3011 /* UIColor+Palette.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58CCA0152242560B004F3011 /* UIColor+Palette.swift */; }; + 58CCA01822426713004F3011 /* AccountViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58CCA01722426713004F3011 /* AccountViewController.swift */; }; + 58CCA01E2242787B004F3011 /* AccountTextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58CCA01D2242787B004F3011 /* AccountTextField.swift */; }; + 58CE5E64224146200008646E /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58CE5E63224146200008646E /* AppDelegate.swift */; }; + 58CE5E66224146200008646E /* LoginViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58CE5E65224146200008646E /* LoginViewController.swift */; }; + 58CE5E69224146200008646E /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 58CE5E67224146200008646E /* Main.storyboard */; }; + 58CE5E6B224146210008646E /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 58CE5E6A224146210008646E /* Assets.xcassets */; }; + 58CE5E6E224146210008646E /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 58CE5E6C224146210008646E /* LaunchScreen.storyboard */; }; + 58CE5E7C224146470008646E /* PacketTunnelProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58CE5E7B224146470008646E /* PacketTunnelProvider.swift */; }; + 58CE5E81224146470008646E /* PacketTunnel.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = 58CE5E79224146470008646E /* PacketTunnel.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; + 58F37E7D2243ECCB00C75C97 /* HeaderBarViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58F37E7C2243ECCB00C75C97 /* HeaderBarViewController.swift */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 58CE5E7F224146470008646E /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 58CE5E58224146200008646E /* Project object */; + proxyType = 1; + remoteGlobalIDString = 58CE5E78224146470008646E; + remoteInfo = PacketTunnel; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 58CE5E85224146470008646E /* Embed App Extensions */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 13; + files = ( + 58CE5E81224146470008646E /* PacketTunnel.appex in Embed App Extensions */, + ); + name = "Embed App Extensions"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 5862805322428EF100F5A6E1 /* TranslucentButtonBlurView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TranslucentButtonBlurView.swift; sourceTree = "<group>"; }; + 5866F39B2243B82D00168AE5 /* MullvadVPN.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = MullvadVPN.entitlements; sourceTree = "<group>"; }; + 5867A51B2248F26A005513C0 /* SegueIdentifier.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SegueIdentifier.swift; sourceTree = "<group>"; }; + 58C3A4B122456F1A00340BDB /* AccountInputGroupView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountInputGroupView.swift; sourceTree = "<group>"; }; + 58CCA00F224249A1004F3011 /* ConnectViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConnectViewController.swift; sourceTree = "<group>"; }; + 58CCA01122424D11004F3011 /* SettingsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsViewController.swift; sourceTree = "<group>"; }; + 58CCA0152242560B004F3011 /* UIColor+Palette.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIColor+Palette.swift"; sourceTree = "<group>"; }; + 58CCA01722426713004F3011 /* AccountViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountViewController.swift; sourceTree = "<group>"; }; + 58CCA01D2242787B004F3011 /* AccountTextField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountTextField.swift; sourceTree = "<group>"; }; + 58CE5E60224146200008646E /* MullvadVPN.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = MullvadVPN.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 58CE5E63224146200008646E /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; }; + 58CE5E65224146200008646E /* LoginViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoginViewController.swift; sourceTree = "<group>"; }; + 58CE5E68224146200008646E /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; }; + 58CE5E6A224146210008646E /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; }; + 58CE5E6D224146210008646E /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; }; + 58CE5E6F224146210008646E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; }; + 58CE5E79224146470008646E /* PacketTunnel.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = PacketTunnel.appex; sourceTree = BUILT_PRODUCTS_DIR; }; + 58CE5E7B224146470008646E /* PacketTunnelProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PacketTunnelProvider.swift; sourceTree = "<group>"; }; + 58CE5E7D224146470008646E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; }; + 58CE5E7E224146470008646E /* PacketTunnel.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = PacketTunnel.entitlements; sourceTree = "<group>"; }; + 58F37E7C2243ECCB00C75C97 /* HeaderBarViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HeaderBarViewController.swift; sourceTree = "<group>"; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 58CE5E5D224146200008646E /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 58CE5E76224146470008646E /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 58CE5E57224146200008646E = { + isa = PBXGroup; + children = ( + 58CE5E62224146200008646E /* MullvadVPN */, + 58CE5E7A224146470008646E /* PacketTunnel */, + 58CE5E61224146200008646E /* Products */, + ); + sourceTree = "<group>"; + }; + 58CE5E61224146200008646E /* Products */ = { + isa = PBXGroup; + children = ( + 58CE5E60224146200008646E /* MullvadVPN.app */, + 58CE5E79224146470008646E /* PacketTunnel.appex */, + ); + name = Products; + sourceTree = "<group>"; + }; + 58CE5E62224146200008646E /* MullvadVPN */ = { + isa = PBXGroup; + children = ( + 58C3A4B122456F1A00340BDB /* AccountInputGroupView.swift */, + 58CCA01D2242787B004F3011 /* AccountTextField.swift */, + 58CCA01722426713004F3011 /* AccountViewController.swift */, + 5862805322428EF100F5A6E1 /* TranslucentButtonBlurView.swift */, + 58CE5E63224146200008646E /* AppDelegate.swift */, + 58CE5E6A224146210008646E /* Assets.xcassets */, + 58CCA00F224249A1004F3011 /* ConnectViewController.swift */, + 58F37E7C2243ECCB00C75C97 /* HeaderBarViewController.swift */, + 58CE5E6F224146210008646E /* Info.plist */, + 58CE5E6C224146210008646E /* LaunchScreen.storyboard */, + 58CE5E65224146200008646E /* LoginViewController.swift */, + 58CE5E67224146200008646E /* Main.storyboard */, + 5866F39B2243B82D00168AE5 /* MullvadVPN.entitlements */, + 58CCA01122424D11004F3011 /* SettingsViewController.swift */, + 58CCA0152242560B004F3011 /* UIColor+Palette.swift */, + 5867A51B2248F26A005513C0 /* SegueIdentifier.swift */, + ); + path = MullvadVPN; + sourceTree = "<group>"; + }; + 58CE5E7A224146470008646E /* PacketTunnel */ = { + isa = PBXGroup; + children = ( + 58CE5E7B224146470008646E /* PacketTunnelProvider.swift */, + 58CE5E7D224146470008646E /* Info.plist */, + 58CE5E7E224146470008646E /* PacketTunnel.entitlements */, + ); + path = PacketTunnel; + sourceTree = "<group>"; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 58CE5E5F224146200008646E /* MullvadVPN */ = { + isa = PBXNativeTarget; + buildConfigurationList = 58CE5E72224146210008646E /* Build configuration list for PBXNativeTarget "MullvadVPN" */; + buildPhases = ( + 58CE5E5C224146200008646E /* Sources */, + 58CE5E5D224146200008646E /* Frameworks */, + 58CE5E5E224146200008646E /* Resources */, + 58CE5E85224146470008646E /* Embed App Extensions */, + ); + buildRules = ( + ); + dependencies = ( + 58CE5E80224146470008646E /* PBXTargetDependency */, + ); + name = MullvadVPN; + productName = MullvadVPN; + productReference = 58CE5E60224146200008646E /* MullvadVPN.app */; + productType = "com.apple.product-type.application"; + }; + 58CE5E78224146470008646E /* PacketTunnel */ = { + isa = PBXNativeTarget; + buildConfigurationList = 58CE5E82224146470008646E /* Build configuration list for PBXNativeTarget "PacketTunnel" */; + buildPhases = ( + 58CE5E75224146470008646E /* Sources */, + 58CE5E76224146470008646E /* Frameworks */, + 58CE5E77224146470008646E /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = PacketTunnel; + productName = PacketTunnel; + productReference = 58CE5E79224146470008646E /* PacketTunnel.appex */; + productType = "com.apple.product-type.app-extension"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 58CE5E58224146200008646E /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 1000; + LastUpgradeCheck = 1000; + ORGANIZATIONNAME = "Amagicom AB"; + TargetAttributes = { + 58CE5E5F224146200008646E = { + CreatedOnToolsVersion = 10.0; + SystemCapabilities = { + com.apple.ApplicationGroups.iOS = { + enabled = 1; + }; + }; + }; + 58CE5E78224146470008646E = { + CreatedOnToolsVersion = 10.0; + }; + }; + }; + buildConfigurationList = 58CE5E5B224146200008646E /* Build configuration list for PBXProject "MullvadVPN" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 58CE5E57224146200008646E; + productRefGroup = 58CE5E61224146200008646E /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 58CE5E5F224146200008646E /* MullvadVPN */, + 58CE5E78224146470008646E /* PacketTunnel */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 58CE5E5E224146200008646E /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 58CE5E6E224146210008646E /* LaunchScreen.storyboard in Resources */, + 58CE5E6B224146210008646E /* Assets.xcassets in Resources */, + 58CE5E69224146200008646E /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 58CE5E77224146470008646E /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 58CE5E5C224146200008646E /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 58CCA010224249A1004F3011 /* ConnectViewController.swift in Sources */, + 58CCA0162242560B004F3011 /* UIColor+Palette.swift in Sources */, + 58CCA01822426713004F3011 /* AccountViewController.swift in Sources */, + 5862805422428EF100F5A6E1 /* TranslucentButtonBlurView.swift in Sources */, + 58CE5E66224146200008646E /* LoginViewController.swift in Sources */, + 58CE5E64224146200008646E /* AppDelegate.swift in Sources */, + 58CCA01222424D11004F3011 /* SettingsViewController.swift in Sources */, + 58F37E7D2243ECCB00C75C97 /* HeaderBarViewController.swift in Sources */, + 5867A51C2248F26A005513C0 /* SegueIdentifier.swift in Sources */, + 58CCA01E2242787B004F3011 /* AccountTextField.swift in Sources */, + 58C3A4B222456F1B00340BDB /* AccountInputGroupView.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 58CE5E75224146470008646E /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 58CE5E7C224146470008646E /* PacketTunnelProvider.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 58CE5E80224146470008646E /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 58CE5E78224146470008646E /* PacketTunnel */; + targetProxy = 58CE5E7F224146470008646E /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin PBXVariantGroup section */ + 58CE5E67224146200008646E /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 58CE5E68224146200008646E /* Base */, + ); + name = Main.storyboard; + sourceTree = "<group>"; + }; + 58CE5E6C224146210008646E /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 58CE5E6D224146210008646E /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = "<group>"; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 58CE5E70224146210008646E /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 10.0; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + 58CE5E71224146210008646E /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 10.0; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 58CE5E73224146210008646E /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_ENTITLEMENTS = MullvadVPN/MullvadVPN.entitlements; + CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = G7CDBEG477; + INFOPLIST_FILE = MullvadVPN/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = net.mullvad.MullvadVPN; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_VERSION = 4.2; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 58CE5E74224146210008646E /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_ENTITLEMENTS = MullvadVPN/MullvadVPN.entitlements; + CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = G7CDBEG477; + INFOPLIST_FILE = MullvadVPN/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = net.mullvad.MullvadVPN; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_VERSION = 4.2; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; + 58CE5E83224146470008646E /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_ENTITLEMENTS = PacketTunnel/PacketTunnel.entitlements; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = G7CDBEG477; + INFOPLIST_FILE = PacketTunnel/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@executable_path/../../Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = net.mullvad.MullvadVPN.PacketTunnel; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + SWIFT_VERSION = 4.2; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 58CE5E84224146470008646E /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_ENTITLEMENTS = PacketTunnel/PacketTunnel.entitlements; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = G7CDBEG477; + INFOPLIST_FILE = PacketTunnel/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@executable_path/../../Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = net.mullvad.MullvadVPN.PacketTunnel; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + SWIFT_VERSION = 4.2; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 58CE5E5B224146200008646E /* Build configuration list for PBXProject "MullvadVPN" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 58CE5E70224146210008646E /* Debug */, + 58CE5E71224146210008646E /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 58CE5E72224146210008646E /* Build configuration list for PBXNativeTarget "MullvadVPN" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 58CE5E73224146210008646E /* Debug */, + 58CE5E74224146210008646E /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 58CE5E82224146470008646E /* Build configuration list for PBXNativeTarget "PacketTunnel" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 58CE5E83224146470008646E /* Debug */, + 58CE5E84224146470008646E /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 58CE5E58224146200008646E /* Project object */; +} diff --git a/ios/MullvadVPN.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/ios/MullvadVPN.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000000..ca6506a98c --- /dev/null +++ b/ios/MullvadVPN.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="UTF-8"?> +<Workspace + version = "1.0"> + <FileRef + location = "self:MullvadVPN.xcodeproj"> + </FileRef> +</Workspace> diff --git a/ios/MullvadVPN.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/ios/MullvadVPN.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000000..18d981003d --- /dev/null +++ b/ios/MullvadVPN.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<plist version="1.0"> +<dict> + <key>IDEDidComputeMac32BitWarning</key> + <true/> +</dict> +</plist> diff --git a/ios/MullvadVPN/AccountInputGroupView.swift b/ios/MullvadVPN/AccountInputGroupView.swift new file mode 100644 index 0000000000..e65443933f --- /dev/null +++ b/ios/MullvadVPN/AccountInputGroupView.swift @@ -0,0 +1,111 @@ +// +// AccountInputGroupView.swift +// MullvadVPN +// +// Created by pronebird on 22/03/2019. +// Copyright © 2019 Amagicom AB. All rights reserved. +// + +import UIKit + +@IBDesignable class AccountInputGroupView: UIView { + + @IBOutlet var textField: UITextField! + + private let borderRadius = CGFloat(8) + private let borderWidth = CGFloat(2) + + private let borderLayer = CAShapeLayer() + private let backgroundLayer = CAShapeLayer() + private let maskLayer = CALayer() + + override init(frame: CGRect) { + super.init(frame: frame) + setup() + } + + required init?(coder aDecoder: NSCoder) { + super.init(coder: aDecoder) + setup() + } + + // MARK: - CALayerDelegate + + override func layoutSublayers(of layer: CALayer) { + super.layoutSublayers(of: layer) + + guard layer == self.layer else { return } + + // extend the border frame outside of the content area + let borderFrame = layer.bounds.insetBy(dx: -borderWidth * 0.5, dy: -borderWidth * 0.5) + + // create a bezier path for border + let borderPath = borderBezierPath(size: borderFrame.size) + + // update the background layer mask + maskLayer.frame.size = borderFrame.size + maskLayer.contents = backgroundMaskImage(borderPath: borderPath).cgImage + + backgroundLayer.frame = borderFrame + + borderLayer.path = borderPath.cgPath + borderLayer.frame = borderFrame + } + + // MARK: - Notifications + + @objc func textDidBeginEditing() { + updateBorderStyle() + } + + @objc func textDidEndEditing() { + updateBorderStyle() + } + + // MARK: - Private + + private func setup() { + backgroundColor = UIColor.clear + + borderLayer.lineWidth = borderWidth + borderLayer.strokeColor = UIColor.clear.cgColor + borderLayer.fillColor = UIColor.clear.cgColor + + backgroundLayer.backgroundColor = UIColor.white.cgColor + backgroundLayer.mask = maskLayer + + layer.insertSublayer(borderLayer, at: 0) + layer.insertSublayer(backgroundLayer, at: 0) + + addTextFieldNotificationObservers() + } + + + private func addTextFieldNotificationObservers() { + NotificationCenter.default.addObserver(self, selector: #selector(textDidBeginEditing), name: UITextField.textDidBeginEditingNotification, object: textField) + NotificationCenter.default.addObserver(self, selector: #selector(textDidEndEditing), name: UITextField.textDidEndEditingNotification, object: textField) + } + + private func updateBorderStyle() { + let borderColor = textField.isEditing ? UIColor.accountTextFieldBorderColor : UIColor.clear + + borderLayer.strokeColor = borderColor.cgColor + } + + private func borderBezierPath(size: CGSize) -> UIBezierPath { + let borderPath = UIBezierPath(roundedRect: CGRect(origin: .zero, size: size), cornerRadius: borderRadius) + borderPath.lineWidth = borderWidth + + return borderPath + } + + private func backgroundMaskImage(borderPath: UIBezierPath) -> UIImage { + let renderer = UIGraphicsImageRenderer(bounds: borderPath.bounds) + return renderer.image { (ctx) in + borderPath.fill() + + // strip out any overlapping pixels between the border and the background + borderPath.stroke(with: .clear, alpha: 0) + } + } +} diff --git a/ios/MullvadVPN/AccountTextField.swift b/ios/MullvadVPN/AccountTextField.swift new file mode 100644 index 0000000000..ebf8f11d54 --- /dev/null +++ b/ios/MullvadVPN/AccountTextField.swift @@ -0,0 +1,34 @@ +// +// AccountTextField.swift +// MullvadVPN +// +// Created by pronebird on 20/03/2019. +// Copyright © 2019 Amagicom AB. All rights reserved. +// + +import UIKit + +@IBDesignable class AccountTextField: UITextField { + + override init(frame: CGRect) { + super.init(frame: frame) + setup() + } + + required init?(coder aDecoder: NSCoder) { + super.init(coder: aDecoder) + setup() + } + + private func setup() { + backgroundColor = UIColor.clear + } + + override func textRect(forBounds bounds: CGRect) -> CGRect { + return bounds.insetBy(dx: 14, dy: 12) + } + + override func editingRect(forBounds bounds: CGRect) -> CGRect { + return textRect(forBounds: bounds) + } +} diff --git a/ios/MullvadVPN/AccountViewController.swift b/ios/MullvadVPN/AccountViewController.swift new file mode 100644 index 0000000000..e9d79a5584 --- /dev/null +++ b/ios/MullvadVPN/AccountViewController.swift @@ -0,0 +1,18 @@ +// +// AccountViewController.swift +// MullvadVPN +// +// Created by pronebird on 20/03/2019. +// Copyright © 2019 Amagicom AB. All rights reserved. +// + +import UIKit + +class AccountViewController: UIViewController { + + override func viewDidLoad() { + super.viewDidLoad() + // Do any additional setup after loading the view, typically from a nib. + } + +} diff --git a/ios/MullvadVPN/AppDelegate.swift b/ios/MullvadVPN/AppDelegate.swift new file mode 100644 index 0000000000..07b96942b9 --- /dev/null +++ b/ios/MullvadVPN/AppDelegate.swift @@ -0,0 +1,46 @@ +// +// AppDelegate.swift +// MullvadVPN +// +// Created by pronebird on 19/03/2019. +// Copyright © 2019 Amagicom AB. All rights reserved. +// + +import UIKit + +@UIApplicationMain +class AppDelegate: UIResponder, UIApplicationDelegate { + + var window: UIWindow? + + + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { + // Override point for customization after application launch. + return true + } + + func applicationWillResignActive(_ application: UIApplication) { + // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. + // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. + } + + func applicationDidEnterBackground(_ application: UIApplication) { + // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. + // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. + } + + func applicationWillEnterForeground(_ application: UIApplication) { + // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. + } + + func applicationDidBecomeActive(_ application: UIApplication) { + // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. + } + + func applicationWillTerminate(_ application: UIApplication) { + // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. + } + + +} + diff --git a/ios/MullvadVPN/Assets.xcassets/AppIcon.appiconset/AppIconPad.png b/ios/MullvadVPN/Assets.xcassets/AppIcon.appiconset/AppIconPad.png Binary files differnew file mode 100644 index 0000000000..3d47d16f74 --- /dev/null +++ b/ios/MullvadVPN/Assets.xcassets/AppIcon.appiconset/AppIconPad.png diff --git a/ios/MullvadVPN/Assets.xcassets/AppIcon.appiconset/AppIconPad@2x.png b/ios/MullvadVPN/Assets.xcassets/AppIcon.appiconset/AppIconPad@2x.png Binary files differnew file mode 100644 index 0000000000..bf9734b497 --- /dev/null +++ b/ios/MullvadVPN/Assets.xcassets/AppIcon.appiconset/AppIconPad@2x.png diff --git a/ios/MullvadVPN/Assets.xcassets/AppIcon.appiconset/AppIconPadNotifications.png b/ios/MullvadVPN/Assets.xcassets/AppIcon.appiconset/AppIconPadNotifications.png Binary files differnew file mode 100644 index 0000000000..2402e7dd15 --- /dev/null +++ b/ios/MullvadVPN/Assets.xcassets/AppIcon.appiconset/AppIconPadNotifications.png diff --git a/ios/MullvadVPN/Assets.xcassets/AppIcon.appiconset/AppIconPadNotifications@2x.png b/ios/MullvadVPN/Assets.xcassets/AppIcon.appiconset/AppIconPadNotifications@2x.png Binary files differnew file mode 100644 index 0000000000..ba28710384 --- /dev/null +++ b/ios/MullvadVPN/Assets.xcassets/AppIcon.appiconset/AppIconPadNotifications@2x.png diff --git a/ios/MullvadVPN/Assets.xcassets/AppIcon.appiconset/AppIconPadPro@2x.png b/ios/MullvadVPN/Assets.xcassets/AppIcon.appiconset/AppIconPadPro@2x.png Binary files differnew file mode 100644 index 0000000000..0562dadc26 --- /dev/null +++ b/ios/MullvadVPN/Assets.xcassets/AppIcon.appiconset/AppIconPadPro@2x.png diff --git a/ios/MullvadVPN/Assets.xcassets/AppIcon.appiconset/AppIconPadSettings.png b/ios/MullvadVPN/Assets.xcassets/AppIcon.appiconset/AppIconPadSettings.png Binary files differnew file mode 100644 index 0000000000..02254f0c54 --- /dev/null +++ b/ios/MullvadVPN/Assets.xcassets/AppIcon.appiconset/AppIconPadSettings.png diff --git a/ios/MullvadVPN/Assets.xcassets/AppIcon.appiconset/AppIconPadSettings@2x.png b/ios/MullvadVPN/Assets.xcassets/AppIcon.appiconset/AppIconPadSettings@2x.png Binary files differnew file mode 100644 index 0000000000..ab11d31088 --- /dev/null +++ b/ios/MullvadVPN/Assets.xcassets/AppIcon.appiconset/AppIconPadSettings@2x.png diff --git a/ios/MullvadVPN/Assets.xcassets/AppIcon.appiconset/AppIconPadSpotlight.png b/ios/MullvadVPN/Assets.xcassets/AppIcon.appiconset/AppIconPadSpotlight.png Binary files differnew file mode 100644 index 0000000000..ba28710384 --- /dev/null +++ b/ios/MullvadVPN/Assets.xcassets/AppIcon.appiconset/AppIconPadSpotlight.png diff --git a/ios/MullvadVPN/Assets.xcassets/AppIcon.appiconset/AppIconPadSpotlight@2x.png b/ios/MullvadVPN/Assets.xcassets/AppIcon.appiconset/AppIconPadSpotlight@2x.png Binary files differnew file mode 100644 index 0000000000..9f02a28b4d --- /dev/null +++ b/ios/MullvadVPN/Assets.xcassets/AppIcon.appiconset/AppIconPadSpotlight@2x.png diff --git a/ios/MullvadVPN/Assets.xcassets/AppIcon.appiconset/AppIconPhone@2x.png b/ios/MullvadVPN/Assets.xcassets/AppIcon.appiconset/AppIconPhone@2x.png Binary files differnew file mode 100644 index 0000000000..bf779d5c20 --- /dev/null +++ b/ios/MullvadVPN/Assets.xcassets/AppIcon.appiconset/AppIconPhone@2x.png diff --git a/ios/MullvadVPN/Assets.xcassets/AppIcon.appiconset/AppIconPhone@3x.png b/ios/MullvadVPN/Assets.xcassets/AppIcon.appiconset/AppIconPhone@3x.png Binary files differnew file mode 100644 index 0000000000..13b50b91cd --- /dev/null +++ b/ios/MullvadVPN/Assets.xcassets/AppIcon.appiconset/AppIconPhone@3x.png diff --git a/ios/MullvadVPN/Assets.xcassets/AppIcon.appiconset/AppIconPhoneNotification@2x.png b/ios/MullvadVPN/Assets.xcassets/AppIcon.appiconset/AppIconPhoneNotification@2x.png Binary files differnew file mode 100644 index 0000000000..ba28710384 --- /dev/null +++ b/ios/MullvadVPN/Assets.xcassets/AppIcon.appiconset/AppIconPhoneNotification@2x.png diff --git a/ios/MullvadVPN/Assets.xcassets/AppIcon.appiconset/AppIconPhoneNotification@3x.png b/ios/MullvadVPN/Assets.xcassets/AppIcon.appiconset/AppIconPhoneNotification@3x.png Binary files differnew file mode 100644 index 0000000000..35f9b9f517 --- /dev/null +++ b/ios/MullvadVPN/Assets.xcassets/AppIcon.appiconset/AppIconPhoneNotification@3x.png diff --git a/ios/MullvadVPN/Assets.xcassets/AppIcon.appiconset/AppIconPhoneSettings@2x.png b/ios/MullvadVPN/Assets.xcassets/AppIcon.appiconset/AppIconPhoneSettings@2x.png Binary files differnew file mode 100644 index 0000000000..ab11d31088 --- /dev/null +++ b/ios/MullvadVPN/Assets.xcassets/AppIcon.appiconset/AppIconPhoneSettings@2x.png diff --git a/ios/MullvadVPN/Assets.xcassets/AppIcon.appiconset/AppIconPhoneSettings@3x.png b/ios/MullvadVPN/Assets.xcassets/AppIcon.appiconset/AppIconPhoneSettings@3x.png Binary files differnew file mode 100644 index 0000000000..09a5531b16 --- /dev/null +++ b/ios/MullvadVPN/Assets.xcassets/AppIcon.appiconset/AppIconPhoneSettings@3x.png diff --git a/ios/MullvadVPN/Assets.xcassets/AppIcon.appiconset/AppIconPhoneSpotlight@2x.png b/ios/MullvadVPN/Assets.xcassets/AppIcon.appiconset/AppIconPhoneSpotlight@2x.png Binary files differnew file mode 100644 index 0000000000..9f02a28b4d --- /dev/null +++ b/ios/MullvadVPN/Assets.xcassets/AppIcon.appiconset/AppIconPhoneSpotlight@2x.png diff --git a/ios/MullvadVPN/Assets.xcassets/AppIcon.appiconset/AppIconPhoneSpotlight@3x.png b/ios/MullvadVPN/Assets.xcassets/AppIcon.appiconset/AppIconPhoneSpotlight@3x.png Binary files differnew file mode 100644 index 0000000000..bf779d5c20 --- /dev/null +++ b/ios/MullvadVPN/Assets.xcassets/AppIcon.appiconset/AppIconPhoneSpotlight@3x.png diff --git a/ios/MullvadVPN/Assets.xcassets/AppIcon.appiconset/AppStoreIosMarketing.png b/ios/MullvadVPN/Assets.xcassets/AppIcon.appiconset/AppStoreIosMarketing.png Binary files differnew file mode 100644 index 0000000000..ed84a9a8a2 --- /dev/null +++ b/ios/MullvadVPN/Assets.xcassets/AppIcon.appiconset/AppStoreIosMarketing.png diff --git a/ios/MullvadVPN/Assets.xcassets/AppIcon.appiconset/Contents.json b/ios/MullvadVPN/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000000..7d5dc9d70b --- /dev/null +++ b/ios/MullvadVPN/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,116 @@ +{ + "images" : [ + { + "size" : "20x20", + "idiom" : "iphone", + "filename" : "AppIconPhoneNotification@2x.png", + "scale" : "2x" + }, + { + "size" : "20x20", + "idiom" : "iphone", + "filename" : "AppIconPhoneNotification@3x.png", + "scale" : "3x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "AppIconPhoneSettings@2x.png", + "scale" : "2x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "AppIconPhoneSettings@3x.png", + "scale" : "3x" + }, + { + "size" : "40x40", + "idiom" : "iphone", + "filename" : "AppIconPhoneSpotlight@2x.png", + "scale" : "2x" + }, + { + "size" : "40x40", + "idiom" : "iphone", + "filename" : "AppIconPhoneSpotlight@3x.png", + "scale" : "3x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "AppIconPhone@2x.png", + "scale" : "2x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "AppIconPhone@3x.png", + "scale" : "3x" + }, + { + "size" : "20x20", + "idiom" : "ipad", + "filename" : "AppIconPadNotifications.png", + "scale" : "1x" + }, + { + "size" : "20x20", + "idiom" : "ipad", + "filename" : "AppIconPadNotifications@2x.png", + "scale" : "2x" + }, + { + "size" : "29x29", + "idiom" : "ipad", + "filename" : "AppIconPadSettings.png", + "scale" : "1x" + }, + { + "size" : "29x29", + "idiom" : "ipad", + "filename" : "AppIconPadSettings@2x.png", + "scale" : "2x" + }, + { + "size" : "40x40", + "idiom" : "ipad", + "filename" : "AppIconPadSpotlight.png", + "scale" : "1x" + }, + { + "size" : "40x40", + "idiom" : "ipad", + "filename" : "AppIconPadSpotlight@2x.png", + "scale" : "2x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "AppIconPad.png", + "scale" : "1x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "AppIconPad@2x.png", + "scale" : "2x" + }, + { + "size" : "83.5x83.5", + "idiom" : "ipad", + "filename" : "AppIconPadPro@2x.png", + "scale" : "2x" + }, + { + "size" : "1024x1024", + "idiom" : "ios-marketing", + "filename" : "AppStoreIosMarketing.png", + "scale" : "1x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +}
\ No newline at end of file diff --git a/ios/MullvadVPN/Assets.xcassets/Contents.json b/ios/MullvadVPN/Assets.xcassets/Contents.json new file mode 100644 index 0000000000..da4a164c91 --- /dev/null +++ b/ios/MullvadVPN/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +}
\ No newline at end of file diff --git a/ios/MullvadVPN/Assets.xcassets/DefaultButton.imageset/Contents.json b/ios/MullvadVPN/Assets.xcassets/DefaultButton.imageset/Contents.json new file mode 100644 index 0000000000..864cb0a750 --- /dev/null +++ b/ios/MullvadVPN/Assets.xcassets/DefaultButton.imageset/Contents.json @@ -0,0 +1,26 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "DefaultButton.pdf", + "resizing" : { + "mode" : "9-part", + "center" : { + "mode" : "tile", + "width" : 1, + "height" : 1 + }, + "cap-insets" : { + "bottom" : 4, + "top" : 4, + "right" : 4, + "left" : 4 + } + } + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +}
\ No newline at end of file diff --git a/ios/MullvadVPN/Assets.xcassets/DefaultButton.imageset/DefaultButton.pdf b/ios/MullvadVPN/Assets.xcassets/DefaultButton.imageset/DefaultButton.pdf Binary files differnew file mode 100644 index 0000000000..ab05d02bb7 --- /dev/null +++ b/ios/MullvadVPN/Assets.xcassets/DefaultButton.imageset/DefaultButton.pdf diff --git a/ios/MullvadVPN/Assets.xcassets/IconAlert.imageset/Contents.json b/ios/MullvadVPN/Assets.xcassets/IconAlert.imageset/Contents.json new file mode 100644 index 0000000000..9ec05af935 --- /dev/null +++ b/ios/MullvadVPN/Assets.xcassets/IconAlert.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "IconAlert.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "IconAlert@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "IconAlert@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +}
\ No newline at end of file diff --git a/ios/MullvadVPN/Assets.xcassets/IconAlert.imageset/IconAlert.png b/ios/MullvadVPN/Assets.xcassets/IconAlert.imageset/IconAlert.png Binary files differnew file mode 100644 index 0000000000..2e7f89f7e8 --- /dev/null +++ b/ios/MullvadVPN/Assets.xcassets/IconAlert.imageset/IconAlert.png diff --git a/ios/MullvadVPN/Assets.xcassets/IconAlert.imageset/IconAlert@2x.png b/ios/MullvadVPN/Assets.xcassets/IconAlert.imageset/IconAlert@2x.png Binary files differnew file mode 100644 index 0000000000..7e3b808250 --- /dev/null +++ b/ios/MullvadVPN/Assets.xcassets/IconAlert.imageset/IconAlert@2x.png diff --git a/ios/MullvadVPN/Assets.xcassets/IconAlert.imageset/IconAlert@3x.png b/ios/MullvadVPN/Assets.xcassets/IconAlert.imageset/IconAlert@3x.png Binary files differnew file mode 100644 index 0000000000..1e5a99a4c2 --- /dev/null +++ b/ios/MullvadVPN/Assets.xcassets/IconAlert.imageset/IconAlert@3x.png diff --git a/ios/MullvadVPN/Assets.xcassets/IconArrow.imageset/Contents.json b/ios/MullvadVPN/Assets.xcassets/IconArrow.imageset/Contents.json new file mode 100644 index 0000000000..094776d80f --- /dev/null +++ b/ios/MullvadVPN/Assets.xcassets/IconArrow.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "IconArrow.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "IconArrow@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "IconArrow@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +}
\ No newline at end of file diff --git a/ios/MullvadVPN/Assets.xcassets/IconArrow.imageset/IconArrow.png b/ios/MullvadVPN/Assets.xcassets/IconArrow.imageset/IconArrow.png Binary files differnew file mode 100644 index 0000000000..051f9c7d8d --- /dev/null +++ b/ios/MullvadVPN/Assets.xcassets/IconArrow.imageset/IconArrow.png diff --git a/ios/MullvadVPN/Assets.xcassets/IconArrow.imageset/IconArrow@2x.png b/ios/MullvadVPN/Assets.xcassets/IconArrow.imageset/IconArrow@2x.png Binary files differnew file mode 100644 index 0000000000..277a1ab36e --- /dev/null +++ b/ios/MullvadVPN/Assets.xcassets/IconArrow.imageset/IconArrow@2x.png diff --git a/ios/MullvadVPN/Assets.xcassets/IconArrow.imageset/IconArrow@3x.png b/ios/MullvadVPN/Assets.xcassets/IconArrow.imageset/IconArrow@3x.png Binary files differnew file mode 100644 index 0000000000..3b2ba8e32f --- /dev/null +++ b/ios/MullvadVPN/Assets.xcassets/IconArrow.imageset/IconArrow@3x.png diff --git a/ios/MullvadVPN/Assets.xcassets/IconBack.imageset/Contents.json b/ios/MullvadVPN/Assets.xcassets/IconBack.imageset/Contents.json new file mode 100644 index 0000000000..7eaaad29b4 --- /dev/null +++ b/ios/MullvadVPN/Assets.xcassets/IconBack.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "IconBack.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "IconBack@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "IconBack@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +}
\ No newline at end of file diff --git a/ios/MullvadVPN/Assets.xcassets/IconBack.imageset/IconBack.png b/ios/MullvadVPN/Assets.xcassets/IconBack.imageset/IconBack.png Binary files differnew file mode 100644 index 0000000000..82197cc9d5 --- /dev/null +++ b/ios/MullvadVPN/Assets.xcassets/IconBack.imageset/IconBack.png diff --git a/ios/MullvadVPN/Assets.xcassets/IconBack.imageset/IconBack@2x.png b/ios/MullvadVPN/Assets.xcassets/IconBack.imageset/IconBack@2x.png Binary files differnew file mode 100644 index 0000000000..caac853142 --- /dev/null +++ b/ios/MullvadVPN/Assets.xcassets/IconBack.imageset/IconBack@2x.png diff --git a/ios/MullvadVPN/Assets.xcassets/IconBack.imageset/IconBack@3x.png b/ios/MullvadVPN/Assets.xcassets/IconBack.imageset/IconBack@3x.png Binary files differnew file mode 100644 index 0000000000..0938917563 --- /dev/null +++ b/ios/MullvadVPN/Assets.xcassets/IconBack.imageset/IconBack@3x.png diff --git a/ios/MullvadVPN/Assets.xcassets/IconChevron.imageset/Contents.json b/ios/MullvadVPN/Assets.xcassets/IconChevron.imageset/Contents.json new file mode 100644 index 0000000000..23a2f2387b --- /dev/null +++ b/ios/MullvadVPN/Assets.xcassets/IconChevron.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "IconChevron.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "IconChevron@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "IconChevron@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +}
\ No newline at end of file diff --git a/ios/MullvadVPN/Assets.xcassets/IconChevron.imageset/IconChevron.png b/ios/MullvadVPN/Assets.xcassets/IconChevron.imageset/IconChevron.png Binary files differnew file mode 100644 index 0000000000..9a2d764f26 --- /dev/null +++ b/ios/MullvadVPN/Assets.xcassets/IconChevron.imageset/IconChevron.png diff --git a/ios/MullvadVPN/Assets.xcassets/IconChevron.imageset/IconChevron@2x.png b/ios/MullvadVPN/Assets.xcassets/IconChevron.imageset/IconChevron@2x.png Binary files differnew file mode 100644 index 0000000000..82c524b419 --- /dev/null +++ b/ios/MullvadVPN/Assets.xcassets/IconChevron.imageset/IconChevron@2x.png diff --git a/ios/MullvadVPN/Assets.xcassets/IconChevron.imageset/IconChevron@3x.png b/ios/MullvadVPN/Assets.xcassets/IconChevron.imageset/IconChevron@3x.png Binary files differnew file mode 100644 index 0000000000..7cbfa8304f --- /dev/null +++ b/ios/MullvadVPN/Assets.xcassets/IconChevron.imageset/IconChevron@3x.png diff --git a/ios/MullvadVPN/Assets.xcassets/IconChevronDown.imageset/Contents.json b/ios/MullvadVPN/Assets.xcassets/IconChevronDown.imageset/Contents.json new file mode 100644 index 0000000000..c2c508144c --- /dev/null +++ b/ios/MullvadVPN/Assets.xcassets/IconChevronDown.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "IconChevronDown.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "IconChevronDown@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "IconChevronDown@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +}
\ No newline at end of file diff --git a/ios/MullvadVPN/Assets.xcassets/IconChevronDown.imageset/IconChevronDown.png b/ios/MullvadVPN/Assets.xcassets/IconChevronDown.imageset/IconChevronDown.png Binary files differnew file mode 100644 index 0000000000..82a19f7740 --- /dev/null +++ b/ios/MullvadVPN/Assets.xcassets/IconChevronDown.imageset/IconChevronDown.png diff --git a/ios/MullvadVPN/Assets.xcassets/IconChevronDown.imageset/IconChevronDown@2x.png b/ios/MullvadVPN/Assets.xcassets/IconChevronDown.imageset/IconChevronDown@2x.png Binary files differnew file mode 100644 index 0000000000..a26570821b --- /dev/null +++ b/ios/MullvadVPN/Assets.xcassets/IconChevronDown.imageset/IconChevronDown@2x.png diff --git a/ios/MullvadVPN/Assets.xcassets/IconChevronDown.imageset/IconChevronDown@3x.png b/ios/MullvadVPN/Assets.xcassets/IconChevronDown.imageset/IconChevronDown@3x.png Binary files differnew file mode 100644 index 0000000000..6bf3cfcbed --- /dev/null +++ b/ios/MullvadVPN/Assets.xcassets/IconChevronDown.imageset/IconChevronDown@3x.png diff --git a/ios/MullvadVPN/Assets.xcassets/IconChevronUp.imageset/Contents.json b/ios/MullvadVPN/Assets.xcassets/IconChevronUp.imageset/Contents.json new file mode 100644 index 0000000000..68781197d1 --- /dev/null +++ b/ios/MullvadVPN/Assets.xcassets/IconChevronUp.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "IconChevronUp.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "IconChevronUp@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "IconChevronUp@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +}
\ No newline at end of file diff --git a/ios/MullvadVPN/Assets.xcassets/IconChevronUp.imageset/IconChevronUp.png b/ios/MullvadVPN/Assets.xcassets/IconChevronUp.imageset/IconChevronUp.png Binary files differnew file mode 100644 index 0000000000..a0e5f6caae --- /dev/null +++ b/ios/MullvadVPN/Assets.xcassets/IconChevronUp.imageset/IconChevronUp.png diff --git a/ios/MullvadVPN/Assets.xcassets/IconChevronUp.imageset/IconChevronUp@2x.png b/ios/MullvadVPN/Assets.xcassets/IconChevronUp.imageset/IconChevronUp@2x.png Binary files differnew file mode 100644 index 0000000000..efcd4d7232 --- /dev/null +++ b/ios/MullvadVPN/Assets.xcassets/IconChevronUp.imageset/IconChevronUp@2x.png diff --git a/ios/MullvadVPN/Assets.xcassets/IconChevronUp.imageset/IconChevronUp@3x.png b/ios/MullvadVPN/Assets.xcassets/IconChevronUp.imageset/IconChevronUp@3x.png Binary files differnew file mode 100644 index 0000000000..1fa11f16a4 --- /dev/null +++ b/ios/MullvadVPN/Assets.xcassets/IconChevronUp.imageset/IconChevronUp@3x.png diff --git a/ios/MullvadVPN/Assets.xcassets/IconClose.imageset/Contents.json b/ios/MullvadVPN/Assets.xcassets/IconClose.imageset/Contents.json new file mode 100644 index 0000000000..483e927f99 --- /dev/null +++ b/ios/MullvadVPN/Assets.xcassets/IconClose.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "IconClose.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "IconClose@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "IconClose@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +}
\ No newline at end of file diff --git a/ios/MullvadVPN/Assets.xcassets/IconClose.imageset/IconClose.png b/ios/MullvadVPN/Assets.xcassets/IconClose.imageset/IconClose.png Binary files differnew file mode 100644 index 0000000000..9e4162b5f6 --- /dev/null +++ b/ios/MullvadVPN/Assets.xcassets/IconClose.imageset/IconClose.png diff --git a/ios/MullvadVPN/Assets.xcassets/IconClose.imageset/IconClose@2x.png b/ios/MullvadVPN/Assets.xcassets/IconClose.imageset/IconClose@2x.png Binary files differnew file mode 100644 index 0000000000..f51727f570 --- /dev/null +++ b/ios/MullvadVPN/Assets.xcassets/IconClose.imageset/IconClose@2x.png diff --git a/ios/MullvadVPN/Assets.xcassets/IconClose.imageset/IconClose@3x.png b/ios/MullvadVPN/Assets.xcassets/IconClose.imageset/IconClose@3x.png Binary files differnew file mode 100644 index 0000000000..9c8e18f244 --- /dev/null +++ b/ios/MullvadVPN/Assets.xcassets/IconClose.imageset/IconClose@3x.png diff --git a/ios/MullvadVPN/Assets.xcassets/IconCloseSml.imageset/Contents.json b/ios/MullvadVPN/Assets.xcassets/IconCloseSml.imageset/Contents.json new file mode 100644 index 0000000000..83221941d2 --- /dev/null +++ b/ios/MullvadVPN/Assets.xcassets/IconCloseSml.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "IconCloseSml.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "IconCloseSml@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "IconCloseSml@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +}
\ No newline at end of file diff --git a/ios/MullvadVPN/Assets.xcassets/IconCloseSml.imageset/IconCloseSml.png b/ios/MullvadVPN/Assets.xcassets/IconCloseSml.imageset/IconCloseSml.png Binary files differnew file mode 100644 index 0000000000..21d229beb6 --- /dev/null +++ b/ios/MullvadVPN/Assets.xcassets/IconCloseSml.imageset/IconCloseSml.png diff --git a/ios/MullvadVPN/Assets.xcassets/IconCloseSml.imageset/IconCloseSml@2x.png b/ios/MullvadVPN/Assets.xcassets/IconCloseSml.imageset/IconCloseSml@2x.png Binary files differnew file mode 100644 index 0000000000..7fb6cc7cb6 --- /dev/null +++ b/ios/MullvadVPN/Assets.xcassets/IconCloseSml.imageset/IconCloseSml@2x.png diff --git a/ios/MullvadVPN/Assets.xcassets/IconCloseSml.imageset/IconCloseSml@3x.png b/ios/MullvadVPN/Assets.xcassets/IconCloseSml.imageset/IconCloseSml@3x.png Binary files differnew file mode 100644 index 0000000000..1b3ef67a7e --- /dev/null +++ b/ios/MullvadVPN/Assets.xcassets/IconCloseSml.imageset/IconCloseSml@3x.png diff --git a/ios/MullvadVPN/Assets.xcassets/IconExtlink.imageset/Contents.json b/ios/MullvadVPN/Assets.xcassets/IconExtlink.imageset/Contents.json new file mode 100644 index 0000000000..e1f118207d --- /dev/null +++ b/ios/MullvadVPN/Assets.xcassets/IconExtlink.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "IconExtlink.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "IconExtlink@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "IconExtlink@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +}
\ No newline at end of file diff --git a/ios/MullvadVPN/Assets.xcassets/IconExtlink.imageset/IconExtlink.png b/ios/MullvadVPN/Assets.xcassets/IconExtlink.imageset/IconExtlink.png Binary files differnew file mode 100644 index 0000000000..19c0777787 --- /dev/null +++ b/ios/MullvadVPN/Assets.xcassets/IconExtlink.imageset/IconExtlink.png diff --git a/ios/MullvadVPN/Assets.xcassets/IconExtlink.imageset/IconExtlink@2x.png b/ios/MullvadVPN/Assets.xcassets/IconExtlink.imageset/IconExtlink@2x.png Binary files differnew file mode 100644 index 0000000000..d34e3f9349 --- /dev/null +++ b/ios/MullvadVPN/Assets.xcassets/IconExtlink.imageset/IconExtlink@2x.png diff --git a/ios/MullvadVPN/Assets.xcassets/IconExtlink.imageset/IconExtlink@3x.png b/ios/MullvadVPN/Assets.xcassets/IconExtlink.imageset/IconExtlink@3x.png Binary files differnew file mode 100644 index 0000000000..6c552a8dd6 --- /dev/null +++ b/ios/MullvadVPN/Assets.xcassets/IconExtlink.imageset/IconExtlink@3x.png diff --git a/ios/MullvadVPN/Assets.xcassets/IconFail.imageset/Contents.json b/ios/MullvadVPN/Assets.xcassets/IconFail.imageset/Contents.json new file mode 100644 index 0000000000..1f51a9467e --- /dev/null +++ b/ios/MullvadVPN/Assets.xcassets/IconFail.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "IconFail.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "IconFail@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "IconFail@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +}
\ No newline at end of file diff --git a/ios/MullvadVPN/Assets.xcassets/IconFail.imageset/IconFail.png b/ios/MullvadVPN/Assets.xcassets/IconFail.imageset/IconFail.png Binary files differnew file mode 100644 index 0000000000..5220441ee5 --- /dev/null +++ b/ios/MullvadVPN/Assets.xcassets/IconFail.imageset/IconFail.png diff --git a/ios/MullvadVPN/Assets.xcassets/IconFail.imageset/IconFail@2x.png b/ios/MullvadVPN/Assets.xcassets/IconFail.imageset/IconFail@2x.png Binary files differnew file mode 100644 index 0000000000..811fc85dcf --- /dev/null +++ b/ios/MullvadVPN/Assets.xcassets/IconFail.imageset/IconFail@2x.png diff --git a/ios/MullvadVPN/Assets.xcassets/IconFail.imageset/IconFail@3x.png b/ios/MullvadVPN/Assets.xcassets/IconFail.imageset/IconFail@3x.png Binary files differnew file mode 100644 index 0000000000..428e7ea542 --- /dev/null +++ b/ios/MullvadVPN/Assets.xcassets/IconFail.imageset/IconFail@3x.png diff --git a/ios/MullvadVPN/Assets.xcassets/IconFastest.imageset/Contents.json b/ios/MullvadVPN/Assets.xcassets/IconFastest.imageset/Contents.json new file mode 100644 index 0000000000..65c53b777e --- /dev/null +++ b/ios/MullvadVPN/Assets.xcassets/IconFastest.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "IconFastest.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "IconFastest@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "IconFastest@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +}
\ No newline at end of file diff --git a/ios/MullvadVPN/Assets.xcassets/IconFastest.imageset/IconFastest.png b/ios/MullvadVPN/Assets.xcassets/IconFastest.imageset/IconFastest.png Binary files differnew file mode 100644 index 0000000000..435d9e3da3 --- /dev/null +++ b/ios/MullvadVPN/Assets.xcassets/IconFastest.imageset/IconFastest.png diff --git a/ios/MullvadVPN/Assets.xcassets/IconFastest.imageset/IconFastest@2x.png b/ios/MullvadVPN/Assets.xcassets/IconFastest.imageset/IconFastest@2x.png Binary files differnew file mode 100644 index 0000000000..d6099c087d --- /dev/null +++ b/ios/MullvadVPN/Assets.xcassets/IconFastest.imageset/IconFastest@2x.png diff --git a/ios/MullvadVPN/Assets.xcassets/IconFastest.imageset/IconFastest@3x.png b/ios/MullvadVPN/Assets.xcassets/IconFastest.imageset/IconFastest@3x.png Binary files differnew file mode 100644 index 0000000000..e8a372a929 --- /dev/null +++ b/ios/MullvadVPN/Assets.xcassets/IconFastest.imageset/IconFastest@3x.png diff --git a/ios/MullvadVPN/Assets.xcassets/IconNearest.imageset/Contents.json b/ios/MullvadVPN/Assets.xcassets/IconNearest.imageset/Contents.json new file mode 100644 index 0000000000..e16c1d4e59 --- /dev/null +++ b/ios/MullvadVPN/Assets.xcassets/IconNearest.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "IconNearest.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "IconNearest@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "IconNearest@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +}
\ No newline at end of file diff --git a/ios/MullvadVPN/Assets.xcassets/IconNearest.imageset/IconNearest.png b/ios/MullvadVPN/Assets.xcassets/IconNearest.imageset/IconNearest.png Binary files differnew file mode 100644 index 0000000000..21bf1912e9 --- /dev/null +++ b/ios/MullvadVPN/Assets.xcassets/IconNearest.imageset/IconNearest.png diff --git a/ios/MullvadVPN/Assets.xcassets/IconNearest.imageset/IconNearest@2x.png b/ios/MullvadVPN/Assets.xcassets/IconNearest.imageset/IconNearest@2x.png Binary files differnew file mode 100644 index 0000000000..612085d214 --- /dev/null +++ b/ios/MullvadVPN/Assets.xcassets/IconNearest.imageset/IconNearest@2x.png diff --git a/ios/MullvadVPN/Assets.xcassets/IconNearest.imageset/IconNearest@3x.png b/ios/MullvadVPN/Assets.xcassets/IconNearest.imageset/IconNearest@3x.png Binary files differnew file mode 100644 index 0000000000..7882424be9 --- /dev/null +++ b/ios/MullvadVPN/Assets.xcassets/IconNearest.imageset/IconNearest@3x.png diff --git a/ios/MullvadVPN/Assets.xcassets/IconSettings.imageset/Contents.json b/ios/MullvadVPN/Assets.xcassets/IconSettings.imageset/Contents.json new file mode 100644 index 0000000000..e7c51be6ee --- /dev/null +++ b/ios/MullvadVPN/Assets.xcassets/IconSettings.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "IconSettings.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "IconSettings@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "IconSettings@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +}
\ No newline at end of file diff --git a/ios/MullvadVPN/Assets.xcassets/IconSettings.imageset/IconSettings.png b/ios/MullvadVPN/Assets.xcassets/IconSettings.imageset/IconSettings.png Binary files differnew file mode 100644 index 0000000000..04036aee49 --- /dev/null +++ b/ios/MullvadVPN/Assets.xcassets/IconSettings.imageset/IconSettings.png diff --git a/ios/MullvadVPN/Assets.xcassets/IconSettings.imageset/IconSettings@2x.png b/ios/MullvadVPN/Assets.xcassets/IconSettings.imageset/IconSettings@2x.png Binary files differnew file mode 100644 index 0000000000..82e21d1735 --- /dev/null +++ b/ios/MullvadVPN/Assets.xcassets/IconSettings.imageset/IconSettings@2x.png diff --git a/ios/MullvadVPN/Assets.xcassets/IconSettings.imageset/IconSettings@3x.png b/ios/MullvadVPN/Assets.xcassets/IconSettings.imageset/IconSettings@3x.png Binary files differnew file mode 100644 index 0000000000..6c938e39a9 --- /dev/null +++ b/ios/MullvadVPN/Assets.xcassets/IconSettings.imageset/IconSettings@3x.png diff --git a/ios/MullvadVPN/Assets.xcassets/IconSpinner.imageset/Contents.json b/ios/MullvadVPN/Assets.xcassets/IconSpinner.imageset/Contents.json new file mode 100644 index 0000000000..363748ee3c --- /dev/null +++ b/ios/MullvadVPN/Assets.xcassets/IconSpinner.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "IconSpinner.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "IconSpinner@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "IconSpinner@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +}
\ No newline at end of file diff --git a/ios/MullvadVPN/Assets.xcassets/IconSpinner.imageset/IconSpinner.png b/ios/MullvadVPN/Assets.xcassets/IconSpinner.imageset/IconSpinner.png Binary files differnew file mode 100644 index 0000000000..2faa618718 --- /dev/null +++ b/ios/MullvadVPN/Assets.xcassets/IconSpinner.imageset/IconSpinner.png diff --git a/ios/MullvadVPN/Assets.xcassets/IconSpinner.imageset/IconSpinner@2x.png b/ios/MullvadVPN/Assets.xcassets/IconSpinner.imageset/IconSpinner@2x.png Binary files differnew file mode 100644 index 0000000000..ebdcd693cc --- /dev/null +++ b/ios/MullvadVPN/Assets.xcassets/IconSpinner.imageset/IconSpinner@2x.png diff --git a/ios/MullvadVPN/Assets.xcassets/IconSpinner.imageset/IconSpinner@3x.png b/ios/MullvadVPN/Assets.xcassets/IconSpinner.imageset/IconSpinner@3x.png Binary files differnew file mode 100644 index 0000000000..9f53def221 --- /dev/null +++ b/ios/MullvadVPN/Assets.xcassets/IconSpinner.imageset/IconSpinner@3x.png diff --git a/ios/MullvadVPN/Assets.xcassets/IconSuccess.imageset/Contents.json b/ios/MullvadVPN/Assets.xcassets/IconSuccess.imageset/Contents.json new file mode 100644 index 0000000000..d75e7e0c18 --- /dev/null +++ b/ios/MullvadVPN/Assets.xcassets/IconSuccess.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "IconSuccess.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "IconSuccess@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "IconSuccess@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +}
\ No newline at end of file diff --git a/ios/MullvadVPN/Assets.xcassets/IconSuccess.imageset/IconSuccess.png b/ios/MullvadVPN/Assets.xcassets/IconSuccess.imageset/IconSuccess.png Binary files differnew file mode 100644 index 0000000000..d90b8e3240 --- /dev/null +++ b/ios/MullvadVPN/Assets.xcassets/IconSuccess.imageset/IconSuccess.png diff --git a/ios/MullvadVPN/Assets.xcassets/IconSuccess.imageset/IconSuccess@2x.png b/ios/MullvadVPN/Assets.xcassets/IconSuccess.imageset/IconSuccess@2x.png Binary files differnew file mode 100644 index 0000000000..6cc39be253 --- /dev/null +++ b/ios/MullvadVPN/Assets.xcassets/IconSuccess.imageset/IconSuccess@2x.png diff --git a/ios/MullvadVPN/Assets.xcassets/IconSuccess.imageset/IconSuccess@3x.png b/ios/MullvadVPN/Assets.xcassets/IconSuccess.imageset/IconSuccess@3x.png Binary files differnew file mode 100644 index 0000000000..e622078494 --- /dev/null +++ b/ios/MullvadVPN/Assets.xcassets/IconSuccess.imageset/IconSuccess@3x.png diff --git a/ios/MullvadVPN/Assets.xcassets/IconTick.imageset/Contents.json b/ios/MullvadVPN/Assets.xcassets/IconTick.imageset/Contents.json new file mode 100644 index 0000000000..667331c0ca --- /dev/null +++ b/ios/MullvadVPN/Assets.xcassets/IconTick.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "IconTick.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "IconTick@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "IconTick@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +}
\ No newline at end of file diff --git a/ios/MullvadVPN/Assets.xcassets/IconTick.imageset/IconTick.png b/ios/MullvadVPN/Assets.xcassets/IconTick.imageset/IconTick.png Binary files differnew file mode 100644 index 0000000000..d090b1837f --- /dev/null +++ b/ios/MullvadVPN/Assets.xcassets/IconTick.imageset/IconTick.png diff --git a/ios/MullvadVPN/Assets.xcassets/IconTick.imageset/IconTick@2x.png b/ios/MullvadVPN/Assets.xcassets/IconTick.imageset/IconTick@2x.png Binary files differnew file mode 100644 index 0000000000..3f8df67842 --- /dev/null +++ b/ios/MullvadVPN/Assets.xcassets/IconTick.imageset/IconTick@2x.png diff --git a/ios/MullvadVPN/Assets.xcassets/IconTick.imageset/IconTick@3x.png b/ios/MullvadVPN/Assets.xcassets/IconTick.imageset/IconTick@3x.png Binary files differnew file mode 100644 index 0000000000..5c3f2a9195 --- /dev/null +++ b/ios/MullvadVPN/Assets.xcassets/IconTick.imageset/IconTick@3x.png diff --git a/ios/MullvadVPN/Assets.xcassets/LocationMarkerSecure.imageset/Contents.json b/ios/MullvadVPN/Assets.xcassets/LocationMarkerSecure.imageset/Contents.json new file mode 100644 index 0000000000..aac19236ab --- /dev/null +++ b/ios/MullvadVPN/Assets.xcassets/LocationMarkerSecure.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "LocationMarkerSecure.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "LocationMarkerSecure@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "LocationMarkerSecure@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +}
\ No newline at end of file diff --git a/ios/MullvadVPN/Assets.xcassets/LocationMarkerSecure.imageset/LocationMarkerSecure.png b/ios/MullvadVPN/Assets.xcassets/LocationMarkerSecure.imageset/LocationMarkerSecure.png Binary files differnew file mode 100644 index 0000000000..08f8601c35 --- /dev/null +++ b/ios/MullvadVPN/Assets.xcassets/LocationMarkerSecure.imageset/LocationMarkerSecure.png diff --git a/ios/MullvadVPN/Assets.xcassets/LocationMarkerSecure.imageset/LocationMarkerSecure@2x.png b/ios/MullvadVPN/Assets.xcassets/LocationMarkerSecure.imageset/LocationMarkerSecure@2x.png Binary files differnew file mode 100644 index 0000000000..df7bfeb4e6 --- /dev/null +++ b/ios/MullvadVPN/Assets.xcassets/LocationMarkerSecure.imageset/LocationMarkerSecure@2x.png diff --git a/ios/MullvadVPN/Assets.xcassets/LocationMarkerSecure.imageset/LocationMarkerSecure@3x.png b/ios/MullvadVPN/Assets.xcassets/LocationMarkerSecure.imageset/LocationMarkerSecure@3x.png Binary files differnew file mode 100644 index 0000000000..6c0bd519bd --- /dev/null +++ b/ios/MullvadVPN/Assets.xcassets/LocationMarkerSecure.imageset/LocationMarkerSecure@3x.png diff --git a/ios/MullvadVPN/Assets.xcassets/LocationMarkerUnsecure.imageset/Contents.json b/ios/MullvadVPN/Assets.xcassets/LocationMarkerUnsecure.imageset/Contents.json new file mode 100644 index 0000000000..e1548e8632 --- /dev/null +++ b/ios/MullvadVPN/Assets.xcassets/LocationMarkerUnsecure.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "LocationMarkerUnsecure.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "LocationMarkerUnsecure@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "LocationMarkerUnsecure@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +}
\ No newline at end of file diff --git a/ios/MullvadVPN/Assets.xcassets/LocationMarkerUnsecure.imageset/LocationMarkerUnsecure.png b/ios/MullvadVPN/Assets.xcassets/LocationMarkerUnsecure.imageset/LocationMarkerUnsecure.png Binary files differnew file mode 100644 index 0000000000..109b5ede07 --- /dev/null +++ b/ios/MullvadVPN/Assets.xcassets/LocationMarkerUnsecure.imageset/LocationMarkerUnsecure.png diff --git a/ios/MullvadVPN/Assets.xcassets/LocationMarkerUnsecure.imageset/LocationMarkerUnsecure@2x.png b/ios/MullvadVPN/Assets.xcassets/LocationMarkerUnsecure.imageset/LocationMarkerUnsecure@2x.png Binary files differnew file mode 100644 index 0000000000..6564a3a341 --- /dev/null +++ b/ios/MullvadVPN/Assets.xcassets/LocationMarkerUnsecure.imageset/LocationMarkerUnsecure@2x.png diff --git a/ios/MullvadVPN/Assets.xcassets/LocationMarkerUnsecure.imageset/LocationMarkerUnsecure@3x.png b/ios/MullvadVPN/Assets.xcassets/LocationMarkerUnsecure.imageset/LocationMarkerUnsecure@3x.png Binary files differnew file mode 100644 index 0000000000..bb7d63a426 --- /dev/null +++ b/ios/MullvadVPN/Assets.xcassets/LocationMarkerUnsecure.imageset/LocationMarkerUnsecure@3x.png diff --git a/ios/MullvadVPN/Assets.xcassets/LogoIcon.imageset/Contents.json b/ios/MullvadVPN/Assets.xcassets/LogoIcon.imageset/Contents.json new file mode 100644 index 0000000000..74e5c9dba2 --- /dev/null +++ b/ios/MullvadVPN/Assets.xcassets/LogoIcon.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "LogoIcon.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "LogoIcon@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "LogoIcon@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +}
\ No newline at end of file diff --git a/ios/MullvadVPN/Assets.xcassets/LogoIcon.imageset/LogoIcon.png b/ios/MullvadVPN/Assets.xcassets/LogoIcon.imageset/LogoIcon.png Binary files differnew file mode 100644 index 0000000000..d082423b0b --- /dev/null +++ b/ios/MullvadVPN/Assets.xcassets/LogoIcon.imageset/LogoIcon.png diff --git a/ios/MullvadVPN/Assets.xcassets/LogoIcon.imageset/LogoIcon@2x.png b/ios/MullvadVPN/Assets.xcassets/LogoIcon.imageset/LogoIcon@2x.png Binary files differnew file mode 100644 index 0000000000..89e31ce99d --- /dev/null +++ b/ios/MullvadVPN/Assets.xcassets/LogoIcon.imageset/LogoIcon@2x.png diff --git a/ios/MullvadVPN/Assets.xcassets/LogoIcon.imageset/LogoIcon@3x.png b/ios/MullvadVPN/Assets.xcassets/LogoIcon.imageset/LogoIcon@3x.png Binary files differnew file mode 100644 index 0000000000..fe7dc555ba --- /dev/null +++ b/ios/MullvadVPN/Assets.xcassets/LogoIcon.imageset/LogoIcon@3x.png diff --git a/ios/MullvadVPN/Assets.xcassets/MapBackground.imageset/Contents.json b/ios/MullvadVPN/Assets.xcassets/MapBackground.imageset/Contents.json new file mode 100644 index 0000000000..3eca6b2b52 --- /dev/null +++ b/ios/MullvadVPN/Assets.xcassets/MapBackground.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "MapBackground.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +}
\ No newline at end of file diff --git a/ios/MullvadVPN/Assets.xcassets/MapBackground.imageset/MapBackground.png b/ios/MullvadVPN/Assets.xcassets/MapBackground.imageset/MapBackground.png Binary files differnew file mode 100644 index 0000000000..6d96307f81 --- /dev/null +++ b/ios/MullvadVPN/Assets.xcassets/MapBackground.imageset/MapBackground.png diff --git a/ios/MullvadVPN/Assets.xcassets/SuccessButton.imageset/Contents.json b/ios/MullvadVPN/Assets.xcassets/SuccessButton.imageset/Contents.json new file mode 100644 index 0000000000..37fe41d860 --- /dev/null +++ b/ios/MullvadVPN/Assets.xcassets/SuccessButton.imageset/Contents.json @@ -0,0 +1,26 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "SuccessButton.pdf", + "resizing" : { + "mode" : "9-part", + "center" : { + "mode" : "tile", + "width" : 1, + "height" : 1 + }, + "cap-insets" : { + "bottom" : 4, + "top" : 4, + "right" : 4, + "left" : 4 + } + } + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +}
\ No newline at end of file diff --git a/ios/MullvadVPN/Assets.xcassets/SuccessButton.imageset/SuccessButton.pdf b/ios/MullvadVPN/Assets.xcassets/SuccessButton.imageset/SuccessButton.pdf Binary files differnew file mode 100644 index 0000000000..3d9f601cd0 --- /dev/null +++ b/ios/MullvadVPN/Assets.xcassets/SuccessButton.imageset/SuccessButton.pdf diff --git a/ios/MullvadVPN/Assets.xcassets/TranslucentDangerButton.imageset/Contents.json b/ios/MullvadVPN/Assets.xcassets/TranslucentDangerButton.imageset/Contents.json new file mode 100644 index 0000000000..d248ba2cd7 --- /dev/null +++ b/ios/MullvadVPN/Assets.xcassets/TranslucentDangerButton.imageset/Contents.json @@ -0,0 +1,26 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "TranslucentDangerButton.pdf", + "resizing" : { + "mode" : "9-part", + "center" : { + "mode" : "tile", + "width" : 1, + "height" : 1 + }, + "cap-insets" : { + "bottom" : 4, + "top" : 4, + "right" : 4, + "left" : 4 + } + } + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +}
\ No newline at end of file diff --git a/ios/MullvadVPN/Assets.xcassets/TranslucentDangerButton.imageset/TranslucentDangerButton.pdf b/ios/MullvadVPN/Assets.xcassets/TranslucentDangerButton.imageset/TranslucentDangerButton.pdf Binary files differnew file mode 100644 index 0000000000..a69b22fb31 --- /dev/null +++ b/ios/MullvadVPN/Assets.xcassets/TranslucentDangerButton.imageset/TranslucentDangerButton.pdf diff --git a/ios/MullvadVPN/Assets.xcassets/TranslucentNeutralButton.imageset/Contents.json b/ios/MullvadVPN/Assets.xcassets/TranslucentNeutralButton.imageset/Contents.json new file mode 100644 index 0000000000..7d2eefb820 --- /dev/null +++ b/ios/MullvadVPN/Assets.xcassets/TranslucentNeutralButton.imageset/Contents.json @@ -0,0 +1,26 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "TranslucentNeutralButton.pdf", + "resizing" : { + "mode" : "9-part", + "center" : { + "mode" : "tile", + "width" : 1, + "height" : 1 + }, + "cap-insets" : { + "bottom" : 4, + "top" : 4, + "right" : 4, + "left" : 4 + } + } + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +}
\ No newline at end of file diff --git a/ios/MullvadVPN/Assets.xcassets/TranslucentNeutralButton.imageset/TranslucentNeutralButton.pdf b/ios/MullvadVPN/Assets.xcassets/TranslucentNeutralButton.imageset/TranslucentNeutralButton.pdf Binary files differnew file mode 100644 index 0000000000..82ee77fd9a --- /dev/null +++ b/ios/MullvadVPN/Assets.xcassets/TranslucentNeutralButton.imageset/TranslucentNeutralButton.pdf diff --git a/ios/MullvadVPN/Base.lproj/LaunchScreen.storyboard b/ios/MullvadVPN/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 0000000000..bfa3612941 --- /dev/null +++ b/ios/MullvadVPN/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="13122.16" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="01J-lp-oVM"> + <dependencies> + <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="13104.12"/> + <capability name="Safe area layout guides" minToolsVersion="9.0"/> + <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/> + </dependencies> + <scenes> + <!--View Controller--> + <scene sceneID="EHf-IW-A2E"> + <objects> + <viewController id="01J-lp-oVM" sceneMemberID="viewController"> + <view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3"> + <rect key="frame" x="0.0" y="0.0" width="375" height="667"/> + <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> + <color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/> + <viewLayoutGuide key="safeArea" id="6Tk-OE-BBY"/> + </view> + </viewController> + <placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/> + </objects> + <point key="canvasLocation" x="53" y="375"/> + </scene> + </scenes> +</document> diff --git a/ios/MullvadVPN/Base.lproj/Main.storyboard b/ios/MullvadVPN/Base.lproj/Main.storyboard new file mode 100644 index 0000000000..b22b75a651 --- /dev/null +++ b/ios/MullvadVPN/Base.lproj/Main.storyboard @@ -0,0 +1,396 @@ +<?xml version="1.0" encoding="UTF-8"?> +<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="14313.18" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="BYZ-38-t0r"> + <device id="retina4_7" orientation="portrait"> + <adaptation id="fullscreen"/> + </device> + <dependencies> + <deployment identifier="iOS"/> + <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14283.14"/> + <capability name="Safe area layout guides" minToolsVersion="9.0"/> + <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/> + </dependencies> + <scenes> + <!--Login View Controller--> + <scene sceneID="tne-QT-ifu"> + <objects> + <viewController id="BYZ-38-t0r" customClass="LoginViewController" customModule="MullvadVPN" customModuleProvider="target" sceneMemberID="viewController"> + <view key="view" contentMode="scaleToFill" id="xpu-Q8-m8b"> + <rect key="frame" x="0.0" y="0.0" width="375" height="667"/> + <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/> + <subviews> + <containerView opaque="NO" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" translatesAutoresizingMaskIntoConstraints="NO" id="VIF-P4-vZU" userLabel="Header"> + <rect key="frame" x="0.0" y="20" width="375" height="74"/> + <constraints> + <constraint firstAttribute="height" constant="74" id="ohH-N4-eN7"/> + </constraints> + <connections> + <segue destination="rCI-6x-aLd" kind="embed" identifier="EmbedHeaderBar" id="tVd-Lw-FVU"/> + </connections> + </containerView> + <view contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" translatesAutoresizingMaskIntoConstraints="NO" id="0ZY-Kh-JiM" userLabel="Container"> + <rect key="frame" x="0.0" y="94" width="375" height="573"/> + <subviews> + <view contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" translatesAutoresizingMaskIntoConstraints="NO" id="V3j-Lb-fSQ" userLabel="Form"> + <rect key="frame" x="0.0" y="203.5" width="375" height="126"/> + <subviews> + <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Login" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Nxn-Fc-EGe"> + <rect key="frame" x="24" y="0.0" width="327" height="39"/> + <fontDescription key="fontDescription" type="system" pointSize="32"/> + <color key="textColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> + <nil key="highlightedColor"/> + </label> + <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Enter your account number" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="XSV-Lk-dj4"> + <rect key="frame" x="24" y="47" width="327" height="21"/> + <fontDescription key="fontDescription" type="system" pointSize="17"/> + <color key="textColor" white="1" alpha="0.60359589041095896" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> + <nil key="highlightedColor"/> + </label> + <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="VmT-ya-ufe" customClass="AccountInputGroupView" customModule="MullvadVPN" customModuleProvider="target"> + <rect key="frame" x="24" y="78" width="327" height="48"/> + <subviews> + <textField opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" placeholder="0000 0000 0000 0000" textAlignment="natural" adjustsFontSizeToFit="NO" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="XOB-ct-yLU" userLabel="Account Text Field" customClass="AccountTextField" customModule="MullvadVPN" customModuleProvider="target"> + <rect key="frame" x="0.0" y="0.0" width="327" height="48"/> + <nil key="textColor"/> + <fontDescription key="fontDescription" type="system" pointSize="20"/> + <textInputTraits key="textInputTraits" autocorrectionType="no" spellCheckingType="no" keyboardType="numberPad" enablesReturnKeyAutomatically="YES" smartDashesType="no" smartInsertDeleteType="no" smartQuotesType="no" textContentType="username"/> + </textField> + </subviews> + <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> + <constraints> + <constraint firstItem="XOB-ct-yLU" firstAttribute="top" secondItem="VmT-ya-ufe" secondAttribute="top" id="6gC-g8-WvR"/> + <constraint firstAttribute="trailing" secondItem="XOB-ct-yLU" secondAttribute="trailing" id="8oc-Rn-csw"/> + <constraint firstAttribute="height" constant="48" placeholder="YES" id="Str-4H-10Q"/> + <constraint firstItem="XOB-ct-yLU" firstAttribute="leading" secondItem="VmT-ya-ufe" secondAttribute="leading" id="dLW-t4-NiY"/> + <constraint firstAttribute="bottom" secondItem="XOB-ct-yLU" secondAttribute="bottom" id="ykb-mC-noi"/> + </constraints> + <connections> + <outlet property="textField" destination="XOB-ct-yLU" id="7VW-eF-gMr"/> + </connections> + </view> + </subviews> + <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> + <constraints> + <constraint firstAttribute="trailingMargin" secondItem="Nxn-Fc-EGe" secondAttribute="trailing" id="1ea-k3-78I"/> + <constraint firstItem="XSV-Lk-dj4" firstAttribute="leading" secondItem="Nxn-Fc-EGe" secondAttribute="leading" id="2Yu-kr-QsE"/> + <constraint firstItem="VmT-ya-ufe" firstAttribute="leading" secondItem="Nxn-Fc-EGe" secondAttribute="leading" id="8FN-nm-t0F"/> + <constraint firstItem="VmT-ya-ufe" firstAttribute="top" secondItem="XSV-Lk-dj4" secondAttribute="bottom" constant="10" id="9pH-T3-2jW"/> + <constraint firstItem="Nxn-Fc-EGe" firstAttribute="leading" secondItem="V3j-Lb-fSQ" secondAttribute="leadingMargin" id="Ce0-1J-FJc"/> + <constraint firstItem="XSV-Lk-dj4" firstAttribute="trailing" secondItem="Nxn-Fc-EGe" secondAttribute="trailing" id="OLs-m1-xHT"/> + <constraint firstAttribute="bottom" secondItem="VmT-ya-ufe" secondAttribute="bottom" id="OhO-fH-gIS"/> + <constraint firstItem="VmT-ya-ufe" firstAttribute="trailing" secondItem="Nxn-Fc-EGe" secondAttribute="trailing" id="RMD-VJ-u4j"/> + <constraint firstItem="XSV-Lk-dj4" firstAttribute="top" secondItem="Nxn-Fc-EGe" secondAttribute="bottom" constant="8" id="aBF-3y-LX5"/> + <constraint firstItem="Nxn-Fc-EGe" firstAttribute="top" secondItem="V3j-Lb-fSQ" secondAttribute="top" id="nCa-l7-I8c"/> + </constraints> + </view> + </subviews> + <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> + <constraints> + <constraint firstItem="V3j-Lb-fSQ" firstAttribute="centerY" secondItem="0ZY-Kh-JiM" secondAttribute="centerY" constant="-20" id="3Uk-YZ-4C3"/> + <constraint firstAttribute="trailing" secondItem="V3j-Lb-fSQ" secondAttribute="trailing" id="EHy-Cx-cGj"/> + <constraint firstItem="V3j-Lb-fSQ" firstAttribute="leading" secondItem="0ZY-Kh-JiM" secondAttribute="leading" id="alr-G1-L4w"/> + </constraints> + </view> + <view contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Ire-2z-eJu" userLabel="Footer"> + <rect key="frame" x="0.0" y="554.5" width="375" height="112.5"/> + <subviews> + <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Don't have an account number?" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="QcG-Tf-YdQ"> + <rect key="frame" x="24" y="16" width="327" height="20.5"/> + <fontDescription key="fontDescription" type="system" pointSize="17"/> + <color key="textColor" white="1" alpha="0.60327482876712324" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> + <nil key="highlightedColor"/> + </label> + <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="osm-vd-aTb"> + <rect key="frame" x="24" y="44.5" width="327" height="44"/> + <fontDescription key="fontDescription" type="system" pointSize="20"/> + <inset key="contentEdgeInsets" minX="0.0" minY="10" maxX="0.0" maxY="10"/> + <state key="normal" title="Create account" backgroundImage="DefaultButton"> + <color key="titleColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> + </state> + </button> + </subviews> + <color key="backgroundColor" red="0.098039215686274508" green="0.1803921568627451" blue="0.27058823529411763" alpha="1" colorSpace="custom" customColorSpace="sRGB"/> + <constraints> + <constraint firstAttribute="trailingMargin" secondItem="osm-vd-aTb" secondAttribute="trailing" id="MCf-FB-2AL"/> + <constraint firstAttribute="bottomMargin" secondItem="osm-vd-aTb" secondAttribute="bottom" id="g0d-lW-N4P"/> + <constraint firstItem="QcG-Tf-YdQ" firstAttribute="leading" secondItem="Ire-2z-eJu" secondAttribute="leadingMargin" id="hLO-0a-7p0"/> + <constraint firstItem="QcG-Tf-YdQ" firstAttribute="top" secondItem="Ire-2z-eJu" secondAttribute="topMargin" id="pOc-kU-kNJ"/> + <constraint firstAttribute="trailingMargin" secondItem="QcG-Tf-YdQ" secondAttribute="trailing" id="rEw-4o-orE"/> + <constraint firstItem="osm-vd-aTb" firstAttribute="leading" secondItem="Ire-2z-eJu" secondAttribute="leadingMargin" id="sLm-Ug-jLY"/> + <constraint firstItem="osm-vd-aTb" firstAttribute="top" secondItem="QcG-Tf-YdQ" secondAttribute="bottom" constant="8" id="yAE-m3-6y0"/> + </constraints> + <edgeInsets key="layoutMargins" top="16" left="0.0" bottom="24" right="0.0"/> + </view> + </subviews> + <color key="backgroundColor" red="0.16078431369999999" green="0.30196078430000001" blue="0.45098039220000002" alpha="1" colorSpace="custom" customColorSpace="sRGB"/> + <constraints> + <constraint firstAttribute="bottom" secondItem="0ZY-Kh-JiM" secondAttribute="bottom" id="09L-EV-qfI"/> + <constraint firstItem="0ZY-Kh-JiM" firstAttribute="leading" secondItem="xpu-Q8-m8b" secondAttribute="leading" id="5T5-Un-Bbw"/> + <constraint firstItem="Ire-2z-eJu" firstAttribute="leading" secondItem="xpu-Q8-m8b" secondAttribute="leading" id="8MY-2T-1p9"/> + <constraint firstItem="VIF-P4-vZU" firstAttribute="top" secondItem="RSb-dJ-fKl" secondAttribute="top" id="A7p-Wh-bUn"/> + <constraint firstItem="RSb-dJ-fKl" firstAttribute="trailing" secondItem="VIF-P4-vZU" secondAttribute="trailing" id="YPn-KH-Dy5"/> + <constraint firstAttribute="trailing" secondItem="0ZY-Kh-JiM" secondAttribute="trailing" id="ZCl-FF-h79"/> + <constraint firstItem="VIF-P4-vZU" firstAttribute="leading" secondItem="RSb-dJ-fKl" secondAttribute="leading" id="bkX-Cb-jYl"/> + <constraint firstItem="0ZY-Kh-JiM" firstAttribute="top" secondItem="VIF-P4-vZU" secondAttribute="bottom" id="d2t-dv-LwM"/> + <constraint firstAttribute="bottom" secondItem="Ire-2z-eJu" secondAttribute="bottom" id="okj-M8-3PQ"/> + <constraint firstAttribute="trailing" secondItem="Ire-2z-eJu" secondAttribute="trailing" id="uZQ-0R-5JT"/> + </constraints> + <edgeInsets key="layoutMargins" top="0.0" left="24" bottom="0.0" right="24"/> + <viewLayoutGuide key="safeArea" id="RSb-dJ-fKl"/> + </view> + <connections> + <outlet property="accountTextField" destination="XOB-ct-yLU" id="mXd-SV-E16"/> + <outlet property="keyboardToolbar" destination="waX-JF-VTG" id="kav-5t-mkA"/> + <outlet property="loginForm" destination="V3j-Lb-fSQ" id="tYu-S8-ylm"/> + <outlet property="loginFormWrapperBottomConstraint" destination="09L-EV-qfI" id="fYF-OK-trh"/> + <segue destination="Ki6-Mt-b6R" kind="presentation" identifier="ShowConnect" animates="NO" id="ccw-Nc-l0Q"/> + <segue destination="Kqv-qu-mfF" kind="presentation" identifier="ShowSettings" id="RjC-Wk-Enk"/> + </connections> + </viewController> + <placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/> + <toolbar opaque="NO" clearsContextBeforeDrawing="NO" contentMode="scaleToFill" id="waX-JF-VTG"> + <rect key="frame" x="0.0" y="0.0" width="375" height="44"/> + <autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/> + <items> + <barButtonItem style="plain" systemItem="cancel" id="hYv-Qq-TND"> + <connections> + <action selector="cancelLogin" destination="BYZ-38-t0r" id="5UA-Vf-AE0"/> + </connections> + </barButtonItem> + <barButtonItem style="plain" systemItem="flexibleSpace" id="Llz-4U-rOT"/> + <barButtonItem title="Log in" style="done" id="0VH-wf-oEs"> + <connections> + <action selector="doLogin" destination="BYZ-38-t0r" id="8Mv-Di-I6Y"/> + </connections> + </barButtonItem> + </items> + </toolbar> + </objects> + <point key="canvasLocation" x="669.60000000000002" y="27.436281859070466"/> + </scene> + <!--Connect View Controller--> + <scene sceneID="Fnf-X9-B7i"> + <objects> + <viewController id="Ki6-Mt-b6R" customClass="ConnectViewController" customModule="MullvadVPN" customModuleProvider="target" sceneMemberID="viewController"> + <view key="view" contentMode="scaleToFill" id="PNd-mm-N1B"> + <rect key="frame" x="0.0" y="0.0" width="375" height="667"/> + <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> + <subviews> + <containerView opaque="NO" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" translatesAutoresizingMaskIntoConstraints="NO" id="C7a-Bl-BmL"> + <rect key="frame" x="0.0" y="20" width="375" height="74"/> + <constraints> + <constraint firstAttribute="height" constant="74" id="Rif-54-EA1"/> + </constraints> + <connections> + <segue destination="rCI-6x-aLd" kind="embed" identifier="EmbedHeaderBar" id="qKR-6L-kfz"/> + </connections> + </containerView> + <imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="MapBackground" translatesAutoresizingMaskIntoConstraints="NO" id="3Ck-JT-ogd"> + <rect key="frame" x="0.0" y="94" width="375" height="573"/> + </imageView> + <stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="16" translatesAutoresizingMaskIntoConstraints="NO" id="shY-Lj-oYx"> + <rect key="frame" x="24" y="533" width="327" height="110"/> + <subviews> + <visualEffectView opaque="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="JHO-Ca-Zzd" customClass="TranslucentButtonBlurView" customModule="MullvadVPN" customModuleProvider="target"> + <rect key="frame" x="0.0" y="0.0" width="327" height="50"/> + <view key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" insetsLayoutMarginsFromSafeArea="NO" id="jVH-JP-pJo"> + <rect key="frame" x="0.0" y="0.0" width="327" height="50"/> + <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> + <subviews> + <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="hVz-q0-Xpd"> + <rect key="frame" x="0.0" y="0.0" width="327" height="50"/> + <fontDescription key="fontDescription" type="system" pointSize="20"/> + <inset key="contentEdgeInsets" minX="0.0" minY="10" maxX="0.0" maxY="10"/> + <state key="normal" title="Select location" backgroundImage="TranslucentNeutralButton"> + <color key="titleColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> + </state> + </button> + </subviews> + <constraints> + <constraint firstAttribute="bottom" secondItem="hVz-q0-Xpd" secondAttribute="bottom" id="4Q2-Zh-7fM"/> + <constraint firstAttribute="trailing" secondItem="hVz-q0-Xpd" secondAttribute="trailing" id="AsY-cg-1fj"/> + <constraint firstItem="hVz-q0-Xpd" firstAttribute="leading" secondItem="jVH-JP-pJo" secondAttribute="leading" id="Eya-ig-8On"/> + <constraint firstItem="hVz-q0-Xpd" firstAttribute="top" secondItem="jVH-JP-pJo" secondAttribute="top" id="UY2-bK-i8s"/> + </constraints> + </view> + <blurEffect style="light"/> + </visualEffectView> + <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="vxU-Mt-fMo"> + <rect key="frame" x="0.0" y="66" width="327" height="44"/> + <fontDescription key="fontDescription" type="system" pointSize="20"/> + <inset key="contentEdgeInsets" minX="0.0" minY="10" maxX="0.0" maxY="10"/> + <state key="normal" title="Secure my connection" backgroundImage="SuccessButton"> + <color key="titleColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> + </state> + </button> + </subviews> + </stackView> + </subviews> + <color key="backgroundColor" red="0.16078431369999999" green="0.30196078430000001" blue="0.45098039220000002" alpha="1" colorSpace="custom" customColorSpace="sRGB"/> + <constraints> + <constraint firstAttribute="trailingMargin" secondItem="shY-Lj-oYx" secondAttribute="trailing" id="2y6-PR-9e3"/> + <constraint firstItem="C7a-Bl-BmL" firstAttribute="top" secondItem="iBo-pG-OTz" secondAttribute="top" id="DAc-is-w0k"/> + <constraint firstItem="3Ck-JT-ogd" firstAttribute="leading" secondItem="PNd-mm-N1B" secondAttribute="leading" id="OEK-r4-gE7"/> + <constraint firstItem="3Ck-JT-ogd" firstAttribute="top" secondItem="C7a-Bl-BmL" secondAttribute="bottom" id="Rzf-01-pyd"/> + <constraint firstAttribute="bottom" secondItem="3Ck-JT-ogd" secondAttribute="bottom" id="e75-bI-sYJ"/> + <constraint firstAttribute="trailing" secondItem="3Ck-JT-ogd" secondAttribute="trailing" id="fXi-Cn-1bF"/> + <constraint firstItem="C7a-Bl-BmL" firstAttribute="leading" secondItem="iBo-pG-OTz" secondAttribute="leading" id="jx2-nb-cxY"/> + <constraint firstAttribute="bottomMargin" secondItem="shY-Lj-oYx" secondAttribute="bottom" id="rYu-al-UqH"/> + <constraint firstItem="iBo-pG-OTz" firstAttribute="trailing" secondItem="C7a-Bl-BmL" secondAttribute="trailing" id="rig-zZ-55o"/> + <constraint firstItem="shY-Lj-oYx" firstAttribute="leading" secondItem="PNd-mm-N1B" secondAttribute="leadingMargin" id="v5s-FD-Iaw"/> + </constraints> + <edgeInsets key="layoutMargins" top="0.0" left="24" bottom="24" right="24"/> + <viewLayoutGuide key="safeArea" id="iBo-pG-OTz"/> + </view> + <connections> + <segue destination="Kqv-qu-mfF" kind="presentation" identifier="ShowSettings" id="fxZ-Uq-nxv"/> + </connections> + </viewController> + <placeholder placeholderIdentifier="IBFirstResponder" id="gkg-dm-hcG" userLabel="First Responder" sceneMemberID="firstResponder"/> + </objects> + <point key="canvasLocation" x="1920.8" y="26.53673163418291"/> + </scene> + <!--Settings--> + <scene sceneID="3oF-uu-3Bk"> + <objects> + <tableViewController id="SHd-a4-ewi" customClass="SettingsViewController" customModule="MullvadVPN" customModuleProvider="target" sceneMemberID="viewController"> + <tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" separatorStyle="default" rowHeight="-1" estimatedRowHeight="-1" sectionHeaderHeight="28" sectionFooterHeight="28" id="6Gz-UM-orK"> + <rect key="frame" x="0.0" y="0.0" width="375" height="667"/> + <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> + <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> + <prototypes> + <tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" accessoryType="disclosureIndicator" indentationWidth="10" reuseIdentifier="Account" textLabel="EgF-AZ-LLU" detailTextLabel="OtL-Zd-v9V" style="IBUITableViewCellStyleValue1" id="ghE-jC-RWf"> + <rect key="frame" x="0.0" y="28" width="375" height="44"/> + <autoresizingMask key="autoresizingMask"/> + <tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="ghE-jC-RWf" id="sTl-gI-g2a"> + <rect key="frame" x="0.0" y="0.0" width="341" height="43.5"/> + <autoresizingMask key="autoresizingMask"/> + <subviews> + <label opaque="NO" multipleTouchEnabled="YES" userInteractionEnabled="NO" contentMode="left" insetsLayoutMarginsFromSafeArea="NO" text="Account" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="EgF-AZ-LLU"> + <rect key="frame" x="16" y="12" width="63.5" height="20.5"/> + <autoresizingMask key="autoresizingMask"/> + <fontDescription key="fontDescription" type="system" pointSize="17"/> + <nil key="textColor"/> + <nil key="highlightedColor"/> + </label> + <label opaque="NO" multipleTouchEnabled="YES" userInteractionEnabled="NO" contentMode="left" insetsLayoutMarginsFromSafeArea="NO" text="5 days left" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="OtL-Zd-v9V"> + <rect key="frame" x="260" y="12" width="80" height="20.5"/> + <autoresizingMask key="autoresizingMask"/> + <fontDescription key="fontDescription" type="system" pointSize="17"/> + <nil key="textColor"/> + <nil key="highlightedColor"/> + </label> + </subviews> + </tableViewCellContentView> + <connections> + <segue destination="ruh-Q2-P39" kind="show" id="Oei-D9-z6L"/> + </connections> + </tableViewCell> + </prototypes> + <sections/> + <connections> + <outlet property="dataSource" destination="SHd-a4-ewi" id="qys-E3-WsY"/> + <outlet property="delegate" destination="SHd-a4-ewi" id="Fwe-NL-Bgt"/> + </connections> + </tableView> + <navigationItem key="navigationItem" title="Settings" id="Xxl-r7-Sbm"> + <barButtonItem key="rightBarButtonItem" style="done" systemItem="done" id="AnV-sJ-aya"> + <connections> + <action selector="handleDismiss" destination="SHd-a4-ewi" id="eE7-bB-mer"/> + </connections> + </barButtonItem> + </navigationItem> + </tableViewController> + <placeholder placeholderIdentifier="IBFirstResponder" id="sR5-ix-4x7" userLabel="First Responder" sceneMemberID="firstResponder"/> + </objects> + <point key="canvasLocation" x="4105" y="27"/> + </scene> + <!--Account--> + <scene sceneID="Ca0-W1-eLb"> + <objects> + <viewController id="ruh-Q2-P39" customClass="AccountViewController" customModule="MullvadVPN" customModuleProvider="target" sceneMemberID="viewController"> + <view key="view" contentMode="scaleToFill" id="Qpl-bL-ZGl"> + <rect key="frame" x="0.0" y="0.0" width="375" height="667"/> + <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> + <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> + <viewLayoutGuide key="safeArea" id="jrJ-di-3DV"/> + </view> + <navigationItem key="navigationItem" title="Account" id="rL3-Y8-3g8"/> + </viewController> + <placeholder placeholderIdentifier="IBFirstResponder" id="3tt-67-nI8" userLabel="First Responder" sceneMemberID="firstResponder"/> + </objects> + <point key="canvasLocation" x="5062" y="24"/> + </scene> + <!--Navigation Controller--> + <scene sceneID="er3-W2-NkS"> + <objects> + <navigationController id="Kqv-qu-mfF" sceneMemberID="viewController"> + <navigationBar key="navigationBar" contentMode="scaleToFill" insetsLayoutMarginsFromSafeArea="NO" id="7PK-0x-byW"> + <rect key="frame" x="0.0" y="20" width="375" height="44"/> + <autoresizingMask key="autoresizingMask"/> + </navigationBar> + <connections> + <segue destination="SHd-a4-ewi" kind="relationship" relationship="rootViewController" id="5n8-Yk-l4C"/> + </connections> + </navigationController> + <placeholder placeholderIdentifier="IBFirstResponder" id="bHt-Id-Zc4" userLabel="First Responder" sceneMemberID="firstResponder"/> + </objects> + <point key="canvasLocation" x="3084" y="27"/> + </scene> + <!--Header Bar View Controller--> + <scene sceneID="XNS-uo-8Yd"> + <objects> + <viewController definesPresentationContext="YES" id="rCI-6x-aLd" customClass="HeaderBarViewController" customModule="MullvadVPN" customModuleProvider="target" sceneMemberID="viewController"> + <view key="view" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" id="cw4-px-5hC"> + <rect key="frame" x="0.0" y="0.0" width="375" height="74"/> + <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> + <subviews> + <imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="LogoIcon" translatesAutoresizingMaskIntoConstraints="NO" id="cKg-hE-JsS"> + <rect key="frame" x="11" y="12" width="49" height="50"/> + </imageView> + <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="uXv-Tf-PET"> + <rect key="frame" x="335" y="25" width="24" height="24"/> + <state key="normal" image="IconSettings"/> + <connections> + <action selector="handleSettingsButton" destination="rCI-6x-aLd" eventType="touchUpInside" id="TaM-cZ-TvJ"/> + </connections> + </button> + <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="MULLVAD VPN" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="dqy-A0-TdV"> + <rect key="frame" x="68" y="22" width="168" height="30"/> + <fontDescription key="fontDescription" type="boldSystem" pointSize="24"/> + <color key="textColor" white="1" alpha="0.59999999999999998" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> + <nil key="highlightedColor"/> + </label> + </subviews> + <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> + <constraints> + <constraint firstAttribute="trailingMargin" secondItem="uXv-Tf-PET" secondAttribute="trailing" id="1LM-Tg-1Kr"/> + <constraint firstItem="cKg-hE-JsS" firstAttribute="centerY" secondItem="cw4-px-5hC" secondAttribute="centerY" id="WVK-1I-XmT"/> + <constraint firstAttribute="bottom" secondItem="dqy-A0-TdV" secondAttribute="bottom" constant="22" id="YTk-xg-wIk"/> + <constraint firstItem="uXv-Tf-PET" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="dqy-A0-TdV" secondAttribute="trailing" constant="8" symbolic="YES" id="ZEb-xZ-1ga"/> + <constraint firstItem="cKg-hE-JsS" firstAttribute="leading" secondItem="cw4-px-5hC" secondAttribute="leadingMargin" constant="-5" id="hGJ-yd-hnp"/> + <constraint firstItem="dqy-A0-TdV" firstAttribute="top" secondItem="cw4-px-5hC" secondAttribute="top" constant="22" id="mMF-ha-mRO"/> + <constraint firstItem="dqy-A0-TdV" firstAttribute="leading" secondItem="cKg-hE-JsS" secondAttribute="trailing" constant="8" id="q8s-25-ASt"/> + <constraint firstItem="uXv-Tf-PET" firstAttribute="centerY" secondItem="cw4-px-5hC" secondAttribute="centerY" id="vEf-j6-cTF"/> + </constraints> + <edgeInsets key="layoutMargins" top="0.0" left="0.0" bottom="0.0" right="0.0"/> + <viewLayoutGuide key="safeArea" id="oeE-aF-UYv"/> + </view> + </viewController> + <placeholder placeholderIdentifier="IBFirstResponder" id="Kbx-AI-gkv" userLabel="First Responder" sceneMemberID="firstResponder"/> + </objects> + <point key="canvasLocation" x="1326" y="-509"/> + </scene> + </scenes> + <resources> + <image name="DefaultButton" width="9" height="9"/> + <image name="IconSettings" width="24" height="24"/> + <image name="LogoIcon" width="49" height="50"/> + <image name="MapBackground" width="318.5" height="491"/> + <image name="SuccessButton" width="9" height="9"/> + <image name="TranslucentNeutralButton" width="9" height="9"/> + </resources> + <inferredMetricsTieBreakers> + <segue reference="tVd-Lw-FVU"/> + <segue reference="RjC-Wk-Enk"/> + </inferredMetricsTieBreakers> +</document> diff --git a/ios/MullvadVPN/ConnectViewController.swift b/ios/MullvadVPN/ConnectViewController.swift new file mode 100644 index 0000000000..df24ef65f5 --- /dev/null +++ b/ios/MullvadVPN/ConnectViewController.swift @@ -0,0 +1,35 @@ +// +// ConnectViewController.swift +// MullvadVPN +// +// Created by pronebird on 20/03/2019. +// Copyright © 2019 Amagicom AB. All rights reserved. +// + +import UIKit + +class ConnectViewController: UIViewController, HeaderBarViewControllerDelegate { + + override var preferredStatusBarStyle: UIStatusBarStyle { + return .lightContent + } + + override func prepare(for segue: UIStoryboardSegue, sender: Any?) { + if case .embedHeader? = SegueIdentifier.Connect.from(segue: segue) { + let headerBarController = segue.destination as? HeaderBarViewController + headerBarController?.delegate = self + } + } + + override func viewDidLoad() { + super.viewDidLoad() + // Do any additional setup after loading the view, typically from a nib. + } + + // MARK: - HeaderBarViewControllerDelegate + + func headerBarViewControllerShouldOpenSettings(_ controller: HeaderBarViewController) { + performSegue(withIdentifier: SegueIdentifier.Connect.showSettings.rawValue, sender: self) + } + +} diff --git a/ios/MullvadVPN/HeaderBarViewController.swift b/ios/MullvadVPN/HeaderBarViewController.swift new file mode 100644 index 0000000000..08ed7560d1 --- /dev/null +++ b/ios/MullvadVPN/HeaderBarViewController.swift @@ -0,0 +1,21 @@ +// +// HeaderBarViewController.swift +// MullvadVPN +// +// Created by pronebird on 21/03/2019. +// Copyright © 2019 Amagicom AB. All rights reserved. +// + +import UIKit + +protocol HeaderBarViewControllerDelegate: class { + func headerBarViewControllerShouldOpenSettings(_ controller: HeaderBarViewController) +} + +class HeaderBarViewController: UIViewController { + weak var delegate: HeaderBarViewControllerDelegate? + + @IBAction func handleSettingsButton() { + delegate?.headerBarViewControllerShouldOpenSettings(self) + } +} diff --git a/ios/MullvadVPN/Info.plist b/ios/MullvadVPN/Info.plist new file mode 100644 index 0000000000..89d7858b37 --- /dev/null +++ b/ios/MullvadVPN/Info.plist @@ -0,0 +1,43 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<plist version="1.0"> +<dict> + <key>CFBundleDevelopmentRegion</key> + <string>$(DEVELOPMENT_LANGUAGE)</string> + <key>CFBundleExecutable</key> + <string>$(EXECUTABLE_NAME)</string> + <key>CFBundleIdentifier</key> + <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string> + <key>CFBundleInfoDictionaryVersion</key> + <string>6.0</string> + <key>CFBundleName</key> + <string>$(PRODUCT_NAME)</string> + <key>CFBundlePackageType</key> + <string>APPL</string> + <key>CFBundleShortVersionString</key> + <string>1.0</string> + <key>CFBundleVersion</key> + <string>1</string> + <key>LSRequiresIPhoneOS</key> + <true/> + <key>UILaunchStoryboardName</key> + <string>LaunchScreen</string> + <key>UIMainStoryboardFile</key> + <string>Main</string> + <key>UIRequiredDeviceCapabilities</key> + <array> + <string>armv7</string> + </array> + <key>UISupportedInterfaceOrientations</key> + <array> + <string>UIInterfaceOrientationPortrait</string> + </array> + <key>UISupportedInterfaceOrientations~ipad</key> + <array> + <string>UIInterfaceOrientationPortrait</string> + <string>UIInterfaceOrientationPortraitUpsideDown</string> + <string>UIInterfaceOrientationLandscapeLeft</string> + <string>UIInterfaceOrientationLandscapeRight</string> + </array> +</dict> +</plist> diff --git a/ios/MullvadVPN/LoginViewController.swift b/ios/MullvadVPN/LoginViewController.swift new file mode 100644 index 0000000000..fa02257513 --- /dev/null +++ b/ios/MullvadVPN/LoginViewController.swift @@ -0,0 +1,87 @@ +// +// LoginViewController.swift +// MullvadVPN +// +// Created by pronebird on 19/03/2019. +// Copyright © 2019 Amagicom AB. All rights reserved. +// + +import UIKit + +class LoginViewController: UIViewController, HeaderBarViewControllerDelegate { + + @IBOutlet var keyboardToolbar: UIToolbar! + @IBOutlet var accountTextField: UITextField! + @IBOutlet var loginForm: UIView! + @IBOutlet var loginFormWrapperBottomConstraint: NSLayoutConstraint! + + override var preferredStatusBarStyle: UIStatusBarStyle { + return .lightContent + } + + override func prepare(for segue: UIStoryboardSegue, sender: Any?) { + if case .embedHeader? = SegueIdentifier.Login.from(segue: segue) { + let headerBarController = segue.destination as? HeaderBarViewController + headerBarController?.delegate = self + } + } + + override func viewDidLoad() { + super.viewDidLoad() + + accountTextField.inputAccessoryView = keyboardToolbar + + NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow(_:)), name: UIWindow.keyboardWillShowNotification, object: nil) + NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillChangeFrame(_:)), name: UIWindow.keyboardWillChangeFrameNotification, object: nil) + NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide(_:)), name: UIWindow.keyboardWillHideNotification, object: nil) + } + + // MARK: - HeaderBarViewControllerDelegate + + func headerBarViewControllerShouldOpenSettings(_ controller: HeaderBarViewController) { + performSegue(withIdentifier: SegueIdentifier.Login.showSettings.rawValue, sender: self) + } + + // MARK: - Keyboard notifications + + @objc private func keyboardWillShow(_ notification: Notification) { + guard let keyboardFrameValue = notification.userInfo?[UIWindow.keyboardFrameEndUserInfoKey] as? NSValue else { return } + + makeLoginFormVisible(keyboardFrame: keyboardFrameValue.cgRectValue) + } + + @objc private func keyboardWillChangeFrame(_ notification: Notification) { + guard let keyboardFrameValue = notification.userInfo?[UIWindow.keyboardFrameEndUserInfoKey] as? NSValue else { return } + + makeLoginFormVisible(keyboardFrame: keyboardFrameValue.cgRectValue) + } + + @objc private func keyboardWillHide(_ notification: Notification) { + loginFormWrapperBottomConstraint.constant = 0 + view.layoutIfNeeded() + } + + // MARK: - IBActions + + @IBAction func cancelLogin() { + view.endEditing(true) + } + + @IBAction func doLogin() { + view.endEditing(true) + + // TODO: Add the code to initiate the log in + performSegue(withIdentifier: "ShowConnect", sender: self) + } + + // MARK: - Private + + private func makeLoginFormVisible(keyboardFrame: CGRect) { + let convertedKeyboardFrame = view.convert(keyboardFrame, from: nil) + let (_, remainder) = view.frame.divided(atDistance: convertedKeyboardFrame.minY, from: CGRectEdge.minYEdge) + + loginFormWrapperBottomConstraint.constant = remainder.height + view.layoutIfNeeded() + } +} + diff --git a/ios/MullvadVPN/MullvadVPN.entitlements b/ios/MullvadVPN/MullvadVPN.entitlements new file mode 100644 index 0000000000..d5ed5f9c41 --- /dev/null +++ b/ios/MullvadVPN/MullvadVPN.entitlements @@ -0,0 +1,10 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<plist version="1.0"> +<dict> + <key>com.apple.security.application-groups</key> + <array> + <string>group.net.mullvad.MullvadVPN</string> + </array> +</dict> +</plist> diff --git a/ios/MullvadVPN/SegueIdentifier.swift b/ios/MullvadVPN/SegueIdentifier.swift new file mode 100644 index 0000000000..1279d8a2bb --- /dev/null +++ b/ios/MullvadVPN/SegueIdentifier.swift @@ -0,0 +1,39 @@ +// +// SegueIdentifier.swift +// MullvadVPN +// +// Created by pronebird on 25/03/2019. +// Copyright © 2019 Amagicom AB. All rights reserved. +// + +import UIKit + +// A phantom struct holding the storyboard segue identifiers for each view controller +struct SegueIdentifier { + + enum Connect: String, SegueConvertible { + case embedHeader = "EmbedHeaderBar" + case showSettings = "ShowSettings" + } + + enum Login: String, SegueConvertible { + case embedHeader = "EmbedHeaderBar" + case showSettings = "ShowSettings" + } + + private init() {} +} + +protocol SegueConvertible: RawRepresentable { + static func from(segue: UIStoryboardSegue) -> Self? +} + +extension SegueConvertible where RawValue == String { + static func from(segue: UIStoryboardSegue) -> Self? { + if let identifier = segue.identifier { + return self.init(rawValue: identifier) + } else { + return nil + } + } +} diff --git a/ios/MullvadVPN/SettingsViewController.swift b/ios/MullvadVPN/SettingsViewController.swift new file mode 100644 index 0000000000..d620b14f37 --- /dev/null +++ b/ios/MullvadVPN/SettingsViewController.swift @@ -0,0 +1,59 @@ +// +// SettingsViewController.swift +// MullvadVPN +// +// Created by pronebird on 20/03/2019. +// Copyright © 2019 Amagicom AB. All rights reserved. +// + +import UIKit + +private let kAccountCellIdentifier = "Account" + +class SettingsViewController: UITableViewController { + + override func viewDidLoad() { + super.viewDidLoad() + // Do any additional setup after loading the view, typically from a nib. + } + + // MARK: - IBActions + + @IBAction func handleDismiss() { + dismiss(animated: true) + } + + // MARK: - UITableViewDataSource + + override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { + // TODO: implement + } + + // MARK: - UITableViewDelegate + + override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + + if indexPath.section == 0 { + switch indexPath.row { + case 0: + let cell = tableView.dequeueReusableCell(withIdentifier: kAccountCellIdentifier, for: indexPath) + + return cell + + default: + break + } + } + + fatalError("Index path \(indexPath) is not handled.") + } + + override func numberOfSections(in tableView: UITableView) -> Int { + return 1 + } + + override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + return 1 + } + +} diff --git a/ios/MullvadVPN/TranslucentButtonBlurView.swift b/ios/MullvadVPN/TranslucentButtonBlurView.swift new file mode 100644 index 0000000000..5b86073ed9 --- /dev/null +++ b/ios/MullvadVPN/TranslucentButtonBlurView.swift @@ -0,0 +1,32 @@ +// +// AppButton.swift +// MullvadVPN +// +// Created by pronebird on 20/03/2019. +// Copyright © 2019 Amagicom AB. All rights reserved. +// + +import UIKit + +private let kButtonCornerRadius = CGFloat(4) + +@IBDesignable class TranslucentButtonBlurView: UIVisualEffectView { + + override init(effect: UIVisualEffect?) { + super.init(effect: effect) + + setup() + } + + required init?(coder aDecoder: NSCoder) { + super.init(coder: aDecoder) + + setup() + } + + private func setup() { + layer.cornerRadius = kButtonCornerRadius + layer.masksToBounds = true + } + +} diff --git a/ios/MullvadVPN/UIColor+Palette.swift b/ios/MullvadVPN/UIColor+Palette.swift new file mode 100644 index 0000000000..c6fa9d4d38 --- /dev/null +++ b/ios/MullvadVPN/UIColor+Palette.swift @@ -0,0 +1,14 @@ +// +// UIColor+Palette.swift +// MullvadVPN +// +// Created by pronebird on 20/03/2019. +// Copyright © 2019 Amagicom AB. All rights reserved. +// + +import UIKit + +extension UIColor { + // Account text field + static let accountTextFieldBorderColor = UIColor(red: 0.10, green: 0.18, blue: 0.27, alpha: 1.0) +} diff --git a/ios/PacketTunnel/Info.plist b/ios/PacketTunnel/Info.plist new file mode 100644 index 0000000000..368f1046e1 --- /dev/null +++ b/ios/PacketTunnel/Info.plist @@ -0,0 +1,31 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<plist version="1.0"> +<dict> + <key>CFBundleDevelopmentRegion</key> + <string>$(DEVELOPMENT_LANGUAGE)</string> + <key>CFBundleDisplayName</key> + <string>PacketTunnel</string> + <key>CFBundleExecutable</key> + <string>$(EXECUTABLE_NAME)</string> + <key>CFBundleIdentifier</key> + <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string> + <key>CFBundleInfoDictionaryVersion</key> + <string>6.0</string> + <key>CFBundleName</key> + <string>$(PRODUCT_NAME)</string> + <key>CFBundlePackageType</key> + <string>XPC!</string> + <key>CFBundleShortVersionString</key> + <string>1.0</string> + <key>CFBundleVersion</key> + <string>1</string> + <key>NSExtension</key> + <dict> + <key>NSExtensionPointIdentifier</key> + <string>com.apple.networkextension.packet-tunnel</string> + <key>NSExtensionPrincipalClass</key> + <string>$(PRODUCT_MODULE_NAME).PacketTunnelProvider</string> + </dict> +</dict> +</plist> diff --git a/ios/PacketTunnel/PacketTunnel.entitlements b/ios/PacketTunnel/PacketTunnel.entitlements new file mode 100644 index 0000000000..a8a939a254 --- /dev/null +++ b/ios/PacketTunnel/PacketTunnel.entitlements @@ -0,0 +1,10 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<plist version="1.0"> +<dict> + <key>com.apple.security.application-groups</key> + <array> + <string>group.net.mullvad.MullvadVPN</string> + </array> +</dict> +</plist> diff --git a/ios/PacketTunnel/PacketTunnelProvider.swift b/ios/PacketTunnel/PacketTunnelProvider.swift new file mode 100644 index 0000000000..914bce9c2c --- /dev/null +++ b/ios/PacketTunnel/PacketTunnelProvider.swift @@ -0,0 +1,37 @@ +// +// PacketTunnelProvider.swift +// PacketTunnel +// +// Created by pronebird on 19/03/2019. +// Copyright © 2019 Amagicom AB. All rights reserved. +// + +import NetworkExtension + +class PacketTunnelProvider: NEPacketTunnelProvider { + + override func startTunnel(options: [String : NSObject]?, completionHandler: @escaping (Error?) -> Void) { + // Add code here to start the process of connecting the tunnel. + } + + override func stopTunnel(with reason: NEProviderStopReason, completionHandler: @escaping () -> Void) { + // Add code here to start the process of stopping the tunnel. + completionHandler() + } + + override func handleAppMessage(_ messageData: Data, completionHandler: ((Data?) -> Void)?) { + // Add code here to handle the message. + if let handler = completionHandler { + handler(messageData) + } + } + + override func sleep(completionHandler: @escaping () -> Void) { + // Add code here to get ready to sleep. + completionHandler() + } + + override func wake() { + // Add code here to wake up. + } +} diff --git a/ios/convert-assets.rb b/ios/convert-assets.rb new file mode 100755 index 0000000000..f0b4c752e6 --- /dev/null +++ b/ios/convert-assets.rb @@ -0,0 +1,177 @@ +#!/usr/bin/ruby + +require 'optparse' + +SCRIPT_DIR = File.expand_path(File.dirname(__FILE__)) +ROOT_DIR = File.dirname(SCRIPT_DIR) + +# assets catalogue root +XCASSETS_DIR = File.join(SCRIPT_DIR, "MullvadVPN/Assets.xcassets") +XCASSETS_APPICON_DIR = File.join(XCASSETS_DIR, "AppIcon.appiconset") + +# graphical assets sources +APPICON_PATH = File.join(ROOT_DIR, "dist-assets/icon-1024.svg") +GRAPHICAL_ASSETS_DIR = File.join(ROOT_DIR, "gui/assets/images") +ADDITIONAL_ASSETS_DIR = File.join(SCRIPT_DIR, "AdditionalAssets") + +# graphical assets to import +GRAPHICAL_ASSETS=[ + "icon-alert.svg", + "icon-arrow.svg", + "icon-back.svg", + "icon-chevron-down.svg", + "icon-chevron-up.svg", + "icon-chevron.svg", + "icon-close-sml.svg", + "icon-close.svg", + "icon-extLink.svg", + "icon-fail.svg", + "icon-fastest.svg", + "icon-nearest.svg", + "icon-settings.svg", + "icon-spinner.svg", + "icon-success.svg", + "icon-tick.svg", + "location-marker-secure.svg", + "location-marker-unsecure.svg", + "logo-icon.svg" +] + +# App icon sizes +APP_ICON_SIZES=[ + # iphone-notification 20pt at 2x, 3x + ["AppIconPhoneNotification", 20, 2, 3], + + # iphone-settings at 29pt, 2x, 3x + ["AppIconPhoneSettings", 29, 2, 3], + + # iphone-spotlight at 40pt, 2x, 3x + ["AppIconPhoneSpotlight", 40, 2, 3], + + # iphone-app at 60pt, 2x, 3x + ["AppIconPhone", 60, 2, 3], + + # ipad-notifications at 20pt, 1x, 2x + ["AppIconPadNotifications", 20, 1, 2], + + # ipad-settings at 29pt, 1x, 2x + ["AppIconPadSettings", 29, 1, 2], + + # ipad-spotlight at 40pt, 1x, 2x + ["AppIconPadSpotlight", 40, 1, 2], + + # ipad-app at 76pt, 1x, 2x + ["AppIconPad", 76, 1, 2], + + # ipad-pro-app at 83.5pt, 2x + ["AppIconPadPro", 83.5, 2], + + # appstore-ios (marketing) at 1024pt, 1x + ["AppStoreIosMarketing", 1024, 1], +] + +# Additional assets generated from SVG -> vector PDF +ADDITIONAL_ASSETS = [ + "DefaultButton.svg", + "SuccessButton.svg", + "TranslucentDangerButton.svg", + "TranslucentNeutralButton.svg" +] + +# Functions + +def generate_graphical_assets() + for asset_name in GRAPHICAL_ASSETS do + svg_file = File.join(GRAPHICAL_ASSETS_DIR, asset_name) + image_name = pascal_case(File.basename(svg_file, ".svg")) + output_dir = File.join(XCASSETS_DIR, "#{image_name}.imageset") + + if !Dir.exists?(output_dir) + puts "Create directory #{output_dir}" + Dir.mkdir(output_dir) + end + + for retina_scale in (1..3) do + scale_suffix = retina_scale_suffix(retina_scale) + output_file = File.join(output_dir, "#{image_name}#{scale_suffix}.png") + + puts "Convert #{svg_file} -> #{output_file}" + system("rsvg-convert", "--zoom=#{retina_scale}", "--format=png", svg_file, "--output", output_file) + end + end +end + +def genereate_app_icon() + for (icon_name, nominal_size, *retina_scales) in APP_ICON_SIZES do + for retina_scale in retina_scales do + scale_suffix = retina_scale_suffix(retina_scale) + output_file = File.join(XCASSETS_APPICON_DIR, "#{icon_name}#{scale_suffix}.png") + actual_size = (nominal_size * retina_scale).to_i + + puts "Generate #{icon_name}: #{nominal_size} (#{retina_scale}x) -> #{output_file}" + system("rsvg-convert", "--width=#{actual_size}", "--height=#{actual_size}", "--format=png", APPICON_PATH, "--output", output_file) + end + end +end + +def generate_additional_assets() + for asset_name in ADDITIONAL_ASSETS do + svg_file = File.join(ADDITIONAL_ASSETS_DIR, asset_name) + image_name = File.basename(svg_file, ".svg") + output_dir = File.join(XCASSETS_DIR, "#{image_name}.imageset") + output_file = File.join(output_dir, "#{image_name}.pdf") + + if !Dir.exists?(output_dir) + puts "Create directory #{output_dir}" + Dir.mkdir(output_dir) + end + + puts "Generate #{image_name} -> #{output_file}" + system("rsvg-convert", "-f", "pdf", "-o", output_file, svg_file) + end +end + +def pascal_case(str) + return str.split('-').collect(&:capitalize).join +end + +def retina_scale_suffix(retina_scale) + return retina_scale == 1 ? "" : "@#{retina_scale}x" +end + +def command?(name) + `which #{name}` + $?.success? +end + +# Check requirements + +if !command?("rsvg-convert") + puts "rsvg-convert is not installed." + exit +end + +# Parse program arguments + +ARGV << '-h' if ARGV.empty? + +OptionParser.new do |opts| + opts.banner = "Usage: convert-assets.rb [options]" + + opts.on("--app-icon", "Generate application icon assets") do |v| + genereate_app_icon + end + + opts.on("--import-desktop-assets", "Import assets from the desktop app") do |v| + generate_graphical_assets + end + + opts.on("--additional-assets", "Generate additional assets") do |v| + generate_additional_assets + end + + opts.on_tail("-h", "--help", "Show this message") do + puts opts + exit + end +end.parse! |
