Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix inconsistent spacing between paragraphs #6422

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 10 additions & 6 deletions ios/MullvadVPN.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -275,7 +275,7 @@
58BDEB992A98F4ED00F578F2 /* AnyTransport.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58BDEB982A98F4ED00F578F2 /* AnyTransport.swift */; };
58BDEB9B2A98F58600F578F2 /* TimeServerProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58BDEB9A2A98F58600F578F2 /* TimeServerProxy.swift */; };
58BDEB9D2A98F69E00F578F2 /* MemoryCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58BDEB9C2A98F69E00F578F2 /* MemoryCache.swift */; };
58BE4B9D2B18A85B007EA1D3 /* NSAttributedString+Markdown.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58DFF7CF2B02560400F864E0 /* NSAttributedString+Markdown.swift */; };
58BE4B9D2B18A85B007EA1D3 /* NSAttributedString+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58DFF7CF2B02560400F864E0 /* NSAttributedString+Extensions.swift */; };
58BFA5C622A7C97F00A6173D /* RelayCacheTracker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58BFA5C522A7C97F00A6173D /* RelayCacheTracker.swift */; };
58BFA5CC22A7CE1F00A6173D /* ApplicationConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58BFA5CB22A7CE1F00A6173D /* ApplicationConfiguration.swift */; };
58C3A4B222456F1B00340BDB /* AccountInputGroupView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58C3A4B122456F1A00340BDB /* AccountInputGroupView.swift */; };
Expand Down Expand Up @@ -390,7 +390,7 @@
58D22435294C975B0029F5F8 /* Operations.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 58D223A5294C8A480029F5F8 /* Operations.framework */; platformFilter = ios; };
58DDA18F2ABC32380039C360 /* Timings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58DDA18E2ABC32380039C360 /* Timings.swift */; };
58DF28A52417CB4B00E836B0 /* StorePaymentManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58DF28A42417CB4B00E836B0 /* StorePaymentManager.swift */; };
58DFF7D02B02560400F864E0 /* NSAttributedString+Markdown.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58DFF7CF2B02560400F864E0 /* NSAttributedString+Markdown.swift */; };
58DFF7D02B02560400F864E0 /* NSAttributedString+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58DFF7CF2B02560400F864E0 /* NSAttributedString+Extensions.swift */; };
58DFF7D22B0256A300F864E0 /* MarkdownStylingOptions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58DFF7D12B0256A300F864E0 /* MarkdownStylingOptions.swift */; };
58DFF7D32B02570000F864E0 /* MarkdownStylingOptions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58DFF7D12B0256A300F864E0 /* MarkdownStylingOptions.swift */; };
58DFF7D82B02774C00F864E0 /* ListItemPickerViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58DFF7D72B02774C00F864E0 /* ListItemPickerViewController.swift */; };
Expand Down Expand Up @@ -605,6 +605,7 @@
7ADCB2DA2B6A730400C88F89 /* IPOverrideRepositoryStub.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7ADCB2D92B6A730400C88F89 /* IPOverrideRepositoryStub.swift */; };
7AE044BB2A935726003915D8 /* Routing.h in Headers */ = {isa = PBXBuildFile; fileRef = 7A88DCD02A8FABBE00D2FF0E /* Routing.h */; settings = {ATTRIBUTES = (Public, ); }; };
7AE2414A2C20682B0076CE33 /* FormsheetPresentationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7AE241482C20682B0076CE33 /* FormsheetPresentationController.swift */; };
7AE90B682C2D726000375A60 /* NSParagraphStyle+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7AE90B672C2D726000375A60 /* NSParagraphStyle+Extensions.swift */; };
7AEBA52C2C22C65B0018BEC5 /* TimeInterval+Timeout.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7AEBA52B2C22C65B0018BEC5 /* TimeInterval+Timeout.swift */; };
7AED35CC2BD13F60002A67D1 /* ApplicationConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58BFA5CB22A7CE1F00A6173D /* ApplicationConfiguration.swift */; };
7AED35CD2BD13FC4002A67D1 /* ApplicationTarget.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58C76A072A33850E00100D75 /* ApplicationTarget.swift */; };
Expand Down Expand Up @@ -1796,7 +1797,7 @@
58D229B6298D1D5200BB5A2D /* URLRequestProxy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = URLRequestProxy.swift; sourceTree = "<group>"; };
58DDA18E2ABC32380039C360 /* Timings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Timings.swift; sourceTree = "<group>"; };
58DF28A42417CB4B00E836B0 /* StorePaymentManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StorePaymentManager.swift; sourceTree = "<group>"; };
58DFF7CF2B02560400F864E0 /* NSAttributedString+Markdown.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NSAttributedString+Markdown.swift"; sourceTree = "<group>"; };
58DFF7CF2B02560400F864E0 /* NSAttributedString+Extensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NSAttributedString+Extensions.swift"; sourceTree = "<group>"; };
58DFF7D12B0256A300F864E0 /* MarkdownStylingOptions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MarkdownStylingOptions.swift; sourceTree = "<group>"; };
58DFF7D72B02774C00F864E0 /* ListItemPickerViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListItemPickerViewController.swift; sourceTree = "<group>"; };
58DFF7D92B02862E00F864E0 /* ShadowsocksCipherOptions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShadowsocksCipherOptions.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -1991,6 +1992,7 @@
7ADCB2D72B6A6EB300C88F89 /* AnyRelay.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnyRelay.swift; sourceTree = "<group>"; };
7ADCB2D92B6A730400C88F89 /* IPOverrideRepositoryStub.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IPOverrideRepositoryStub.swift; sourceTree = "<group>"; };
7AE241482C20682B0076CE33 /* FormsheetPresentationController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FormsheetPresentationController.swift; sourceTree = "<group>"; };
7AE90B672C2D726000375A60 /* NSParagraphStyle+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NSParagraphStyle+Extensions.swift"; sourceTree = "<group>"; };
7AEBA52B2C22C65B0018BEC5 /* TimeInterval+Timeout.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "TimeInterval+Timeout.swift"; sourceTree = "<group>"; };
7AEF7F192AD00F52006FE45D /* AppMessageHandler.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppMessageHandler.swift; sourceTree = "<group>"; };
7AF10EB12ADE859200C090B9 /* AlertViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AlertViewController.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -3011,9 +3013,10 @@
7AF9BE8F2A39F26000DBFEDB /* Collection+Sorting.swift */,
7A0C0F622A979C4A0058EFCE /* Coordinator+Router.swift */,
5811DE4F239014550011EB53 /* NEVPNStatus+Debug.swift */,
58DFF7CF2B02560400F864E0 /* NSAttributedString+Markdown.swift */,
58DFF7CF2B02560400F864E0 /* NSAttributedString+Extensions.swift */,
5827B0C42B14D3E800CCBBA1 /* NSDiffableDataSourceSnapshot+Reconfigure.swift */,
587D9675288989DB00CD8F1C /* NSLayoutConstraint+Helpers.swift */,
7AE90B672C2D726000375A60 /* NSParagraphStyle+Extensions.swift */,
5871FB9F254C26BF0051A0A4 /* NSRegularExpression+IPAddress.swift */,
06FAE67828F83CA50033DD93 /* RESTCreateApplePaymentResponse+Localization.swift */,
58B9EB142489139B00095626 /* RESTError+Display.swift */,
Expand Down Expand Up @@ -5494,7 +5497,7 @@
A9A5FA162ACB05160083449F /* RotateKeyOperation.swift in Sources */,
F072D3CF2C07122400906F64 /* MultihopUpdaterTests.swift in Sources */,
F09D04B52AE93CB6003D4F89 /* OutgoingConnectionProxy+Stub.swift in Sources */,
58BE4B9D2B18A85B007EA1D3 /* NSAttributedString+Markdown.swift in Sources */,
58BE4B9D2B18A85B007EA1D3 /* NSAttributedString+Extensions.swift in Sources */,
A9A5FA172ACB05160083449F /* SendTunnelProviderMessageOperation.swift in Sources */,
7A83A0C62B29A750008B5CE7 /* APIAccessMethodsTests.swift in Sources */,
A9A5FA182ACB05160083449F /* SetAccountOperation.swift in Sources */,
Expand Down Expand Up @@ -5784,6 +5787,7 @@
5820EDA9288FE064006BF4E4 /* DeviceManagementInteractor.swift in Sources */,
7A9CCCB92A96302800DD6A34 /* LocationCoordinator.swift in Sources */,
58FB865A26EA214400F188BC /* RelayCacheTrackerObserver.swift in Sources */,
7AE90B682C2D726000375A60 /* NSParagraphStyle+Extensions.swift in Sources */,
581DFAEC2B1770C1005D6D1C /* AccessMethodViewModel+NavigationItem.swift in Sources */,
58ACF64D26567A5000ACE4B7 /* CustomSwitch.swift in Sources */,
F0DA874B2A9CBACB006044F1 /* AccountNumberRow.swift in Sources */,
Expand Down Expand Up @@ -5942,7 +5946,7 @@
5878A27329091D6D0096FC88 /* TunnelBlockObserver.swift in Sources */,
A9E034642ABB302000E59A5A /* UIEdgeInsets+Extensions.swift in Sources */,
58CEB2E92AFBBA4A00E6E088 /* AddAccessMethodCoordinator.swift in Sources */,
58DFF7D02B02560400F864E0 /* NSAttributedString+Markdown.swift in Sources */,
58DFF7D02B02560400F864E0 /* NSAttributedString+Extensions.swift in Sources */,
58E0A98827C8F46300FE6BDD /* Tunnel.swift in Sources */,
7A12D0762B062D5C00E9602D /* URLSessionProtocol.swift in Sources */,
58ACF64F26567A7100ACE4B7 /* CustomSwitchContainer.swift in Sources */,
Expand Down
6 changes: 4 additions & 2 deletions ios/MullvadVPN/Coordinators/ApplicationCoordinator.swift
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,7 @@ final class ApplicationCoordinator: Coordinator, Presenting, RootContainerViewCo
Continues application flow by evaluating what route to present next.
*/
private func continueFlow(animated: Bool) {
var nextRoutes = evaluateNextRoutes()
let nextRoutes = evaluateNextRoutes()

for nextRoute in nextRoutes {
router.present(nextRoute, animated: animated)
Expand Down Expand Up @@ -413,7 +413,9 @@ final class ApplicationCoordinator: Coordinator, Presenting, RootContainerViewCo
coordinator.didLogout = { [weak self] preferredAccountNumber in
guard let self else { return }
router.dismissAll(.primary, animated: true)
continueFlow(animated: true)
DispatchQueue.main.async {
self.continueFlow(animated: true)
}
preferredAccountNumberSubject.send(preferredAccountNumber)
}

Expand Down
2 changes: 0 additions & 2 deletions ios/MullvadVPN/Coordinators/WelcomeCoordinator.swift
Original file line number Diff line number Diff line change
Expand Up @@ -90,9 +90,7 @@ extension WelcomeCoordinator: WelcomeViewControllerDelegate {
This is the name assigned to the device. Each device logged in on a \
Mullvad account gets a unique name that helps \
you identify it when you manage your devices in the app or on the website.
You can have up to 5 devices logged in on one Mullvad account.
If you log out, the device and the device name is removed. \
When you log back in again, the device will get a new name.
""",
Expand Down
52 changes: 52 additions & 0 deletions ios/MullvadVPN/Extensions/NSAttributedString+Extensions.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
//
// NSAttributedString+Markdown.swift
// MullvadVPN
//
// Created by pronebird on 19/11/2021.
// Copyright © 2021 Mullvad VPN AB. All rights reserved.
//

import UIKit

extension NSAttributedString {
enum MarkdownElement {
case bold
}

convenience init(
markdownString: String,
options: MarkdownStylingOptions,
applyEffect: ((MarkdownElement, String) -> [NSAttributedString.Key: Any])? = nil
) {
let attributedString = NSMutableAttributedString()
let components = markdownString.components(separatedBy: "**")

for (stringIndex, string) in components.enumerated() {
var attributes: [NSAttributedString.Key: Any] = [:]

if stringIndex % 2 == 0 {
attributes[.font] = options.font
} else {
attributes[.font] = options.boldFont
attributes.merge(applyEffect?(.bold, string) ?? [:], uniquingKeysWith: { $1 })
}

attributedString.append(NSAttributedString(string: string, attributes: attributes))
}

attributedString.addAttribute(
.paragraphStyle,
value: options.paragraphStyle,
range: NSRange(location: 0, length: attributedString.length)
)

self.init(attributedString: attributedString)
}
}

extension NSMutableAttributedString {
func apply(paragraphStyle: NSParagraphStyle) {
let attributeRange = NSRange(location: 0, length: length)
addAttribute(.paragraphStyle, value: paragraphStyle, range: attributeRange)
}
}
60 changes: 0 additions & 60 deletions ios/MullvadVPN/Extensions/NSAttributedString+Markdown.swift

This file was deleted.

20 changes: 20 additions & 0 deletions ios/MullvadVPN/Extensions/NSParagraphStyle+Extensions.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
//
// NSParagraphStyle+Extensions.swift
// MullvadVPN
//
// Created by Jon Petersson on 2024-06-27.
// Copyright © 2024 Mullvad VPN AB. All rights reserved.
//

import UIKit

extension NSParagraphStyle {
static var alert: NSParagraphStyle {
let style = NSMutableParagraphStyle()

style.paragraphSpacing = 16
style.lineBreakMode = .byWordWrapping

return style
}
}
24 changes: 7 additions & 17 deletions ios/MullvadVPN/View controllers/Alert/AlertViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -225,16 +225,11 @@ class AlertViewController: UIViewController {
private func addMessage(_ message: String) {
let label = UILabel()

let font = UIFont.preferredFont(forTextStyle: .body)
let style = NSMutableParagraphStyle()
style.paragraphSpacing = 16
style.lineBreakMode = .byWordWrapping

label.attributedText = NSAttributedString(
string: message,
attributes: [.paragraphStyle: style]
)
label.font = font
let message = NSMutableAttributedString(string: message)
message.apply(paragraphStyle: .alert)

label.attributedText = message
label.font = .preferredFont(forTextStyle: .body)
label.textColor = .white.withAlphaComponent(0.8)
label.adjustsFontForContentSizeCategory = true
label.numberOfLines = 0
Expand All @@ -245,14 +240,9 @@ class AlertViewController: UIViewController {
private func addMessage(_ message: NSAttributedString) {
let label = UILabel()

let style = NSMutableParagraphStyle()
style.paragraphSpacing = 16
style.lineBreakMode = .byWordWrapping

let message = NSMutableAttributedString(attributedString: message)
let attributeRange = NSRange(location: 0, length: message.length)
message.removeAttribute(.paragraphStyle, range: attributeRange)
message.addAttribute(.paragraphStyle, value: style, range: attributeRange)
message.removeAttribute(.paragraphStyle, range: NSRange(location: 0, length: message.length))
message.apply(paragraphStyle: .alert)

label.attributedText = message
label.textColor = .white.withAlphaComponent(0.8)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,22 +32,25 @@ class SetupAccountCompletedContentView: UIView {

private let commentLabel: UILabel = {
let label = UILabel()
label.font = .preferredFont(forTextStyle: .body)
label.textColor = .white
label.adjustsFontForContentSizeCategory = true
label.lineBreakMode = .byWordWrapping
label.numberOfLines = .zero
label.text = NSLocalizedString(

let message = NSMutableAttributedString(string: NSLocalizedString(
"CREATED_ACCOUNT_CONFIRMATION_PAGE_BODY",
tableName: "CreatedAccountConfirmation",
value: """
Go ahead and start using the app to begin reclaiming your online privacy.
To continue your journey as a privacy ninja, \
visit our website to pick up other privacy-friendly habits and tools.
""",
comment: ""
)
))
message.apply(paragraphStyle: .alert)

label.attributedText = message
label.font = .preferredFont(forTextStyle: .body)
label.textColor = .white
label.adjustsFontForContentSizeCategory = true
label.numberOfLines = .zero

return label
}()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,8 @@ class LogoutDialogueView: UIView {

private let messageLabel: UILabel = {
let label = UILabel()
label.font = .preferredFont(forTextStyle: .callout, weight: .semibold)
label.numberOfLines = .zero
label.lineBreakMode = .byWordWrapping
label.textColor = .white
label.text = NSLocalizedString(

let message = NSMutableAttributedString(string: NSLocalizedString(
"ACCOUNT_NUMBER_AS_VOUCHER_INPUT_ERROR_BODY",
tableName: "CreateAccountRedeemingVoucher",
value: """
Expand All @@ -33,7 +30,14 @@ class LogoutDialogueView: UIView {
If so, click log out below to log in with the other account number.
""",
comment: ""
)
))
message.apply(paragraphStyle: .alert)

label.attributedText = message
label.font = .preferredFont(forTextStyle: .callout, weight: .semibold)
label.numberOfLines = .zero
label.textColor = .white

return label
}()

Expand Down
Loading
Loading