mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
Video avatar fixes
This commit is contained in:
parent
eebcab90b9
commit
aaff05021d
@ -928,8 +928,8 @@ final class UniversalVideoGalleryItemNode: ZoomableContentGalleryItemNode {
|
||||
let transformedCopyViewFinalFrame = videoNode.view.convert(videoNode.view.bounds, to: self.view)
|
||||
|
||||
let (maybeSurfaceCopyView, _) = node.2()
|
||||
let (maybeCopyView, copyViewBackgrond) = node.2()
|
||||
copyViewBackgrond?.alpha = 0.0
|
||||
let (maybeCopyView, copyViewBackground) = node.2()
|
||||
copyViewBackground?.alpha = 0.0
|
||||
let surfaceCopyView = maybeSurfaceCopyView!
|
||||
let copyView = maybeCopyView!
|
||||
|
||||
@ -1032,8 +1032,8 @@ final class UniversalVideoGalleryItemNode: ZoomableContentGalleryItemNode {
|
||||
var copyCompleted = false
|
||||
|
||||
let (maybeSurfaceCopyView, _) = node.2()
|
||||
let (maybeCopyView, copyViewBackgrond) = node.2()
|
||||
copyViewBackgrond?.alpha = 0.0
|
||||
let (maybeCopyView, copyViewBackground) = node.2()
|
||||
copyViewBackground?.alpha = 0.0
|
||||
let surfaceCopyView = maybeSurfaceCopyView!
|
||||
let copyView = maybeCopyView!
|
||||
|
||||
|
@ -1716,7 +1716,7 @@
|
||||
CGFloat duration = self.view.frame.size.height / velocity;
|
||||
CGRect targetFrame = CGRectOffset(self.view.frame, 0, self.view.frame.size.height);
|
||||
|
||||
[UIView animateWithDuration:duration animations:^
|
||||
[UIView animateWithDuration:duration delay:0.4 options:kNilOptions animations:^
|
||||
{
|
||||
self.view.frame = targetFrame;
|
||||
} completion:^(__unused BOOL finished)
|
||||
|
@ -112,39 +112,53 @@ public func normalizeEntries(_ entries: [AvatarGalleryEntry]) -> [AvatarGalleryE
|
||||
return updatedEntries
|
||||
}
|
||||
|
||||
public func initialAvatarGalleryEntries(peer: Peer) -> [AvatarGalleryEntry] {
|
||||
public func initialAvatarGalleryEntries(account: Account, peer: Peer) -> Signal<[AvatarGalleryEntry], NoError> {
|
||||
var initialEntries: [AvatarGalleryEntry] = []
|
||||
if !peer.profileImageRepresentations.isEmpty, let peerReference = PeerReference(peer) {
|
||||
initialEntries.append(.topImage(peer.profileImageRepresentations.map({ ImageRepresentationWithReference(representation: $0, reference: MediaResourceReference.avatar(peer: peerReference, resource: $0.resource)) }), nil, nil, nil))
|
||||
}
|
||||
return initialEntries
|
||||
|
||||
if let peer = peer as? TelegramChannel {
|
||||
return account.postbox.transaction { transaction in
|
||||
return transaction.getPeerCachedData(peerId: peer.id)
|
||||
} |> map { cachedData in
|
||||
if let cachedData = cachedData as? CachedChannelData, let photo = cachedData.photo {
|
||||
return [.image(photo.imageId, photo.reference, photo.representations.map({ ImageRepresentationWithReference(representation: $0, reference: MediaResourceReference.standalone(resource: $0.resource)) }), photo.videoRepresentations, peer, 0, nil, nil, photo.immediateThumbnailData, nil)]
|
||||
} else {
|
||||
return initialEntries
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return .single(initialEntries)
|
||||
}
|
||||
}
|
||||
|
||||
public func fetchedAvatarGalleryEntries(account: Account, peer: Peer) -> Signal<[AvatarGalleryEntry], NoError> {
|
||||
let initialEntries = initialAvatarGalleryEntries(peer: peer)
|
||||
return Signal<[AvatarGalleryEntry], NoError>.single(initialEntries)
|
||||
|> then(
|
||||
requestPeerPhotos(account: account, peerId: peer.id)
|
||||
|> map { photos -> [AvatarGalleryEntry] in
|
||||
var result: [AvatarGalleryEntry] = []
|
||||
let initialEntries = initialAvatarGalleryEntries(peer: peer)
|
||||
if photos.isEmpty {
|
||||
result = initialEntries
|
||||
} else {
|
||||
var index: Int32 = 0
|
||||
for photo in photos {
|
||||
let indexData = GalleryItemIndexData(position: index, totalCount: Int32(photos.count))
|
||||
if result.isEmpty, let first = initialEntries.first {
|
||||
result.append(.image(photo.image.imageId, photo.image.reference, first.representations, photo.image.videoRepresentations, peer, photo.date, indexData, photo.messageId, photo.image.immediateThumbnailData, nil))
|
||||
} else {
|
||||
result.append(.image(photo.image.imageId, photo.image.reference, photo.image.representations.map({ ImageRepresentationWithReference(representation: $0, reference: MediaResourceReference.standalone(resource: $0.resource)) }), photo.image.videoRepresentations, peer, photo.date, indexData, photo.messageId, photo.image.immediateThumbnailData, nil))
|
||||
return initialAvatarGalleryEntries(account: account, peer: peer)
|
||||
|> mapToSignal { initialEntries in
|
||||
return .single(initialEntries)
|
||||
|> then(
|
||||
requestPeerPhotos(account: account, peerId: peer.id)
|
||||
|> map { photos -> [AvatarGalleryEntry] in
|
||||
var result: [AvatarGalleryEntry] = []
|
||||
if photos.isEmpty {
|
||||
result = initialEntries
|
||||
} else {
|
||||
var index: Int32 = 0
|
||||
for photo in photos {
|
||||
let indexData = GalleryItemIndexData(position: index, totalCount: Int32(photos.count))
|
||||
if result.isEmpty, let first = initialEntries.first {
|
||||
result.append(.image(photo.image.imageId, photo.image.reference, first.representations, photo.image.videoRepresentations, peer, photo.date, indexData, photo.messageId, photo.image.immediateThumbnailData, nil))
|
||||
} else {
|
||||
result.append(.image(photo.image.imageId, photo.image.reference, photo.image.representations.map({ ImageRepresentationWithReference(representation: $0, reference: MediaResourceReference.standalone(resource: $0.resource)) }), photo.image.videoRepresentations, peer, photo.date, indexData, photo.messageId, photo.image.immediateThumbnailData, nil))
|
||||
}
|
||||
index += 1
|
||||
}
|
||||
index += 1
|
||||
}
|
||||
return result
|
||||
}
|
||||
return result
|
||||
}
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
public func fetchedAvatarGalleryEntries(account: Account, peer: Peer, firstEntry: AvatarGalleryEntry) -> Signal<[AvatarGalleryEntry], NoError> {
|
||||
@ -242,7 +256,7 @@ public class AvatarGalleryController: ViewController, StandalonePresentableContr
|
||||
remoteEntriesSignal = fetchedAvatarGalleryEntries(account: context.account, peer: peer)
|
||||
}
|
||||
|
||||
let entriesSignal: Signal<[AvatarGalleryEntry], NoError> = .single(initialAvatarGalleryEntries(peer: peer)) |> then(remoteEntriesSignal)
|
||||
let entriesSignal: Signal<[AvatarGalleryEntry], NoError> = initialAvatarGalleryEntries(account: context.account, peer: peer) |> then(remoteEntriesSignal)
|
||||
|
||||
let presentationData = self.presentationData
|
||||
|
||||
|
@ -449,7 +449,10 @@ final class PeerAvatarImageGalleryItemNode: ZoomableContentGalleryItemNode {
|
||||
var copyCompleted = false
|
||||
var surfaceCopyCompleted = false
|
||||
|
||||
let copyView = node.2().0!
|
||||
let (maybeCopyView, copyViewBackground) = node.2()
|
||||
copyViewBackground?.alpha = 1.0
|
||||
|
||||
let copyView = maybeCopyView!
|
||||
|
||||
if self.sourceHasRoundCorners {
|
||||
self.view.insertSubview(copyView, belowSubview: self.scrollNode.view)
|
||||
|
@ -168,6 +168,7 @@ public final class CachedChannelData: CachedPeerData {
|
||||
public let hasScheduledMessages: Bool
|
||||
public let statsDatacenterId: Int32
|
||||
public let invitedBy: PeerId?
|
||||
public let photo: TelegramMediaImage?
|
||||
|
||||
public let peerIds: Set<PeerId>
|
||||
public let messageIds: Set<MessageId>
|
||||
@ -196,9 +197,10 @@ public final class CachedChannelData: CachedPeerData {
|
||||
self.hasScheduledMessages = false
|
||||
self.statsDatacenterId = 0
|
||||
self.invitedBy = nil
|
||||
self.photo = nil
|
||||
}
|
||||
|
||||
public init(isNotAccessible: Bool, flags: CachedChannelFlags, about: String?, participantsSummary: CachedChannelParticipantsSummary, exportedInvitation: ExportedInvitation?, botInfos: [CachedPeerBotInfo], peerStatusSettings: PeerStatusSettings?, pinnedMessageId: MessageId?, stickerPack: StickerPackCollectionInfo?, minAvailableMessageId: MessageId?, migrationReference: ChannelMigrationReference?, linkedDiscussionPeerId: PeerId?, peerGeoLocation: PeerGeoLocation?, slowModeTimeout: Int32?, slowModeValidUntilTimestamp: Int32?, hasScheduledMessages: Bool, statsDatacenterId: Int32, invitedBy: PeerId?) {
|
||||
public init(isNotAccessible: Bool, flags: CachedChannelFlags, about: String?, participantsSummary: CachedChannelParticipantsSummary, exportedInvitation: ExportedInvitation?, botInfos: [CachedPeerBotInfo], peerStatusSettings: PeerStatusSettings?, pinnedMessageId: MessageId?, stickerPack: StickerPackCollectionInfo?, minAvailableMessageId: MessageId?, migrationReference: ChannelMigrationReference?, linkedDiscussionPeerId: PeerId?, peerGeoLocation: PeerGeoLocation?, slowModeTimeout: Int32?, slowModeValidUntilTimestamp: Int32?, hasScheduledMessages: Bool, statsDatacenterId: Int32, invitedBy: PeerId?, photo: TelegramMediaImage?) {
|
||||
self.isNotAccessible = isNotAccessible
|
||||
self.flags = flags
|
||||
self.about = about
|
||||
@ -217,6 +219,7 @@ public final class CachedChannelData: CachedPeerData {
|
||||
self.hasScheduledMessages = hasScheduledMessages
|
||||
self.statsDatacenterId = statsDatacenterId
|
||||
self.invitedBy = invitedBy
|
||||
self.photo = photo
|
||||
|
||||
var peerIds = Set<PeerId>()
|
||||
for botInfo in botInfos {
|
||||
@ -242,75 +245,79 @@ public final class CachedChannelData: CachedPeerData {
|
||||
}
|
||||
|
||||
public func withUpdatedIsNotAccessible(_ isNotAccessible: Bool) -> CachedChannelData {
|
||||
return CachedChannelData(isNotAccessible: isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy)
|
||||
return CachedChannelData(isNotAccessible: isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, photo: self.photo)
|
||||
}
|
||||
|
||||
public func withUpdatedFlags(_ flags: CachedChannelFlags) -> CachedChannelData {
|
||||
return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy)
|
||||
return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, photo: self.photo)
|
||||
}
|
||||
|
||||
public func withUpdatedAbout(_ about: String?) -> CachedChannelData {
|
||||
return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy)
|
||||
return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, photo: self.photo)
|
||||
}
|
||||
|
||||
public func withUpdatedParticipantsSummary(_ participantsSummary: CachedChannelParticipantsSummary) -> CachedChannelData {
|
||||
return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy)
|
||||
return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, photo: self.photo)
|
||||
}
|
||||
|
||||
public func withUpdatedExportedInvitation(_ exportedInvitation: ExportedInvitation?) -> CachedChannelData {
|
||||
return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy)
|
||||
return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, photo: self.photo)
|
||||
}
|
||||
|
||||
public func withUpdatedBotInfos(_ botInfos: [CachedPeerBotInfo]) -> CachedChannelData {
|
||||
return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy)
|
||||
return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, photo: self.photo)
|
||||
}
|
||||
|
||||
public func withUpdatedPeerStatusSettings(_ peerStatusSettings: PeerStatusSettings?) -> CachedChannelData {
|
||||
return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy)
|
||||
return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, photo: self.photo)
|
||||
}
|
||||
|
||||
public func withUpdatedPinnedMessageId(_ pinnedMessageId: MessageId?) -> CachedChannelData {
|
||||
return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy)
|
||||
return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, photo: self.photo)
|
||||
}
|
||||
|
||||
public func withUpdatedStickerPack(_ stickerPack: StickerPackCollectionInfo?) -> CachedChannelData {
|
||||
return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy)
|
||||
return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, photo: self.photo)
|
||||
}
|
||||
|
||||
public func withUpdatedMinAvailableMessageId(_ minAvailableMessageId: MessageId?) -> CachedChannelData {
|
||||
return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy)
|
||||
return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, photo: self.photo)
|
||||
}
|
||||
|
||||
public func withUpdatedMigrationReference(_ migrationReference: ChannelMigrationReference?) -> CachedChannelData {
|
||||
return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy)
|
||||
return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, photo: self.photo)
|
||||
}
|
||||
|
||||
public func withUpdatedLinkedDiscussionPeerId(_ linkedDiscussionPeerId: PeerId?) -> CachedChannelData {
|
||||
return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy)
|
||||
return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, photo: self.photo)
|
||||
}
|
||||
|
||||
public func withUpdatedPeerGeoLocation(_ peerGeoLocation: PeerGeoLocation?) -> CachedChannelData {
|
||||
return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy)
|
||||
return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, photo: self.photo)
|
||||
}
|
||||
|
||||
public func withUpdatedSlowModeTimeout(_ slowModeTimeout: Int32?) -> CachedChannelData {
|
||||
return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy)
|
||||
return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, photo: self.photo)
|
||||
}
|
||||
|
||||
public func withUpdatedSlowModeValidUntilTimestamp(_ slowModeValidUntilTimestamp: Int32?) -> CachedChannelData {
|
||||
return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy)
|
||||
return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, photo: self.photo)
|
||||
}
|
||||
|
||||
public func withUpdatedHasScheduledMessages(_ hasScheduledMessages: Bool) -> CachedChannelData {
|
||||
return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy)
|
||||
return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, photo: self.photo)
|
||||
}
|
||||
|
||||
public func withUpdatedStatsDatacenterId(_ statsDatacenterId: Int32) -> CachedChannelData {
|
||||
return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: statsDatacenterId, invitedBy: self.invitedBy)
|
||||
return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: statsDatacenterId, invitedBy: self.invitedBy, photo: self.photo)
|
||||
}
|
||||
|
||||
public func withUpdatedInvitedBy(_ invitedBy: PeerId?) -> CachedChannelData {
|
||||
return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: invitedBy)
|
||||
return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: invitedBy, photo: self.photo)
|
||||
}
|
||||
|
||||
public func withUpdatedPhoto(_ photo: TelegramMediaImage?) -> CachedChannelData {
|
||||
return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, photo: photo)
|
||||
}
|
||||
|
||||
public init(decoder: PostboxDecoder) {
|
||||
@ -372,6 +379,12 @@ public final class CachedChannelData: CachedPeerData {
|
||||
|
||||
self.invitedBy = decoder.decodeOptionalInt64ForKey("invBy").flatMap(PeerId.init)
|
||||
|
||||
if let photo = decoder.decodeObjectForKey("ph", decoder: { TelegramMediaImage(decoder: $0) }) as? TelegramMediaImage {
|
||||
self.photo = photo
|
||||
} else {
|
||||
self.photo = nil
|
||||
}
|
||||
|
||||
if let linkedDiscussionPeerId = self.linkedDiscussionPeerId {
|
||||
peerIds.insert(linkedDiscussionPeerId)
|
||||
}
|
||||
@ -462,6 +475,12 @@ public final class CachedChannelData: CachedPeerData {
|
||||
} else {
|
||||
encoder.encodeNil(forKey: "invBy")
|
||||
}
|
||||
|
||||
if let photo = self.photo {
|
||||
encoder.encodeObject(photo, forKey: "ph")
|
||||
} else {
|
||||
encoder.encodeNil(forKey: "ph")
|
||||
}
|
||||
}
|
||||
|
||||
public func isEqual(to: CachedPeerData) -> Bool {
|
||||
@ -541,6 +560,10 @@ public final class CachedChannelData: CachedPeerData {
|
||||
return false
|
||||
}
|
||||
|
||||
if other.photo != self.photo {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
@ -36,7 +36,7 @@ public enum AdminLogEventAction {
|
||||
case changeTitle(prev: String, new: String)
|
||||
case changeAbout(prev: String, new: String)
|
||||
case changeUsername(prev: String, new: String)
|
||||
case changePhoto(prev: [TelegramMediaImageRepresentation], new: [TelegramMediaImageRepresentation])
|
||||
case changePhoto(prev: ([TelegramMediaImageRepresentation], [TelegramMediaImage.VideoRepresentation]), new: ([TelegramMediaImageRepresentation], [TelegramMediaImage.VideoRepresentation]))
|
||||
case toggleInvites(Bool)
|
||||
case toggleSignatures(Bool)
|
||||
case updatePinned(Message?)
|
||||
@ -149,7 +149,9 @@ public func channelAdminLogEvents(postbox: Postbox, network: Network, peerId: Pe
|
||||
case let .channelAdminLogEventActionChangeUsername(prev, new):
|
||||
action = .changeUsername(prev: prev, new: new)
|
||||
case let .channelAdminLogEventActionChangePhoto(prev, new):
|
||||
action = .changePhoto(prev: telegramMediaImageFromApiPhoto(prev)?.representations ?? [], new: telegramMediaImageFromApiPhoto(new)?.representations ?? [])
|
||||
let previousImage = telegramMediaImageFromApiPhoto(prev)
|
||||
let newImage = telegramMediaImageFromApiPhoto(new)
|
||||
action = .changePhoto(prev: (previousImage?.representations ?? [], previousImage?.videoRepresentations ?? []) , new: (newImage?.representations ?? [], newImage?.videoRepresentations ?? []))
|
||||
case let .channelAdminLogEventActionToggleInvites(new):
|
||||
action = .toggleInvites(boolFromApiValue(new))
|
||||
case let .channelAdminLogEventActionToggleSignatures(new):
|
||||
|
@ -337,7 +337,7 @@ func fetchAndUpdateCachedPeerData(accountPeerId: PeerId, peerId rawPeerId: PeerI
|
||||
}
|
||||
|
||||
switch fullChat {
|
||||
case let .channelFull(flags, _, about, participantsCount, adminsCount, kickedCount, bannedCount, _, _, _, _, _, _, apiExportedInvite, apiBotInfos, migratedFromChatId, migratedFromMaxId, pinnedMsgId, stickerSet, minAvailableMsgId, folderId, linkedChatId, location, slowmodeSeconds, slowmodeNextSendDate, statsDc, pts):
|
||||
case let .channelFull(flags, _, about, participantsCount, adminsCount, kickedCount, bannedCount, _, _, _, _, chatPhoto, _, apiExportedInvite, apiBotInfos, migratedFromChatId, migratedFromMaxId, pinnedMsgId, stickerSet, minAvailableMsgId, folderId, linkedChatId, location, slowmodeSeconds, slowmodeNextSendDate, statsDc, pts):
|
||||
var channelFlags = CachedChannelFlags()
|
||||
if (flags & (1 << 3)) != 0 {
|
||||
channelFlags.insert(.canDisplayParticipants)
|
||||
@ -467,6 +467,8 @@ func fetchAndUpdateCachedPeerData(accountPeerId: PeerId, peerId rawPeerId: PeerI
|
||||
}
|
||||
}
|
||||
|
||||
let photo = telegramMediaImageFromApiPhoto(chatPhoto)
|
||||
|
||||
var minAvailableMessageIdUpdated = false
|
||||
transaction.updatePeerCachedData(peerIds: [peerId], update: { _, current in
|
||||
var previous: CachedChannelData
|
||||
@ -496,6 +498,7 @@ func fetchAndUpdateCachedPeerData(accountPeerId: PeerId, peerId rawPeerId: PeerI
|
||||
.withUpdatedHasScheduledMessages(hasScheduledMessages)
|
||||
.withUpdatedStatsDatacenterId(statsDc ?? 0)
|
||||
.withUpdatedInvitedBy(invitedBy)
|
||||
.withUpdatedPhoto(photo)
|
||||
})
|
||||
|
||||
if let minAvailableMessageId = minAvailableMessageId, minAvailableMessageIdUpdated {
|
||||
|
@ -65,9 +65,28 @@ class ChatMessageActionBubbleContentNode: ChatMessageBubbleContentNode {
|
||||
|
||||
override func transitionNode(messageId: MessageId, media: Media) -> (ASDisplayNode, CGRect, () -> (UIView?, UIView?))? {
|
||||
if let imageNode = self.imageNode, self.item?.message.id == messageId {
|
||||
return (imageNode, imageNode.bounds, { [weak imageNode] in
|
||||
let snapshot = imageNode?.view.snapshotContentTree(unhide: true)
|
||||
return (snapshot, nil)
|
||||
return (imageNode, imageNode.bounds, { [weak self] in
|
||||
guard let strongSelf = self, let imageNode = strongSelf.imageNode else {
|
||||
return (nil, nil)
|
||||
}
|
||||
|
||||
let resultView = imageNode.view.snapshotContentTree(unhide: true)
|
||||
if let resultView = resultView, strongSelf.mediaBackgroundNode.supernode != nil, let backgroundView = strongSelf.mediaBackgroundNode.view.snapshotContentTree(unhide: true) {
|
||||
let backgroundContainer = UIView()
|
||||
|
||||
backgroundContainer.addSubview(backgroundView)
|
||||
let backgroundFrame = strongSelf.mediaBackgroundNode.layer.convert(strongSelf.mediaBackgroundNode.bounds, to: resultView.layer)
|
||||
backgroundContainer.frame = CGRect(origin: CGPoint(x: -2.0, y: -2.0), size: CGSize(width: resultView.frame.width + 4.0, height: resultView.frame.height + 4.0))
|
||||
backgroundView.frame = backgroundContainer.bounds
|
||||
let viewWithBackground = UIView()
|
||||
viewWithBackground.addSubview(backgroundContainer)
|
||||
viewWithBackground.frame = CGRect(origin: CGPoint(x: 0.0, y: 0.0), size: resultView.frame.size)
|
||||
resultView.frame = CGRect(origin: CGPoint(x: 0.0, y: 0.0), size: resultView.frame.size)
|
||||
viewWithBackground.addSubview(resultView)
|
||||
return (viewWithBackground, backgroundContainer)
|
||||
}
|
||||
|
||||
return (resultView, nil)
|
||||
})
|
||||
} else {
|
||||
return nil
|
||||
@ -100,6 +119,7 @@ class ChatMessageActionBubbleContentNode: ChatMessageBubbleContentNode {
|
||||
}
|
||||
|
||||
self.imageNode?.isHidden = mediaHidden
|
||||
self.mediaBackgroundNode.isHidden = mediaHidden
|
||||
return mediaHidden
|
||||
}
|
||||
|
||||
|
@ -44,6 +44,7 @@ final class ChatRecentActionsControllerNode: ViewControllerTracingNode {
|
||||
private var controllerInteraction: ChatControllerInteraction!
|
||||
|
||||
private let galleryHiddenMesageAndMediaDisposable = MetaDisposable()
|
||||
private let temporaryHiddenGalleryMediaDisposable = MetaDisposable()
|
||||
|
||||
private var chatPresentationDataPromise: Promise<ChatPresentationData>
|
||||
private var presentationDataDisposable: Disposable?
|
||||
@ -183,7 +184,27 @@ final class ChatRecentActionsControllerNode: ViewControllerTracingNode {
|
||||
}, callPeer: { peerId, isVideo in
|
||||
self?.controllerInteraction?.callPeer(peerId, isVideo)
|
||||
}, enqueueMessage: { _ in
|
||||
}, sendSticker: nil, setupTemporaryHiddenMedia: { _, _, _ in }, chatAvatarHiddenMedia: { _, _ in }))
|
||||
}, sendSticker: nil, setupTemporaryHiddenMedia: { _, _, _ in }, chatAvatarHiddenMedia: { signal, media in
|
||||
if let strongSelf = self {
|
||||
strongSelf.temporaryHiddenGalleryMediaDisposable.set((signal |> deliverOnMainQueue).start(next: { messageId in
|
||||
if let strongSelf = self, let controllerInteraction = strongSelf.controllerInteraction {
|
||||
var messageIdAndMedia: [MessageId: [Media]] = [:]
|
||||
|
||||
if let messageId = messageId {
|
||||
messageIdAndMedia[messageId] = [media]
|
||||
}
|
||||
|
||||
controllerInteraction.hiddenMedia = messageIdAndMedia
|
||||
|
||||
strongSelf.listNode.forEachItemNode { itemNode in
|
||||
if let itemNode = itemNode as? ChatMessageItemView {
|
||||
itemNode.updateHiddenMedia()
|
||||
}
|
||||
}
|
||||
}
|
||||
}))
|
||||
}
|
||||
}))
|
||||
}
|
||||
return false
|
||||
}, openPeer: { [weak self] peerId, _, message in
|
||||
@ -516,6 +537,7 @@ final class ChatRecentActionsControllerNode: ViewControllerTracingNode {
|
||||
self.historyDisposable?.dispose()
|
||||
self.navigationActionDisposable.dispose()
|
||||
self.galleryHiddenMesageAndMediaDisposable.dispose()
|
||||
self.temporaryHiddenGalleryMediaDisposable.dispose()
|
||||
self.resolvePeerByNameDisposable.dispose()
|
||||
self.adminsDisposable?.dispose()
|
||||
self.banDisposables.dispose()
|
||||
|
@ -219,8 +219,9 @@ struct ChatRecentActionsEntry: Comparable, Identifiable {
|
||||
peers[peer.id] = peer
|
||||
|
||||
var photo: TelegramMediaImage?
|
||||
if !new.isEmpty {
|
||||
photo = TelegramMediaImage(imageId: MediaId(namespace: 0, id: 0), representations: new, immediateThumbnailData: nil, reference: nil, partialReference: nil, flags: [])
|
||||
let (newPhoto, newVideo) = new
|
||||
if !newPhoto.isEmpty || !newVideo.isEmpty {
|
||||
photo = TelegramMediaImage(imageId: MediaId(namespace: 0, id: 0), representations: newPhoto, videoRepresentations: newVideo, immediateThumbnailData: nil, reference: nil, partialReference: nil, flags: [])
|
||||
}
|
||||
|
||||
let action = TelegramMediaActionType.photoUpdated(image: photo)
|
||||
|
@ -26,6 +26,7 @@ import PeerInfoUI
|
||||
import MapResourceToAvatarSizes
|
||||
import ItemListAddressItem
|
||||
import ItemListVenueItem
|
||||
import LegacyMediaPickerUI
|
||||
|
||||
private struct CreateGroupArguments {
|
||||
let context: AccountContext
|
||||
@ -383,6 +384,7 @@ public func createGroupControllerImpl(context: AccountContext, peerIds: [PeerId]
|
||||
let currentAvatarMixin = Atomic<TGMediaAvatarMenuMixin?>(value: nil)
|
||||
|
||||
let uploadedAvatar = Promise<UploadedPeerPhotoData>()
|
||||
var uploadedVideoAvatar: Promise<UploadedPeerPhotoData?>? = nil
|
||||
|
||||
let addressPromise = Promise<String?>(nil)
|
||||
let venuesPromise = Promise<[TelegramMediaMap]?>(nil)
|
||||
@ -480,7 +482,7 @@ public func createGroupControllerImpl(context: AccountContext, peerIds: [PeerId]
|
||||
return $0.avatar
|
||||
}
|
||||
if let _ = updatingAvatar {
|
||||
return updatePeerPhoto(postbox: context.account.postbox, network: context.account.network, stateManager: context.account.stateManager, accountPeerId: context.account.peerId, peerId: peerId, photo: uploadedAvatar.get(), mapResourceToAvatarSizes: { resource, representations in
|
||||
return updatePeerPhoto(postbox: context.account.postbox, network: context.account.network, stateManager: context.account.stateManager, accountPeerId: context.account.peerId, peerId: peerId, photo: uploadedAvatar.get(), video: uploadedVideoAvatar?.get(), mapResourceToAvatarSizes: { resource, representations in
|
||||
return mapResourceToAvatarSizes(postbox: context.account.postbox, resource: resource, representations: representations)
|
||||
})
|
||||
|> ignoreValues
|
||||
@ -569,12 +571,13 @@ public func createGroupControllerImpl(context: AccountContext, peerIds: [PeerId]
|
||||
endEditingImpl?()
|
||||
presentControllerImpl?(legacyController, nil)
|
||||
|
||||
let completedImpl: (UIImage) -> Void = { image in
|
||||
let completedGroupPhotoImpl: (UIImage) -> Void = { image in
|
||||
if let data = image.jpegData(compressionQuality: 0.6) {
|
||||
let resource = LocalFileMediaResource(fileId: arc4random64())
|
||||
context.account.postbox.mediaBox.storeResourceData(resource.id, data: data)
|
||||
let representation = TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: 640, height: 640), resource: resource)
|
||||
uploadedAvatar.set(uploadedPeerPhoto(postbox: context.account.postbox, network: context.account.network, resource: resource))
|
||||
uploadedVideoAvatar = nil
|
||||
updateState { current in
|
||||
var current = current
|
||||
current.avatar = .image(representation, false)
|
||||
@ -583,19 +586,99 @@ public func createGroupControllerImpl(context: AccountContext, peerIds: [PeerId]
|
||||
}
|
||||
}
|
||||
|
||||
let completedGroupVideoImpl: (UIImage, URL, TGVideoEditAdjustments?) -> Void = { image, url, adjustments in
|
||||
if let data = image.jpegData(compressionQuality: 0.6) {
|
||||
let photoResource = LocalFileMediaResource(fileId: arc4random64())
|
||||
context.account.postbox.mediaBox.storeResourceData(photoResource.id, data: data)
|
||||
let representation = TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: 640, height: 640), resource: photoResource)
|
||||
updateState { state in
|
||||
var state = state
|
||||
state.avatar = .image(representation, true)
|
||||
return state
|
||||
}
|
||||
|
||||
var videoStartTimestamp: Double? = nil
|
||||
if let adjustments = adjustments, adjustments.videoStartValue > 0.0 {
|
||||
videoStartTimestamp = adjustments.videoStartValue - adjustments.trimStartValue
|
||||
}
|
||||
|
||||
let signal = Signal<TelegramMediaResource, UploadPeerPhotoError> { subscriber in
|
||||
var filteredPath = url.path
|
||||
if filteredPath.hasPrefix("file://") {
|
||||
filteredPath = String(filteredPath[filteredPath.index(filteredPath.startIndex, offsetBy: "file://".count)])
|
||||
}
|
||||
|
||||
let avAsset = AVURLAsset(url: URL(fileURLWithPath: filteredPath))
|
||||
let entityRenderer: LegacyPaintEntityRenderer? = adjustments.flatMap { adjustments in
|
||||
if let paintingData = adjustments.paintingData, paintingData.hasAnimation {
|
||||
return LegacyPaintEntityRenderer(account: context.account, adjustments: adjustments)
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
let uploadInterface = LegacyLiveUploadInterface(account: context.account)
|
||||
let signal = TGMediaVideoConverter.convert(avAsset, adjustments: adjustments, watcher: uploadInterface, entityRenderer: entityRenderer)!
|
||||
|
||||
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) {
|
||||
context.account.postbox.mediaBox.storeResourceData(photoResource.id, data: data)
|
||||
}
|
||||
|
||||
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: arc4random64())
|
||||
}
|
||||
context.account.postbox.mediaBox.storeResourceData(resource.id, data: data, synchronous: true)
|
||||
subscriber.putNext(resource)
|
||||
}
|
||||
}
|
||||
subscriber.putCompletion()
|
||||
}
|
||||
}, error: { _ in
|
||||
}, completed: nil)
|
||||
|
||||
let disposable = ActionDisposable {
|
||||
signalDisposable?.dispose()
|
||||
}
|
||||
|
||||
return ActionDisposable {
|
||||
disposable.dispose()
|
||||
}
|
||||
}
|
||||
|
||||
// let promise = Promise<UploadedPeerPhotoData?>()
|
||||
// promise.set(signal |> mapToSignal { resource in
|
||||
// return uploadedPeerVideo(postbox: context.account.postbox, network: context.account.network, messageMediaPreuploadManager: context.account.messageMediaPreuploadManager, resource: resource) |> map(Optional.init)
|
||||
// |> `catch` { _ -> Signal<UploadedPeerPhotoData?, NoError> in
|
||||
// return .single(nil)
|
||||
// }
|
||||
// })
|
||||
// uploadedVideoAvatar = promise
|
||||
}
|
||||
}
|
||||
|
||||
let mixin = TGMediaAvatarMenuMixin(context: legacyController.context, parentController: emptyController, hasSearchButton: true, hasDeleteButton: stateValue.with({ $0.avatar }) != nil, hasViewButton: false, personalPhoto: false, isVideo: false, saveEditedPhotos: false, saveCapturedMedia: false, signup: false)!
|
||||
let _ = currentAvatarMixin.swap(mixin)
|
||||
mixin.requestSearchController = { assetsController in
|
||||
let controller = WebSearchController(context: context, peer: peer, configuration: searchBotsConfiguration, mode: .avatar(initialQuery: title, completion: { result in
|
||||
assetsController?.dismiss()
|
||||
completedImpl(result)
|
||||
completedGroupPhotoImpl(result)
|
||||
}))
|
||||
presentControllerImpl?(controller, ViewControllerPresentationArguments(presentationAnimation: .modalSheet))
|
||||
}
|
||||
mixin.didFinishWithImage = { image in
|
||||
if let image = image {
|
||||
completedImpl(image)
|
||||
completedGroupPhotoImpl(image)
|
||||
}
|
||||
}
|
||||
mixin.didFinishWithVideo = { _, _, _ in
|
||||
|
||||
}
|
||||
if stateValue.with({ $0.avatar }) != nil {
|
||||
mixin.didFinishWithDelete = {
|
||||
|
@ -318,11 +318,14 @@ private func peerInfoScreenInputData(context: AccountContext, peerId: PeerId, is
|
||||
|
||||
private func peerInfoProfilePhotos(context: AccountContext, peerId: PeerId) -> Signal<Any, NoError> {
|
||||
return context.account.postbox.combinedView(keys: [.basicPeer(peerId)])
|
||||
|> map { view -> AvatarGalleryEntry? in
|
||||
|> mapToSignal { view -> Signal<AvatarGalleryEntry?, NoError> in
|
||||
guard let peer = (view.views[.basicPeer(peerId)] as? BasicPeerView)?.peer else {
|
||||
return nil
|
||||
return .single(nil)
|
||||
}
|
||||
return initialAvatarGalleryEntries(account: context.account, peer: peer)
|
||||
|> map { entries in
|
||||
return entries.first
|
||||
}
|
||||
return initialAvatarGalleryEntries(peer: peer).first
|
||||
}
|
||||
|> distinctUntilChanged
|
||||
|> mapToSignal { firstEntry -> Signal<[AvatarGalleryEntry], NoError> in
|
||||
|
@ -273,7 +273,7 @@ final class PeerInfoAvatarListItemNode: ASDisplayNode {
|
||||
videoNode.isUserInteractionEnabled = false
|
||||
videoNode.isHidden = true
|
||||
|
||||
if let _ = video.startTimestamp {
|
||||
if let startTimestamp = video.startTimestamp {
|
||||
self.playbackStatusDisposable.set((videoNode.status
|
||||
|> map { status -> Bool in
|
||||
if let status = status, case .playing = status.status {
|
||||
@ -288,20 +288,17 @@ final class PeerInfoAvatarListItemNode: ASDisplayNode {
|
||||
|> take(1)
|
||||
|> deliverOnMainQueue).start(completed: { [weak self] in
|
||||
if let strongSelf = self {
|
||||
Queue.mainQueue().after(0.1) {
|
||||
Queue.mainQueue().after(0.15) {
|
||||
strongSelf.videoNode?.isHidden = false
|
||||
}
|
||||
}
|
||||
}))
|
||||
videoNode.seek(startTimestamp)
|
||||
} else {
|
||||
self.playbackStatusDisposable.set(nil)
|
||||
videoNode.isHidden = false
|
||||
}
|
||||
|
||||
if let startTimestamp = video.startTimestamp {
|
||||
videoNode.seek(startTimestamp)
|
||||
}
|
||||
|
||||
|
||||
self.videoContent = videoContent
|
||||
self.videoNode = videoNode
|
||||
self.statusPromise.set(videoNode.status |> map { ($0, video.startTimestamp) })
|
||||
@ -1035,6 +1032,7 @@ final class PeerInfoAvatarTransformContainerNode: ASDisplayNode {
|
||||
var tapped: (() -> Void)?
|
||||
|
||||
private var isFirstAvatarLoading = true
|
||||
var item: PeerInfoAvatarListItem?
|
||||
|
||||
private let playbackStatusDisposable = MetaDisposable()
|
||||
|
||||
@ -1090,11 +1088,22 @@ final class PeerInfoAvatarTransformContainerNode: ASDisplayNode {
|
||||
}
|
||||
}
|
||||
|
||||
var removedPhotoResourceIds = Set<String>()
|
||||
func update(peer: Peer?, item: PeerInfoAvatarListItem?, theme: PresentationTheme, avatarSize: CGFloat, isExpanded: Bool) {
|
||||
if let peer = peer {
|
||||
let previousItem = self.item
|
||||
self.item = item
|
||||
|
||||
var overrideImage: AvatarNodeImageOverride?
|
||||
if peer.isDeleted {
|
||||
overrideImage = .deletedIcon
|
||||
} else if let previousItem = previousItem, item == nil {
|
||||
if case let .image(image) = previousItem, let rep = image.1.last {
|
||||
self.removedPhotoResourceIds.insert(rep.representation.resource.id.uniqueId)
|
||||
}
|
||||
overrideImage = AvatarNodeImageOverride.none
|
||||
} else if let rep = peer.profileImageRepresentations.last, self.removedPhotoResourceIds.contains(rep.resource.id.uniqueId) {
|
||||
overrideImage = AvatarNodeImageOverride.none
|
||||
}
|
||||
self.avatarNode.setPeer(context: self.context, theme: theme, peer: peer, overrideImage: overrideImage, synchronousLoad: self.isFirstAvatarLoading, displayDimensions: CGSize(width: avatarSize, height: avatarSize), storeUnrounded: true)
|
||||
self.isFirstAvatarLoading = false
|
||||
@ -1128,7 +1137,7 @@ final class PeerInfoAvatarTransformContainerNode: ASDisplayNode {
|
||||
|> take(1)
|
||||
|> deliverOnMainQueue).start(completed: { [weak self] in
|
||||
if let strongSelf = self {
|
||||
Queue.mainQueue().after(0.1) {
|
||||
Queue.mainQueue().after(0.15) {
|
||||
strongSelf.videoNode?.isHidden = false
|
||||
}
|
||||
}
|
||||
@ -1213,6 +1222,7 @@ final class PeerInfoEditingAvatarOverlayNode: ASDisplayNode {
|
||||
|
||||
self.iconNode = ASImageNode()
|
||||
self.iconNode.image = generateTintedImage(image: UIImage(bundleImageName: "Avatar/EditAvatarIconLarge"), color: .white)
|
||||
self.iconNode.isHidden = true
|
||||
|
||||
super.init()
|
||||
|
||||
@ -1248,7 +1258,7 @@ final class PeerInfoEditingAvatarOverlayNode: ASDisplayNode {
|
||||
overlayHidden = false
|
||||
iconHidden = true
|
||||
|
||||
self.statusNode.transitionToState(.progress(color: .white, lineWidth: nil, value: uploadProgress ?? 0.0, cancelEnabled: true))
|
||||
self.statusNode.transitionToState(.progress(color: .white, lineWidth: nil, value: max(0.027, uploadProgress ?? 0.0), cancelEnabled: true))
|
||||
|
||||
if case let .image(representation) = updatingAvatar {
|
||||
if representation != self.currentRepresentation {
|
||||
@ -1262,12 +1272,13 @@ final class PeerInfoEditingAvatarOverlayNode: ASDisplayNode {
|
||||
self.updatingAvatarOverlay.isHidden = overlayHidden
|
||||
} else {
|
||||
if isEditing {
|
||||
iconHidden = false
|
||||
iconHidden = peer.profileImageRepresentations.isEmpty
|
||||
overlayHidden = peer.profileImageRepresentations.isEmpty
|
||||
} else {
|
||||
iconHidden = true
|
||||
overlayHidden = true
|
||||
}
|
||||
Queue.mainQueue().after(0.1) { [weak self] in
|
||||
Queue.mainQueue().after(0.15) { [weak self] in
|
||||
self?.statusNode.transitionToState(.none)
|
||||
self?.currentRepresentation = nil
|
||||
self?.imageNode.setSignal(.single(nil))
|
||||
@ -1283,7 +1294,6 @@ final class PeerInfoEditingAvatarOverlayNode: ASDisplayNode {
|
||||
self.iconNode.isHidden = true
|
||||
self.updatingAvatarOverlay.isHidden = true
|
||||
self.currentRepresentation = nil
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1296,7 +1306,7 @@ final class PeerInfoEditingAvatarNode: ASDisplayNode {
|
||||
private var videoStartTimestamp: Double?
|
||||
|
||||
var tapped: ((Bool) -> Void)?
|
||||
|
||||
|
||||
var canAttachVideo: Bool = true
|
||||
|
||||
init(context: AccountContext) {
|
||||
@ -1322,7 +1332,7 @@ final class PeerInfoEditingAvatarNode: ASDisplayNode {
|
||||
guard let peer = peer else {
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
let overrideImage: AvatarNodeImageOverride?
|
||||
if canEditPeerInfo(context: self.context, peer: peer), peer.profileImageRepresentations.isEmpty {
|
||||
overrideImage = .editAvatarIcon
|
||||
@ -1393,6 +1403,8 @@ final class PeerInfoAvatarListNode: ASDisplayNode {
|
||||
var arguments: (Peer?, PresentationTheme, CGFloat, Bool)?
|
||||
var item: PeerInfoAvatarListItem?
|
||||
|
||||
var itemsUpdated: (([PeerInfoAvatarListItem]) -> Void)?
|
||||
|
||||
init(context: AccountContext, readyWhenGalleryLoads: Bool) {
|
||||
self.avatarContainerNode = PeerInfoAvatarTransformContainerNode(context: context)
|
||||
self.listContainerTransformNode = ASDisplayNode()
|
||||
@ -1440,6 +1452,7 @@ final class PeerInfoAvatarListNode: ASDisplayNode {
|
||||
self.listContainerNode.itemsUpdated = { [weak self] items in
|
||||
if let strongSelf = self {
|
||||
strongSelf.item = items.first
|
||||
strongSelf.itemsUpdated?(items)
|
||||
if let (peer, theme, avatarSize, isExpanded) = strongSelf.arguments {
|
||||
strongSelf.avatarContainerNode.update(peer: peer, item: strongSelf.item, theme: theme, avatarSize: avatarSize, isExpanded: isExpanded)
|
||||
}
|
||||
@ -2190,6 +2203,9 @@ private let TitleNodeStateExpanded = 1
|
||||
final class PeerInfoHeaderNode: ASDisplayNode {
|
||||
private var context: AccountContext
|
||||
private var presentationData: PresentationData?
|
||||
private var state: PeerInfoState?
|
||||
private var peer: Peer?
|
||||
private var avatarSize: CGFloat?
|
||||
|
||||
private let isOpenedFromChat: Bool
|
||||
private let isSettings: Bool
|
||||
@ -2218,6 +2234,10 @@ final class PeerInfoHeaderNode: ASDisplayNode {
|
||||
private let backgroundNode: ASDisplayNode
|
||||
private let expandedBackgroundNode: ASDisplayNode
|
||||
let separatorNode: ASDisplayNode
|
||||
let navigationBackgroundNode: ASDisplayNode
|
||||
var navigationTitle: String?
|
||||
let navigationTitleNode: ImmediateTextNode
|
||||
let navigationSeparatorNode: ASDisplayNode
|
||||
let navigationButtonContainer: PeerInfoHeaderNavigationButtonContainerNode
|
||||
|
||||
var performButtonAction: ((PeerInfoHeaderButtonKey) -> Void)?
|
||||
@ -2272,6 +2292,13 @@ final class PeerInfoHeaderNode: ASDisplayNode {
|
||||
|
||||
self.avatarOverlayNode = PeerInfoEditingAvatarOverlayNode(context: context)
|
||||
|
||||
self.navigationBackgroundNode = ASDisplayNode()
|
||||
self.navigationBackgroundNode.isUserInteractionEnabled = false
|
||||
|
||||
self.navigationTitleNode = ImmediateTextNode()
|
||||
|
||||
self.navigationSeparatorNode = ASDisplayNode()
|
||||
|
||||
self.navigationButtonContainer = PeerInfoHeaderNavigationButtonContainerNode()
|
||||
|
||||
self.backgroundNode = ASDisplayNode()
|
||||
@ -2303,6 +2330,9 @@ final class PeerInfoHeaderNode: ASDisplayNode {
|
||||
self.addSubnode(self.regularContentNode)
|
||||
self.addSubnode(self.editingContentNode)
|
||||
self.addSubnode(self.avatarOverlayNode)
|
||||
self.addSubnode(self.navigationBackgroundNode)
|
||||
self.navigationBackgroundNode.addSubnode(self.navigationTitleNode)
|
||||
self.navigationBackgroundNode.addSubnode(self.navigationSeparatorNode)
|
||||
self.addSubnode(self.navigationButtonContainer)
|
||||
self.addSubnode(self.separatorNode)
|
||||
|
||||
@ -2310,10 +2340,14 @@ final class PeerInfoHeaderNode: ASDisplayNode {
|
||||
self?.initiateAvatarExpansion()
|
||||
}
|
||||
self.editingContentNode.avatarNode.tapped = { [weak self] confirm in
|
||||
guard let strongSelf = self else {
|
||||
self?.requestOpenAvatarForEditing?(confirm)
|
||||
}
|
||||
|
||||
self.avatarListNode.itemsUpdated = { [weak self] items in
|
||||
guard let strongSelf = self, let state = strongSelf.state, let peer = strongSelf.peer, let presentationData = strongSelf.presentationData, let avatarSize = strongSelf.avatarSize else {
|
||||
return
|
||||
}
|
||||
strongSelf.requestOpenAvatarForEditing?(confirm)
|
||||
strongSelf.editingContentNode.avatarNode.update(peer: peer, item: strongSelf.avatarListNode.item, updatingAvatar: state.updatingAvatar, uploadProgress: state.avatarUploadProgress, theme: presentationData.theme, avatarSize: avatarSize, isEditing: state.isEditing)
|
||||
}
|
||||
}
|
||||
|
||||
@ -2387,6 +2421,12 @@ final class PeerInfoHeaderNode: ASDisplayNode {
|
||||
}
|
||||
|
||||
func update(width: CGFloat, containerHeight: CGFloat, containerInset: CGFloat, statusBarHeight: CGFloat, navigationHeight: CGFloat, isModalOverlay: Bool, isMediaOnly: Bool, contentOffset: CGFloat, presentationData: PresentationData, peer: Peer?, cachedData: CachedPeerData?, notificationSettings: TelegramPeerNotificationSettings?, statusData: PeerInfoStatusData?, isContact: Bool, isSettings: Bool, state: PeerInfoState, transition: ContainedViewLayoutTransition, additive: Bool) -> CGFloat {
|
||||
self.state = state
|
||||
self.peer = peer
|
||||
|
||||
let avatarSize: CGFloat = isModalOverlay ? 200.0 : 100.0
|
||||
self.avatarSize = avatarSize
|
||||
|
||||
var contentOffset = contentOffset
|
||||
|
||||
if isMediaOnly {
|
||||
@ -2446,7 +2486,6 @@ final class PeerInfoHeaderNode: ASDisplayNode {
|
||||
self.avatarListNode.animateAvatarCollapse(transition: transition)
|
||||
}
|
||||
} else {
|
||||
let avatarSize: CGFloat = isModalOverlay ? 200.0 : 100.0
|
||||
let backgroundTransitionFraction: CGFloat = max(0.0, min(1.0, contentOffset / (112.0 + avatarSize)))
|
||||
transition.updateAlpha(node: self.expandedBackgroundNode, alpha: backgroundTransitionFraction)
|
||||
}
|
||||
@ -2454,6 +2493,18 @@ final class PeerInfoHeaderNode: ASDisplayNode {
|
||||
self.avatarListNode.avatarContainerNode.updateTransitionFraction(transitionFraction, transition: transition)
|
||||
self.avatarListNode.listContainerNode.currentItemNode?.updateTransitionFraction(transitionFraction, transition: transition)
|
||||
|
||||
if self.navigationTitle != presentationData.strings.EditProfile_Title || themeUpdated {
|
||||
self.navigationTitleNode.attributedText = NSAttributedString(string: presentationData.strings.EditProfile_Title, font: Font.bold(17.0), textColor: presentationData.theme.rootController.navigationBar.primaryTextColor)
|
||||
}
|
||||
|
||||
let navigationTitleSize = self.navigationTitleNode.updateLayout(CGSize(width: width, height: navigationHeight))
|
||||
self.navigationTitleNode.frame = CGRect(origin: CGPoint(x: floorToScreenPixels((width - navigationTitleSize.width) / 2.0), y: navigationHeight - 44.0 + floorToScreenPixels((44.0 - navigationTitleSize.height) / 2.0)), size: navigationTitleSize)
|
||||
|
||||
self.navigationBackgroundNode.frame = CGRect(origin: CGPoint(), size: CGSize(width: width, height: navigationHeight))
|
||||
self.navigationSeparatorNode.frame = CGRect(origin: CGPoint(x: 0.0, y: navigationHeight), size: CGSize(width: width, height: UIScreenPixel))
|
||||
self.navigationBackgroundNode.backgroundColor = presentationData.theme.rootController.navigationBar.backgroundColor
|
||||
self.navigationSeparatorNode.backgroundColor = presentationData.theme.rootController.navigationBar.separatorColor
|
||||
transition.updateAlpha(node: self.navigationBackgroundNode, alpha: state.isEditing && self.isSettings ? min(1.0, contentOffset / (navigationHeight * 0.5)) : 0.0)
|
||||
self.separatorNode.backgroundColor = presentationData.theme.list.itemBlocksSeparatorColor
|
||||
|
||||
let defaultButtonSize: CGFloat = 40.0
|
||||
@ -2521,7 +2572,6 @@ final class PeerInfoHeaderNode: ASDisplayNode {
|
||||
TitleNodeStateExpanded: MultiScaleTextState(attributedText: usernameString, constrainedSize: CGSize(width: width - titleNodeLayout[TitleNodeStateExpanded]!.size.width - 8.0, height: titleConstrainedSize.height))
|
||||
], mainState: TitleNodeStateRegular)
|
||||
|
||||
let avatarSize: CGFloat = isModalOverlay ? 200.0 : 100.0
|
||||
let avatarFrame = CGRect(origin: CGPoint(x: floor((width - avatarSize) / 2.0), y: statusBarHeight + 10.0), size: CGSize(width: avatarSize, height: avatarSize))
|
||||
let avatarCenter = CGPoint(x: (1.0 - transitionFraction) * avatarFrame.midX + transitionFraction * transitionSourceAvatarFrame.midX, y: (1.0 - transitionFraction) * avatarFrame.midY + transitionFraction * transitionSourceAvatarFrame.midY)
|
||||
|
||||
|
@ -5415,11 +5415,19 @@ private final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewD
|
||||
guard let (_, navigationHeight) = self.validLayout else {
|
||||
return
|
||||
}
|
||||
var height: CGFloat = self.isSettings ? 140.0 : 212.0
|
||||
if self.headerNode.twoLineInfo {
|
||||
height += 17.0
|
||||
}
|
||||
if !self.state.isEditing {
|
||||
if self.state.isEditing && self.isSettings {
|
||||
if targetContentOffset.pointee.y < navigationHeight {
|
||||
if targetContentOffset.pointee.y < navigationHeight / 2.0 {
|
||||
targetContentOffset.pointee.y = 0.0
|
||||
} else {
|
||||
targetContentOffset.pointee.y = navigationHeight
|
||||
}
|
||||
}
|
||||
} else {
|
||||
var height: CGFloat = self.isSettings ? 140.0 : 212.0
|
||||
if self.headerNode.twoLineInfo {
|
||||
height += 17.0
|
||||
}
|
||||
if targetContentOffset.pointee.y < height {
|
||||
if targetContentOffset.pointee.y < height / 2.0 {
|
||||
targetContentOffset.pointee.y = 0.0
|
||||
|
Loading…
x
Reference in New Issue
Block a user