Refactor theme styles
- Hide colors behind styles - Add "Style" suffix
This commit is contained in:
parent
0d8121f73d
commit
6aee88e69a
|
@ -71,43 +71,28 @@ extension View {
|
|||
func themeSecondaryView() -> some View {
|
||||
navigationBarTitleDisplayMode(.inline)
|
||||
}
|
||||
|
||||
func themeLongText() -> some View {
|
||||
lineLimit(1)
|
||||
.truncationMode(.middle)
|
||||
}
|
||||
|
||||
func themeInformativeText() -> some View {
|
||||
font(.title)
|
||||
.foregroundColor(themeSecondaryColor)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: Colors
|
||||
|
||||
extension View {
|
||||
var themeAccentColor: Color {
|
||||
fileprivate var themeAccentColor: Color {
|
||||
Color(Asset.Assets.accentColor.color)
|
||||
}
|
||||
|
||||
var themePrimaryBackgroundColor: Color {
|
||||
fileprivate var themePrimaryBackgroundColor: Color {
|
||||
Color(Asset.Assets.primaryColor.color)
|
||||
}
|
||||
|
||||
var themePrimaryBackground: some View {
|
||||
themePrimaryBackgroundColor
|
||||
.ignoresSafeArea()
|
||||
}
|
||||
|
||||
var themeSecondaryColor: Color {
|
||||
fileprivate var themeSecondaryColor: Color {
|
||||
.secondary
|
||||
}
|
||||
|
||||
var themeLightTextColor: Color {
|
||||
fileprivate var themeLightTextColor: Color {
|
||||
Color(Asset.Assets.lightTextColor.color)
|
||||
}
|
||||
|
||||
var themeErrorColor: Color {
|
||||
fileprivate var themeErrorColor: Color {
|
||||
.red
|
||||
}
|
||||
|
||||
|
@ -124,14 +109,6 @@ extension View {
|
|||
}
|
||||
}
|
||||
|
||||
// MARK: Fonts
|
||||
|
||||
extension View {
|
||||
func themeDebugLogFont() -> some View {
|
||||
font(.system(size: 13, weight: .medium, design: .monospaced))
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: Images
|
||||
|
||||
extension View {
|
||||
|
@ -280,6 +257,55 @@ extension String {
|
|||
}
|
||||
}
|
||||
|
||||
// MARK: Styles
|
||||
|
||||
extension View {
|
||||
var themePrimaryBackground: some View {
|
||||
themePrimaryBackgroundColor
|
||||
.ignoresSafeArea()
|
||||
}
|
||||
|
||||
func themeAccentForegroundStyle() -> some View {
|
||||
foregroundColor(themeAccentColor)
|
||||
}
|
||||
|
||||
func themeSecondaryTextStyle() -> some View {
|
||||
foregroundColor(themeSecondaryColor)
|
||||
}
|
||||
|
||||
func themeLightTextStyle() -> some View {
|
||||
foregroundColor(themeLightTextColor)
|
||||
}
|
||||
|
||||
func themeErrorTextStyle() -> some View {
|
||||
foregroundColor(themeErrorColor)
|
||||
}
|
||||
|
||||
func themeDestructiveButtonStyle() -> some View {
|
||||
foregroundColor(themeErrorColor)
|
||||
}
|
||||
|
||||
@available(iOS 15, *)
|
||||
func themePrimaryTintStyle() -> some View {
|
||||
tint(themePrimaryBackgroundColor)
|
||||
}
|
||||
|
||||
func themeLongTextStyle() -> some View {
|
||||
lineLimit(1)
|
||||
.truncationMode(.middle)
|
||||
}
|
||||
|
||||
func themeInformativeTextStyle() -> some View {
|
||||
multilineTextAlignment(.center)
|
||||
.font(.title)
|
||||
.foregroundColor(themeSecondaryColor)
|
||||
}
|
||||
|
||||
func themeDebugLogStyle() -> some View {
|
||||
font(.system(size: 13, weight: .medium, design: .monospaced))
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: Shortcuts
|
||||
|
||||
extension View {
|
||||
|
|
|
@ -48,12 +48,12 @@ extension View {
|
|||
}
|
||||
}
|
||||
|
||||
func withTrailingText(_ text: String?, color: Color? = nil, truncationMode: Text.TruncationMode = .tail, copyOnTap: Bool = false) -> some View {
|
||||
func withTrailingText(_ text: String?, truncationMode: Text.TruncationMode = .tail, copyOnTap: Bool = false) -> some View {
|
||||
HStack {
|
||||
self
|
||||
Spacer()
|
||||
let trailing = text.map(Text.init)
|
||||
.foregroundColor(color ?? themeSecondaryColor)
|
||||
.themeSecondaryTextStyle()
|
||||
.lineLimit(1)
|
||||
.truncationMode(truncationMode)
|
||||
if copyOnTap {
|
||||
|
@ -73,7 +73,7 @@ extension View {
|
|||
if condition {
|
||||
Spacer()
|
||||
themeCheckmarkImage.asSystemImage
|
||||
.foregroundColor(themeAccentColor)
|
||||
.themeAccentForegroundStyle()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -77,10 +77,10 @@ struct AccountView: View {
|
|||
|
||||
RevealingSecureField(L10n.Account.Items.Password.placeholder, text: $liveAccount.password) {
|
||||
themeConceilImage.asSystemImage
|
||||
.foregroundColor(themeAccentColor)
|
||||
.themeAccentForegroundStyle()
|
||||
} revealImage: {
|
||||
themeRevealImage.asSystemImage
|
||||
.foregroundColor(themeAccentColor)
|
||||
.themeAccentForegroundStyle()
|
||||
}.textContentType(.password)
|
||||
.disableAutocorrection(true)
|
||||
.autocapitalization(.none)
|
||||
|
|
|
@ -64,7 +64,7 @@ enum AddProfileView {
|
|||
private func existingProfileButton(_ header: Profile.Header) -> some View {
|
||||
Button(header.name) {
|
||||
profileName = header.name
|
||||
}.themeLongText()
|
||||
}.themeLongTextStyle()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -70,7 +70,7 @@ struct DebugLogView: View {
|
|||
.edgesIgnoringSafeArea([.leading, .trailing])
|
||||
.onReceive(timer, perform: refreshLog)
|
||||
.navigationTitle(L10n.DebugLog.title)
|
||||
.themeDebugLogFont()
|
||||
.themeDebugLogStyle()
|
||||
}
|
||||
|
||||
private var contentView: some View {
|
||||
|
|
|
@ -120,7 +120,7 @@ struct DonateView: View {
|
|||
} else {
|
||||
product.localizedPrice.map {
|
||||
Text($0)
|
||||
.foregroundColor(themeSecondaryColor)
|
||||
.themeSecondaryTextStyle()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -187,7 +187,7 @@ extension EndpointView.OpenVPNView {
|
|||
|
||||
private func text(forEndpoint endpoint: Endpoint?) -> some View {
|
||||
Text(endpoint?.address ?? L10n.Global.Strings.automatic)
|
||||
.themeLongText()
|
||||
.themeLongTextStyle()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -89,7 +89,7 @@ extension OrganizerView {
|
|||
private var emptyView: some View {
|
||||
VStack {
|
||||
Text(L10n.Organizer.Empty.noProfiles)
|
||||
.themeInformativeText()
|
||||
.themeInformativeTextStyle()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -298,7 +298,7 @@ private struct PurchaseRow: View {
|
|||
} else {
|
||||
product.localizedPrice.map {
|
||||
Text($0)
|
||||
.foregroundColor(themeSecondaryColor)
|
||||
.themeSecondaryTextStyle()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,12 +39,12 @@ struct ProfileHeaderRow: View {
|
|||
} else {
|
||||
hostView
|
||||
}
|
||||
}.themeLongText()
|
||||
}.themeLongTextStyle()
|
||||
.font(.headline)
|
||||
|
||||
if isActive {
|
||||
VPNStatusText()
|
||||
.foregroundColor(themeSecondaryColor)
|
||||
.themeSecondaryTextStyle()
|
||||
.font(.subheadline)
|
||||
}
|
||||
}.frame(height: 60)
|
||||
|
|
|
@ -165,7 +165,7 @@ extension ProfileView {
|
|||
isAskingUninstallVPN = true
|
||||
} label: {
|
||||
Label(L10n.Profile.Items.Uninstall.caption, systemImage: themeDeleteImage)
|
||||
}.foregroundColor(themeErrorColor)
|
||||
}.themeErrorTextStyle()
|
||||
.actionSheet(isPresented: $isAskingUninstallVPN) {
|
||||
ActionSheet(
|
||||
title: Text(L10n.Profile.Alerts.UninstallVpn.message),
|
||||
|
|
|
@ -199,7 +199,7 @@ struct ProviderLocationView: View, ProviderProfileAvailability {
|
|||
}
|
||||
} label: {
|
||||
themeFavoriteActionImage(!isFavoriteLocation(location)).asSystemImage
|
||||
}.tint(themePrimaryBackgroundColor)
|
||||
}.themePrimaryTintStyle()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -35,6 +35,6 @@ struct VersionView: View {
|
|||
versionString: versionString,
|
||||
extraString: L10n.Version.Labels.intro
|
||||
).background(themePrimaryBackground)
|
||||
.foregroundColor(themeLightTextColor)
|
||||
.themeLightTextStyle()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,7 +28,6 @@ import SwiftUI
|
|||
struct WelcomeView: View {
|
||||
var body: some View {
|
||||
Text(L10n.Profile.Welcome.message)
|
||||
.multilineTextAlignment(.center)
|
||||
.themeInformativeText()
|
||||
.themeInformativeTextStyle()
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue