123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177 |
- //
- // SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors
- // SPDX-License-Identifier: GPL-3.0-or-later
- //
- import UIKit
- import SDWebImage
- @objcMembers class AvatarManager: NSObject {
- public static let shared = AvatarManager()
- private let avatarDefaultSize = CGRect(x: 0, y: 0, width: 32, height: 32)
- // MARK: - Conversation avatars
- public func getAvatar(for room: NCRoom, with style: UIUserInterfaceStyle, completionBlock: @escaping (_ image: UIImage?) -> Void) -> SDWebImageCombinedOperation? {
- if room.accountId != nil, NCDatabaseManager.sharedInstance().serverHasTalkCapability(kCapabilityConversationAvatars, forAccountId: room.accountId) {
- // Server supports conversation avatars -> try to get the avatar using this API
- return NCAPIController.sharedInstance().getAvatarFor(room, with: style) { image, _ in
- completionBlock(image)
- }
- } else {
- // Server does not support conversation avatars -> use the legacy way to obtain an avatar
- return self.getFallbackAvatar(for: room, with: style, completionBlock: completionBlock)
- }
- }
- public func getGroupAvatar(with style: UIUserInterfaceStyle) -> UIImage? {
- let traitCollection = UITraitCollection(userInterfaceStyle: style)
- return UIImage(named: "group-avatar", in: nil, compatibleWith: traitCollection)
- }
- public func getMailAvatar(with style: UIUserInterfaceStyle) -> UIImage? {
- let traitCollection = UITraitCollection(userInterfaceStyle: style)
- return UIImage(named: "mail-avatar", in: nil, compatibleWith: traitCollection)
- }
- private func getFallbackAvatar(for room: NCRoom,
- with style: UIUserInterfaceStyle,
- completionBlock: @escaping (_ image: UIImage?) -> Void) -> SDWebImageCombinedOperation? {
- let traitCollection = UITraitCollection(userInterfaceStyle: style)
- if room.objectType == NCRoomObjectTypeFile {
- completionBlock(UIImage(named: "file-avatar", in: nil, compatibleWith: traitCollection))
- } else if room.objectType == NCRoomObjectTypeSharePassword {
- completionBlock(UIImage(named: "password-avatar", in: nil, compatibleWith: traitCollection))
- } else {
- switch room.type {
- case .oneToOne:
- let account = NCDatabaseManager.sharedInstance().talkAccount(forAccountId: room.accountId)
- return self.getUserAvatar(forId: room.name, withStyle: style, usingAccount: account, completionBlock: completionBlock)
- case .formerOneToOne:
- completionBlock(UIImage(named: "user-avatar", in: nil, compatibleWith: traitCollection))
- case .public:
- completionBlock(UIImage(named: "public-avatar", in: nil, compatibleWith: traitCollection))
- case .group:
- completionBlock(UIImage(named: "group-avatar", in: nil, compatibleWith: traitCollection))
- case .changelog:
- completionBlock(UIImage(named: "changelog-avatar", in: nil, compatibleWith: traitCollection))
- default:
- completionBlock(nil)
- }
- }
- return nil
- }
- // MARK: - Actor avatars
- // swiftlint:disable:next function_parameter_count
- public func getActorAvatar(forId actorId: String?, withType actorType: String?, withDisplayName actorDisplayName: String?, withRoomToken roomToken: String?, withStyle style: UIUserInterfaceStyle, usingAccount account: TalkAccount?, completionBlock: @escaping (_ image: UIImage?) -> Void) -> SDWebImageCombinedOperation? {
- if let actorId {
- if actorType == "bots" {
- return getBotsAvatar(forId: actorId, withStyle: style, completionBlock: completionBlock)
- } else if actorType == "guests" {
- return getGuestsAvatar(withDisplayName: actorDisplayName ?? "", completionBlock: completionBlock)
- } else if actorType == "users" {
- return getUserAvatar(forId: actorId, withStyle: style, usingAccount: account, completionBlock: completionBlock)
- } else if actorType == "federated_users" {
- return getFederatedUserAvatar(forId: actorId, withRoomToken: roomToken, withStyle: style, usingAccount: account, completionBlock: completionBlock)
- } else if actorType == "deleted_users" {
- return getDeletedUserAvatar(completionBlock: completionBlock)
- }
- }
- var image: UIImage?
- if actorType == NCAttendeeTypeEmail {
- image = self.getMailAvatar(with: style)
- } else if actorType == NCAttendeeTypeGroup || actorType == NCAttendeeTypeCircle {
- image = self.getGroupAvatar(with: style)
- } else {
- image = NCUtils.getImage(withString: "?", withBackgroundColor: .systemGray3, withBounds: self.avatarDefaultSize, isCircular: true)
- }
- completionBlock(image)
- return nil
- }
- private func getBotsAvatar(forId actorId: String, withStyle style: UIUserInterfaceStyle, completionBlock: @escaping (_ image: UIImage?) -> Void) -> SDWebImageCombinedOperation? {
- if actorId == "changelog" {
- let traitCollection = UITraitCollection(userInterfaceStyle: style)
- completionBlock(UIImage(named: "changelog-avatar", in: nil, compatibleWith: traitCollection))
- } else {
- let image = NCUtils.getImage(withString: ">", withBackgroundColor: .systemGray3, withBounds: self.avatarDefaultSize, isCircular: true)
- completionBlock(image)
- }
- return nil
- }
- private func getGuestsAvatar(withDisplayName actorDisplayName: String, completionBlock: @escaping (_ image: UIImage?) -> Void) -> SDWebImageCombinedOperation? {
- let name = actorDisplayName.isEmpty ? "?" : actorDisplayName
- let image = NCUtils.getImage(withString: name, withBackgroundColor: .systemGray3, withBounds: self.avatarDefaultSize, isCircular: true)
- completionBlock(image)
- return nil
- }
- private func getDeletedUserAvatar(completionBlock: @escaping (_ image: UIImage?) -> Void) -> SDWebImageCombinedOperation? {
- let image = NCUtils.getImage(withString: "X", withBackgroundColor: .systemGray3, withBounds: self.avatarDefaultSize, isCircular: true)
- completionBlock(image)
- return nil
- }
- private func getUserAvatar(forId actorId: String, withStyle style: UIUserInterfaceStyle, usingAccount account: TalkAccount?, completionBlock: @escaping (_ image: UIImage?) -> Void) -> SDWebImageCombinedOperation? {
- let account = account ?? NCDatabaseManager.sharedInstance().activeAccount()
- return NCAPIController.sharedInstance().getUserAvatar(forUser: actorId, using: account, with: style) { image, _ in
- if image != nil {
- completionBlock(image)
- } else {
- NSLog("Unable to get avatar for user %@", actorId)
- let traitCollection = UITraitCollection(userInterfaceStyle: style)
- completionBlock(UIImage(named: "user-avatar", in: nil, compatibleWith: traitCollection))
- }
- }
- }
- private func getFederatedUserAvatar(forId actorId: String, withRoomToken roomToken: String?, withStyle style: UIUserInterfaceStyle, usingAccount account: TalkAccount?, completionBlock: @escaping (_ image: UIImage?) -> Void) -> SDWebImageCombinedOperation? {
- let account = account ?? NCDatabaseManager.sharedInstance().activeAccount()
- return NCAPIController.sharedInstance().getFederatedUserAvatar(forUser: actorId, inRoom: roomToken, using: account, with: style) { image, _ in
- if image != nil {
- completionBlock(image)
- } else {
- NSLog("Unable to get federated avatar for user %@", actorId)
- let traitCollection = UITraitCollection(userInterfaceStyle: style)
- completionBlock(UIImage(named: "user-avatar", in: nil, compatibleWith: traitCollection))
- }
- }
- }
- // MARK: - Utils
- public func createRenderedImage(image: UIImage) -> UIImage? {
- return self.createRenderedImage(image: image, width: 120, height: 120)
- }
- private func createRenderedImage(image: UIImage, width: Int, height: Int) -> UIImage? {
- UIGraphicsBeginImageContextWithOptions(.init(width: width, height: height), false, 0.0)
- image.draw(in: .init(x: 0, y: 0, width: width, height: height))
- let newImage = UIGraphicsGetImageFromCurrentImageContext()
- UIGraphicsEndImageContext()
- return newImage
- }
- }
|