mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-15 21:45:19 +00:00
Avatar upload improvements
This commit is contained in:
parent
8e7936bb57
commit
1b723cd2a7
@ -142,6 +142,15 @@ public enum AvatarGalleryEntry: Equatable {
|
||||
}
|
||||
}
|
||||
|
||||
public var emojiMarkup: TelegramMediaImage.EmojiMarkup? {
|
||||
switch self {
|
||||
case .topImage:
|
||||
return nil
|
||||
case let .image(_, _, _, _, _, _, _, _, _, _, _, markup):
|
||||
return markup
|
||||
}
|
||||
}
|
||||
|
||||
public var indexData: GalleryItemIndexData? {
|
||||
switch self {
|
||||
case let .topImage(_, _, _, indexData, _, _):
|
||||
@ -343,11 +352,16 @@ public func fetchedAvatarGalleryEntries(engine: TelegramEngine, account: Account
|
||||
let indexData = GalleryItemIndexData(position: index, totalCount: Int32(photos.count))
|
||||
if result.isEmpty, let first = initialEntries.first {
|
||||
var videoRepresentations: [VideoRepresentationWithReference] = first.videoRepresentations
|
||||
var emojiMarkup: TelegramMediaImage.EmojiMarkup? = first.emojiMarkup
|
||||
let isPersonal = first.representations.first?.representation.isPersonal == true
|
||||
if videoRepresentations.isEmpty, !isPersonal {
|
||||
videoRepresentations = photo.image.videoRepresentations.map({ VideoRepresentationWithReference(representation: $0, reference: MediaResourceReference.avatarList(peer: peerReference, resource: $0.resource)) })
|
||||
}
|
||||
result.append(.image(photo.image.imageId, photo.image.reference, first.representations, videoRepresentations, peer, secondEntry != nil ? 0 : photo.date, indexData, photo.messageId, photo.image.immediateThumbnailData, nil, false, photo.image.emojiMarkup))
|
||||
if emojiMarkup == nil, !isPersonal {
|
||||
emojiMarkup = photo.image.emojiMarkup
|
||||
}
|
||||
|
||||
result.append(.image(photo.image.imageId, photo.image.reference, first.representations, videoRepresentations, peer, secondEntry != nil ? 0 : photo.date, indexData, photo.messageId, first.immediateThumbnailData ?? photo.image.immediateThumbnailData, nil, false, emojiMarkup))
|
||||
} else {
|
||||
result.append(.image(photo.image.imageId, photo.image.reference, photo.image.representations.map({ ImageRepresentationWithReference(representation: $0, reference: MediaResourceReference.avatarList(peer: peerReference, resource: $0.resource)) }), photo.image.videoRepresentations.map({ VideoRepresentationWithReference(representation: $0, reference: MediaResourceReference.avatarList(peer: peerReference, resource: $0.resource)) }), peer, photo.date, indexData, photo.messageId, photo.image.immediateThumbnailData, nil, photo.image.id == lastEntry?.id, photo.image.emojiMarkup))
|
||||
}
|
||||
|
@ -4676,6 +4676,21 @@ public extension Api.functions.messages {
|
||||
})
|
||||
}
|
||||
}
|
||||
public extension Api.functions.messages {
|
||||
static func getEmojiProfilePhotoGroups(hash: Int32) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.messages.EmojiGroups>) {
|
||||
let buffer = Buffer()
|
||||
buffer.appendInt32(564480243)
|
||||
serializeInt32(hash, buffer: buffer, boxed: false)
|
||||
return (FunctionDescription(name: "messages.getEmojiProfilePhotoGroups", parameters: [("hash", String(describing: hash))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.messages.EmojiGroups? in
|
||||
let reader = BufferReader(buffer)
|
||||
var result: Api.messages.EmojiGroups?
|
||||
if let signature = reader.readInt32() {
|
||||
result = Api.parse(reader, signature: signature) as? Api.messages.EmojiGroups
|
||||
}
|
||||
return result
|
||||
})
|
||||
}
|
||||
}
|
||||
public extension Api.functions.messages {
|
||||
static func getEmojiStatusGroups(hash: Int32) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.messages.EmojiGroups>) {
|
||||
let buffer = Buffer()
|
||||
@ -7764,15 +7779,16 @@ public extension Api.functions.photos {
|
||||
}
|
||||
}
|
||||
public extension Api.functions.photos {
|
||||
static func uploadContactProfilePhoto(flags: Int32, userId: Api.InputUser, file: Api.InputFile?, video: Api.InputFile?, videoStartTs: Double?) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.photos.Photo>) {
|
||||
static func uploadContactProfilePhoto(flags: Int32, userId: Api.InputUser, file: Api.InputFile?, video: Api.InputFile?, videoStartTs: Double?, videoEmojiMarkup: Api.VideoSize?) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.photos.Photo>) {
|
||||
let buffer = Buffer()
|
||||
buffer.appendInt32(-1189444673)
|
||||
buffer.appendInt32(-515093903)
|
||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||
userId.serialize(buffer, true)
|
||||
if Int(flags) & Int(1 << 0) != 0 {file!.serialize(buffer, true)}
|
||||
if Int(flags) & Int(1 << 1) != 0 {video!.serialize(buffer, true)}
|
||||
if Int(flags) & Int(1 << 2) != 0 {serializeDouble(videoStartTs!, buffer: buffer, boxed: false)}
|
||||
return (FunctionDescription(name: "photos.uploadContactProfilePhoto", parameters: [("flags", String(describing: flags)), ("userId", String(describing: userId)), ("file", String(describing: file)), ("video", String(describing: video)), ("videoStartTs", String(describing: videoStartTs))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.photos.Photo? in
|
||||
if Int(flags) & Int(1 << 5) != 0 {videoEmojiMarkup!.serialize(buffer, true)}
|
||||
return (FunctionDescription(name: "photos.uploadContactProfilePhoto", parameters: [("flags", String(describing: flags)), ("userId", String(describing: userId)), ("file", String(describing: file)), ("video", String(describing: video)), ("videoStartTs", String(describing: videoStartTs)), ("videoEmojiMarkup", String(describing: videoEmojiMarkup))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.photos.Photo? in
|
||||
let reader = BufferReader(buffer)
|
||||
var result: Api.photos.Photo?
|
||||
if let signature = reader.readInt32() {
|
||||
|
@ -26,8 +26,8 @@ public extension TelegramEngine {
|
||||
return _internal_updateContactName(account: self.account, peerId: peerId, firstName: firstName, lastName: lastName)
|
||||
}
|
||||
|
||||
public func updateContactPhoto(peerId: PeerId, resource: MediaResource?, videoResource: MediaResource?, videoStartTimestamp: Double?, mode: SetCustomPeerPhotoMode, mapResourceToAvatarSizes: @escaping (MediaResource, [TelegramMediaImageRepresentation]) -> Signal<[Int: Data], NoError>) -> Signal<UpdatePeerPhotoStatus, UploadPeerPhotoError> {
|
||||
return _internal_updateContactPhoto(account: self.account, peerId: peerId, resource: resource, videoResource: videoResource, videoStartTimestamp: videoStartTimestamp, mode: mode, mapResourceToAvatarSizes: mapResourceToAvatarSizes)
|
||||
public func updateContactPhoto(peerId: PeerId, resource: MediaResource?, videoResource: MediaResource?, videoStartTimestamp: Double?, markup: UploadPeerPhotoMarkup?, mode: SetCustomPeerPhotoMode, mapResourceToAvatarSizes: @escaping (MediaResource, [TelegramMediaImageRepresentation]) -> Signal<[Int: Data], NoError>) -> Signal<UpdatePeerPhotoStatus, UploadPeerPhotoError> {
|
||||
return _internal_updateContactPhoto(account: self.account, peerId: peerId, resource: resource, videoResource: videoResource, videoStartTimestamp: videoStartTimestamp, markup: markup, mode: mode, mapResourceToAvatarSizes: mapResourceToAvatarSizes)
|
||||
}
|
||||
|
||||
public func deviceContactsImportedByCount(contacts: [(String, [DeviceContactNormalizedPhoneNumber])]) -> Signal<[String: Int32], NoError> {
|
||||
|
@ -19,7 +19,13 @@ public enum UploadPeerPhotoMarkup {
|
||||
}
|
||||
|
||||
func _internal_updateAccountPhoto(account: Account, resource: MediaResource?, videoResource: MediaResource?, videoStartTimestamp: Double?, markup: UploadPeerPhotoMarkup?, fallback: Bool, mapResourceToAvatarSizes: @escaping (MediaResource, [TelegramMediaImageRepresentation]) -> Signal<[Int: Data], NoError>) -> Signal<UpdatePeerPhotoStatus, UploadPeerPhotoError> {
|
||||
return _internal_updatePeerPhoto(postbox: account.postbox, network: account.network, stateManager: account.stateManager, accountPeerId: account.peerId, peerId: account.peerId, photo: resource.flatMap({ _internal_uploadedPeerPhoto(postbox: account.postbox, network: account.network, resource: $0) }), video: videoResource.flatMap({ _internal_uploadedPeerVideo(postbox: account.postbox, network: account.network, messageMediaPreuploadManager: account.messageMediaPreuploadManager, resource: $0) |> map(Optional.init) }), videoStartTimestamp: videoStartTimestamp, markup: markup, fallback: fallback, mapResourceToAvatarSizes: mapResourceToAvatarSizes)
|
||||
let photo: Signal<UploadedPeerPhotoData, NoError>?
|
||||
if videoResource == nil && markup != nil, let resource = resource {
|
||||
photo = .single(UploadedPeerPhotoData.withResource(resource))
|
||||
} else {
|
||||
photo = resource.flatMap({ _internal_uploadedPeerPhoto(postbox: account.postbox, network: account.network, resource: $0) })
|
||||
}
|
||||
return _internal_updatePeerPhoto(postbox: account.postbox, network: account.network, stateManager: account.stateManager, accountPeerId: account.peerId, peerId: account.peerId, photo: photo, video: videoResource.flatMap({ _internal_uploadedPeerVideo(postbox: account.postbox, network: account.network, messageMediaPreuploadManager: account.messageMediaPreuploadManager, resource: $0) |> map(Optional.init) }), videoStartTimestamp: videoStartTimestamp, markup: markup, fallback: fallback, mapResourceToAvatarSizes: mapResourceToAvatarSizes)
|
||||
}
|
||||
|
||||
public enum SetCustomPeerPhotoMode {
|
||||
@ -28,13 +34,14 @@ public enum SetCustomPeerPhotoMode {
|
||||
case customAndSuggest
|
||||
}
|
||||
|
||||
func _internal_updateContactPhoto(account: Account, peerId: PeerId, resource: MediaResource?, videoResource: MediaResource?, videoStartTimestamp: Double?, mode: SetCustomPeerPhotoMode, mapResourceToAvatarSizes: @escaping (MediaResource, [TelegramMediaImageRepresentation]) -> Signal<[Int: Data], NoError>) -> Signal<UpdatePeerPhotoStatus, UploadPeerPhotoError> {
|
||||
return _internal_updatePeerPhoto(postbox: account.postbox, network: account.network, stateManager: account.stateManager, accountPeerId: account.peerId, peerId: peerId, photo: resource.flatMap({ _internal_uploadedPeerPhoto(postbox: account.postbox, network: account.network, resource: $0) }), video: videoResource.flatMap({ _internal_uploadedPeerVideo(postbox: account.postbox, network: account.network, messageMediaPreuploadManager: account.messageMediaPreuploadManager, resource: $0) |> map(Optional.init) }), videoStartTimestamp: videoStartTimestamp, customPeerPhotoMode: mode, mapResourceToAvatarSizes: mapResourceToAvatarSizes)
|
||||
func _internal_updateContactPhoto(account: Account, peerId: PeerId, resource: MediaResource?, videoResource: MediaResource?, videoStartTimestamp: Double?, markup: UploadPeerPhotoMarkup?, mode: SetCustomPeerPhotoMode, mapResourceToAvatarSizes: @escaping (MediaResource, [TelegramMediaImageRepresentation]) -> Signal<[Int: Data], NoError>) -> Signal<UpdatePeerPhotoStatus, UploadPeerPhotoError> {
|
||||
return _internal_updatePeerPhoto(postbox: account.postbox, network: account.network, stateManager: account.stateManager, accountPeerId: account.peerId, peerId: peerId, photo: resource.flatMap({ _internal_uploadedPeerPhoto(postbox: account.postbox, network: account.network, resource: $0) }), video: videoResource.flatMap({ _internal_uploadedPeerVideo(postbox: account.postbox, network: account.network, messageMediaPreuploadManager: account.messageMediaPreuploadManager, resource: $0) |> map(Optional.init) }), videoStartTimestamp: videoStartTimestamp, markup: markup, customPeerPhotoMode: mode, mapResourceToAvatarSizes: mapResourceToAvatarSizes)
|
||||
}
|
||||
|
||||
public struct UploadedPeerPhotoData {
|
||||
fileprivate let resource: MediaResource
|
||||
fileprivate let content: UploadedPeerPhotoDataContent
|
||||
fileprivate let local: Bool
|
||||
|
||||
public var isCompleted: Bool {
|
||||
if case let .result(result) = content, case .inputFile = result {
|
||||
@ -43,6 +50,10 @@ public struct UploadedPeerPhotoData {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
static func withResource(_ resource: MediaResource) -> UploadedPeerPhotoData {
|
||||
return UploadedPeerPhotoData(resource: resource, content: .result(.inputFile(.inputFile(id: 0, parts: 0, name: "", md5Checksum: ""))), local: true)
|
||||
}
|
||||
}
|
||||
|
||||
enum UploadedPeerPhotoDataContent {
|
||||
@ -53,10 +64,10 @@ enum UploadedPeerPhotoDataContent {
|
||||
func _internal_uploadedPeerPhoto(postbox: Postbox, network: Network, resource: MediaResource) -> Signal<UploadedPeerPhotoData, NoError> {
|
||||
return multipartUpload(network: network, postbox: postbox, source: .resource(.standalone(resource: resource)), encrypt: false, tag: TelegramMediaResourceFetchTag(statsCategory: .image, userContentType: .image), hintFileSize: nil, hintFileIsLarge: false, forceNoBigParts: false)
|
||||
|> map { result -> UploadedPeerPhotoData in
|
||||
return UploadedPeerPhotoData(resource: resource, content: .result(result))
|
||||
return UploadedPeerPhotoData(resource: resource, content: .result(result), local: false)
|
||||
}
|
||||
|> `catch` { _ -> Signal<UploadedPeerPhotoData, NoError> in
|
||||
return .single(UploadedPeerPhotoData(resource: resource, content: .error))
|
||||
return .single(UploadedPeerPhotoData(resource: resource, content: .error, local: false))
|
||||
}
|
||||
}
|
||||
|
||||
@ -64,18 +75,18 @@ func _internal_uploadedPeerVideo(postbox: Postbox, network: Network, messageMedi
|
||||
if let messageMediaPreuploadManager = messageMediaPreuploadManager {
|
||||
return messageMediaPreuploadManager.upload(network: network, postbox: postbox, source: .resource(.standalone(resource: resource)), encrypt: false, tag: TelegramMediaResourceFetchTag(statsCategory: .video, userContentType: .video), hintFileSize: nil, hintFileIsLarge: false)
|
||||
|> map { result -> UploadedPeerPhotoData in
|
||||
return UploadedPeerPhotoData(resource: resource, content: .result(result))
|
||||
return UploadedPeerPhotoData(resource: resource, content: .result(result), local: false)
|
||||
}
|
||||
|> `catch` { _ -> Signal<UploadedPeerPhotoData, NoError> in
|
||||
return .single(UploadedPeerPhotoData(resource: resource, content: .error))
|
||||
return .single(UploadedPeerPhotoData(resource: resource, content: .error, local: false))
|
||||
}
|
||||
} else {
|
||||
return multipartUpload(network: network, postbox: postbox, source: .resource(.standalone(resource: resource)), encrypt: false, tag: TelegramMediaResourceFetchTag(statsCategory: .video, userContentType: .video), hintFileSize: nil, hintFileIsLarge: false, forceNoBigParts: false)
|
||||
|> map { result -> UploadedPeerPhotoData in
|
||||
return UploadedPeerPhotoData(resource: resource, content: .result(result))
|
||||
return UploadedPeerPhotoData(resource: resource, content: .result(result), local: false)
|
||||
}
|
||||
|> `catch` { _ -> Signal<UploadedPeerPhotoData, NoError> in
|
||||
return .single(UploadedPeerPhotoData(resource: resource, content: .error))
|
||||
return .single(UploadedPeerPhotoData(resource: resource, content: .error, local: false))
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -88,6 +99,16 @@ func _internal_updatePeerPhotoInternal(postbox: Postbox, network: Network, state
|
||||
return peer
|
||||
|> mapError { _ -> UploadPeerPhotoError in }
|
||||
|> mapToSignal { peer -> Signal<UpdatePeerPhotoStatus, UploadPeerPhotoError> in
|
||||
var videoEmojiMarkup: Api.VideoSize?
|
||||
if let markup = markup {
|
||||
switch markup {
|
||||
case let .emoji(fileId, backgroundColors):
|
||||
videoEmojiMarkup = .videoSizeEmojiMarkup(emojiId: fileId, backgroundColors: backgroundColors)
|
||||
case let .sticker(packReference, fileId, backgroundColors):
|
||||
videoEmojiMarkup = .videoSizeStickerMarkup(stickerset: packReference.apiInputStickerSet, stickerId: fileId, backgroundColors: backgroundColors)
|
||||
}
|
||||
}
|
||||
|
||||
if let photo = photo {
|
||||
let mappedPhoto = photo
|
||||
|> take(until: { value in
|
||||
@ -111,7 +132,7 @@ func _internal_updatePeerPhotoInternal(postbox: Postbox, network: Network, state
|
||||
} else {
|
||||
mappedVideo = .single(nil)
|
||||
}
|
||||
|
||||
|
||||
return combineLatest(mappedPhoto, mappedVideo)
|
||||
|> mapError { _ -> UploadPeerPhotoError in }
|
||||
|> mapToSignal { photoResult, videoResult -> Signal<(UpdatePeerPhotoStatus, MediaResource?, MediaResource?), UploadPeerPhotoError> in
|
||||
@ -145,33 +166,33 @@ func _internal_updatePeerPhotoInternal(postbox: Postbox, network: Network, state
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var photoFile: Api.InputFile?
|
||||
if !photoResult.local {
|
||||
photoFile = file
|
||||
}
|
||||
|
||||
if peer is TelegramUser {
|
||||
var flags: Int32 = (1 << 0)
|
||||
var flags: Int32 = 0
|
||||
if let _ = photoFile {
|
||||
flags = (1 << 0)
|
||||
}
|
||||
if let _ = videoFile {
|
||||
flags |= (1 << 1)
|
||||
if let _ = videoStartTimestamp {
|
||||
flags |= (1 << 2)
|
||||
}
|
||||
}
|
||||
|
||||
var videoEmojiMarkup: Api.VideoSize?
|
||||
if let markup = markup{
|
||||
switch markup {
|
||||
case let .emoji(fileId, backgroundColors):
|
||||
videoEmojiMarkup = .videoSizeEmojiMarkup(emojiId: fileId, backgroundColors: backgroundColors)
|
||||
case let .sticker(packReference, fileId, backgroundColors):
|
||||
videoEmojiMarkup = .videoSizeStickerMarkup(stickerset: packReference.apiInputStickerSet, stickerId: fileId, backgroundColors: backgroundColors)
|
||||
}
|
||||
flags |= (1 << 4)
|
||||
}
|
||||
|
||||
|
||||
let request: Signal<Api.photos.Photo, MTRpcError>
|
||||
if peer.id == accountPeerId {
|
||||
if fallback {
|
||||
flags |= (1 << 3)
|
||||
}
|
||||
request = network.request(Api.functions.photos.uploadProfilePhoto(flags: flags, file: file, video: videoFile, videoStartTs: videoStartTimestamp, videoEmojiMarkup: videoEmojiMarkup))
|
||||
if let _ = videoEmojiMarkup {
|
||||
flags |= (1 << 4)
|
||||
}
|
||||
request = network.request(Api.functions.photos.uploadProfilePhoto(flags: flags, file: photoFile, video: videoFile, videoStartTs: videoStartTimestamp, videoEmojiMarkup: videoEmojiMarkup))
|
||||
} else if let inputUser = apiInputUser(peer) {
|
||||
if let customPeerPhotoMode = customPeerPhotoMode {
|
||||
switch customPeerPhotoMode {
|
||||
@ -184,8 +205,10 @@ func _internal_updatePeerPhotoInternal(postbox: Postbox, network: Network, state
|
||||
flags |= (1 << 4)
|
||||
}
|
||||
}
|
||||
|
||||
request = network.request(Api.functions.photos.uploadContactProfilePhoto(flags: flags, userId: inputUser, file: file, video: videoFile, videoStartTs: videoStartTimestamp))
|
||||
if let _ = videoEmojiMarkup {
|
||||
flags |= (1 << 5)
|
||||
}
|
||||
request = network.request(Api.functions.photos.uploadContactProfilePhoto(flags: flags, userId: inputUser, file: file, video: videoFile, videoStartTs: videoStartTimestamp, videoEmojiMarkup: videoEmojiMarkup))
|
||||
} else {
|
||||
request = .complete()
|
||||
}
|
||||
@ -273,6 +296,14 @@ func _internal_updatePeerPhotoInternal(postbox: Postbox, network: Network, state
|
||||
return nil
|
||||
}
|
||||
}
|
||||
} else if peer.id == accountPeerId && customPeerPhotoMode == nil {
|
||||
transaction.updatePeerCachedData(peerIds: Set([peer.id])) { peerId, cachedPeerData in
|
||||
if let cachedPeerData = cachedPeerData as? CachedUserData {
|
||||
return cachedPeerData.withUpdatedPhoto(.known(image))
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return (.complete(representations), photoResult.resource, videoResult?.resource)
|
||||
@ -287,17 +318,10 @@ func _internal_updatePeerPhotoInternal(postbox: Postbox, network: Network, state
|
||||
}
|
||||
}
|
||||
|
||||
var videoEmojiMarkup: Api.VideoSize?
|
||||
if let markup = markup {
|
||||
switch markup {
|
||||
case let .emoji(fileId, backgroundColors):
|
||||
videoEmojiMarkup = .videoSizeEmojiMarkup(emojiId: fileId, backgroundColors: backgroundColors)
|
||||
case let .sticker(packReference, fileId, backgroundColors):
|
||||
videoEmojiMarkup = .videoSizeStickerMarkup(stickerset: packReference.apiInputStickerSet, stickerId: fileId, backgroundColors: backgroundColors)
|
||||
}
|
||||
if let _ = videoEmojiMarkup {
|
||||
flags |= (1 << 3)
|
||||
}
|
||||
|
||||
|
||||
let request: Signal<Api.Updates, MTRpcError>
|
||||
if let peer = peer as? TelegramGroup {
|
||||
request = network.request(Api.functions.messages.editChatPhoto(chatId: peer.id.id._internalGetInt64Value(), photo: .inputChatUploadedPhoto(flags: flags, file: file, video: videoFile, videoStartTs: videoStartTimestamp, videoEmojiMarkup: videoEmojiMarkup)))
|
||||
@ -388,7 +412,7 @@ func _internal_updatePeerPhotoInternal(postbox: Postbox, network: Network, state
|
||||
request = network.request(Api.functions.photos.updateProfilePhoto(flags: flags, id: Api.InputPhoto.inputPhotoEmpty))
|
||||
} else if let inputUser = apiInputUser(peer) {
|
||||
let flags: Int32 = (1 << 4)
|
||||
request = network.request(Api.functions.photos.uploadContactProfilePhoto(flags: flags, userId: inputUser, file: nil, video: nil, videoStartTs: nil))
|
||||
request = network.request(Api.functions.photos.uploadContactProfilePhoto(flags: flags, userId: inputUser, file: nil, video: nil, videoStartTs: nil, videoEmojiMarkup: nil))
|
||||
} else {
|
||||
request = .complete()
|
||||
}
|
||||
|
@ -14,6 +14,7 @@ import GalleryUI
|
||||
import HierarchyTrackingLayer
|
||||
import WallpaperBackgroundNode
|
||||
import ChatControllerInteraction
|
||||
import AvatarVideoNode
|
||||
|
||||
private let timezoneOffset: Int32 = {
|
||||
let nowTimestamp = Int32(CFAbsoluteTimeGetCurrent() + NSTimeIntervalSince1970)
|
||||
@ -446,20 +447,17 @@ final class ChatMessageAvatarHeaderNode: ListViewItemHeaderNode {
|
||||
|
||||
private let containerNode: ContextControllerSourceNode
|
||||
private let avatarNode: AvatarNode
|
||||
private var videoNode: UniversalVideoNode?
|
||||
|
||||
private var videoContent: NativeVideoContent?
|
||||
private let playbackStartDisposable = MetaDisposable()
|
||||
private var avatarVideoNode: AvatarVideoNode?
|
||||
|
||||
private var cachedDataDisposable = MetaDisposable()
|
||||
private var hierarchyTrackingLayer: HierarchyTrackingLayer?
|
||||
private var videoLoopCount = 0
|
||||
|
||||
private var trackingIsInHierarchy: Bool = false {
|
||||
didSet {
|
||||
if self.trackingIsInHierarchy != oldValue {
|
||||
Queue.mainQueue().justDispatch {
|
||||
if self.trackingIsInHierarchy {
|
||||
self.videoLoopCount = 0
|
||||
self.avatarVideoNode?.resetPlayback()
|
||||
}
|
||||
self.updateVideoVisibility()
|
||||
}
|
||||
@ -507,7 +505,6 @@ final class ChatMessageAvatarHeaderNode: ListViewItemHeaderNode {
|
||||
|
||||
deinit {
|
||||
self.cachedDataDisposable.dispose()
|
||||
self.playbackStartDisposable.dispose()
|
||||
}
|
||||
|
||||
func setCustomLetters(context: AccountContext, theme: PresentationTheme, synchronousLoad: Bool, letters: [String], emptyColor: UIColor) {
|
||||
@ -531,16 +528,35 @@ final class ChatMessageAvatarHeaderNode: ListViewItemHeaderNode {
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
let cachedPeerData = peerView.cachedData
|
||||
if let cachedPeerData = cachedPeerData as? CachedUserData, case let .known(maybePhoto) = cachedPeerData.photo {
|
||||
if let photo = maybePhoto, let video = photo.videoRepresentations.last, let peerReference = PeerReference(peer) {
|
||||
let videoId = photo.id?.id ?? peer.id.id._internalGetInt64Value()
|
||||
let videoFileReference = FileMediaReference.avatarList(peer: peerReference, media: TelegramMediaFile(fileId: MediaId(namespace: Namespaces.Media.LocalFile, id: 0), partialReference: nil, resource: video.resource, previewRepresentations: photo.representations, videoThumbnails: [], immediateThumbnailData: photo.immediateThumbnailData, mimeType: "video/mp4", size: nil, attributes: [.Animated, .Video(duration: 0, size: video.dimensions, flags: [])]))
|
||||
let videoContent = NativeVideoContent(id: .profileVideo(videoId, "\(Int32.random(in: 0 ..< Int32.max))"), userLocation: .other, fileReference: videoFileReference, streamVideo: isMediaStreamable(resource: video.resource) ? .conservative : .none, loopVideo: true, enableSound: false, fetchAutomatically: true, onlyFullSizeThumbnail: false, useLargeThumbnail: true, autoFetchFullSizeThumbnail: true, startTimestamp: video.startTimestamp, continuePlayingWithoutSoundOnLostAudioSession: false, placeholderColor: .clear, captureProtected: false, storeAfterDownload: nil)
|
||||
if videoContent.id != strongSelf.videoContent?.id {
|
||||
strongSelf.videoNode?.removeFromSupernode()
|
||||
strongSelf.videoContent = videoContent
|
||||
|
||||
let cachedPeerData = peerView.cachedData as? CachedUserData
|
||||
var personalPhoto: TelegramMediaImage?
|
||||
var profilePhoto: TelegramMediaImage?
|
||||
var isKnown = false
|
||||
|
||||
if let cachedPeerData = cachedPeerData {
|
||||
if case let .known(maybePersonalPhoto) = cachedPeerData.personalPhoto {
|
||||
personalPhoto = maybePersonalPhoto
|
||||
isKnown = true
|
||||
}
|
||||
if case let .known(maybePhoto) = cachedPeerData.photo {
|
||||
profilePhoto = maybePhoto
|
||||
isKnown = true
|
||||
}
|
||||
}
|
||||
|
||||
if isKnown {
|
||||
let photo = personalPhoto ?? profilePhoto
|
||||
if let photo = photo, !photo.videoRepresentations.isEmpty || photo.emojiMarkup != nil {
|
||||
let videoNode: AvatarVideoNode
|
||||
if let current = strongSelf.avatarVideoNode {
|
||||
videoNode = current
|
||||
} else {
|
||||
videoNode = AvatarVideoNode(context: context)
|
||||
strongSelf.avatarNode.addSubnode(videoNode)
|
||||
strongSelf.avatarVideoNode = videoNode
|
||||
}
|
||||
videoNode.update(peer: EnginePeer(peer), photo: photo, size: CGSize(width: 38.0, height: 38.0))
|
||||
|
||||
if strongSelf.hierarchyTrackingLayer == nil {
|
||||
let hierarchyTrackingLayer = HierarchyTrackingLayer()
|
||||
@ -561,23 +577,65 @@ final class ChatMessageAvatarHeaderNode: ListViewItemHeaderNode {
|
||||
strongSelf.layer.addSublayer(hierarchyTrackingLayer)
|
||||
}
|
||||
} else {
|
||||
strongSelf.videoContent = nil
|
||||
|
||||
if let avatarVideoNode = strongSelf.avatarVideoNode {
|
||||
avatarVideoNode.removeFromSupernode()
|
||||
strongSelf.avatarVideoNode = nil
|
||||
}
|
||||
strongSelf.hierarchyTrackingLayer?.removeFromSuperlayer()
|
||||
strongSelf.hierarchyTrackingLayer = nil
|
||||
}
|
||||
|
||||
strongSelf.updateVideoVisibility()
|
||||
} else {
|
||||
let _ = context.engine.peers.fetchAndUpdateCachedPeerData(peerId: peer.id).start()
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// let cachedPeerData = peerView.cachedData
|
||||
// if let cachedPeerData = cachedPeerData as? CachedUserData, case let .known(maybePhoto) = cachedPeerData.photo {
|
||||
// if let photo = maybePhoto, let video = photo.videoRepresentations.last, let peerReference = PeerReference(peer) {
|
||||
// let videoId = photo.id?.id ?? peer.id.id._internalGetInt64Value()
|
||||
// let videoFileReference = FileMediaReference.avatarList(peer: peerReference, media: TelegramMediaFile(fileId: MediaId(namespace: Namespaces.Media.LocalFile, id: 0), partialReference: nil, resource: video.resource, previewRepresentations: photo.representations, videoThumbnails: [], immediateThumbnailData: photo.immediateThumbnailData, mimeType: "video/mp4", size: nil, attributes: [.Animated, .Video(duration: 0, size: video.dimensions, flags: [])]))
|
||||
// let videoContent = NativeVideoContent(id: .profileVideo(videoId, "\(Int32.random(in: 0 ..< Int32.max))"), userLocation: .other, fileReference: videoFileReference, streamVideo: isMediaStreamable(resource: video.resource) ? .conservative : .none, loopVideo: true, enableSound: false, fetchAutomatically: true, onlyFullSizeThumbnail: false, useLargeThumbnail: true, autoFetchFullSizeThumbnail: true, startTimestamp: video.startTimestamp, continuePlayingWithoutSoundOnLostAudioSession: false, placeholderColor: .clear, captureProtected: false, storeAfterDownload: nil)
|
||||
// if videoContent.id != strongSelf.videoContent?.id {
|
||||
// strongSelf.videoNode?.removeFromSupernode()
|
||||
// strongSelf.videoContent = videoContent
|
||||
// }
|
||||
//
|
||||
// if strongSelf.hierarchyTrackingLayer == nil {
|
||||
// let hierarchyTrackingLayer = HierarchyTrackingLayer()
|
||||
// hierarchyTrackingLayer.didEnterHierarchy = { [weak self] in
|
||||
// guard let strongSelf = self else {
|
||||
// return
|
||||
// }
|
||||
// strongSelf.trackingIsInHierarchy = true
|
||||
// }
|
||||
//
|
||||
// hierarchyTrackingLayer.didExitHierarchy = { [weak self] in
|
||||
// guard let strongSelf = self else {
|
||||
// return
|
||||
// }
|
||||
// strongSelf.trackingIsInHierarchy = false
|
||||
// }
|
||||
// strongSelf.hierarchyTrackingLayer = hierarchyTrackingLayer
|
||||
// strongSelf.layer.addSublayer(hierarchyTrackingLayer)
|
||||
// }
|
||||
// } else {
|
||||
// strongSelf.videoContent = nil
|
||||
//
|
||||
// strongSelf.hierarchyTrackingLayer?.removeFromSuperlayer()
|
||||
// strongSelf.hierarchyTrackingLayer = nil
|
||||
// }
|
||||
//
|
||||
// strongSelf.updateVideoVisibility()
|
||||
// } else {
|
||||
}))
|
||||
} else {
|
||||
self.cachedDataDisposable.set(nil)
|
||||
self.videoContent = nil
|
||||
|
||||
self.videoNode?.removeFromSupernode()
|
||||
self.videoNode = nil
|
||||
self.avatarVideoNode?.removeFromSupernode()
|
||||
self.avatarVideoNode = nil
|
||||
|
||||
self.hierarchyTrackingLayer?.removeFromSuperlayer()
|
||||
self.hierarchyTrackingLayer = nil
|
||||
@ -659,74 +717,12 @@ final class ChatMessageAvatarHeaderNode: ListViewItemHeaderNode {
|
||||
}
|
||||
|
||||
private func updateVideoVisibility() {
|
||||
let context = self.context
|
||||
let isVisible = self.trackingIsInHierarchy
|
||||
if isVisible, let videoContent = self.videoContent, self.videoLoopCount != maxVideoLoopCount {
|
||||
if self.videoNode == nil {
|
||||
let mediaManager = context.sharedContext.mediaManager
|
||||
let videoNode = UniversalVideoNode(postbox: context.account.postbox, audioSession: mediaManager.audioSession, manager: mediaManager.universalVideoManager, decoration: GalleryVideoDecoration(), content: videoContent, priority: .embedded)
|
||||
videoNode.clipsToBounds = true
|
||||
videoNode.isUserInteractionEnabled = false
|
||||
videoNode.isHidden = true
|
||||
videoNode.playbackCompleted = { [weak self] in
|
||||
Queue.mainQueue().async {
|
||||
if let strongSelf = self {
|
||||
strongSelf.videoLoopCount += 1
|
||||
if strongSelf.videoLoopCount == maxVideoLoopCount {
|
||||
if let videoNode = strongSelf.videoNode {
|
||||
strongSelf.videoNode = nil
|
||||
videoNode.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.2, removeOnCompletion: false, completion: { [weak videoNode] _ in
|
||||
videoNode?.removeFromSupernode()
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if let _ = videoContent.startTimestamp {
|
||||
self.playbackStartDisposable.set((videoNode.status
|
||||
|> map { status -> Bool in
|
||||
if let status = status, case .playing = status.status {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|> filter { playing in
|
||||
return playing
|
||||
}
|
||||
|> take(1)
|
||||
|> deliverOnMainQueue).start(completed: { [weak self] in
|
||||
if let strongSelf = self {
|
||||
Queue.mainQueue().after(0.15) {
|
||||
strongSelf.videoNode?.isHidden = false
|
||||
}
|
||||
}
|
||||
}))
|
||||
} else {
|
||||
self.playbackStartDisposable.set(nil)
|
||||
videoNode.isHidden = false
|
||||
}
|
||||
videoNode.layer.cornerRadius = self.avatarNode.frame.size.width / 2.0
|
||||
if #available(iOS 13.0, *) {
|
||||
videoNode.layer.cornerCurve = .circular
|
||||
}
|
||||
|
||||
videoNode.canAttachContent = true
|
||||
videoNode.play()
|
||||
|
||||
self.containerNode.insertSubnode(videoNode, aboveSubnode: self.avatarNode)
|
||||
self.videoNode = videoNode
|
||||
}
|
||||
} else if let videoNode = self.videoNode {
|
||||
self.videoNode = nil
|
||||
videoNode.removeFromSupernode()
|
||||
}
|
||||
|
||||
if let videoNode = self.videoNode {
|
||||
videoNode.updateLayout(size: self.avatarNode.frame.size, transition: .immediate)
|
||||
videoNode.frame = self.avatarNode.frame
|
||||
self.avatarVideoNode?.updateVisibility(isVisible)
|
||||
|
||||
if let videoNode = self.avatarVideoNode {
|
||||
videoNode.updateLayout(size: self.avatarNode.frame.size, cornerRadius: self.avatarNode.frame.size.width / 2.0, transition: .immediate)
|
||||
videoNode.frame = self.avatarNode.bounds
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -6919,11 +6919,11 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate
|
||||
})
|
||||
}
|
||||
} else if case .custom = mode {
|
||||
signal = self.context.engine.contacts.updateContactPhoto(peerId: self.peerId, resource: resource, videoResource: nil, videoStartTimestamp: nil, mode: .custom, mapResourceToAvatarSizes: { resource, representations in
|
||||
signal = self.context.engine.contacts.updateContactPhoto(peerId: self.peerId, resource: resource, videoResource: nil, videoStartTimestamp: nil, markup: nil, mode: .custom, mapResourceToAvatarSizes: { resource, representations in
|
||||
return mapResourceToAvatarSizes(postbox: postbox, resource: resource, representations: representations)
|
||||
})
|
||||
} else if case .suggest = mode {
|
||||
signal = self.context.engine.contacts.updateContactPhoto(peerId: self.peerId, resource: resource, videoResource: nil, videoStartTimestamp: nil, mode: .suggest, mapResourceToAvatarSizes: { resource, representations in
|
||||
signal = self.context.engine.contacts.updateContactPhoto(peerId: self.peerId, resource: resource, videoResource: nil, videoStartTimestamp: nil, markup: nil, mode: .suggest, mapResourceToAvatarSizes: { resource, representations in
|
||||
return mapResourceToAvatarSizes(postbox: postbox, resource: resource, representations: representations)
|
||||
})
|
||||
} else {
|
||||
@ -7030,85 +7030,109 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate
|
||||
videoStartTimestamp = adjustments.videoStartValue - adjustments.trimStartValue
|
||||
}
|
||||
|
||||
var markup: UploadPeerPhotoMarkup? = nil
|
||||
if let fileId = adjustments?.documentId, let backgroundColors = adjustments?.colors as? [Int32], fileId != 0 {
|
||||
if let packId = adjustments?.stickerPackId, let accessHash = adjustments?.stickerPackAccessHash, packId != 0 {
|
||||
markup = .sticker(packReference: .id(id: packId, accessHash: accessHash), fileId: fileId, backgroundColors: backgroundColors)
|
||||
} else {
|
||||
markup = .emoji(fileId: fileId, backgroundColors: backgroundColors)
|
||||
}
|
||||
}
|
||||
|
||||
var uploadVideo = true
|
||||
if let _ = markup {
|
||||
if let data = self.context.currentAppConfiguration.with({ $0 }).data, let uploadVideoValue = data["upload_markup_video"] as? Bool, uploadVideoValue {
|
||||
uploadVideo = true
|
||||
} else {
|
||||
uploadVideo = false
|
||||
}
|
||||
}
|
||||
|
||||
let account = self.context.account
|
||||
let context = self.context
|
||||
let signal = Signal<TelegramMediaResource, UploadPeerPhotoError> { [weak self] subscriber in
|
||||
let entityRenderer: LegacyPaintEntityRenderer? = adjustments.flatMap { adjustments in
|
||||
if let paintingData = adjustments.paintingData, paintingData.hasAnimation {
|
||||
return LegacyPaintEntityRenderer(account: account, adjustments: adjustments)
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
let uploadInterface = LegacyLiveUploadInterface(context: context)
|
||||
let signal: SSignal
|
||||
if let url = asset as? URL, url.absoluteString.hasSuffix(".jpg"), let data = try? Data(contentsOf: url, options: [.mappedRead]), let image = UIImage(data: data), let entityRenderer = entityRenderer {
|
||||
let durationSignal: SSignal = SSignal(generator: { subscriber in
|
||||
let disposable = (entityRenderer.duration()).start(next: { duration in
|
||||
subscriber.putNext(duration)
|
||||
subscriber.putCompletion()
|
||||
})
|
||||
|
||||
return SBlockDisposable(block: {
|
||||
disposable.dispose()
|
||||
})
|
||||
})
|
||||
signal = durationSignal.map(toSignal: { duration -> SSignal in
|
||||
if let duration = duration as? Double {
|
||||
return TGMediaVideoConverter.renderUIImage(image, duration: duration, adjustments: adjustments, watcher: nil, entityRenderer: entityRenderer)!
|
||||
|
||||
let videoResource: Signal<TelegramMediaResource?, UploadPeerPhotoError>
|
||||
if uploadVideo {
|
||||
videoResource = Signal<TelegramMediaResource?, UploadPeerPhotoError> { [weak self] subscriber in
|
||||
let entityRenderer: LegacyPaintEntityRenderer? = adjustments.flatMap { adjustments in
|
||||
if let paintingData = adjustments.paintingData, paintingData.hasAnimation {
|
||||
return LegacyPaintEntityRenderer(account: account, adjustments: adjustments)
|
||||
} else {
|
||||
return SSignal.single(nil)
|
||||
}
|
||||
})
|
||||
|
||||
} else if let asset = asset as? AVAsset {
|
||||
signal = TGMediaVideoConverter.convert(asset, adjustments: adjustments, watcher: uploadInterface, entityRenderer: entityRenderer)!
|
||||
} else {
|
||||
signal = SSignal.complete()
|
||||
}
|
||||
|
||||
let signalDisposable = signal.start(next: { next in
|
||||
if let result = next as? TGMediaVideoConversionResult {
|
||||
if let image = result.coverImage, let data = image.jpegData(compressionQuality: 0.7) {
|
||||
account.postbox.mediaBox.storeResourceData(photoResource.id, data: data)
|
||||
}
|
||||
|
||||
if let timestamp = videoStartTimestamp {
|
||||
videoStartTimestamp = max(0.0, min(timestamp, result.duration - 0.05))
|
||||
}
|
||||
|
||||
var value = stat()
|
||||
if stat(result.fileURL.path, &value) == 0 {
|
||||
if let data = try? Data(contentsOf: result.fileURL) {
|
||||
let resource: TelegramMediaResource
|
||||
if let liveUploadData = result.liveUploadData as? LegacyLiveUploadInterfaceResult {
|
||||
resource = LocalFileMediaResource(fileId: liveUploadData.id)
|
||||
} else {
|
||||
resource = LocalFileMediaResource(fileId: Int64.random(in: Int64.min ... Int64.max))
|
||||
}
|
||||
account.postbox.mediaBox.storeResourceData(resource.id, data: data, synchronous: true)
|
||||
subscriber.putNext(resource)
|
||||
}
|
||||
}
|
||||
subscriber.putCompletion()
|
||||
} else if let strongSelf = self, let progress = next as? NSNumber {
|
||||
Queue.mainQueue().async {
|
||||
strongSelf.state = strongSelf.state.withAvatarUploadProgress(CGFloat(progress.floatValue * 0.45))
|
||||
if let (layout, navigationHeight) = strongSelf.validLayout {
|
||||
strongSelf.containerLayoutUpdated(layout: layout, navigationHeight: navigationHeight, transition: .immediate, additive: false)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}, error: { _ in
|
||||
}, completed: nil)
|
||||
|
||||
let disposable = ActionDisposable {
|
||||
signalDisposable?.dispose()
|
||||
}
|
||||
|
||||
return ActionDisposable {
|
||||
disposable.dispose()
|
||||
let uploadInterface = LegacyLiveUploadInterface(context: context)
|
||||
let signal: SSignal
|
||||
if let url = asset as? URL, url.absoluteString.hasSuffix(".jpg"), let data = try? Data(contentsOf: url, options: [.mappedRead]), let image = UIImage(data: data), let entityRenderer = entityRenderer {
|
||||
let durationSignal: SSignal = SSignal(generator: { subscriber in
|
||||
let disposable = (entityRenderer.duration()).start(next: { duration in
|
||||
subscriber.putNext(duration)
|
||||
subscriber.putCompletion()
|
||||
})
|
||||
|
||||
return SBlockDisposable(block: {
|
||||
disposable.dispose()
|
||||
})
|
||||
})
|
||||
signal = durationSignal.map(toSignal: { duration -> SSignal in
|
||||
if let duration = duration as? Double {
|
||||
return TGMediaVideoConverter.renderUIImage(image, duration: duration, adjustments: adjustments, watcher: nil, entityRenderer: entityRenderer)!
|
||||
} else {
|
||||
return SSignal.single(nil)
|
||||
}
|
||||
})
|
||||
|
||||
} else if let asset = asset as? AVAsset {
|
||||
signal = TGMediaVideoConverter.convert(asset, adjustments: adjustments, watcher: uploadInterface, entityRenderer: entityRenderer)!
|
||||
} else {
|
||||
signal = SSignal.complete()
|
||||
}
|
||||
|
||||
let signalDisposable = signal.start(next: { next in
|
||||
if let result = next as? TGMediaVideoConversionResult {
|
||||
if let image = result.coverImage, let data = image.jpegData(compressionQuality: 0.7) {
|
||||
account.postbox.mediaBox.storeResourceData(photoResource.id, data: data)
|
||||
}
|
||||
|
||||
if let timestamp = videoStartTimestamp {
|
||||
videoStartTimestamp = max(0.0, min(timestamp, result.duration - 0.05))
|
||||
}
|
||||
|
||||
var value = stat()
|
||||
if stat(result.fileURL.path, &value) == 0 {
|
||||
if let data = try? Data(contentsOf: result.fileURL) {
|
||||
let resource: TelegramMediaResource
|
||||
if let liveUploadData = result.liveUploadData as? LegacyLiveUploadInterfaceResult {
|
||||
resource = LocalFileMediaResource(fileId: liveUploadData.id)
|
||||
} else {
|
||||
resource = LocalFileMediaResource(fileId: Int64.random(in: Int64.min ... Int64.max))
|
||||
}
|
||||
account.postbox.mediaBox.storeResourceData(resource.id, data: data, synchronous: true)
|
||||
subscriber.putNext(resource)
|
||||
}
|
||||
}
|
||||
subscriber.putCompletion()
|
||||
} else if let strongSelf = self, let progress = next as? NSNumber {
|
||||
Queue.mainQueue().async {
|
||||
strongSelf.state = strongSelf.state.withAvatarUploadProgress(CGFloat(progress.floatValue * 0.45))
|
||||
if let (layout, navigationHeight) = strongSelf.validLayout {
|
||||
strongSelf.containerLayoutUpdated(layout: layout, navigationHeight: navigationHeight, transition: .immediate, additive: false)
|
||||
}
|
||||
}
|
||||
}
|
||||
}, error: { _ in
|
||||
}, completed: nil)
|
||||
|
||||
let disposable = ActionDisposable {
|
||||
signalDisposable?.dispose()
|
||||
}
|
||||
|
||||
return ActionDisposable {
|
||||
disposable.dispose()
|
||||
}
|
||||
}
|
||||
} else {
|
||||
videoResource = .single(nil)
|
||||
}
|
||||
|
||||
var dismissStatus: (() -> Void)?
|
||||
@ -7131,17 +7155,9 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate
|
||||
|
||||
let peerId = self.peerId
|
||||
let isSettings = self.isSettings
|
||||
self.updateAvatarDisposable.set((signal
|
||||
self.updateAvatarDisposable.set((videoResource
|
||||
|> mapToSignal { videoResource -> Signal<UpdatePeerPhotoStatus, UploadPeerPhotoError> in
|
||||
var markup: UploadPeerPhotoMarkup? = nil
|
||||
if isSettings {
|
||||
if let fileId = adjustments?.documentId, let backgroundColors = adjustments?.colors as? [Int32], fileId != 0 {
|
||||
if let packId = adjustments?.stickerPackId, let accessHash = adjustments?.stickerPackAccessHash, packId != 0 {
|
||||
markup = .sticker(packReference: .id(id: packId, accessHash: accessHash), fileId: fileId, backgroundColors: backgroundColors)
|
||||
} else {
|
||||
markup = .emoji(fileId: fileId, backgroundColors: backgroundColors)
|
||||
}
|
||||
}
|
||||
if case .fallback = mode {
|
||||
return context.engine.accountData.updateFallbackPhoto(resource: photoResource, videoResource: videoResource, videoStartTimestamp: videoStartTimestamp, markup: markup, mapResourceToAvatarSizes: { resource, representations in
|
||||
return mapResourceToAvatarSizes(postbox: account.postbox, resource: resource, representations: representations)
|
||||
@ -7152,15 +7168,15 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate
|
||||
})
|
||||
}
|
||||
} else if case .custom = mode {
|
||||
return context.engine.contacts.updateContactPhoto(peerId: peerId, resource: photoResource, videoResource: videoResource, videoStartTimestamp: videoStartTimestamp, mode: .custom, mapResourceToAvatarSizes: { resource, representations in
|
||||
return context.engine.contacts.updateContactPhoto(peerId: peerId, resource: photoResource, videoResource: videoResource, videoStartTimestamp: videoStartTimestamp, markup: markup, mode: .custom, mapResourceToAvatarSizes: { resource, representations in
|
||||
return mapResourceToAvatarSizes(postbox: account.postbox, resource: resource, representations: representations)
|
||||
})
|
||||
} else if case .suggest = mode {
|
||||
return context.engine.contacts.updateContactPhoto(peerId: peerId, resource: photoResource, videoResource: videoResource, videoStartTimestamp: videoStartTimestamp, mode: .suggest, mapResourceToAvatarSizes: { resource, representations in
|
||||
return context.engine.contacts.updateContactPhoto(peerId: peerId, resource: photoResource, videoResource: videoResource, videoStartTimestamp: videoStartTimestamp, markup: markup, mode: .suggest, mapResourceToAvatarSizes: { resource, representations in
|
||||
return mapResourceToAvatarSizes(postbox: account.postbox, resource: resource, representations: representations)
|
||||
})
|
||||
} else {
|
||||
return context.engine.peers.updatePeerPhoto(peerId: peerId, photo: context.engine.peers.uploadedPeerPhoto(resource: photoResource), video: context.engine.peers.uploadedPeerVideo(resource: videoResource) |> map(Optional.init), videoStartTimestamp: videoStartTimestamp, markup: markup, mapResourceToAvatarSizes: { resource, representations in
|
||||
return context.engine.peers.updatePeerPhoto(peerId: peerId, photo: context.engine.peers.uploadedPeerPhoto(resource: photoResource), video: videoResource.flatMap { context.engine.peers.uploadedPeerVideo(resource: $0) |> map(Optional.init) }, videoStartTimestamp: videoStartTimestamp, markup: markup, mapResourceToAvatarSizes: { resource, representations in
|
||||
return mapResourceToAvatarSizes(postbox: account.postbox, resource: resource, representations: representations)
|
||||
})
|
||||
}
|
||||
@ -7418,7 +7434,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate
|
||||
let postbox = strongSelf.context.account.postbox
|
||||
let signal: Signal<UpdatePeerPhotoStatus, UploadPeerPhotoError>
|
||||
if case .custom = mode {
|
||||
signal = strongSelf.context.engine.contacts.updateContactPhoto(peerId: strongSelf.peerId, resource: nil, videoResource: nil, videoStartTimestamp: nil, mode: .custom, mapResourceToAvatarSizes: { resource, representations in
|
||||
signal = strongSelf.context.engine.contacts.updateContactPhoto(peerId: strongSelf.peerId, resource: nil, videoResource: nil, videoStartTimestamp: nil, markup: nil, mode: .custom, mapResourceToAvatarSizes: { resource, representations in
|
||||
return mapResourceToAvatarSizes(postbox: postbox, resource: resource, representations: representations)
|
||||
})
|
||||
} else if case .fallback = mode {
|
||||
@ -8507,7 +8523,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
strongSelf.updateAvatarDisposable.set((strongSelf.context.engine.contacts.updateContactPhoto(peerId: strongSelf.peerId, resource: nil, videoResource: nil, videoStartTimestamp: nil, mode: .custom, mapResourceToAvatarSizes: { resource, representations in
|
||||
strongSelf.updateAvatarDisposable.set((strongSelf.context.engine.contacts.updateContactPhoto(peerId: strongSelf.peerId, resource: nil, videoResource: nil, videoStartTimestamp: nil, markup: nil, mode: .custom, mapResourceToAvatarSizes: { resource, representations in
|
||||
mapResourceToAvatarSizes(postbox: strongSelf.context.account.postbox, resource: resource, representations: representations)
|
||||
})
|
||||
|> deliverOnMainQueue).start(next: { [weak self] _ in
|
||||
|
Loading…
x
Reference in New Issue
Block a user