Skip to content

Commit 231a3d5

Browse files
author
Rover Release Bot 🤖
committed
Releasing 4.2.3
1 parent 90a687f commit 231a3d5

File tree

12 files changed

+211
-72
lines changed

12 files changed

+211
-72
lines changed
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// Copyright (c) 2020-present, Rover Labs, Inc. All rights reserved.
2+
// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
3+
// copy, modify, and distribute this software in source code or binary form for use
4+
// in connection with the web services and APIs provided by Rover.
5+
//
6+
// This copyright notice shall be included in all copies or substantial portions of
7+
// the software.
8+
//
9+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
10+
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
11+
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
12+
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
13+
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
14+
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
15+
16+
import Foundation
17+
18+
internal extension Array where Element == String {
19+
func toStringDictionary() -> [String: String] {
20+
var iterator = makeIterator()
21+
var result: UserInfo = [:]
22+
while var current = iterator.next() {
23+
if let next = iterator.next() {
24+
result[current] = next
25+
current = next
26+
}
27+
}
28+
29+
return result
30+
}
31+
}

Sources/Experiences/Experiences/Extensions/Collection+items.swift

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,10 +70,9 @@ extension Collection {
7070
let startAt = max(limit.startAt - 1, 0)
7171
let lowerBound = min(startAt, result.indices.upperBound)
7272
let limitedRange = result.indices.clamped(to: lowerBound..<result.endIndex)
73-
result = Array(result[limitedRange])
73+
result = Array(result[limitedRange].prefix(limit.show))
7474
}
7575

76-
result = Array(result.prefix(limit?.show ?? 100))
7776
return result
7877
}
7978
}

Sources/Experiences/Experiences/Model/ExperienceModel.swift

Lines changed: 2 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -117,10 +117,10 @@ final class ExperienceModel: Decodable {
117117
appearance = try container.decode(Appearance.self, forKey: .appearance)
118118

119119
let parameterArray = try container.decode([String].self, forKey: .urlParameters)
120-
self.urlParameters = parameterArray.toUserInfo()
120+
self.urlParameters = parameterArray.toStringDictionary()
121121

122122
let userArray = try container.decode([String].self, forKey: .userInfo)
123-
self.userInfo = userArray.toUserInfo()
123+
self.userInfo = userArray.toStringDictionary()
124124

125125
authorizers = try container.decode([DocumentAuthorizer].self, forKey: .authorizers)
126126

@@ -142,18 +142,3 @@ final class ExperienceModel: Decodable {
142142
try coordinator.resolveRelationships(nodes: nodes, documentColors: colors, documentGradients: gradients)
143143
}
144144
}
145-
146-
fileprivate extension Array where Element == String {
147-
func toUserInfo() -> UserInfo {
148-
var iterator = makeIterator()
149-
var result: UserInfo = [:]
150-
while var current = iterator.next() {
151-
if let next = iterator.next() {
152-
result[current] = next
153-
current = next
154-
}
155-
}
156-
157-
return result
158-
}
159-
}

Sources/Experiences/Experiences/Model/Value Types/DocumentFont.swift

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,3 +63,34 @@ public extension DocumentFont {
6363
self.sources.map { $0.assetUrl }
6464
}
6565
}
66+
67+
extension DocumentFont {
68+
func fontForStyle(_ textStyle: SwiftUI.Font.TextStyle) -> CustomFont {
69+
switch textStyle {
70+
case .largeTitle:
71+
return self.largeTitle
72+
case .title:
73+
return self.title
74+
case.title2:
75+
return self.title2
76+
case .title3:
77+
return self.title3
78+
case .headline:
79+
return self.headline
80+
case .body:
81+
return self.body
82+
case .callout:
83+
return self.callout
84+
case .subheadline:
85+
return self.subheadline
86+
case .footnote:
87+
return self.footnote
88+
case .caption:
89+
return self.caption
90+
case .caption2:
91+
return self.caption2
92+
default:
93+
return self.body
94+
}
95+
}
96+
}

Sources/Experiences/Experiences/Model/Value Types/Metadata.swift

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,4 +21,18 @@ public struct Metadata: Codable, Hashable {
2121
self.properties = properties
2222
self.tags = tags
2323
}
24+
25+
private enum CodingKeys: String, CodingKey {
26+
case properties
27+
case tags
28+
}
29+
30+
public init(from decoder: Decoder) throws {
31+
let container = try decoder.container(keyedBy: CodingKeys.self)
32+
33+
let propertiesArray: Array = try container.decode([String].self, forKey: .properties)
34+
properties = propertiesArray.toStringDictionary()
35+
36+
tags = try container.decode(Set<String>.self, forKey: .tags)
37+
}
2438
}

Sources/Experiences/Experiences/UI/Model/Font+uikit.swift

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import UIKit
1919
import SwiftUI
2020

2121
extension RoverExperiences.Font {
22-
var uikitFont: UIFont? {
22+
func uikitFont(with experience: ExperienceModel?) -> UIFont? {
2323
switch self {
2424
case .dynamic(let textStyle, let emphases):
2525
let font = UIFont.preferredFont(forTextStyle: textStyle.uiTextStyle)
@@ -37,12 +37,18 @@ extension RoverExperiences.Font {
3737
return UIFont.systemFont(ofSize: scaledSize, weight: weight.uiWeight)
3838

3939
case .document(let fontFamily, let textStyle):
40-
//TODO: how do I get the list of fonts from the document here? fontFamily must be converted to font name.
4140
let font: UIFont?
42-
43-
//TODO: the app takes the size of the custom font from the font style. But in order to achieve this, the font family must first be converted to a font name.
44-
let scaledSize = UIFontMetrics.default.scaledValue(for: 14)
45-
font = UIFont(name: fontFamily, size: scaledSize)
41+
42+
if let experience = experience,
43+
let documentFont = experience.fonts.first(where: { $0.fontFamily == fontFamily }) {
44+
let customFont = documentFont.fontForStyle(textStyle)
45+
let scaledSize = UIFontMetrics.default.scaledValue(for: customFont.size)
46+
font = UIFont(name: customFont.fontName,
47+
size: scaledSize)
48+
} else {
49+
let scaledSize = UIFontMetrics.default.scaledValue(for: 14)
50+
font = UIFont(name: fontFamily, size: scaledSize)
51+
}
4652

4753
if font == nil {
4854
rover_log(.debug, "Missing font %@", fontFamily)

Sources/Experiences/Experiences/UI/Modifiers/FontModifier.swift

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,27 +20,34 @@ import UIKit
2020

2121
struct FontModifier: ViewModifier {
2222
@Environment(\.sizeCategory) private var sizeCategory
23+
@Environment(\.experience) private var experience
2324
@State private var uiFont: SwiftUI.Font
2425

2526
var font: RoverExperiences.Font
2627

27-
init(font: RoverExperiences.Font) {
28+
init(font: RoverExperiences.Font,
29+
experience: ExperienceModel?) {
2830
self.font = font
29-
self._uiFont = .init(initialValue: getUIFont(for: font))
31+
self._uiFont =
32+
.init(initialValue: getUIFont(
33+
for: font,
34+
experience: experience))
3035
}
3136

3237
func body(content: Content) -> some View {
3338
content
3439
.font(uiFont)
3540
.onReceive(NotificationCenter.default.publisher(for: ExperienceManager.didRegisterCustomFontNotification)) { _ in
36-
uiFont = getUIFont(for: font)
41+
uiFont = getUIFont(for: font,
42+
experience: experience)
3743
}
3844
}
3945
}
4046

4147

42-
private func getUIFont(for font: RoverExperiences.Font) -> SwiftUI.Font {
43-
if let uifont = font.uikitFont {
48+
private func getUIFont(for font: RoverExperiences.Font,
49+
experience: ExperienceModel?) -> SwiftUI.Font {
50+
if let uifont = font.uikitFont(with: experience) {
4451
return SwiftUI.Font(uifont)
4552
}
4653

Sources/Experiences/Experiences/UI/ScreenViewController.swift

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ class ScreenViewController: UIViewController, UIScrollViewDelegate {
141141
if let navBar = navBar {
142142
navigationItem.configure(
143143
navBar: navBar,
144-
stringTable: experience.localization,
144+
experience: experience,
145145
data: data,
146146
urlParameters: urlParameters,
147147
userInfo: userInfo,
@@ -223,7 +223,8 @@ class ScreenViewController: UIViewController, UIScrollViewDelegate {
223223
navigationItem.configureInlineAppearance(
224224
navBar: navBar,
225225
traits: traitCollection,
226-
isScrolling: isScrolling
226+
isScrolling: isScrolling,
227+
experience: experience
227228
)
228229

229230
navigationController?.navigationBar.adjustTintColor(

Sources/Experiences/Experiences/UI/UIKitExtensions.swift

Lines changed: 44 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -83,26 +83,42 @@ extension UINavigationBar {
8383

8484

8585
extension UINavigationItem {
86-
func configure(navBar: NavBar, stringTable: StringTable, data: Any?, urlParameters: [String: String], userInfo: [String: Any], traits: UITraitCollection, buttonHandler: @escaping (NavBarButton) -> Void) {
87-
88-
title = stringTable.resolve(key: navBar.title).evaluatingExpressions(data: data, urlParameters: urlParameters, userInfo: userInfo)
86+
func configure(
87+
navBar: NavBar,
88+
experience: ExperienceModel,
89+
data: Any?,
90+
urlParameters: [String: String],
91+
userInfo: [String: Any],
92+
traits: UITraitCollection,
93+
buttonHandler: @escaping (NavBarButton) -> Void
94+
) {
95+
title = experience.localization.resolve(key: navBar.title)
96+
.evaluatingExpressions(
97+
data: data, urlParameters:
98+
urlParameters,
99+
userInfo: userInfo
100+
)
89101

90102
hidesBackButton = navBar.hidesBackButton
91103

92104
switch navBar.titleDisplayMode {
93105
case .large:
94106
largeTitleDisplayMode = .always
95-
configureLargeAppearance(navBar: navBar, traits: traits)
107+
configureLargeAppearance(navBar: navBar, traits: traits, experience: experience)
96108
case .inline:
97109
largeTitleDisplayMode = .never
98-
configureInlineAppearance(navBar: navBar, traits: traits)
110+
configureInlineAppearance(
111+
navBar: navBar,
112+
traits: traits,
113+
experience: experience
114+
)
99115
}
100116

101117
leftBarButtonItems = navBar.children
102118
.compactMap { $0 as? NavBarButton }
103119
.filter { $0.placement == .leading }
104120
.map { navBarButton in
105-
UIBarButtonItem(navBarButton: navBarButton, stringTable: stringTable, data: data, urlParameters: urlParameters, userInfo: userInfo) {
121+
UIBarButtonItem(navBarButton: navBarButton, stringTable: experience.localization, data: data, urlParameters: urlParameters, userInfo: userInfo) {
106122
buttonHandler(navBarButton)
107123
}
108124
}
@@ -111,14 +127,19 @@ extension UINavigationItem {
111127
.compactMap { $0 as? NavBarButton }
112128
.filter { $0.placement == .trailing }
113129
.map { navBarButton in
114-
UIBarButtonItem(navBarButton: navBarButton, stringTable: stringTable, data: data, urlParameters: urlParameters, userInfo: userInfo) {
130+
UIBarButtonItem(navBarButton: navBarButton, stringTable: experience.localization, data: data, urlParameters: urlParameters, userInfo: userInfo) {
115131
buttonHandler(navBarButton)
116132
}
117133
}
118134
.reversed()
119135
}
120136

121-
func configureInlineAppearance(navBar: NavBar, traits: UITraitCollection, isScrolling: Bool = false) {
137+
func configureInlineAppearance(
138+
navBar: NavBar,
139+
traits: UITraitCollection,
140+
isScrolling: Bool = false,
141+
experience: ExperienceModel
142+
) {
122143
guard navBar.titleDisplayMode == .inline else {
123144
return
124145
}
@@ -131,7 +152,7 @@ extension UINavigationItem {
131152
}
132153

133154
let appearance = UINavigationBarAppearance()
134-
appearance.configureFonts(navBar: navBar)
155+
appearance.configureFonts(navBar: navBar, experience: experience)
135156
appearance.configureBackground(background: navBarAppearance.background, traits: traits)
136157
appearance.configureButtonColor(appearance: navBarAppearance, traits: traits)
137158
appearance.configureTitleColor(appearance: navBarAppearance, traits: traits)
@@ -144,13 +165,17 @@ extension UINavigationItem {
144165
}
145166
}
146167

147-
func configureLargeAppearance(navBar: NavBar, traits: UITraitCollection) {
168+
func configureLargeAppearance(
169+
navBar: NavBar,
170+
traits: UITraitCollection,
171+
experience: ExperienceModel
172+
) {
148173
guard navBar.titleDisplayMode == .large else {
149174
return
150175
}
151176

152177
let largeAppearance = UINavigationBarAppearance()
153-
largeAppearance.configureFonts(navBar: navBar)
178+
largeAppearance.configureFonts(navBar: navBar, experience: experience)
154179

155180
let navBarAppearance = navBar.appearance
156181
let navBarAlternateAppearance = navBar.alternateAppearance
@@ -163,7 +188,7 @@ extension UINavigationItem {
163188

164189
if let alternateAppearance = navBarAlternateAppearance {
165190
let inlineAppearance = UINavigationBarAppearance()
166-
inlineAppearance.configureFonts(navBar: navBar)
191+
inlineAppearance.configureFonts(navBar: navBar, experience: experience)
167192
inlineAppearance.configureBackground(background: alternateAppearance.background, traits: traits)
168193
inlineAppearance.configureButtonColor(appearance: alternateAppearance, traits: traits)
169194
inlineAppearance.configureTitleColor(appearance: alternateAppearance, traits: traits)
@@ -180,10 +205,13 @@ extension UINavigationItem {
180205

181206

182207
private extension UINavigationBarAppearance {
183-
func configureFonts(navBar: NavBar) {
184-
titleTextAttributes[.font] = navBar.titleFont.uikitFont
185-
largeTitleTextAttributes[.font] = navBar.largeTitleFont.uikitFont
186-
buttonAppearance.normal.titleTextAttributes[.font] = navBar.buttonFont.uikitFont
208+
func configureFonts(
209+
navBar: NavBar,
210+
experience: ExperienceModel
211+
) {
212+
titleTextAttributes[.font] = navBar.titleFont.uikitFont(with: experience)
213+
largeTitleTextAttributes[.font] = navBar.largeTitleFont.uikitFont(with: experience)
214+
buttonAppearance.normal.titleTextAttributes[.font] = navBar.buttonFont.uikitFont(with: experience)
187215
}
188216

189217
func configureBackground(background: NavBar.Background, traits: UITraitCollection) {

Sources/Experiences/Experiences/UI/Views/TextView.swift

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ struct TextView: View {
2222
@Environment(\.stringTable) private var stringTable
2323
@Environment(\.urlParameters) private var urlParameters
2424
@Environment(\.userInfo) private var userInfo
25+
@Environment(\.experience) private var experience
2526

2627
var text: RoverExperiences.Text
2728

@@ -32,7 +33,8 @@ struct TextView: View {
3233
RealizeColor(self.text.textColor) { textColor in
3334
SwiftUI.Text(transformed(textValue))
3435
.modifier(
35-
FontModifier(font: self.text.font)
36+
FontModifier(font: self.text.font,
37+
experience: experience)
3638
)
3739
.foregroundColor(textColor)
3840
}

0 commit comments

Comments
 (0)