mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-15 21:45:19 +00:00
Merge branch 'master' into beta
This commit is contained in:
commit
2bf65535f0
@ -5,7 +5,7 @@ set -e
|
||||
BUILD_TELEGRAM_VERSION="1"
|
||||
|
||||
MACOS_VERSION="10.15"
|
||||
XCODE_VERSION="12.1"
|
||||
XCODE_VERSION="12.2"
|
||||
GUEST_SHELL="bash"
|
||||
|
||||
VM_BASE_NAME="macos$(echo $MACOS_VERSION | sed -e 's/\.'/_/g)_Xcode$(echo $XCODE_VERSION | sed -e 's/\.'/_/g)"
|
||||
|
@ -1319,7 +1319,7 @@ class ChatListItemNode: ItemListRevealOptionsItemNode {
|
||||
}
|
||||
badgeSize = max(badgeSize, reorderInset)
|
||||
|
||||
let (authorLayout, authorApply) = authorLayout(TextNodeLayoutArguments(attributedString: hideAuthor ? nil : authorAttributedString, backgroundColor: nil, maximumNumberOfLines: 1, truncationType: .end, constrainedSize: CGSize(width: rawContentWidth - badgeSize, height: CGFloat.greatestFiniteMagnitude), alignment: .natural, cutout: nil, insets: UIEdgeInsets(top: 2.0, left: 1.0, bottom: 2.0, right: 1.0)))
|
||||
let (authorLayout, authorApply) = authorLayout(TextNodeLayoutArguments(attributedString: (hideAuthor && !hasDraft) ? nil : authorAttributedString, backgroundColor: nil, maximumNumberOfLines: 1, truncationType: .end, constrainedSize: CGSize(width: rawContentWidth - badgeSize, height: CGFloat.greatestFiniteMagnitude), alignment: .natural, cutout: nil, insets: UIEdgeInsets(top: 2.0, left: 1.0, bottom: 2.0, right: 1.0)))
|
||||
|
||||
var textCutout: TextNodeCutout?
|
||||
if !textLeftCutout.isZero {
|
||||
|
@ -19,6 +19,7 @@ swift_library(
|
||||
"//submodules/AnimatedStickerNode:AnimatedStickerNode",
|
||||
"//submodules/TelegramAnimatedStickerNode:TelegramAnimatedStickerNode",
|
||||
"//submodules/PresentationDataUtils:PresentationDataUtils",
|
||||
"//submodules/ShimmerEffect:ShimmerEffect",
|
||||
],
|
||||
visibility = [
|
||||
"//visibility:public",
|
||||
|
@ -12,6 +12,7 @@ import PresentationDataUtils
|
||||
import StickerResources
|
||||
import AnimatedStickerNode
|
||||
import TelegramAnimatedStickerNode
|
||||
import ShimmerEffect
|
||||
|
||||
public struct ItemListStickerPackItemEditing: Equatable {
|
||||
public var editable: Bool
|
||||
@ -149,6 +150,7 @@ class ItemListStickerPackItemNode: ItemListRevealOptionsItemNode {
|
||||
|
||||
fileprivate let imageNode: TransformImageNode
|
||||
private var animationNode: AnimatedStickerNode?
|
||||
private var placeholderNode: StickerShimmerEffectNode?
|
||||
private let unreadNode: ASImageNode
|
||||
private let titleNode: TextNode
|
||||
private let statusNode: TextNode
|
||||
@ -200,6 +202,9 @@ class ItemListStickerPackItemNode: ItemListRevealOptionsItemNode {
|
||||
self.imageNode = TransformImageNode()
|
||||
self.imageNode.isLayerBacked = !smartInvertColorsEnabled()
|
||||
|
||||
self.placeholderNode = StickerShimmerEffectNode()
|
||||
self.placeholderNode?.isUserInteractionEnabled = false
|
||||
|
||||
self.titleNode = TextNode()
|
||||
self.titleNode.isUserInteractionEnabled = false
|
||||
self.titleNode.contentMode = .left
|
||||
@ -231,7 +236,11 @@ class ItemListStickerPackItemNode: ItemListRevealOptionsItemNode {
|
||||
|
||||
super.init(layerBacked: false, dynamicBounce: false, rotated: false, seeThrough: false)
|
||||
|
||||
if let placeholderNode = self.placeholderNode {
|
||||
self.addSubnode(placeholderNode)
|
||||
}
|
||||
self.addSubnode(self.imageNode)
|
||||
|
||||
self.addSubnode(self.titleNode)
|
||||
self.addSubnode(self.statusNode)
|
||||
self.addSubnode(self.unreadNode)
|
||||
@ -251,12 +260,50 @@ class ItemListStickerPackItemNode: ItemListRevealOptionsItemNode {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var firstTime = true
|
||||
self.imageNode.imageUpdated = { [weak self] image in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
if image != nil {
|
||||
strongSelf.removePlaceholder(animated: !firstTime)
|
||||
if firstTime {
|
||||
strongSelf.imageNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2)
|
||||
}
|
||||
}
|
||||
firstTime = false
|
||||
}
|
||||
}
|
||||
|
||||
deinit {
|
||||
self.fetchDisposable.dispose()
|
||||
}
|
||||
|
||||
private func removePlaceholder(animated: Bool) {
|
||||
if let placeholderNode = self.placeholderNode {
|
||||
self.placeholderNode = nil
|
||||
if !animated {
|
||||
placeholderNode.removeFromSupernode()
|
||||
} else {
|
||||
placeholderNode.allowsGroupOpacity = true
|
||||
placeholderNode.alpha = 0.0
|
||||
placeholderNode.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.2, completion: { [weak placeholderNode] _ in
|
||||
placeholderNode?.removeFromSupernode()
|
||||
placeholderNode?.allowsGroupOpacity = false
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private var absoluteLocation: (CGRect, CGSize)?
|
||||
override func updateAbsoluteRect(_ rect: CGRect, within containerSize: CGSize) {
|
||||
self.absoluteLocation = (rect, containerSize)
|
||||
if let placeholderNode = placeholderNode {
|
||||
placeholderNode.updateAbsoluteRect(CGRect(origin: CGPoint(x: rect.minX + placeholderNode.frame.minX, y: rect.minY + placeholderNode.frame.minY), size: placeholderNode.frame.size), within: containerSize)
|
||||
}
|
||||
}
|
||||
|
||||
func asyncLayout() -> (_ item: ItemListStickerPackItem, _ params: ListViewItemLayoutParams, _ neighbors: ItemListNeighbors) -> (ListViewItemNodeLayout, (Bool) -> Void) {
|
||||
let makeImageLayout = self.imageNode.asyncLayout()
|
||||
let makeTitleLayout = TextNode.asyncLayout(self.titleNode)
|
||||
@ -397,14 +444,14 @@ class ItemListStickerPackItemNode: ItemListRevealOptionsItemNode {
|
||||
|
||||
if fileUpdated {
|
||||
imageApply = makeImageLayout(TransformImageArguments(corners: ImageCorners(), imageSize: stillImageSize, boundingSize: stillImageSize, intrinsicInsets: UIEdgeInsets()))
|
||||
updatedImageSignal = chatMessageStickerPackThumbnail(postbox: item.account.postbox, resource: representation.resource)
|
||||
updatedImageSignal = chatMessageStickerPackThumbnail(postbox: item.account.postbox, resource: representation.resource, nilIfEmpty: true)
|
||||
}
|
||||
case let .animated(resource):
|
||||
imageSize = imageBoundingSize
|
||||
|
||||
if fileUpdated {
|
||||
imageApply = makeImageLayout(TransformImageArguments(corners: ImageCorners(), imageSize: imageBoundingSize, boundingSize: imageBoundingSize, intrinsicInsets: UIEdgeInsets()))
|
||||
updatedImageSignal = chatMessageStickerPackThumbnail(postbox: item.account.postbox, resource: resource, animated: true)
|
||||
updatedImageSignal = chatMessageStickerPackThumbnail(postbox: item.account.postbox, resource: resource, animated: true, nilIfEmpty: true)
|
||||
}
|
||||
}
|
||||
if fileUpdated, let resourceReference = resourceReference {
|
||||
@ -610,6 +657,7 @@ class ItemListStickerPackItemNode: ItemListRevealOptionsItemNode {
|
||||
animationNode = AnimatedStickerNode()
|
||||
strongSelf.animationNode = animationNode
|
||||
strongSelf.addSubnode(animationNode)
|
||||
|
||||
animationNode.setup(source: AnimatedStickerResourceSource(account: item.account, resource: resource), width: 80, height: 80, mode: .cached)
|
||||
}
|
||||
animationNode.visibility = strongSelf.visibility != .none && item.playAnimatedStickers
|
||||
@ -619,6 +667,12 @@ class ItemListStickerPackItemNode: ItemListRevealOptionsItemNode {
|
||||
transition.updateFrame(node: animationNode, frame: imageFrame)
|
||||
}
|
||||
}
|
||||
|
||||
if let placeholderNode = strongSelf.placeholderNode {
|
||||
placeholderNode.frame = imageFrame
|
||||
|
||||
placeholderNode.update(backgroundColor: nil, foregroundColor: item.presentationData.theme.list.disclosureArrowColor.blitOver(item.presentationData.theme.list.itemBlocksBackgroundColor, alpha: 0.55), shimmeringColor: item.presentationData.theme.list.itemBlocksBackgroundColor.withAlphaComponent(0.4), data: item.packInfo.immediateThumbnailData, size: imageFrame.size, small: true)
|
||||
}
|
||||
}
|
||||
|
||||
if let updatedImageSignal = updatedImageSignal {
|
||||
|
@ -263,6 +263,16 @@ class ChannelMembersSearchControllerNode: ASDisplayNode {
|
||||
}
|
||||
var entries: [ChannelMembersSearchEntry] = []
|
||||
|
||||
if case .inviteToCall = mode, !filters.contains(where: { filter in
|
||||
if case .excludeNonMembers = filter {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}) {
|
||||
entries.append(.copyInviteLink)
|
||||
}
|
||||
|
||||
var index = 0
|
||||
for participant in participants.participants {
|
||||
guard let peer = peerView.peers[participant.peerId] else {
|
||||
|
@ -168,7 +168,7 @@ public class StickerShimmerEffectNode: ASDisplayNode {
|
||||
self.effectNode.updateAbsoluteRect(rect, within: containerSize)
|
||||
}
|
||||
|
||||
public func update(backgroundColor: UIColor?, foregroundColor: UIColor, shimmeringColor: UIColor, data: Data?, size: CGSize) {
|
||||
public func update(backgroundColor: UIColor?, foregroundColor: UIColor, shimmeringColor: UIColor, data: Data?, size: CGSize, small: Bool = false) {
|
||||
if data == nil {
|
||||
return
|
||||
}
|
||||
@ -205,7 +205,7 @@ public class StickerShimmerEffectNode: ASDisplayNode {
|
||||
let reader = PathDataReader(input: path)
|
||||
let segments = reader.read()
|
||||
|
||||
let scale = size.width / 512.0
|
||||
let scale = size.width / (small ? 100.0 : 512.0)
|
||||
context.scaleBy(x: scale, y: scale)
|
||||
renderPath(segments, context: context)
|
||||
} else {
|
||||
|
@ -1,3 +1,4 @@
|
||||
import Foundation
|
||||
import Postbox
|
||||
|
||||
public struct StickerPackCollectionInfoFlags: OptionSet {
|
||||
@ -40,16 +41,18 @@ public final class StickerPackCollectionInfo: ItemCollectionInfo, Equatable {
|
||||
public let title: String
|
||||
public let shortName: String
|
||||
public let thumbnail: TelegramMediaImageRepresentation?
|
||||
public let immediateThumbnailData: Data?
|
||||
public let hash: Int32
|
||||
public let count: Int32
|
||||
|
||||
public init(id: ItemCollectionId, flags: StickerPackCollectionInfoFlags, accessHash: Int64, title: String, shortName: String, thumbnail: TelegramMediaImageRepresentation?, hash: Int32, count: Int32) {
|
||||
public init(id: ItemCollectionId, flags: StickerPackCollectionInfoFlags, accessHash: Int64, title: String, shortName: String, thumbnail: TelegramMediaImageRepresentation?, immediateThumbnailData: Data?, hash: Int32, count: Int32) {
|
||||
self.id = id
|
||||
self.flags = flags
|
||||
self.accessHash = accessHash
|
||||
self.title = title
|
||||
self.shortName = shortName
|
||||
self.thumbnail = thumbnail
|
||||
self.immediateThumbnailData = immediateThumbnailData
|
||||
self.hash = hash
|
||||
self.count = count
|
||||
}
|
||||
@ -60,6 +63,7 @@ public final class StickerPackCollectionInfo: ItemCollectionInfo, Equatable {
|
||||
self.title = decoder.decodeStringForKey("t", orElse: "")
|
||||
self.shortName = decoder.decodeStringForKey("s", orElse: "")
|
||||
self.thumbnail = decoder.decodeObjectForKey("th", decoder: { TelegramMediaImageRepresentation(decoder: $0) }) as? TelegramMediaImageRepresentation
|
||||
self.immediateThumbnailData = decoder.decodeDataForKey("itd")
|
||||
self.hash = decoder.decodeInt32ForKey("h", orElse: 0)
|
||||
self.flags = StickerPackCollectionInfoFlags(rawValue: decoder.decodeInt32ForKey("f", orElse: 0))
|
||||
self.count = decoder.decodeInt32ForKey("n", orElse: 0)
|
||||
@ -76,6 +80,11 @@ public final class StickerPackCollectionInfo: ItemCollectionInfo, Equatable {
|
||||
} else {
|
||||
encoder.encodeNil(forKey: "th")
|
||||
}
|
||||
if let immediateThumbnailData = self.immediateThumbnailData {
|
||||
encoder.encodeData(immediateThumbnailData, forKey: "itd")
|
||||
} else {
|
||||
encoder.encodeNil(forKey: "itd")
|
||||
}
|
||||
encoder.encodeInt32(self.hash, forKey: "h")
|
||||
encoder.encodeInt32(self.flags.rawValue, forKey: "f")
|
||||
encoder.encodeInt32(self.count, forKey: "n")
|
||||
@ -98,6 +107,10 @@ public final class StickerPackCollectionInfo: ItemCollectionInfo, Equatable {
|
||||
return false
|
||||
}
|
||||
|
||||
if lhs.immediateThumbnailData != rhs.immediateThumbnailData {
|
||||
return false
|
||||
}
|
||||
|
||||
if lhs.flags != rhs.flags {
|
||||
return false
|
||||
}
|
||||
|
@ -1114,13 +1114,27 @@ public final class PresentationGroupCallImpl: PresentationGroupCall {
|
||||
self._canBeRemoved.set(.single(true))
|
||||
|
||||
if self.didConnectOnce {
|
||||
let toneRenderer = PresentationCallToneRenderer(tone: .groupLeft)
|
||||
self.toneRenderer = toneRenderer
|
||||
toneRenderer.setAudioSessionActive(self.isAudioSessionActive)
|
||||
|
||||
Queue.mainQueue().after(1.0, {
|
||||
self.wasRemoved.set(.single(true))
|
||||
})
|
||||
if let callManager = self.accountContext.sharedContext.callManager {
|
||||
let _ = (callManager.currentGroupCallSignal
|
||||
|> take(1)
|
||||
|> deliverOnMainQueue).start(next: { [weak self] call in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
if let call = call, call !== strongSelf {
|
||||
strongSelf.wasRemoved.set(.single(true))
|
||||
return
|
||||
}
|
||||
|
||||
let toneRenderer = PresentationCallToneRenderer(tone: .groupLeft)
|
||||
strongSelf.toneRenderer = toneRenderer
|
||||
toneRenderer.setAudioSessionActive(strongSelf.isAudioSessionActive)
|
||||
|
||||
Queue.mainQueue().after(1.0, {
|
||||
strongSelf.wasRemoved.set(.single(true))
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -575,7 +575,7 @@ public final class VoiceChatController: ViewController {
|
||||
filters.append(.excludeNonMembers)
|
||||
}
|
||||
} else if let groupPeer = groupPeer as? TelegramGroup {
|
||||
if !groupPeer.hasBannedPermission(.banAddMembers) {
|
||||
if groupPeer.hasBannedPermission(.banAddMembers) {
|
||||
filters.append(.excludeNonMembers)
|
||||
}
|
||||
}
|
||||
@ -984,11 +984,20 @@ public final class VoiceChatController: ViewController {
|
||||
strongSelf.accountPeer = accountPeer
|
||||
strongSelf.updateMembers(muteState: strongSelf.effectiveMuteState, callMembers: strongSelf.currentCallMembers ?? [], invitedPeers: strongSelf.currentInvitedPeers ?? [], speakingPeers: strongSelf.currentSpeakingPeers ?? Set())
|
||||
|
||||
if let peer = peerViewMainPeer(view), let channel = peer as? TelegramChannel {
|
||||
let addressName = channel.addressName ?? ""
|
||||
if channel.flags.contains(.isCreator) || channel.hasPermission(.inviteMembers) {
|
||||
if addressName.isEmpty {
|
||||
if let peer = peerViewMainPeer(view) {
|
||||
if let channel = peer as? TelegramChannel {
|
||||
let addressName = channel.addressName ?? ""
|
||||
if channel.flags.contains(.isCreator) || channel.hasPermission(.inviteMembers) {
|
||||
if addressName.isEmpty {
|
||||
let _ = ensuredExistingPeerExportedInvitation(account: strongSelf.context.account, peerId: call.peerId).start()
|
||||
}
|
||||
}
|
||||
} else if let group = peer as? TelegramGroup {
|
||||
switch group.role {
|
||||
case .creator, .admin:
|
||||
let _ = ensuredExistingPeerExportedInvitation(account: strongSelf.context.account, peerId: call.peerId).start()
|
||||
default:
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -224,10 +224,10 @@ public func channelAdminLogEvents(postbox: Postbox, network: Network, peerId: Pe
|
||||
action = .endGroupCall
|
||||
case let .channelAdminLogEventActionParticipantMute(participant):
|
||||
let parsedParticipant = GroupCallParticipantsContext.Update.StateUpdate.ParticipantUpdate(participant)
|
||||
action = .groupCallUpdateParticipantMuteStatus(peerId: parsedParticipant.peerId, isMuted: parsedParticipant.muteState != nil)
|
||||
action = .groupCallUpdateParticipantMuteStatus(peerId: parsedParticipant.peerId, isMuted: true)
|
||||
case let .channelAdminLogEventActionParticipantUnmute(participant):
|
||||
let parsedParticipant = GroupCallParticipantsContext.Update.StateUpdate.ParticipantUpdate(participant)
|
||||
action = .groupCallUpdateParticipantMuteStatus(peerId: parsedParticipant.peerId, isMuted: parsedParticipant.muteState != nil)
|
||||
action = .groupCallUpdateParticipantMuteStatus(peerId: parsedParticipant.peerId, isMuted: false)
|
||||
case let .channelAdminLogEventActionToggleGroupCallSetting(joinMuted):
|
||||
action = .updateGroupCallSettings(joinMuted: joinMuted == .boolTrue)
|
||||
}
|
||||
|
@ -5,33 +5,38 @@ import SwiftSignalKit
|
||||
import SyncCore
|
||||
import MtProtoKit
|
||||
|
||||
func telegramStickerPackThumbnailRepresentationFromApiSize(datacenterId: Int32, size: Api.PhotoSize) -> TelegramMediaImageRepresentation? {
|
||||
switch size {
|
||||
case let .photoCachedSize(_, location, w, h, _):
|
||||
switch location {
|
||||
case let .fileLocationToBeDeprecated(volumeId, localId):
|
||||
let resource = CloudStickerPackThumbnailMediaResource(datacenterId: datacenterId, volumeId: volumeId, localId: localId)
|
||||
return TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: w, height: h), resource: resource, progressiveSizes: [])
|
||||
}
|
||||
case let .photoSize(_, location, w, h, _):
|
||||
switch location {
|
||||
case let .fileLocationToBeDeprecated(volumeId, localId):
|
||||
let resource = CloudStickerPackThumbnailMediaResource(datacenterId: datacenterId, volumeId: volumeId, localId: localId)
|
||||
return TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: w, height: h), resource: resource, progressiveSizes: [])
|
||||
}
|
||||
case let .photoSizeProgressive(_, location, w, h, sizes):
|
||||
switch location {
|
||||
case let .fileLocationToBeDeprecated(volumeId, localId):
|
||||
let resource = CloudStickerPackThumbnailMediaResource(datacenterId: datacenterId, volumeId: volumeId, localId: localId)
|
||||
return TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: w, height: h), resource: resource, progressiveSizes: sizes)
|
||||
}
|
||||
case let .photoPathSize(_, data):
|
||||
return nil
|
||||
case .photoStrippedSize:
|
||||
return nil
|
||||
case .photoSizeEmpty:
|
||||
return nil
|
||||
func telegramStickerPackThumbnailRepresentationFromApiSizes(datacenterId: Int32, sizes: [Api.PhotoSize]) -> (immediateThumbnail: Data?, representations: [TelegramMediaImageRepresentation]) {
|
||||
var immediateThumbnailData: Data?
|
||||
var representations: [TelegramMediaImageRepresentation] = []
|
||||
for size in sizes {
|
||||
switch size {
|
||||
case let .photoCachedSize(_, location, w, h, _):
|
||||
switch location {
|
||||
case let .fileLocationToBeDeprecated(volumeId, localId):
|
||||
let resource = CloudStickerPackThumbnailMediaResource(datacenterId: datacenterId, volumeId: volumeId, localId: localId)
|
||||
representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: w, height: h), resource: resource, progressiveSizes: []))
|
||||
}
|
||||
case let .photoSize(_, location, w, h, _):
|
||||
switch location {
|
||||
case let .fileLocationToBeDeprecated(volumeId, localId):
|
||||
let resource = CloudStickerPackThumbnailMediaResource(datacenterId: datacenterId, volumeId: volumeId, localId: localId)
|
||||
representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: w, height: h), resource: resource, progressiveSizes: []))
|
||||
}
|
||||
case let .photoSizeProgressive(_, location, w, h, sizes):
|
||||
switch location {
|
||||
case let .fileLocationToBeDeprecated(volumeId, localId):
|
||||
let resource = CloudStickerPackThumbnailMediaResource(datacenterId: datacenterId, volumeId: volumeId, localId: localId)
|
||||
representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: w, height: h), resource: resource, progressiveSizes: sizes))
|
||||
}
|
||||
case let .photoPathSize(_, data):
|
||||
immediateThumbnailData = data.makeData()
|
||||
case .photoStrippedSize:
|
||||
break
|
||||
case .photoSizeEmpty:
|
||||
break
|
||||
}
|
||||
}
|
||||
return (immediateThumbnailData, representations)
|
||||
}
|
||||
|
||||
extension StickerPackCollectionInfo {
|
||||
@ -50,11 +55,14 @@ extension StickerPackCollectionInfo {
|
||||
}
|
||||
|
||||
var thumbnailRepresentation: TelegramMediaImageRepresentation?
|
||||
if let thumb = thumbs?.first, let thumbDcId = thumbDcId {
|
||||
thumbnailRepresentation = telegramStickerPackThumbnailRepresentationFromApiSize(datacenterId: thumbDcId, size: thumb)
|
||||
var immediateThumbnailData: Data?
|
||||
if let thumbs = thumbs, let thumbDcId = thumbDcId {
|
||||
let (data, representations) = telegramStickerPackThumbnailRepresentationFromApiSizes(datacenterId: thumbDcId, sizes: thumbs)
|
||||
thumbnailRepresentation = representations.first
|
||||
immediateThumbnailData = data
|
||||
}
|
||||
|
||||
self.init(id: ItemCollectionId(namespace: namespace, id: id), flags: setFlags, accessHash: accessHash, title: title, shortName: shortName, thumbnail: thumbnailRepresentation, hash: nHash, count: count)
|
||||
self.init(id: ItemCollectionId(namespace: namespace, id: id), flags: setFlags, accessHash: accessHash, title: title, shortName: shortName, thumbnail: thumbnailRepresentation, immediateThumbnailData: immediateThumbnailData, hash: nHash, count: count)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -18,7 +18,7 @@ public func addStickerPackInteractively(postbox: Postbox, info: StickerPackColle
|
||||
if let namespace = namespace {
|
||||
var mappedInfo = info
|
||||
if items.isEmpty {
|
||||
mappedInfo = StickerPackCollectionInfo(id: info.id, flags: info.flags, accessHash: info.accessHash, title: info.title, shortName: info.shortName, thumbnail: info.thumbnail, hash: Int32(bitPattern: arc4random()), count: info.count)
|
||||
mappedInfo = StickerPackCollectionInfo(id: info.id, flags: info.flags, accessHash: info.accessHash, title: info.title, shortName: info.shortName, thumbnail: info.thumbnail, immediateThumbnailData: info.immediateThumbnailData, hash: Int32(bitPattern: arc4random()), count: info.count)
|
||||
}
|
||||
addSynchronizeInstalledStickerPacksOperation(transaction: transaction, namespace: namespace, content: .add([mappedInfo.id]), noDelay: items.isEmpty)
|
||||
var updatedInfos = transaction.getItemCollectionsInfos(namespace: mappedInfo.id.namespace).map { $0.1 as! StickerPackCollectionInfo }
|
||||
|
@ -238,7 +238,7 @@ func chatMediaInputGridEntries(view: ItemCollectionsView, savedStickers: Ordered
|
||||
if view.lower == nil {
|
||||
var savedStickerIds = Set<Int64>()
|
||||
if let savedStickers = savedStickers, !savedStickers.items.isEmpty {
|
||||
let packInfo = StickerPackCollectionInfo(id: ItemCollectionId(namespace: ChatMediaInputPanelAuxiliaryNamespace.savedStickers.rawValue, id: 0), flags: [], accessHash: 0, title: strings.Stickers_FavoriteStickers.uppercased(), shortName: "", thumbnail: nil, hash: 0, count: 0)
|
||||
let packInfo = StickerPackCollectionInfo(id: ItemCollectionId(namespace: ChatMediaInputPanelAuxiliaryNamespace.savedStickers.rawValue, id: 0), flags: [], accessHash: 0, title: strings.Stickers_FavoriteStickers.uppercased(), shortName: "", thumbnail: nil, immediateThumbnailData: nil, hash: 0, count: 0)
|
||||
for i in 0 ..< savedStickers.items.count {
|
||||
if let item = savedStickers.items[i].contents as? SavedStickerItem {
|
||||
savedStickerIds.insert(item.file.fileId.id)
|
||||
@ -250,7 +250,7 @@ func chatMediaInputGridEntries(view: ItemCollectionsView, savedStickers: Ordered
|
||||
}
|
||||
|
||||
if let recentStickers = recentStickers, !recentStickers.items.isEmpty {
|
||||
let packInfo = StickerPackCollectionInfo(id: ItemCollectionId(namespace: ChatMediaInputPanelAuxiliaryNamespace.recentStickers.rawValue, id: 0), flags: [], accessHash: 0, title: strings.Stickers_FrequentlyUsed.uppercased(), shortName: "", thumbnail: nil, hash: 0, count: 0)
|
||||
let packInfo = StickerPackCollectionInfo(id: ItemCollectionId(namespace: ChatMediaInputPanelAuxiliaryNamespace.recentStickers.rawValue, id: 0), flags: [], accessHash: 0, title: strings.Stickers_FrequentlyUsed.uppercased(), shortName: "", thumbnail: nil, immediateThumbnailData: nil, hash: 0, count: 0)
|
||||
var addedCount = 0
|
||||
for i in 0 ..< recentStickers.items.count {
|
||||
if addedCount >= 20 {
|
||||
@ -278,7 +278,7 @@ func chatMediaInputGridEntries(view: ItemCollectionsView, savedStickers: Ordered
|
||||
|
||||
if let peerSpecificPack = peerSpecificPack {
|
||||
for i in 0 ..< peerSpecificPack.items.count {
|
||||
let packInfo = StickerPackCollectionInfo(id: ItemCollectionId(namespace: ChatMediaInputPanelAuxiliaryNamespace.peerSpecific.rawValue, id: 0), flags: [], accessHash: 0, title: strings.Stickers_GroupStickers, shortName: "", thumbnail: nil, hash: 0, count: 0)
|
||||
let packInfo = StickerPackCollectionInfo(id: ItemCollectionId(namespace: ChatMediaInputPanelAuxiliaryNamespace.peerSpecific.rawValue, id: 0), flags: [], accessHash: 0, title: strings.Stickers_GroupStickers, shortName: "", thumbnail: nil, immediateThumbnailData: nil, hash: 0, count: 0)
|
||||
|
||||
if let item = peerSpecificPack.items[i] as? StickerPackItem {
|
||||
let index = ItemCollectionItemIndex(index: Int32(i), id: item.file.fileId.id)
|
||||
|
@ -76,8 +76,7 @@ private let verticalOffset: CGFloat = 3.0
|
||||
final class ChatMediaInputStickerPackItemNode: ListViewItemNode {
|
||||
private let imageNode: TransformImageNode
|
||||
private var animatedStickerNode: AnimatedStickerNode?
|
||||
private var placeholderNode: ShimmerEffectNode?
|
||||
private var placeholderImageNode: ASImageNode?
|
||||
private var placeholderNode: StickerShimmerEffectNode?
|
||||
private let highlightNode: ASImageNode
|
||||
|
||||
var inputNodeInteraction: ChatMediaInputNodeInteraction?
|
||||
@ -109,11 +108,9 @@ final class ChatMediaInputStickerPackItemNode: ListViewItemNode {
|
||||
|
||||
self.imageNode = TransformImageNode()
|
||||
self.imageNode.isLayerBacked = !smartInvertColorsEnabled()
|
||||
|
||||
self.placeholderImageNode = ASImageNode()
|
||||
self.placeholderImageNode?.isUserInteractionEnabled = false
|
||||
|
||||
//self.placeholderNode = ShimmerEffectNode()
|
||||
|
||||
self.placeholderNode = StickerShimmerEffectNode()
|
||||
self.placeholderNode?.transform = CATransform3DMakeRotation(CGFloat.pi / 2.0, 0.0, 0.0, 1.0)
|
||||
|
||||
self.highlightNode.frame = CGRect(origin: CGPoint(x: floor((boundingSize.width - highlightSize.width) / 2.0) + verticalOffset - UIScreenPixel, y: floor((boundingSize.height - highlightSize.height) / 2.0) - UIScreenPixel), size: highlightSize)
|
||||
|
||||
@ -124,9 +121,6 @@ final class ChatMediaInputStickerPackItemNode: ListViewItemNode {
|
||||
|
||||
self.addSubnode(self.highlightNode)
|
||||
self.addSubnode(self.imageNode)
|
||||
if let placeholderImageNode = self.placeholderImageNode {
|
||||
self.addSubnode(placeholderImageNode)
|
||||
}
|
||||
if let placeholderNode = self.placeholderNode {
|
||||
self.addSubnode(placeholderNode)
|
||||
}
|
||||
@ -138,6 +132,9 @@ final class ChatMediaInputStickerPackItemNode: ListViewItemNode {
|
||||
}
|
||||
if image != nil {
|
||||
strongSelf.removePlaceholder(animated: !firstTime)
|
||||
if firstTime {
|
||||
strongSelf.imageNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2)
|
||||
}
|
||||
}
|
||||
firstTime = false
|
||||
}
|
||||
@ -159,17 +156,6 @@ final class ChatMediaInputStickerPackItemNode: ListViewItemNode {
|
||||
})
|
||||
}
|
||||
}
|
||||
if let placeholderImageNode = self.placeholderImageNode {
|
||||
self.placeholderImageNode = nil
|
||||
if !animated {
|
||||
placeholderImageNode.removeFromSupernode()
|
||||
} else {
|
||||
placeholderImageNode.alpha = 0.0
|
||||
placeholderImageNode.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.2, completion: { [weak placeholderImageNode] _ in
|
||||
placeholderImageNode?.removeFromSupernode()
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func updateStickerPackItem(account: Account, info: StickerPackCollectionInfo, item: StickerPackItem?, collectionId: ItemCollectionId, theme: PresentationTheme) {
|
||||
@ -244,24 +230,13 @@ final class ChatMediaInputStickerPackItemNode: ListViewItemNode {
|
||||
self.stickerFetchedDisposable.set(fetchedMediaResource(mediaBox: account.postbox.mediaBox, reference: resourceReference).start())
|
||||
}
|
||||
}
|
||||
|
||||
if let placeholderImageNode = self.placeholderImageNode {
|
||||
if placeholderImageNode.image == nil {
|
||||
placeholderImageNode.image = generateStretchableFilledCircleImage(diameter: 10.0, color: theme.chat.inputMediaPanel.panelHighlightedIconBackgroundColor.withMultipliedAlpha(0.3))
|
||||
}
|
||||
let size = boundingSize
|
||||
let imageSize = boundingImageSize
|
||||
let placeholderFrame = CGRect(origin: CGPoint(x: floor((boundingSize.width - imageSize.width) / 2.0) + verticalOffset, y: floor((boundingSize.height - imageSize.height) / 2.0)), size: imageSize)
|
||||
placeholderImageNode.frame = placeholderFrame
|
||||
}
|
||||
|
||||
|
||||
if let placeholderNode = self.placeholderNode {
|
||||
let size = boundingSize
|
||||
let imageSize = boundingImageSize
|
||||
let placeholderFrame = CGRect(origin: CGPoint(x: floor((boundingSize.width - imageSize.width) / 2.0) + verticalOffset, y: floor((boundingSize.height - imageSize.height) / 2.0)), size: imageSize)
|
||||
placeholderNode.frame = CGRect(origin: CGPoint(), size: size)
|
||||
placeholderNode.frame = placeholderFrame
|
||||
|
||||
placeholderNode.update(backgroundColor: theme.chat.inputPanel.panelBackgroundColor, foregroundColor: theme.chat.inputMediaPanel.stickersSectionTextColor.blitOver(theme.chat.inputPanel.panelBackgroundColor, alpha: 0.4), shimmeringColor: theme.chat.inputMediaPanel.panelHighlightedIconBackgroundColor.withMultipliedAlpha(0.2), shapes: [.roundedRect(rect: placeholderFrame, cornerRadius: 5.0)], size: bounds.size)
|
||||
placeholderNode.update(backgroundColor: nil, foregroundColor: theme.chat.inputMediaPanel.stickersSectionTextColor.blitOver(theme.chat.inputPanel.panelBackgroundColor, alpha: 0.4), shimmeringColor: theme.chat.inputMediaPanel.panelHighlightedIconBackgroundColor.withMultipliedAlpha(0.2), data: info.immediateThumbnailData, size: imageSize, small: true)
|
||||
}
|
||||
|
||||
self.updateIsHighlighted()
|
||||
@ -270,7 +245,7 @@ final class ChatMediaInputStickerPackItemNode: ListViewItemNode {
|
||||
|
||||
override func updateAbsoluteRect(_ rect: CGRect, within containerSize: CGSize) {
|
||||
if let placeholderNode = self.placeholderNode {
|
||||
//placeholderNode.updateAbsoluteRect(rect, within: containerSize)
|
||||
placeholderNode.updateAbsoluteRect(rect, within: containerSize)
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user