add new placeholder icon
This commit is contained in:
parent
65030b7b46
commit
38c6d05236
|
@ -472,6 +472,7 @@
|
|||
7BDCFC08242186E700641C39 /* NotificationServiceExtensionContext.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BDCFC07242186E700641C39 /* NotificationServiceExtensionContext.swift */; };
|
||||
7BDCFC092421894900641C39 /* MessageFetcherJob.swift in Sources */ = {isa = PBXBuildFile; fileRef = 452ECA4C1E087E7200E2F016 /* MessageFetcherJob.swift */; };
|
||||
7BDCFC0B2421EB7600641C39 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = B6F509951AA53F760068F56A /* Localizable.strings */; };
|
||||
7BF3FF002505B8E400609570 /* PlaceholderIcon.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BF3FEFF2505B8E400609570 /* PlaceholderIcon.swift */; };
|
||||
A10FDF79184FB4BB007FF963 /* MediaPlayer.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 76C87F18181EFCE600C4ACAB /* MediaPlayer.framework */; };
|
||||
A11CD70D17FA230600A2D1B1 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A11CD70C17FA230600A2D1B1 /* QuartzCore.framework */; };
|
||||
A123C14916F902EE000AE905 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A163E8AA16F3F6A90094D68B /* Security.framework */; };
|
||||
|
@ -1247,6 +1248,7 @@
|
|||
7BC01A3F241F40AB00BC7C55 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
7BDCFC0424206E7300641C39 /* LokiPushNotificationService.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = LokiPushNotificationService.entitlements; sourceTree = "<group>"; };
|
||||
7BDCFC07242186E700641C39 /* NotificationServiceExtensionContext.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NotificationServiceExtensionContext.swift; sourceTree = "<group>"; };
|
||||
7BF3FEFF2505B8E400609570 /* PlaceholderIcon.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlaceholderIcon.swift; sourceTree = "<group>"; };
|
||||
8981C8F64D94D3C52EB67A2C /* Pods-SignalTests.test.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SignalTests.test.xcconfig"; path = "Pods/Target Support Files/Pods-SignalTests/Pods-SignalTests.test.xcconfig"; sourceTree = "<group>"; };
|
||||
8EEE74B0753448C085B48721 /* Pods-SignalMessaging.app store release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SignalMessaging.app store release.xcconfig"; path = "Pods/Target Support Files/Pods-SignalMessaging/Pods-SignalMessaging.app store release.xcconfig"; sourceTree = "<group>"; };
|
||||
948239851C08032C842937CC /* Pods-SignalMessaging.test.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SignalMessaging.test.xcconfig"; path = "Pods/Target Support Files/Pods-SignalMessaging/Pods-SignalMessaging.test.xcconfig"; sourceTree = "<group>"; };
|
||||
|
@ -2601,6 +2603,7 @@
|
|||
B846365A22B7418B00AF1514 /* Identicon+ObjC.swift */,
|
||||
241C6312231F5F1D00B4198E /* CGFloat+Rounding.swift */,
|
||||
241C6310231F5C4400B4198E /* UIColor+Helper.swift */,
|
||||
7BF3FEFF2505B8E400609570 /* PlaceholderIcon.swift */,
|
||||
);
|
||||
path = "Jazz Icon";
|
||||
sourceTree = "<group>";
|
||||
|
@ -3700,6 +3703,7 @@
|
|||
241C6315231F64CE00B4198E /* CGFloat+Rounding.swift in Sources */,
|
||||
34480B561FD0A7A400BC14EF /* DebugLogger.m in Sources */,
|
||||
459B775C207BA46C0071D0AB /* OWSQuotedReplyModel.m in Sources */,
|
||||
7BF3FF002505B8E400609570 /* PlaceholderIcon.swift in Sources */,
|
||||
340872D622397E6800CB25B0 /* AttachmentCaptionToolbar.swift in Sources */,
|
||||
34ABB2C42090C59700C727A6 /* OWSResaveCollectionDBMigration.m in Sources */,
|
||||
4C948FF72146EB4800349F0D /* BlockListCache.swift in Sources */,
|
||||
|
|
|
@ -10,4 +10,13 @@ public final class Identicon : NSObject {
|
|||
let image = renderer.image { iconLayer.render(in: $0.cgContext) }
|
||||
return image
|
||||
}
|
||||
|
||||
@objc public static func generatePlaceholderIcon(seed: String, text: String, size: CGFloat) -> UIImage {
|
||||
let icon = PlaceholderIcon(seed: seed)
|
||||
let iconLayer = icon.generateLayer(ofSize: size, with: text.substring(to: 1))
|
||||
let rect = CGRect(origin: CGPoint.zero, size: iconLayer.frame.size)
|
||||
let renderer = UIGraphicsImageRenderer(size: rect.size)
|
||||
let image = renderer.image { iconLayer.render(in: $0.cgContext) }
|
||||
return image
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,67 @@
|
|||
|
||||
import CryptoSwift
|
||||
|
||||
public class PlaceholderIcon {
|
||||
private let seed: Int
|
||||
// Colour palette
|
||||
private var colours: [UIColor] = [
|
||||
0x5ff8b0,
|
||||
0x26cdb9,
|
||||
0xf3c615,
|
||||
0xfcac5a
|
||||
].map { UIColor(rgb: $0) }
|
||||
|
||||
init(seed: Int, colours: [UIColor]? = nil) {
|
||||
self.seed = seed
|
||||
if let colours = colours {
|
||||
self.colours = colours
|
||||
}
|
||||
}
|
||||
|
||||
convenience init(seed: String, colours: [UIColor]? = nil) {
|
||||
// Ensure we have a correct hash
|
||||
var hash = seed
|
||||
if !hash.matches("^[0-9A-Fa-f]+$") || hash.count < 12 { hash = seed.sha512() }
|
||||
|
||||
guard let number = Int(hash.substring(to: 12), radix: 16) else {
|
||||
owsFailDebug("[PlaceholderIcon] Failed to generate number from seed string: \(seed)")
|
||||
self.init(seed: 0, colours: colours)
|
||||
return
|
||||
}
|
||||
|
||||
self.init(seed: number, colours: colours)
|
||||
}
|
||||
|
||||
public func generateLayer(ofSize diameter: CGFloat, with text: String) -> CALayer {
|
||||
let colour = self.colours[seed % self.colours.count].cgColor
|
||||
let base = getTextLayer(with: diameter, colour: colour, text: text)
|
||||
base.masksToBounds = true
|
||||
return base
|
||||
}
|
||||
|
||||
private func getTextLayer(with diameter: CGFloat, colour: CGColor? = nil, text: String) -> CALayer {
|
||||
let font = UIFont.boldSystemFont(ofSize: diameter/2)
|
||||
let height = NSString(string: text).boundingRect(with: CGSize(width: diameter, height: CGFloat(MAXFLOAT)), options: .usesLineFragmentOrigin, attributes: [NSAttributedString.Key.font: font], context: nil).height
|
||||
let frame = CGRect(x: 0, y: (diameter - height)/2, width: diameter, height: height)
|
||||
|
||||
let layer = CATextLayer()
|
||||
layer.frame = frame
|
||||
layer.foregroundColor = UIColor.white.cgColor
|
||||
layer.contentsScale = UIScreen.main.scale
|
||||
|
||||
let fontName = font.fontName;
|
||||
let fontRef = CGFont(fontName as CFString);
|
||||
layer.font = fontRef;
|
||||
layer.fontSize = font.pointSize;
|
||||
layer.alignmentMode = .center
|
||||
|
||||
layer.string = text
|
||||
|
||||
let base = CALayer()
|
||||
base.frame = CGRect(x: 0, y: 0, width: diameter, height: diameter)
|
||||
base.backgroundColor = colour
|
||||
base.addSublayer(layer)
|
||||
|
||||
return base
|
||||
}
|
||||
}
|
|
@ -46,8 +46,9 @@ public final class ProfilePictureView : UIView {
|
|||
@objc public func update() {
|
||||
AssertIsOnMainThread()
|
||||
func getProfilePicture(of size: CGFloat, for hexEncodedPublicKey: String) -> UIImage? {
|
||||
OWSLogger.debug("[Ryan] \(hexEncodedPublicKey)")
|
||||
guard !hexEncodedPublicKey.isEmpty else { return nil }
|
||||
return OWSProfileManager.shared().profileAvatar(forRecipientId: hexEncodedPublicKey) ?? Identicon.generateIcon(string: hexEncodedPublicKey, size: size)
|
||||
return OWSProfileManager.shared().profileAvatar(forRecipientId: hexEncodedPublicKey) ?? Identicon.generatePlaceholderIcon(seed: hexEncodedPublicKey, text: OWSProfileManager.shared().profileNameForRecipient(withID: hexEncodedPublicKey) ?? hexEncodedPublicKey, size: size)
|
||||
}
|
||||
let size: CGFloat
|
||||
if let additionalHexEncodedPublicKey = additionalHexEncodedPublicKey, !isRSSFeed, openGroupProfilePicture == nil {
|
||||
|
|
Loading…
Reference in New Issue