Skip to content

Commit e2579bf

Browse files
author
Jon Petersson
committed
Move the title 'Server IP Override' up
1 parent a50aa86 commit e2579bf

File tree

12 files changed

+201
-81
lines changed

12 files changed

+201
-81
lines changed

Diff for: ios/MullvadVPN.xcodeproj/project.pbxproj

+4
Original file line numberDiff line numberDiff line change
@@ -482,6 +482,7 @@
482482
7A1A26492A29D48A00B978AA /* RelayFilterCellFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A1A26482A29D48A00B978AA /* RelayFilterCellFactory.swift */; };
483483
7A21DACF2A30AA3700A787A9 /* UITextField+Appearance.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A21DACE2A30AA3700A787A9 /* UITextField+Appearance.swift */; };
484484
7A28826A2BA8336600FD9F20 /* VPNSettingsCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A2882692BA8336600FD9F20 /* VPNSettingsCoordinator.swift */; };
485+
7A28826D2BAAC9DE00FD9F20 /* IPOverrideHeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A28826C2BAAC9DE00FD9F20 /* IPOverrideHeaderView.swift */; };
485486
7A2960F62A963F7500389B82 /* AlertCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A2960F52A963F7500389B82 /* AlertCoordinator.swift */; };
486487
7A2960FD2A964BB700389B82 /* AlertPresentation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A2960FC2A964BB700389B82 /* AlertPresentation.swift */; };
487488
7A307AD92A8CD8DA0017618B /* Duration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A307AD82A8CD8DA0017618B /* Duration.swift */; };
@@ -1737,6 +1738,7 @@
17371738
7A1A264A2A29D65E00B978AA /* SelectableSettingsCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SelectableSettingsCell.swift; sourceTree = "<group>"; };
17381739
7A21DACE2A30AA3700A787A9 /* UITextField+Appearance.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UITextField+Appearance.swift"; sourceTree = "<group>"; };
17391740
7A2882692BA8336600FD9F20 /* VPNSettingsCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPNSettingsCoordinator.swift; sourceTree = "<group>"; };
1741+
7A28826C2BAAC9DE00FD9F20 /* IPOverrideHeaderView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IPOverrideHeaderView.swift; sourceTree = "<group>"; };
17401742
7A2960F52A963F7500389B82 /* AlertCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AlertCoordinator.swift; sourceTree = "<group>"; };
17411743
7A2960FC2A964BB700389B82 /* AlertPresentation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AlertPresentation.swift; sourceTree = "<group>"; };
17421744
7A307AD82A8CD8DA0017618B /* Duration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Duration.swift; sourceTree = "<group>"; };
@@ -3476,6 +3478,7 @@
34763478
isa = PBXGroup;
34773479
children = (
34783480
7A5869AA2B55527C00640D27 /* IPOverrideCoordinator.swift */,
3481+
7A28826C2BAAC9DE00FD9F20 /* IPOverrideHeaderView.swift */,
34793482
7AB4CCBA2B691BBB006037F5 /* IPOverrideInteractor.swift */,
34803483
7A5869BE2B57D0A100640D27 /* IPOverrideStatus.swift */,
34813484
7A5869C02B57D21A00640D27 /* IPOverrideStatusView.swift */,
@@ -5289,6 +5292,7 @@
52895292
F0C6FA852A6A733700F521F0 /* InAppPurchaseInteractor.swift in Sources */,
52905293
58CEB2F92AFD136E00E6E088 /* UIBackgroundConfiguration+Extensions.swift in Sources */,
52915294
5878F50029CDA742003D4BE2 /* UIView+AutoLayoutBuilder.swift in Sources */,
5295+
7A28826D2BAAC9DE00FD9F20 /* IPOverrideHeaderView.swift in Sources */,
52925296
A98502032B627B120061901E /* LocalNetworkProbe.swift in Sources */,
52935297
583FE01029C0F532006E85F9 /* CustomSplitViewController.swift in Sources */,
52945298
7A6F2FA92AFD0842006D0856 /* CustomDNSDataSource.swift in Sources */,

Diff for: ios/MullvadVPN.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
{
2+
"originHash" : "c15149b2d59d9e9c72375f65339c04f41a19943e1117e682df27fc9f943fdc56",
23
"pins" : [
34
{
45
"identity" : "swift-log",
@@ -18,5 +19,5 @@
1819
}
1920
}
2021
],
21-
"version" : 2
22+
"version" : 3
2223
}

Diff for: ios/MullvadVPN/Containers/Navigation/UINavigationBar+Appearance.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ extension UINavigationBar {
3232

3333
private func makeNavigationBarAppearance(isTransparent: Bool) -> UINavigationBarAppearance {
3434
let backIndicatorImage = UIImage(named: "IconBack")?.withTintColor(
35-
UIColor.NavigationBar.backButtonIndicatorColor,
35+
UIColor.NavigationBar.buttonColor,
3636
renderingMode: .alwaysOriginal
3737
)
3838
let backIndicatorTransitionMask = UIImage(named: "IconBackTransitionMask")

Diff for: ios/MullvadVPN/Coordinators/Settings/APIAccess/Cells/ListCellContentConfiguration.swift

+6-1
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,12 @@ struct ListCellContentConfiguration: UIContentConfiguration, Equatable {
3838
let tertiaryTextProperties = TertiaryTextProperties()
3939

4040
/// Content view layout margins.
41-
var directionalLayoutMargins: NSDirectionalEdgeInsets = UIMetrics.SettingsCell.apiAccessInsetLayoutMargins
41+
var directionalLayoutMargins = NSDirectionalEdgeInsets(
42+
top: 8,
43+
leading: 24,
44+
bottom: 8,
45+
trailing: 24
46+
)
4247

4348
func makeContentView() -> UIView & UIContentView {
4449
return ListCellContentView(configuration: self)

Diff for: ios/MullvadVPN/Coordinators/Settings/APIAccess/Cells/TextCellContentConfiguration.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ struct TextCellContentConfiguration: UIContentConfiguration, Equatable {
2828
/// The editing events configuration.
2929
var editingEvents = EditingEvents()
3030

31-
/// The text properties confgiuration.
31+
/// The text properties configuration.
3232
var textProperties = TextProperties()
3333

3434
/// The text field properties configuration.

Diff for: ios/MullvadVPN/Coordinators/Settings/APIAccess/List/ListAccessMethodCoordinator.swift

+5
Original file line numberDiff line numberDiff line change
@@ -76,17 +76,20 @@ class ListAccessMethodCoordinator: Coordinator, Presenting, SettingsChildCoordin
7676
private func about() {
7777
let header = NSLocalizedString(
7878
"ABOUT_API_ACCESS_HEADER",
79+
tableName: "APIAccess",
7980
value: "API access",
8081
comment: ""
8182
)
8283
let preamble = NSLocalizedString(
8384
"ABOUT_API_ACCESS_PREAMBLE",
85+
tableName: "APIAccess",
8486
value: "Manage default and setup custom methods to access the Mullvad API.",
8587
comment: ""
8688
)
8789
let body = [
8890
NSLocalizedString(
8991
"ABOUT_API_ACCESS_BODY_1",
92+
tableName: "APIAccess",
9093
value: """
9194
The app needs to communicate with a Mullvad API server to log you in, fetch server lists, \
9295
and other critical operations.
@@ -95,6 +98,7 @@ class ListAccessMethodCoordinator: Coordinator, Presenting, SettingsChildCoordin
9598
),
9699
NSLocalizedString(
97100
"ABOUT_API_ACCESS_BODY_2",
101+
tableName: "APIAccess",
98102
value: """
99103
On some networks, where various types of censorship are being used, the API servers might \
100104
not be directly reachable.
@@ -103,6 +107,7 @@ class ListAccessMethodCoordinator: Coordinator, Presenting, SettingsChildCoordin
103107
),
104108
NSLocalizedString(
105109
"ABOUT_API_ACCESS_BODY_3",
110+
tableName: "APIAccess",
106111
value: """
107112
This feature allows you to circumvent that censorship by adding custom ways to access the \
108113
API via proxies and similar methods.

Diff for: ios/MullvadVPN/Coordinators/Settings/IPOverride/IPOverrideCoordinator.swift

+49
Original file line numberDiff line numberDiff line change
@@ -47,4 +47,53 @@ extension IPOverrideCoordinator: IPOverrideViewControllerDelegate {
4747

4848
presentationContext.present(customNavigationController, animated: true)
4949
}
50+
51+
func presentAbout() {
52+
let header = NSLocalizedString(
53+
"IP_OVERRIDE_HEADER",
54+
tableName: "IPOverride",
55+
value: "IP Override",
56+
comment: ""
57+
)
58+
let body = [
59+
NSLocalizedString(
60+
"IP_OVERRIDE_BODY_1",
61+
tableName: "IPOverride",
62+
value: """
63+
On some networks, where various types of censorship are being used, our server IP addresses are \
64+
sometimes blocked.
65+
""",
66+
comment: ""
67+
),
68+
NSLocalizedString(
69+
"IP_OVERRIDE_BODY_2",
70+
tableName: "IPOverride",
71+
value: """
72+
To circumvent this you can import a file or a text, provided by our support team, \
73+
with new IP addresses that override the default addresses of the servers in the Select location view.
74+
""",
75+
comment: ""
76+
),
77+
NSLocalizedString(
78+
"IP_OVERRIDE_BODY_3",
79+
tableName: "IPOverride",
80+
value: """
81+
If you are having issues connecting to VPN servers, please contact support.
82+
""",
83+
comment: ""
84+
),
85+
]
86+
87+
let aboutController = AboutViewController(header: header, preamble: nil, body: body)
88+
let aboutNavController = UINavigationController(rootViewController: aboutController)
89+
90+
aboutController.navigationItem.rightBarButtonItem = UIBarButtonItem(
91+
systemItem: .done,
92+
primaryAction: UIAction { [weak aboutNavController] _ in
93+
aboutNavController?.dismiss(animated: true)
94+
}
95+
)
96+
97+
navigationController.present(aboutNavController, animated: true)
98+
}
5099
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
//
2+
// IPOverrideHeaderView.swift
3+
// MullvadVPN
4+
//
5+
// Created by Jon Petersson on 2024-03-20.
6+
// Copyright © 2024 Mullvad VPN AB. All rights reserved.
7+
//
8+
9+
import UIKit
10+
11+
/// Header view pinned at the top of ``IPOverrideViewController``.
12+
class IPOverrideHeaderView: UIView, UITextViewDelegate {
13+
/// Event handler invoked when user taps on the link to learn more about API access.
14+
var onAbout: (() -> Void)?
15+
16+
private let textView = UITextView()
17+
18+
override init(frame: CGRect) {
19+
super.init(frame: frame)
20+
21+
textView.backgroundColor = .clear
22+
textView.dataDetectorTypes = .link
23+
textView.isSelectable = true
24+
textView.isEditable = false
25+
textView.isScrollEnabled = false
26+
textView.contentInset = .zero
27+
textView.textContainerInset = .zero
28+
textView.attributedText = makeAttributedString()
29+
textView.linkTextAttributes = defaultLinkAttributes
30+
textView.textContainer.lineFragmentPadding = 0
31+
textView.delegate = self
32+
33+
directionalLayoutMargins = .zero
34+
35+
addSubviews()
36+
}
37+
38+
required init?(coder: NSCoder) {
39+
fatalError("init(coder:) has not been implemented")
40+
}
41+
42+
private let defaultTextAttributes: [NSAttributedString.Key: Any] = [
43+
.font: UIFont.systemFont(ofSize: 13),
44+
.foregroundColor: UIColor.ContentHeading.textColor,
45+
]
46+
47+
private let defaultLinkAttributes: [NSAttributedString.Key: Any] = [
48+
.font: UIFont.systemFont(ofSize: 13),
49+
.foregroundColor: UIColor.ContentHeading.linkColor,
50+
]
51+
52+
private func makeAttributedString() -> NSAttributedString {
53+
let body = NSLocalizedString(
54+
"IP_OVERRIDE_HEADER_BODY",
55+
tableName: "IPOverride",
56+
value: "Import files or text with new IP addresses for the servers in the Select location view.",
57+
comment: ""
58+
)
59+
let link = NSLocalizedString(
60+
"IP_OVERRIDE_HEADER_LINK",
61+
tableName: "IPOverride",
62+
value: "About IP override...",
63+
comment: ""
64+
)
65+
66+
var linkAttributes = defaultLinkAttributes
67+
linkAttributes[.link] = "#"
68+
69+
let paragraphStyle = NSMutableParagraphStyle()
70+
paragraphStyle.lineBreakMode = .byWordWrapping
71+
72+
let attributedString = NSMutableAttributedString()
73+
attributedString.append(NSAttributedString(string: body, attributes: defaultTextAttributes))
74+
attributedString.append(NSAttributedString(string: " ", attributes: defaultTextAttributes))
75+
attributedString.append(NSAttributedString(string: link, attributes: linkAttributes))
76+
attributedString.addAttribute(
77+
.paragraphStyle,
78+
value: paragraphStyle,
79+
range: NSRange(location: 0, length: attributedString.length)
80+
)
81+
return attributedString
82+
}
83+
84+
private func addSubviews() {
85+
addConstrainedSubviews([textView]) {
86+
textView.pinEdgesToSuperviewMargins()
87+
}
88+
}
89+
90+
func textView(
91+
_ textView: UITextView,
92+
shouldInteractWith URL: URL,
93+
in characterRange: NSRange,
94+
interaction: UITextItemInteraction
95+
) -> Bool {
96+
onAbout?()
97+
return false
98+
}
99+
100+
@available(iOS 17.0, *)
101+
func textView(_ textView: UITextView, menuConfigurationFor textItem: UITextItem, defaultMenu: UIMenu) -> UITextItem
102+
.MenuConfiguration? {
103+
return nil
104+
}
105+
106+
@available(iOS 17.0, *)
107+
func textView(_ textView: UITextView, primaryActionFor textItem: UITextItem, defaultAction: UIAction) -> UIAction? {
108+
if case .link = textItem.content {
109+
return UIAction { [weak self] _ in
110+
self?.onAbout?()
111+
}
112+
}
113+
return nil
114+
}
115+
}

0 commit comments

Comments
 (0)