Skip to content

Commit

Permalink
Update cell layout and behavior for obfuscation methods
Browse files Browse the repository at this point in the history
  • Loading branch information
rablador authored and buggmagnet committed Oct 30, 2024
1 parent 72b4281 commit 80eb27b
Show file tree
Hide file tree
Showing 16 changed files with 282 additions and 74 deletions.
10 changes: 9 additions & 1 deletion ios/MullvadVPN.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -466,6 +466,8 @@
7A27E3C92CAE85710088BCFF /* SettingsInfoButtonItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A27E3C82CAE85660088BCFF /* SettingsInfoButtonItem.swift */; };
7A27E3CB2CAE861D0088BCFF /* SettingsViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A27E3CA2CAE86170088BCFF /* SettingsViewModel.swift */; };
7A27E3CD2CB814EF0088BCFF /* DAITAInfoView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A27E3CC2CB814EA0088BCFF /* DAITAInfoView.swift */; };
7A27E3CF2CBD4A8C0088BCFF /* SelectableSettingsDetailsCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A27E3CE2CBD4A830088BCFF /* SelectableSettingsDetailsCell.swift */; };
7A27E3D12CC299F90088BCFF /* VPNSettingsDetailsButtonItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A27E3D02CC299E60088BCFF /* VPNSettingsDetailsButtonItem.swift */; };
7A28826A2BA8336600FD9F20 /* VPNSettingsCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A2882692BA8336600FD9F20 /* VPNSettingsCoordinator.swift */; };
7A2960F62A963F7500389B82 /* AlertCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A2960F52A963F7500389B82 /* AlertCoordinator.swift */; };
7A2960FD2A964BB700389B82 /* AlertPresentation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A2960FC2A964BB700389B82 /* AlertPresentation.swift */; };
Expand Down Expand Up @@ -1803,6 +1805,8 @@
7A27E3C82CAE85660088BCFF /* SettingsInfoButtonItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsInfoButtonItem.swift; sourceTree = "<group>"; };
7A27E3CA2CAE86170088BCFF /* SettingsViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsViewModel.swift; sourceTree = "<group>"; };
7A27E3CC2CB814EA0088BCFF /* DAITAInfoView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DAITAInfoView.swift; sourceTree = "<group>"; };
7A27E3CE2CBD4A830088BCFF /* SelectableSettingsDetailsCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SelectableSettingsDetailsCell.swift; sourceTree = "<group>"; };
7A27E3D02CC299E60088BCFF /* VPNSettingsDetailsButtonItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPNSettingsDetailsButtonItem.swift; sourceTree = "<group>"; };
7A2882692BA8336600FD9F20 /* VPNSettingsCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPNSettingsCoordinator.swift; sourceTree = "<group>"; };
7A2960F52A963F7500389B82 /* AlertCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AlertCoordinator.swift; sourceTree = "<group>"; };
7A2960FC2A964BB700389B82 /* AlertPresentation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AlertPresentation.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -2802,7 +2806,9 @@
isa = PBXGroup;
children = (
7A9FA1432A2E3FE5000B728D /* CheckableSettingsCell.swift */,
F041BE4E2C983C2B0083EC28 /* DAITASettingsPromptItem.swift */,
7A1A264A2A29D65E00B978AA /* SelectableSettingsCell.swift */,
7A27E3CE2CBD4A830088BCFF /* SelectableSettingsDetailsCell.swift */,
5819C2162729595500D6EC38 /* SettingsAddDNSEntryCell.swift */,
582BB1AE229566420055B6EF /* SettingsCell.swift */,
5864AF0029C7879B005B0CD9 /* SettingsCellFactory.swift */,
Expand All @@ -2815,7 +2821,6 @@
7A42DEC82A05164100B209BE /* SettingsInputCell.swift */,
58677711290976FB006F721F /* SettingsInteractor.swift */,
5867770F290975E8006F721F /* SettingsInteractorFactory.swift */,
F041BE4E2C983C2B0083EC28 /* DAITASettingsPromptItem.swift */,
58ACF64A26553C3F00ACE4B7 /* SettingsSwitchCell.swift */,
58CCA01122424D11004F3011 /* SettingsViewController.swift */,
7A27E3CA2CAE86170088BCFF /* SettingsViewModel.swift */,
Expand Down Expand Up @@ -2845,6 +2850,7 @@
5864AF0229C7879B005B0CD9 /* VPNSettingsCellFactory.swift */,
584D26C3270C855A004EA533 /* VPNSettingsDataSource.swift */,
587EB6732714520600123C75 /* VPNSettingsDataSourceDelegate.swift */,
7A27E3D02CC299E60088BCFF /* VPNSettingsDetailsButtonItem.swift */,
7A6F2FAE2AFE36E7006D0856 /* VPNSettingsInfoButtonItem.swift */,
5871167E2910035700D41AAC /* VPNSettingsInteractor.swift */,
58ACF6482655365700ACE4B7 /* VPNSettingsViewController.swift */,
Expand Down Expand Up @@ -5658,6 +5664,7 @@
A91614D62B10B26B00F416EB /* TunnelControlViewModel.swift in Sources */,
7A5869972B32EA4500640D27 /* AppButton.swift in Sources */,
586C0D8F2B03D88100E7CDD7 /* ProxyProtocolConfigurationItemIdentifier.swift in Sources */,
7A27E3CF2CBD4A8C0088BCFF /* SelectableSettingsDetailsCell.swift in Sources */,
7A27E3CB2CAE861D0088BCFF /* SettingsViewModel.swift in Sources */,
588527B2276B3F0700BAA373 /* LoadTunnelConfigurationOperation.swift in Sources */,
7A9F29392CABFAFC005F2089 /* InfoHeaderView.swift in Sources */,
Expand Down Expand Up @@ -5854,6 +5861,7 @@
F0DA87492A9CBA9F006044F1 /* AccountDeviceRow.swift in Sources */,
58FF9FE42B075BDD00E4C97D /* EditAccessMethodItemIdentifier.swift in Sources */,
5878A27329091D6D0096FC88 /* TunnelBlockObserver.swift in Sources */,
7A27E3D12CC299F90088BCFF /* VPNSettingsDetailsButtonItem.swift in Sources */,
A9E034642ABB302000E59A5A /* UIEdgeInsets+Extensions.swift in Sources */,
58CEB2E92AFBBA4A00E6E088 /* AddAccessMethodCoordinator.swift in Sources */,
58DFF7D02B02560400F864E0 /* NSAttributedString+Extensions.swift in Sources */,
Expand Down
3 changes: 2 additions & 1 deletion ios/MullvadVPN/Classes/AccessbilityIdentifier.swift
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,8 @@ public enum AccessibilityIdentifier: String {
case wireGuardObfuscationAutomatic
case wireGuardObfuscationPort
case wireGuardObfuscationOff
case wireGuardObfuscationOn
case wireGuardObfuscationUdpOverTcp
case wireGuardObfuscationShadowsocks
case wireGuardPort

// Custom DNS
Expand Down
2 changes: 2 additions & 0 deletions ios/MullvadVPN/UI appearance/UIMetrics.swift
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,8 @@ enum UIMetrics {
static let customListsCellHeight: CGFloat = 44
static let apiAccessSwitchCellTrailingMargin: CGFloat = apiAccessInsetLayoutMargins.trailing - 4
static let apiAccessPickerListContentInsetTop: CGFloat = 16
static let verticalDividerHeight: CGFloat = 22
static let detailsButtonSize: CGFloat = 60
}

enum InAppBannerNotification {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ class CheckableSettingsCell: SettingsCell {
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)

setLeftView(checkboxView, spacing: UIMetrics.SettingsCell.checkableSettingsCellLeftViewSpacing)
setCheckboxView()
selectedBackgroundView?.backgroundColor = .clear
}

Expand All @@ -24,8 +24,7 @@ class CheckableSettingsCell: SettingsCell {

override func prepareForReuse() {
super.prepareForReuse()

setLeftView(checkboxView, spacing: UIMetrics.SettingsCell.checkableSettingsCellLeftViewSpacing)
setCheckboxView()
}

override func setSelected(_ selected: Bool, animated: Bool) {
Expand All @@ -39,4 +38,17 @@ class CheckableSettingsCell: SettingsCell {

contentView.layoutMargins.left = 0
}

private func setCheckboxView() {
setLeadingView { superview in
superview.addConstrainedSubviews([checkboxView]) {
checkboxView.pinEdgesToSuperview(PinnableEdges([
.leading(0),
.trailing(UIMetrics.SettingsCell.checkableSettingsCellLeftViewSpacing),
.top(0),
.bottom(0),
]))
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import UIKit
class SelectableSettingsCell: SettingsCell {
let tickImageView: UIImageView = {
let imageView = UIImageView(image: UIImage(named: "IconTick"))
imageView.contentMode = .center
imageView.tintColor = .white
imageView.alpha = 0
return imageView
Expand All @@ -19,7 +20,7 @@ class SelectableSettingsCell: SettingsCell {
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)

setLeftView(tickImageView, spacing: UIMetrics.SettingsCell.selectableSettingsCellLeftViewSpacing)
setTickView()
selectedBackgroundView?.backgroundColor = UIColor.Cell.Background.selected
}

Expand All @@ -29,13 +30,23 @@ class SelectableSettingsCell: SettingsCell {

override func prepareForReuse() {
super.prepareForReuse()

setLeftView(tickImageView, spacing: UIMetrics.SettingsCell.selectableSettingsCellLeftViewSpacing)
setTickView()
}

override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)

tickImageView.alpha = selected ? 1 : 0
}

private func setTickView() {
setLeadingView { superview in
superview.addConstrainedSubviews([tickImageView]) {
tickImageView.pinEdgesToSuperview(PinnableEdges([
.leading(0), .top(0), .bottom(0),
.trailing(UIMetrics.SettingsCell.selectableSettingsCellLeftViewSpacing),
]))
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
//
// SelectableSettingsDetailsCell.swift
// MullvadVPN
//
// Created by Jon Petersson on 2024-10-14.
// Copyright © 2024 Mullvad VPN AB. All rights reserved.
//

import UIKit

class SelectableSettingsDetailsCell: SelectableSettingsCell {
let viewContainer = UIView()

var buttonAction: (() -> Void)?

override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: .subtitle, reuseIdentifier: reuseIdentifier)

let actionButton = IncreasedHitButton(type: .system)
var actionButtonConfiguration = actionButton.configuration ?? .plain()
actionButtonConfiguration.image = UIImage(systemName: "ellipsis")?
.withRenderingMode(.alwaysOriginal)
.withTintColor(.white)
actionButton.configuration = actionButtonConfiguration

actionButton.addTarget(
self,
action: #selector(didPressActionButton),
for: .touchUpInside
)

let separatorView = UIView()
separatorView.backgroundColor = .secondaryColor

viewContainer.addConstrainedSubviews([separatorView, actionButton]) {
separatorView.leadingAnchor.constraint(equalTo: viewContainer.leadingAnchor, constant: 16)
separatorView.centerYAnchor.constraint(equalTo: viewContainer.centerYAnchor)
separatorView.heightAnchor.constraint(equalToConstant: UIMetrics.SettingsCell.verticalDividerHeight)
separatorView.widthAnchor.constraint(equalToConstant: 1)

actionButton.pinEdgesToSuperview(.all().excluding(.leading))
actionButton.leadingAnchor.constraint(equalTo: separatorView.trailingAnchor)
actionButton.widthAnchor.constraint(equalToConstant: UIMetrics.SettingsCell.detailsButtonSize)
}

setViewContainer()
}

required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}

override func prepareForReuse() {
super.prepareForReuse()
setViewContainer()
}

private func setViewContainer() {
#if DEBUG
setTrailingView { superview in
superview.addConstrainedSubviews([viewContainer]) {
viewContainer.pinEdgesToSuperview()
}
}
#endif
}

// MARK: - Actions

@objc private func didPressActionButton() {
buttonAction?()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
import UIKit

class SettingsAddDNSEntryCell: SettingsCell {
var action: (() -> Void)?
var tapAction: (() -> Void)?

override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
Expand All @@ -29,7 +29,7 @@ class SettingsAddDNSEntryCell: SettingsCell {

@objc func handleTap(_ sender: UIGestureRecognizer) {
if case .ended = sender.state {
action?()
tapAction?()
}
}
}
Loading

0 comments on commit 80eb27b

Please sign in to comment.