-
Notifications
You must be signed in to change notification settings - Fork 366
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
8f5363a
commit 4dc7f05
Showing
10 changed files
with
384 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
88 changes: 88 additions & 0 deletions
88
ios/MullvadVPN/View controllers/Tunnel/FeatureIndicators/ChipFeatures.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
// | ||
// ChipFeatures.swift | ||
// MullvadVPN | ||
// | ||
// Created by Mojgan on 2024-12-06. | ||
// Copyright © 2024 Mullvad VPN AB. All rights reserved. | ||
// | ||
import Foundation | ||
import MullvadSettings | ||
import SwiftUI | ||
|
||
protocol ChipFeature { | ||
var isEnabled: Bool { get } | ||
func name() -> LocalizedStringKey | ||
} | ||
|
||
struct DaitaFeature: ChipFeature { | ||
let settings: LatestTunnelSettings | ||
|
||
var isEnabled: Bool { | ||
settings.daita.daitaState.isEnabled | ||
} | ||
|
||
func name() -> LocalizedStringKey { | ||
LocalizedStringKey("DAITA") | ||
} | ||
} | ||
|
||
struct QuantumResistanceFeature: ChipFeature { | ||
let settings: LatestTunnelSettings | ||
var isEnabled: Bool { | ||
settings.tunnelQuantumResistance.isEnabled | ||
} | ||
|
||
func name() -> LocalizedStringKey { | ||
LocalizedStringKey("Quantum resistance") | ||
} | ||
} | ||
|
||
struct MultihopFeature: ChipFeature { | ||
let settings: LatestTunnelSettings | ||
var isEnabled: Bool { | ||
settings.tunnelMultihopState.isEnabled | ||
} | ||
|
||
func name() -> LocalizedStringKey { | ||
LocalizedStringKey("Multihop") | ||
} | ||
} | ||
|
||
struct ObfuscationFeature: ChipFeature { | ||
let settings: LatestTunnelSettings | ||
|
||
var isEnabled: Bool { | ||
settings.wireGuardObfuscation.state.isEnabled | ||
} | ||
|
||
func name() -> LocalizedStringKey { | ||
LocalizedStringKey("Obfuscation") | ||
} | ||
} | ||
|
||
struct DNSFeature: ChipFeature { | ||
let settings: LatestTunnelSettings | ||
|
||
var isEnabled: Bool { | ||
settings.dnsSettings.enableCustomDNS || !settings.dnsSettings.blockingOptions.isEmpty | ||
} | ||
|
||
func name() -> LocalizedStringKey { | ||
if !settings.dnsSettings.blockingOptions.isEmpty { | ||
return LocalizedStringKey("DNS content blockers") | ||
} | ||
return LocalizedStringKey("Custom DNS") | ||
} | ||
} | ||
|
||
struct IPOverrideFeature: ChipFeature { | ||
let repository: IPOverrideRepositoryProtocol | ||
|
||
var isEnabled: Bool { | ||
!repository.fetchAll().isEmpty | ||
} | ||
|
||
func name() -> LocalizedStringKey { | ||
LocalizedStringKey("Server IP override") | ||
} | ||
} |
89 changes: 89 additions & 0 deletions
89
ios/MullvadVPN/View controllers/Tunnel/FeatureIndicators/ChipsView/ChipContainerView.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
// | ||
// ChipContainerView.swift | ||
// MullvadVPN | ||
// | ||
// Created by Mojgan on 2024-12-05. | ||
// Copyright © 2024 Mullvad VPN AB. All rights reserved. | ||
// | ||
|
||
import Foundation | ||
import SwiftUI | ||
struct ChipContainerView<ViewModel>: View where ViewModel: ChipViewModelProtocol { | ||
@ObservedObject var viewModel: ViewModel | ||
@State private var isExpanded = false | ||
|
||
init(viewModel: ViewModel) { | ||
self.viewModel = viewModel | ||
} | ||
|
||
var body: some View { | ||
GeometryReader { geo in | ||
let containerWidth = geo.size.width | ||
let chipsPerLine = 2 | ||
if isExpanded { | ||
ZStack(alignment: .topLeading) { | ||
createChipViews(chips: viewModel.chips, containerWidth: containerWidth) | ||
} | ||
} else { | ||
HStack { | ||
createChipViews(chips: Array(viewModel.chips.prefix(chipsPerLine)), containerWidth: containerWidth) | ||
if viewModel.chips.count > chipsPerLine { | ||
Button(action: { | ||
withAnimation { | ||
isExpanded.toggle() | ||
} | ||
}, label: { | ||
Text(LocalizedStringKey("\(viewModel.chips.count - chipsPerLine) more...")) | ||
.font(.body) | ||
.lineLimit(1) | ||
.multilineTextAlignment(.center) | ||
.foregroundStyle(UIColor.primaryTextColor.color) | ||
}) | ||
} | ||
Spacer() | ||
} | ||
} | ||
} | ||
} | ||
|
||
private func createChipViews(chips: [ChipModel], containerWidth: CGFloat) -> some View { | ||
var width = CGFloat.zero | ||
var height = CGFloat.zero | ||
|
||
return ForEach(chips) { data in | ||
ChipView(item: data) | ||
.padding(UIMetrics.padding4) | ||
.alignmentGuide(.leading) { dimension in | ||
if abs(width - dimension.width) > containerWidth { | ||
width = 0 | ||
height -= dimension.height | ||
} | ||
let result = width | ||
if data.id == viewModel.chips.last!.id { | ||
width = 0 | ||
} else { | ||
width -= dimension.width | ||
} | ||
return result | ||
} | ||
.alignmentGuide(.top) { _ in | ||
let result = height | ||
if data.id == viewModel.chips.last!.id { | ||
height = 0 | ||
} | ||
return result | ||
} | ||
} | ||
} | ||
} | ||
|
||
#Preview("ChipContainerView") { | ||
ChipContainerView(viewModel: MockChipViewModel()) | ||
} | ||
|
||
private class MockChipViewModel: ChipViewModelProtocol { | ||
@Published var chips: [ChipModel] = (5 ..< 20).map { index in | ||
let letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" | ||
return ChipModel(name: LocalizedStringKey(String((0 ..< index).map { _ in letters.randomElement()! }))) | ||
} | ||
} |
15 changes: 15 additions & 0 deletions
15
ios/MullvadVPN/View controllers/Tunnel/FeatureIndicators/ChipsView/ChipModel.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
// | ||
// FeatureChipModel.swift | ||
// MullvadVPN | ||
// | ||
// Created by Mojgan on 2024-12-05. | ||
// Copyright © 2024 Mullvad VPN AB. All rights reserved. | ||
// | ||
|
||
import Foundation | ||
import SwiftUI | ||
|
||
struct ChipModel: Identifiable { | ||
let id = UUID() | ||
let name: LocalizedStringKey | ||
} |
39 changes: 39 additions & 0 deletions
39
ios/MullvadVPN/View controllers/Tunnel/FeatureIndicators/ChipsView/ChipView.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
// | ||
// FeatureChipView.swift | ||
// MullvadVPN | ||
// | ||
// Created by Mojgan on 2024-12-05. | ||
// Copyright © 2024 Mullvad VPN AB. All rights reserved. | ||
// | ||
|
||
import SwiftUI | ||
|
||
struct ChipView: View { | ||
let item: ChipModel | ||
var body: some View { | ||
HStack(spacing: UIMetrics.padding4) { | ||
Text(item.name) | ||
.font(.body) | ||
.lineLimit(1) | ||
.multilineTextAlignment(.center) | ||
.foregroundStyle(UIColor.primaryTextColor.color) | ||
} | ||
.padding(.horizontal, UIMetrics.padding8) | ||
.padding(.vertical, UIMetrics.padding4) | ||
.background( | ||
RoundedRectangle(cornerRadius: 8.0) | ||
.stroke( | ||
UIColor.primaryColor.color, | ||
lineWidth: 1 | ||
) | ||
.background( | ||
RoundedRectangle(cornerRadius: 8.0) | ||
.fill(UIColor.secondaryColor.color) | ||
) | ||
) | ||
} | ||
} | ||
|
||
#Preview { | ||
ChipView(item: ChipModel(name: LocalizedStringKey("Example"))) | ||
} |
24 changes: 24 additions & 0 deletions
24
...ullvadVPN/View controllers/Tunnel/FeatureIndicators/ChipsView/ChipViewModelProtocol.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
// | ||
// ChipViewModelProtocol.swift | ||
// MullvadVPN | ||
// | ||
// Created by Mojgan on 2024-12-05. | ||
// Copyright © 2024 Mullvad VPN AB. All rights reserved. | ||
// | ||
|
||
import SwiftUI | ||
protocol ChipViewModelProtocol: ObservableObject { | ||
var chips: [ChipModel] { get } | ||
} | ||
|
||
class FeaturesIndicatoresMockViewModel: ChipViewModelProtocol { | ||
@Published var chips: [ChipModel] = [ | ||
ChipModel(name: LocalizedStringKey("DAITA")), | ||
ChipModel(name: LocalizedStringKey("Obfuscation")), | ||
ChipModel(name: LocalizedStringKey("Quantum resistance")), | ||
ChipModel(name: LocalizedStringKey("Multihop")), | ||
ChipModel(name: LocalizedStringKey("DNS content blockers")), | ||
ChipModel(name: LocalizedStringKey("Custom DNS")), | ||
ChipModel(name: LocalizedStringKey("Server IP override")), | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.