@craft-native/ios 0.0.127 → 0.0.128

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@craft-native/ios",
3
- "version": "0.0.127",
3
+ "version": "0.0.128",
4
4
  "homepage": "https://github.com/craft-native/craft/tree/main/packages/ios#readme",
5
5
  "repository": {
6
6
  "type": "git",
@@ -1662,9 +1662,38 @@ final class CraftNativeScreenController: UIViewController, UIScrollViewDelegate,
1662
1662
  item.accessibilityLabel = id
1663
1663
  }
1664
1664
  if let tint = (spec["color"] as? String).flatMap({ UIColor(hex: $0) }) { item.tintColor = tint }
1665
+ // `image`: a picture (an https URL, the account's own photo), drawn
1666
+ // round as iOS draws an account button. The symbol or title shows
1667
+ // until it has loaded, and stays if it cannot be.
1668
+ if let source = spec["image"] as? String, let url = URL(string: source), url.scheme == "https" {
1669
+ loadBarImage(url) { [weak item] image in
1670
+ guard let item, let image else { return }
1671
+ let size = CGSize(width: 32, height: 32)
1672
+ let round = UIGraphicsImageRenderer(size: size).image { _ in
1673
+ UIBezierPath(ovalIn: CGRect(origin: .zero, size: size)).addClip()
1674
+ let scale = max(size.width / image.size.width, size.height / image.size.height)
1675
+ let drawn = CGSize(width: image.size.width * scale, height: image.size.height * scale)
1676
+ image.draw(in: CGRect(x: (size.width - drawn.width) / 2, y: (size.height - drawn.height) / 2, width: drawn.width, height: drawn.height))
1677
+ }
1678
+ item.title = nil
1679
+ item.image = round.withRenderingMode(.alwaysOriginal)
1680
+ }
1681
+ }
1665
1682
  return item
1666
1683
  }
1667
1684
 
1685
+ /// A bar picture, kept for the app's life so each screen does not fetch it again.
1686
+ private static let barImages = NSCache<NSURL, UIImage>()
1687
+
1688
+ private func loadBarImage(_ url: URL, _ done: @escaping (UIImage?) -> Void) {
1689
+ if let cached = Self.barImages.object(forKey: url as NSURL) { done(cached); return }
1690
+ URLSession.shared.dataTask(with: url) { data, _, _ in
1691
+ let image = data.flatMap(UIImage.init(data:))
1692
+ if let image { Self.barImages.setObject(image, forKey: url as NSURL) }
1693
+ DispatchQueue.main.async { done(image) }
1694
+ }.resume()
1695
+ }
1696
+
1668
1697
  /// The first vertical scroll view of the screen drives the bar: a large
1669
1698
  /// title collapses as it scrolls, and the bar's background follows it.
1670
1699
  private func trackContentScrollView() {