Skip to content

Commit

Permalink
GravatarUI docc bundle (#229)
Browse files Browse the repository at this point in the history
* Adding docc bundle to GravatarUI

* Updating example profile

* Lint

* Update example profile view
  • Loading branch information
etoledom committed Apr 30, 2024
1 parent e35eeec commit bbda3a3
Show file tree
Hide file tree
Showing 28 changed files with 168 additions and 7 deletions.
9 changes: 8 additions & 1 deletion .spi.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
# This is manifest file for the Swift Package Index for it to auto-generate and
# host DocC documentation.
#
# For reference see https://swiftpackageindex.com/swiftpackageindex/spimanifest/documentation/spimanifest/commonusecases#Host-DocC-documentation-in-the-Swift-Package-Index

version: 1
builder:
configs:
- documentation_targets: [Gravatar, GravatarUI]
- documentation_targets:
- GravatarUI
- Gravatar
platform: ios
custom_documentation_parameters: [--include-extended-types]
11 changes: 10 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -41,4 +41,13 @@ validate-pod: bundle-install
xcrun simctl list >> /dev/null
bundle exec pod lib lint \
--include-podspecs="*.podspec" \
--verbose --fail-fast
--verbose --fail-fast

update-example-snapshots:
for filePath in ./Sources/GravatarUI/GravatarUI.docc/Resources/ProfileExamples/*; \
do rm $$filePath; done
cp ./Tests/GravatarUITests/__Snapshots__/ProvileViewSnapshots/* ./Sources/GravatarUI/GravatarUI.docc/Resources/ProfileExamples
# Append @2x to the file name.
cd ./Sources/GravatarUI/GravatarUI.docc/Resources/ProfileExamples && \
for filePath in *; do name=$${filePath%.*}; mv $$filePath $${name//-dark/~dark}@2x$${filePath#$$name}; done

11 changes: 6 additions & 5 deletions Sources/Gravatar/Gravatar.docc/Gravatar.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,17 @@ A Gravatar is a Globally Recognized Avatar. You upload an image and create your

This SDK will allow you to easily implement the Gravatar services in your project.

### Displaying a Gravatar Image
### Obtaining a Gravatar Image

The easiest way is to use the `UIImageView.gravatar` extension.
Using the **AvatarService**:

```swift
gravatarImageView.gravatar.setImage(email: "user@email.com")
let service = AvatarService()
let result = try await imageRetriever.fetch(with: .email("some@email.com"))
let avatar = result.image
```

For more info check:
- `GravatarWrapper/setImage(email:placeholder:rating:preferredSize:defaultAvatarOption:options:completionHandler:)`
For more information, check ``AvatarService``.

## Featured

Expand Down
44 changes: 44 additions & 0 deletions Sources/GravatarUI/GravatarUI.docc/GravatarUI.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# ``GravatarUI``

Gravatar iOS SDK

@Metadata {
@PageImage(
purpose: icon,
source: "gravatar-sdk"
)
}

## Overview

An “avatar” is an image that represents you online—a little picture that appears next to your name when you interact with websites.

A Gravatar is a Globally Recognized Avatar. You upload an image and create your public profile just once, and then when you participate in any Gravatar-enabled site, your Gravatar image and public profile will automatically follow you there.

This SDK offers an easy way to present Gravatar user's visually in your app.

### How to:

We offer a variety of profile view layouts for different usecases. As an example, you can use a ```ProfileView``` to be added to your UI in this way:

```swift
// 1. Get an instance of a ProfileService
let service = ProfileService()
// 2. Get the user's profile:
let profile = try await service.fetch(with: .email("user@email.com"))
// 3. Get the instance of a ProfileView:
let profileView = ProfileView()
// 4. Set the profile to the view:
profileView.update(with: profile)
```
`ProfileView` will look like this:
![Profile view example](profileView.view)

## Topics

### Profile views

- ``ProfileView``
- ``ProfileSummaryView``
- ``LargeProfileView``
- ``LargeProfileSummaryView``
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 2 additions & 0 deletions Sources/GravatarUI/ProfileView/LargeProfileSummaryView.swift
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import Gravatar
import UIKit

/// ![](largeProfileSummaryView.view)
/// A profile view with large avatar image and sumarized information..
public class LargeProfileSummaryView: BaseProfileView {
private enum Constants {
static let avatarLength: CGFloat = 132.0
Expand Down
2 changes: 2 additions & 0 deletions Sources/GravatarUI/ProfileView/LargeProfileView.swift
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import Gravatar
import UIKit

/// ![](largeProfileView.view)
/// A profile view with large avatar image.
public class LargeProfileView: BaseProfileView {
private enum Constants {
static let avatarLength: CGFloat = 132.0
Expand Down
2 changes: 2 additions & 0 deletions Sources/GravatarUI/ProfileView/ProfileSummaryView.swift
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import Gravatar
import UIKit

/// ![](profileSummaryView.view)
/// A smaller profile view with sumarized information
public class ProfileSummaryView: BaseProfileView {
private lazy var basicInfoStackView: UIStackView = {
let stack = UIStackView(arrangedSubviews: [displayNameLabel, personalInfoLabel, profileButton])
Expand Down
2 changes: 2 additions & 0 deletions Sources/GravatarUI/ProfileView/ProfileView.swift
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import Gravatar
import UIKit

/// ![](profileView.view)
/// A profile view with standard layout
public class ProfileView: BaseProfileView {
private lazy var topStackView: UIStackView = {
let stack = UIStackView(arrangedSubviews: [avatarImageView, basicInfoStackView])
Expand Down
4 changes: 4 additions & 0 deletions Tests/GravatarUITests/ImageHelper.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ class ImageHelper {
image(named: "placeholder", type: "png")!
}

static var exampleAvatarImage: UIImage {
image(named: "example_avatar", type: "png")!
}

static func dataFromImage(named: String, type: String) -> Data? {
guard let url = Bundle.testsBundle.url(forResource: named, withExtension: type) else {
return nil
Expand Down
88 changes: 88 additions & 0 deletions Tests/GravatarUITests/ProvileViewSnapshots.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
import Gravatar
import GravatarUI
import SnapshotTesting
import XCTest

final class ProfileViewSnapshots: XCTestCase {
enum Constants {
static let width: CGFloat = 320
}

override func setUp() async throws {
try await super.setUp()
// isRecording = true
}

func testProfileView() throws {
for interfaceStyle in UIUserInterfaceStyle.allCases {
let profileView = ProfileView()
profileView.update(with: TestProfileCardModel.exampleModel)
let containerView = wrap(profileView)
containerView.overrideUserInterfaceStyle = interfaceStyle
let postfix = interfaceStyle == .dark ? "view-dark" : "view"
assertSnapshot(of: containerView, as: .image, named: postfix, testName: "profileView")
}
}

func testProfileSummaryView() throws {
for interfaceStyle in UIUserInterfaceStyle.allCases {
let profileView = ProfileSummaryView()
profileView.update(with: TestProfileCardModel.exampleModel)
let containerView = wrap(profileView)
containerView.overrideUserInterfaceStyle = interfaceStyle
let postfix = interfaceStyle == .dark ? "view-dark" : "view"
assertSnapshot(of: containerView, as: .image, named: postfix, testName: "profileSummaryView")
}
}

func testLargeProfileView() throws {
for interfaceStyle in UIUserInterfaceStyle.allCases {
let profileView = LargeProfileView()
profileView.update(with: TestProfileCardModel.exampleModel)
let containerView = wrap(profileView)
containerView.overrideUserInterfaceStyle = interfaceStyle
let postfix = interfaceStyle == .dark ? "view-dark" : "view"
assertSnapshot(of: containerView, as: .image, named: postfix, testName: "largeProfileView")
}
}

func testLargeProfileSummaryView() throws {
for interfaceStyle in UIUserInterfaceStyle.allCases {
let profileView = LargeProfileSummaryView()
profileView.update(with: TestProfileCardModel.exampleModel)
let containerView = wrap(profileView)
containerView.overrideUserInterfaceStyle = interfaceStyle
let postfix = interfaceStyle == .dark ? "view-dark" : "view"
assertSnapshot(of: containerView, as: .image, named: postfix, testName: "largeProfileSummaryView")
}
}

private func wrap(_ view: BaseProfileView) -> UIView {
view.avatarImageView.backgroundColor = .systemBlue
view.avatarImageView.image = ImageHelper.exampleAvatarImage
view.translatesAutoresizingMaskIntoConstraints = false
view.widthAnchor.constraint(equalToConstant: Constants.width).isActive = true

return view.wrapInSuperView(with: Constants.width)
}
}

extension TestProfileCardModel {
fileprivate static let exampleModel = TestProfileCardModel(
accountsList: [
TestAccountModel(display: "Gravatar", shortname: "gravatar"),
TestAccountModel(display: "WordPress", shortname: "wordpress"),
TestAccountModel(display: "Tumblr", shortname: "tumblr"),
TestAccountModel(display: "GitHub", shortname: "github"),
],
aboutMe: "Engineer at heart, problem-solver by nature. Passionate about innovation and pushing boundaries. Let's build something incredible together.",
displayName: "John Appleseed",
fullName: "John Appleseed",
userName: "username",
jobTitle: "Engineer",
pronouns: "he/him",
currentLocation: "Atlanta GA",
avatarIdentifier: .email("email@domain.com"),
profileURL: URL(string: "https://gravatar.com/profile")
)
}
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit bbda3a3

Please sign in to comment.