Fixup missing colours and use resolved colours in UIKit.

Fix the confetti colour when using DesignKit.
Pin swift packages.
Fix UI tests target.
This commit is contained in:
Doug 2022-05-27 20:42:44 +01:00 committed by Doug
parent ef5365ab24
commit 545b641e53
30 changed files with 195 additions and 51 deletions

8
.gitignore vendored
View file

@ -30,8 +30,14 @@ vendor/
Pods/
## Ignore project files as we generate them with xcodegen (https://github.com/yonaskolb/XcodeGen)
# Plus ridiculous workaround to unignore the Package.resolved file for SwiftPM.
*.xcodeproj
*.xcworkspace
*.xcworkspace/*
!Riot.xcworkspace/xcshareddata
Riot.xcworkspace/xcshareddata/*
!Riot.xcworkspace/xcshareddata/swiftpm/
Riot.xcworkspace/xcshareddata/swiftpm/*
!Riot.xcworkspace/xcshareddata/swiftpm/Package.resolved
# Fastlane
fastlane/report.xml

View file

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1200"
version = "1.3">
version = "1.7">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES"

View file

@ -0,0 +1,50 @@
{
"pins" : [
{
"identity" : "element-design-tokens",
"kind" : "remoteSourceControl",
"location" : "https://github.com/vector-im/element-design-tokens.git",
"state" : {
"revision" : "4aafdc25ca0e322c0de930d4ec86121f5503023e",
"version" : "0.0.1"
}
},
{
"identity" : "element-x-ios",
"kind" : "remoteSourceControl",
"location" : "https://github.com/vector-im/element-x-ios",
"state" : {
"branch" : "develop",
"revision" : "272fc5000bfe6e15a0f0ea669ef3088c7d163ce7"
}
},
{
"identity" : "maplibre-gl-native-distribution",
"kind" : "remoteSourceControl",
"location" : "https://github.com/maplibre/maplibre-gl-native-distribution",
"state" : {
"revision" : "d761956e81e74d8bdbfba31e0ec3a75616190658",
"version" : "5.12.2"
}
},
{
"identity" : "swift-collections",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-collections",
"state" : {
"revision" : "48254824bb4248676bf7ce56014ff57b142b77eb",
"version" : "1.0.2"
}
},
{
"identity" : "swiftui-introspect",
"kind" : "remoteSourceControl",
"location" : "https://github.com/siteline/SwiftUI-Introspect.git",
"state" : {
"revision" : "f2616860a41f9d9932da412a8978fec79c06fe24",
"version" : "0.1.4"
}
}
],
"version" : 2
}

View file

@ -0,0 +1,91 @@
//
// Copyright 2022 New Vector Ltd
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
import UIKit
import DesignTokens
extension UIColor {
/// The colors from DesignKit, resolved for light mode only.
static let elementLight = ElementUIColorsResolved(dynamicColors: element, userInterfaceStyle: .light)
/// The colors from DesignKit, resolved for dark mode only.
static let elementDark = ElementUIColorsResolved(dynamicColors: element, userInterfaceStyle: .dark)
}
/// The dynamic colors from DesignKit, resolved to light or dark mode for use in the UIKit themes.
///
/// As Element doesn't (currently) update the app's `UIUserInterfaceStyle` when selecting
/// a custom theme, the dynamic colors provided by DesignKit need resolving for each theme to
/// prevent them from respecting the interface style and rendering in the wrong style.
@objcMembers public class ElementUIColorsResolved: NSObject {
// MARK: Compound
public let accent: UIColor
public let alert: UIColor
public let primaryContent: UIColor
public let secondaryContent: UIColor
public let tertiaryContent: UIColor
public let quaternaryContent: UIColor
public let quinaryContent: UIColor
public let system: UIColor
public let background: UIColor
public let namesAndAvatars: [UIColor]
// MARK: Legacy
public let quarterlyContent: UIColor
public let navigation: UIColor
public let tile: UIColor
public let separator: UIColor
// MARK: Setup
public init(dynamicColors: ElementUIColors, userInterfaceStyle: UIUserInterfaceStyle) {
let traitCollection = UITraitCollection(userInterfaceStyle: userInterfaceStyle)
self.accent = dynamicColors.accent.resolvedColor(with: traitCollection)
self.alert = dynamicColors.alert.resolvedColor(with: traitCollection)
self.primaryContent = dynamicColors.primaryContent.resolvedColor(with: traitCollection)
self.secondaryContent = dynamicColors.secondaryContent.resolvedColor(with: traitCollection)
self.tertiaryContent = dynamicColors.tertiaryContent.resolvedColor(with: traitCollection)
self.quaternaryContent = dynamicColors.quaternaryContent.resolvedColor(with: traitCollection)
self.quinaryContent = dynamicColors.quinaryContent.resolvedColor(with: traitCollection)
self.system = dynamicColors.system.resolvedColor(with: traitCollection)
self.background = dynamicColors.background.resolvedColor(with: traitCollection)
self.namesAndAvatars = [
dynamicColors.globalAzure.resolvedColor(with: traitCollection),
dynamicColors.globalGrape.resolvedColor(with: traitCollection),
dynamicColors.globalVerde.resolvedColor(with: traitCollection),
dynamicColors.globalPolly.resolvedColor(with: traitCollection),
dynamicColors.globalMelon.resolvedColor(with: traitCollection),
dynamicColors.globalAqua.resolvedColor(with: traitCollection),
dynamicColors.globalPrune.resolvedColor(with: traitCollection),
dynamicColors.globalKiwi.resolvedColor(with: traitCollection)
]
// Legacy colours
self.quarterlyContent = dynamicColors.quaternaryContent.resolvedColor(with: traitCollection)
self.navigation = dynamicColors.system.resolvedColor(with: traitCollection)
if userInterfaceStyle == .light {
self.tile = UIColor(rgb: 0xF3F8FD)
self.separator = dynamicColors.quinaryContent.resolvedColor(with: traitCollection)
} else {
self.tile = dynamicColors.quinaryContent.resolvedColor(with: traitCollection)
self.separator = dynamicColors.system.resolvedColor(with: traitCollection)
}
super.init()
}
}

View file

@ -22,30 +22,10 @@ import DesignTokens
@objc public protocol ThemeV2 {
/// Colors object
var colors: ElementUIColors { get }
var colors: ElementUIColorsResolved { get }
/// Fonts object
var fonts: ElementUIFonts { get }
/// may contain more design components in future, like icons, audio files etc.
}
#warning("Temporary missing colors")
public extension ElementUIColors {
var quarterlyContent: UIColor { quaternaryContent }
var navigation: UIColor { system }
var tile: UIColor { system }
var separator: UIColor { system }
var namesAndAvatars: [UIColor] {
[
globalAzure,
globalGrape,
globalVerde,
globalPolly,
globalMelon,
globalAqua,
globalPrune,
globalKiwi
]
}
}

View file

@ -182,7 +182,7 @@ class DarkTheme: NSObject, Theme {
}
// MARK: - Theme v2
var colors = UIColor.element
var colors = UIColor.elementDark
var fonts = UIFont.element

View file

@ -186,7 +186,7 @@ class DefaultTheme: NSObject, Theme {
}
// MARK: - Theme v2
var colors = UIColor.element
var colors = UIColor.elementLight
var fonts = UIFont.element
}

View file

@ -127,6 +127,9 @@ class VectorHostingController: UIHostingController<AnyView> {
}
private func update(theme: Theme) {
// Ensure dynamic colors are shown correctly when the theme is the opposite appearance to the system.
overrideUserInterfaceStyle = theme.userInterfaceStyle
if let navigationBar = self.navigationController?.navigationBar {
theme.applyStyle(onNavigationBar: navigationBar, withModernScrollEdgeAppearance: enableNavigationBarScrollEdgeAppearance)
}

View file

@ -65,9 +65,12 @@ fileprivate extension Color {
///
/// SceneKit works in a colorspace with a linear gamma, which is why this conversion is necessary.
var floatComponents: [Float]? {
// Get the CGColor from a UIColor as it is nil on Color when loaded from an asset catalog.
let cgColor = UIColor(self).cgColor
guard
let colorSpace = CGColorSpace(name: CGColorSpace.extendedLinearSRGB),
let linearColor = cgColor?.converted(to: colorSpace, intent: .defaultIntent, options: nil),
let linearColor = cgColor.converted(to: colorSpace, intent: .defaultIntent, options: nil),
let components = linearColor.components
else { return nil }

View file

@ -59,3 +59,9 @@ struct EffectsView: UIViewRepresentable {
}
}
}
struct EffectsView_Previews: PreviewProvider {
static var previews: some View {
EffectsView(effect: .confetti)
}
}

View file

@ -36,11 +36,14 @@ public protocol ThemeSwiftUIType {
/// may contain more design components in future, like icons, audio files etc.
}
#warning("Temporary missing colors")
public extension ElementColors {
var quarterlyContent: Color { quaternaryContent }
var navigation: Color { system }
var tile: Color { system }
// MARK: - Legacy
var legacyTile: Color {
let dynamicColor = UIColor { $0.userInterfaceStyle == .light ? .elementLight.tile : .elementDark.tile }
return Color(dynamicColor)
}
// TODO: Generate in DesignTokens repo.
var namesAndAvatars: [Color] {
[
globalAzure,

View file

@ -50,7 +50,7 @@ struct BorderedInputFieldStyle: TextFieldStyle {
if (theme.identifier == ThemeIdentifier.dark) {
return (isEnabled ? theme.colors.primaryContent : theme.colors.tertiaryContent)
} else {
return (isEnabled ? theme.colors.primaryContent : theme.colors.quarterlyContent)
return (isEnabled ? theme.colors.primaryContent : theme.colors.quaternaryContent)
}
}

View file

@ -47,7 +47,7 @@ struct ClearViewModifier: ViewModifier {
}) {
Image(systemName: "xmark.circle.fill")
.renderingMode(.template)
.foregroundColor(theme.colors.quarterlyContent)
.foregroundColor(theme.colors.quaternaryContent)
}
.padding(.top, alignment == .top ? 8 : 0)
.padding(.bottom, alignment == .bottom ? 8 : 0)

View file

@ -56,7 +56,7 @@ struct MultilineTextField: View {
return theme.colors.accent
}
return theme.colors.quarterlyContent
return theme.colors.quaternaryContent
}
private var borderWidth: CGFloat {

View file

@ -55,7 +55,7 @@ struct OptionButton: View {
}
}
Spacer()
Image(systemName: "chevron.right").font(.system(size: 16, weight: .regular)).foregroundColor(theme.colors.quarterlyContent)
Image(systemName: "chevron.right").font(.system(size: 16, weight: .regular)).foregroundColor(theme.colors.quaternaryContent)
}
.padding(EdgeInsets(top: 15, leading: 16, bottom: 15, trailing: 16))
.background(theme.colors.quinaryContent)

View file

@ -38,7 +38,7 @@ struct SearchBar: View {
}
.padding(8)
.padding(.horizontal, 25)
.background(theme.colors.navigation)
.background(theme.colors.system)
.cornerRadius(8)
.padding(.leading)
.padding(.trailing, isEditing ? 8 : 16)
@ -46,7 +46,7 @@ struct SearchBar: View {
HStack {
Image(systemName: "magnifyingglass")
.renderingMode(.template)
.foregroundColor(theme.colors.quarterlyContent)
.foregroundColor(theme.colors.quaternaryContent)
.frame(minWidth: 0, maxWidth: .infinity, alignment: .leading)
if isEditing && !text.isEmpty {
@ -55,7 +55,7 @@ struct SearchBar: View {
}) {
Image(systemName: "multiply.circle.fill")
.renderingMode(.template)
.foregroundColor(theme.colors.quarterlyContent)
.foregroundColor(theme.colors.quaternaryContent)
}
}
}

View file

@ -68,7 +68,7 @@ struct SecondaryActionButtonStyle_Previews: PreviewProvider {
Text("Custom")
.foregroundColor(theme.colors.secondaryContent)
}
.buttonStyle(SecondaryActionButtonStyle(customColor: theme.colors.quarterlyContent))
.buttonStyle(SecondaryActionButtonStyle(customColor: theme.colors.quaternaryContent))
}
.padding()
}

View file

@ -89,7 +89,7 @@ struct WaitOverlay: ViewModifier {
}
.padding(12)
.background(RoundedRectangle(cornerRadius: 8, style: .continuous)
.fill(theme.colors.navigation.opacity(0.9)))
.fill(theme.colors.system.opacity(0.9)))
}
.edgesIgnoringSafeArea(.all)
.transition(.opacity)

View file

@ -47,7 +47,7 @@ struct OnboardingSplashScreenPageIndicator: View {
ForEach(0..<pageCount) { index in
Circle()
.frame(width: 8, height: 8)
.foregroundColor(index == pageIndex ? .accentColor : theme.colors.quarterlyContent)
.foregroundColor(index == pageIndex ? .accentColor : theme.colors.quaternaryContent)
}
}
}

View file

@ -45,7 +45,7 @@ struct RoomAccessTypeChooserRow: View {
Spacer()
Image(systemName: isSelected ? "checkmark.circle.fill" : "circle")
.renderingMode(.template)
.foregroundColor(isSelected ? theme.colors.accent : theme.colors.quarterlyContent)
.foregroundColor(isSelected ? theme.colors.accent : theme.colors.quaternaryContent)
}
if let badgeText = badgeText {
Text(badgeText)

View file

@ -37,7 +37,7 @@ struct RoomRestrictedAccessSpaceChooserSelector: View {
Button(VectorL10n.cancel) {
viewModel.send(viewAction: .cancel)
}
.foregroundColor(viewModel.viewState.loading ? theme.colors.quarterlyContent : theme.colors.accent)
.foregroundColor(viewModel.viewState.loading ? theme.colors.quaternaryContent : theme.colors.accent)
.opacity(viewModel.viewState.loading ? 0.7 : 1)
.disabled(viewModel.viewState.loading)
}
@ -45,7 +45,7 @@ struct RoomRestrictedAccessSpaceChooserSelector: View {
Button(VectorL10n.done) {
viewModel.send(viewAction: .done)
}
.foregroundColor(viewModel.viewState.selectedItemIds.isEmpty || viewModel.viewState.loading ? theme.colors.quarterlyContent : theme.colors.accent)
.foregroundColor(viewModel.viewState.selectedItemIds.isEmpty || viewModel.viewState.loading ? theme.colors.quaternaryContent : theme.colors.accent)
.opacity(viewModel.viewState.selectedItemIds.isEmpty || viewModel.viewState.loading ? 0.7 : 1)
.disabled(viewModel.viewState.selectedItemIds.isEmpty || viewModel.viewState.loading)
}

View file

@ -89,10 +89,10 @@ struct TimelinePollAnswerOptionButton: View {
var progressViewAccentColor: Color {
guard !poll.closed else {
return (answerOption.winner ? theme.colors.accent : theme.colors.quarterlyContent)
return (answerOption.winner ? theme.colors.accent : theme.colors.quaternaryContent)
}
return answerOption.selected ? theme.colors.accent : theme.colors.quarterlyContent
return answerOption.selected ? theme.colors.accent : theme.colors.quaternaryContent
}
}

View file

@ -25,7 +25,7 @@ struct FormInputFieldStyle: TextFieldStyle {
private var textColor: Color {
if !isEnabled {
return theme.colors.quarterlyContent
return theme.colors.quaternaryContent
}
return theme.colors.primaryContent
}

View file

@ -144,7 +144,7 @@ struct MatrixItemChooser: View {
}
.padding(.vertical, 4)
.padding(.horizontal)
.background(theme.colors.tile)
.background(theme.colors.legacyTile)
}
}

View file

@ -52,7 +52,7 @@ struct MatrixItemChooserSectionHeader: View {
.frame(maxWidth: .infinity, alignment: .leading)
.padding(.vertical, 8)
.padding(.horizontal)
.background(theme.colors.navigation)
.background(theme.colors.system)
.cornerRadius(8)
}
}

View file

@ -39,7 +39,7 @@ struct SpaceSettings: View {
.padding(.bottom, 32)
}
}
.background(theme.colors.navigation.ignoresSafeArea())
.background(theme.colors.system.ignoresSafeArea())
.waitOverlay(show: viewModel.viewState.isLoading, allowUserInteraction: false)
.ignoresSafeArea(.container, edges: .bottom)
.frame(maxHeight: .infinity)

View file

@ -67,7 +67,7 @@ struct SpaceSettingsOptionListItem: View {
Image(systemName: "chevron.right")
.renderingMode(.template)
.font(.system(size: 16, weight: .regular))
.foregroundColor(theme.colors.quarterlyContent)
.foregroundColor(theme.colors.quaternaryContent)
}
.opacity(isEnabled ? 1 : 0.5)
}

View file

@ -32,6 +32,7 @@ targets:
dependencies:
- target: RiotSwiftUI
- package: DesignKit
settings:
base:

1
changelog.d/6276.change Normal file
View file

@ -0,0 +1 @@
DesignKit: Replace the local DesignKit target with the shared Swift package from ElementX.

View file

@ -41,7 +41,7 @@ include:
packages:
DesignKit:
url: https://github.com/vector-im/element-x-ios
branch: doug/designkit
branch: develop
Mapbox:
url: https://github.com/maplibre/maplibre-gl-native-distribution
minVersion: 5.12.2