Skip to content

Commit 337a2b6

Browse files
authored
Decouple avatarID from Profile model (#304)
* Decouple the avatar identifier from the model * Update demo app * Update minor version * Allow warnings * Use `profileIdentifier?.avatarIdentifier in the demo screen.
1 parent 4deb714 commit 337a2b6

File tree

10 files changed

+40
-12
lines changed

10 files changed

+40
-12
lines changed

.buildkite/commands/publish-pod.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ echo "--- :rubygems: Setting up Gems"
1212
install_gems
1313

1414
echo "--- :cocoapods: Publishing $PODSPEC_PATH to CocoaPods CDN"
15-
publish_pod --synchronous "$PODSPEC_PATH"
15+
publish_pod --allow-warnings --synchronous "$PODSPEC_PATH"
1616

1717
echo "--- :slack: Notifying Slack"
1818
slack_notify_pod_published "$PODSPEC_PATH" "$SLACK_WEBHOOK"
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#!/bin/bash -eu
22

33
echo "--- :cocoapods: Validate Gravatar.podspec"
4-
validate_podspec Gravatar.podspec
4+
validate_podspec --allow-warnings Gravatar.podspec
55

66
echo "--- :cocoapods: Validate GravatarUI.podspec"
7-
validate_podspec GravatarUI.podspec
7+
validate_podspec --allow-warnings GravatarUI.podspec

Demo/Demo/Gravatar-Demo/DemoProfileConfigurationViewController.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ class DemoProfileConfigurationViewController: UITableViewController {
6666
guard !email.isEmpty else { return }
6767

6868
var config = ProfileViewConfiguration.standard()
69+
config.avatarIdentifier = .email(email)
6970
config.isLoading = true
7071
models[email] = config
7172
snapshot.appendItems([email])
@@ -75,6 +76,7 @@ class DemoProfileConfigurationViewController: UITableViewController {
7576
do {
7677
let profile = try await service.fetch(with: .email(email))
7778
models[email] = .standard(model: profile)
79+
models[email]?.avatarIdentifier = .email(email)
7880
snapshot.reloadItems([email])
7981
await dataSource.apply(snapshot)
8082
} catch APIError.responseError(let reason) where reason.httpStatusCode == 404 {

Demo/Demo/Gravatar-Demo/DemoProfilePresentationStylesViewController.swift

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ class DemoProfilePresentationStylesViewController: DemoBaseProfileViewController
3535
}
3636
}
3737
else {
38-
let viewController = ProfileViewController(configuration: newConfig(), viewModel: .init(), profileIdentifier: profileIdentifier)
38+
let viewController = ProfileViewController(configuration: newConfig(profileIdentifier: profileIdentifier), viewModel: .init(), profileIdentifier: profileIdentifier)
3939
self.profileViewController = viewController
4040
presentInBottomSheet(viewController)
4141
}
@@ -74,7 +74,7 @@ class DemoProfilePresentationStylesViewController: DemoBaseProfileViewController
7474
bottomSheetNavigationViewController?.navigationBar.scrollEdgeAppearance = appearance
7575
}
7676

77-
func newConfig() -> ProfileViewConfiguration {
77+
func newConfig(profileIdentifier: ProfileIdentifier?) -> ProfileViewConfiguration {
7878
var config: ProfileViewConfiguration
7979
switch preferredProfileStyle {
8080
case .large:
@@ -86,6 +86,7 @@ class DemoProfilePresentationStylesViewController: DemoBaseProfileViewController
8686
case .summary:
8787
config = ProfileViewConfiguration.summary(palette: preferredPaletteType)
8888
}
89+
config.avatarIdentifier = profileIdentifier?.avatarIdentifier
8990
if customizeAvatarSwitchWithLabel.isOn {
9091
config.avatarConfiguration.borderColor = .green
9192
config.avatarConfiguration.borderWidth = 3

Demo/Demo/Gravatar-Demo/DemoProfileViewsViewController.swift

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,11 @@ class DemoProfileViewsViewController: DemoBaseProfileViewController {
8484

8585
guard largeProfileView.isLoading == false else { return }
8686

87+
largeProfileView.loadAvatar(with: .email(email), defaultAvatarOption: .status404, options: [.transition(.fade(0.2))])
88+
largeProfileSummaryView.loadAvatar(with: .email(email), defaultAvatarOption: .status404, options: [.transition(.fade(0.2))])
89+
profileView.loadAvatar(with: .email(email), defaultAvatarOption: .status404, options: [.transition(.fade(0.2))])
90+
profileSummaryView.loadAvatar(with: .email(email), defaultAvatarOption: .status404, options: [.transition(.fade(0.2))])
91+
8792
updateLoading(isLoading: true)
8893
let service = ProfileService()
8994
Task {
@@ -92,16 +97,12 @@ class DemoProfileViewsViewController: DemoBaseProfileViewController {
9297
let profile = try await service.fetch(with: identifier)
9398
largeProfileView.update(with: profile)
9499
largeProfileView.profileButtonStyle = .view
95-
largeProfileView.loadAvatar(with: profile.avatarIdentifier, options: [.transition(.fade(0.2))])
96100
largeProfileSummaryView.update(with: profile)
97101
largeProfileSummaryView.profileButtonStyle = .view
98-
largeProfileSummaryView.loadAvatar(with: profile.avatarIdentifier, options: [.transition(.fade(0.2))])
99102
profileView.update(with: profile)
100103
profileView.profileButtonStyle = .view
101-
profileView.loadAvatar(with: profile.avatarIdentifier, options: [.transition(.fade(0.2))])
102104
profileSummaryView.update(with: profile)
103105
profileSummaryView.profileButtonStyle = .view
104-
profileSummaryView.loadAvatar(with: profile.avatarIdentifier, options: [.transition(.fade(0.2))])
105106
} catch APIError.responseError(reason: let reason) where reason.httpStatusCode == 404 {
106107
largeProfileView.updateWithClaimProfilePrompt()
107108
largeProfileSummaryView.updateWithClaimProfilePrompt()

Sources/Gravatar/Identifiers/ProfileIdentifier.swift

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,4 +37,14 @@ extension ProfileIdentifier: Identifiable {
3737
hashID.id
3838
}
3939
}
40+
41+
// Returns the `AvatarIdentifier` popuplated from `self`.
42+
public var avatarIdentifier: AvatarIdentifier {
43+
switch self {
44+
case .email(let email):
45+
AvatarIdentifier.email(email.string)
46+
case .hashID(let hashID):
47+
AvatarIdentifier.hashID(hashID.string)
48+
}
49+
}
4050
}

Sources/GravatarUI/ProfileView/BaseProfileView.swift

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,8 @@ open class BaseProfileView: UIView, UIContentView {
9999
}
100100
}
101101

102+
private var avatarIdentifier: AvatarIdentifier?
103+
102104
var padding: UIEdgeInsets {
103105
get {
104106
// layoutMargins is automatically synced with directionalLayoutMargins
@@ -288,6 +290,7 @@ open class BaseProfileView: UIView, UIContentView {
288290
defaultAvatarOption: DefaultAvatarOption? = nil,
289291
options: [ImageSettingOption]? = nil
290292
) {
293+
self.avatarIdentifier = avatarIdentifier
291294
guard let avatarIdentifier else {
292295
avatarProvider.setImage(placeholder)
293296
return
@@ -407,7 +410,7 @@ open class BaseProfileView: UIView, UIContentView {
407410

408411
private func loadAvatar(with config: ProfileViewConfiguration) {
409412
loadAvatar(
410-
with: config.avatarID,
413+
with: config.avatarIdentifier ?? config.avatarID,
411414
placeholder: config.avatarConfiguration.placeholder,
412415
rating: config.avatarConfiguration.rating,
413416
defaultAvatarOption: config.avatarConfiguration.defaultAvatarOption,
@@ -426,7 +429,7 @@ open class BaseProfileView: UIView, UIContentView {
426429

427430
@objc
428431
private func avatarTapped() {
429-
delegate?.profileView(self, didTapOnAvatarWithID: model?.avatarIdentifier)
432+
delegate?.profileView(self, didTapOnAvatarWithID: avatarIdentifier)
430433
}
431434

432435
// MARK: - Placeholder handling

Sources/GravatarUI/ProfileView/ProfileViewConfiguration.swift

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,18 @@ public struct ProfileViewConfiguration: UIContentConfiguration {
2424
/// The style for the profile view.
2525
public let profileStyle: Style
2626
/// The identifier for the avatar image to be loaded in the profile view.
27+
@available(
28+
*,
29+
deprecated,
30+
renamed: "avatarIdentifier",
31+
message: "Set `avatarIdentifier` explicitly and don't use the model's avatarIdentifier. It's because the `ProfileModel.avatarIdentifier` always refers to the primary email's avatar even if we query the profile with a secondary email."
32+
)
2733
var avatarID: AvatarIdentifier? {
2834
model?.avatarIdentifier ?? summaryModel?.avatarIdentifier
2935
}
3036

37+
/// The identifier for the avatar image to be loaded in the profile view.
38+
public var avatarIdentifier: AvatarIdentifier?
3139
/// The palette to be used to style the view.
3240
public var palette: PaletteType
3341
/// Creates a padding space around the content of the profile view.

Sources/GravatarUI/ProfileViewController/ProfileViewController.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,9 @@ public class ProfileViewController: UIViewController {
9191
}
9292

9393
public func fetchProfile(profileIdentifier: ProfileIdentifier) {
94+
var newConfig = self.configuration
95+
newConfig.avatarIdentifier = profileIdentifier.avatarIdentifier
96+
self.configuration = newConfig
9497
Task {
9598
await viewModel.fetchProfile(profileIdentifier: profileIdentifier)
9699
}

version.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
module Gravatar
2-
VERSION = '2.0.2'.freeze
2+
VERSION = '2.1.0'.freeze
33
end

0 commit comments

Comments
 (0)