mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-15 13:35:19 +00:00
Various improvements
This commit is contained in:
parent
004ebd58ad
commit
681b5c9d3a
@ -492,6 +492,30 @@ public final class AvatarNode: ASDisplayNode {
|
||||
}
|
||||
}
|
||||
|
||||
public func playCameraAnimation() {
|
||||
let animationBackgroundNode = ASImageNode()
|
||||
animationBackgroundNode.isUserInteractionEnabled = false
|
||||
animationBackgroundNode.frame = self.imageNode.frame
|
||||
animationBackgroundNode.image = generateGradientFilledCircleImage(diameter: self.imageNode.frame.width, colors: AvatarNode.repostColors.map { $0.cgColor } as NSArray)
|
||||
self.addSubnode(animationBackgroundNode)
|
||||
|
||||
let animationNode = AnimationNode(animation: "anim_camera", colors: [:], scale: 0.082)
|
||||
animationNode.isUserInteractionEnabled = false
|
||||
self.addSubnode(animationNode)
|
||||
|
||||
if var size = animationNode.preferredSize() {
|
||||
size = CGSize(width: ceil(size.width), height: ceil(size.height))
|
||||
animationNode.frame = CGRect(x: floor((self.bounds.width - size.width) / 2.0) + 1.0, y: floor((self.bounds.height - size.height) / 2.0), width: size.width, height: size.height)
|
||||
Queue.mainQueue().after(0.15, {
|
||||
animationNode.play()
|
||||
animationNode.completion = { [weak animationNode, weak animationBackgroundNode] in
|
||||
animationNode?.removeFromSupernode()
|
||||
animationBackgroundNode?.removeFromSupernode()
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
public func setPeer(
|
||||
accountPeerId: EnginePeer.Id,
|
||||
postbox: Postbox,
|
||||
@ -1151,6 +1175,10 @@ public final class AvatarNode: ASDisplayNode {
|
||||
self.contentNode.playRepostAnimation()
|
||||
}
|
||||
|
||||
public func playCameraAnimation() {
|
||||
self.contentNode.playCameraAnimation ()
|
||||
}
|
||||
|
||||
public func setPeer(
|
||||
accountPeerId: EnginePeer.Id,
|
||||
postbox: Postbox,
|
||||
|
@ -163,6 +163,7 @@ public final class BrowserBookmarksScreen: ViewController {
|
||||
}, playMessageEffect: { _ in
|
||||
}, editMessageFactCheck: { _ in
|
||||
}, sendGift: { _ in
|
||||
}, openUniqueGift: { _ in
|
||||
}, requestMessageUpdate: { _, _ in
|
||||
}, cancelInteractiveKeyboardGestures: {
|
||||
}, dismissTextInput: {
|
||||
|
@ -137,10 +137,6 @@ final class ChatListNoticeItemNode: ItemListRevealOptionsItemNode {
|
||||
self.zPosition = 1.0
|
||||
}
|
||||
|
||||
override func didLoad() {
|
||||
super.didLoad()
|
||||
}
|
||||
|
||||
@objc private func closePressed() {
|
||||
guard let item = self.item else {
|
||||
return
|
||||
@ -500,6 +496,14 @@ final class ChatListNoticeItemNode: ItemListRevealOptionsItemNode {
|
||||
}
|
||||
}
|
||||
|
||||
override public func selected() {
|
||||
super.selected()
|
||||
|
||||
if case .setupPhoto = self.item?.notice {
|
||||
self.avatarNode?.playCameraAnimation()
|
||||
}
|
||||
}
|
||||
|
||||
@objc private func okButtonPressed() {
|
||||
self.item?.action(.buttonChoice(isPositive: true))
|
||||
}
|
||||
|
@ -791,6 +791,7 @@ public class ContactsPeerItemNode: ItemListRevealOptionsItemNode {
|
||||
let premiumConfiguration = PremiumConfiguration.with(appConfiguration: item.context.currentAppConfiguration.with { $0 })
|
||||
|
||||
var credibilityIcon: EmojiStatusComponent.Content?
|
||||
var credibilityParticleColor: UIColor?
|
||||
var verifiedIcon: EmojiStatusComponent.Content?
|
||||
switch item.peer {
|
||||
case let .peer(peer, _):
|
||||
@ -801,6 +802,9 @@ public class ContactsPeerItemNode: ItemListRevealOptionsItemNode {
|
||||
credibilityIcon = .text(color: item.presentationData.theme.chat.message.incoming.scamColor, string: item.presentationData.strings.Message_FakeAccount.uppercased())
|
||||
} else if let emojiStatus = peer.emojiStatus {
|
||||
credibilityIcon = .animation(content: .customEmoji(fileId: emojiStatus.fileId), size: CGSize(width: 20.0, height: 20.0), placeholderColor: item.presentationData.theme.list.mediaPlaceholderColor, themeColor: item.presentationData.theme.list.itemAccentColor, loopMode: .count(2))
|
||||
if let color = emojiStatus.color {
|
||||
credibilityParticleColor = UIColor(rgb: UInt32(bitPattern: color))
|
||||
}
|
||||
} else if peer.isPremium && !premiumConfiguration.isPremiumDisabled {
|
||||
credibilityIcon = .premium(color: item.presentationData.theme.list.itemAccentColor)
|
||||
}
|
||||
@ -1498,6 +1502,7 @@ public class ContactsPeerItemNode: ItemListRevealOptionsItemNode {
|
||||
animationCache: animationCache,
|
||||
animationRenderer: animationRenderer,
|
||||
content: credibilityIcon,
|
||||
particleColor: credibilityParticleColor,
|
||||
isVisibleForAnimations: strongSelf.visibilityStatus,
|
||||
action: nil,
|
||||
emojiFileUpdated: nil
|
||||
|
@ -141,6 +141,7 @@ public final class ContextMenuActionItem {
|
||||
public let textIcon: (PresentationTheme) -> UIImage?
|
||||
public let textLinkAction: () -> Void
|
||||
public let action: ((Action) -> Void)?
|
||||
public let longPressAction: ((Action) -> Void)?
|
||||
|
||||
convenience public init(
|
||||
id: AnyHashable? = nil,
|
||||
@ -160,7 +161,8 @@ public final class ContextMenuActionItem {
|
||||
iconAnimation: IconAnimation? = nil,
|
||||
textIcon: @escaping (PresentationTheme) -> UIImage? = { _ in return nil },
|
||||
textLinkAction: @escaping () -> Void = {},
|
||||
action: ((ContextControllerProtocol?, @escaping (ContextMenuActionResult) -> Void) -> Void)?
|
||||
action: ((ContextControllerProtocol?, @escaping (ContextMenuActionResult) -> Void) -> Void)?,
|
||||
longPressAction: ((ContextControllerProtocol?, @escaping (ContextMenuActionResult) -> Void) -> Void)? = nil
|
||||
) {
|
||||
self.init(
|
||||
id: id,
|
||||
@ -184,6 +186,11 @@ public final class ContextMenuActionItem {
|
||||
return { impl in
|
||||
action(impl.controller, impl.dismissWithResult)
|
||||
}
|
||||
},
|
||||
longPressAction: longPressAction.flatMap { longPressAction in
|
||||
return { impl in
|
||||
longPressAction(impl.controller, impl.dismissWithResult)
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
@ -206,7 +213,8 @@ public final class ContextMenuActionItem {
|
||||
iconAnimation: IconAnimation? = nil,
|
||||
textIcon: @escaping (PresentationTheme) -> UIImage? = { _ in return nil },
|
||||
textLinkAction: @escaping () -> Void = {},
|
||||
action: ((Action) -> Void)?
|
||||
action: ((Action) -> Void)?,
|
||||
longPressAction: ((Action) -> Void)? = nil
|
||||
) {
|
||||
self.id = id
|
||||
self.text = text
|
||||
@ -226,6 +234,7 @@ public final class ContextMenuActionItem {
|
||||
self.textIcon = textIcon
|
||||
self.textLinkAction = textLinkAction
|
||||
self.action = action
|
||||
self.longPressAction = longPressAction
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -922,6 +922,7 @@ public class ItemListPeerItemNode: ItemListRevealOptionsItemNode, ItemListItemNo
|
||||
|
||||
var updatedLabelBadgeImage: UIImage?
|
||||
var credibilityIcon: EmojiStatusComponent.Content?
|
||||
var credibilityParticleColor: UIColor?
|
||||
var verifiedIcon: EmojiStatusComponent.Content?
|
||||
|
||||
if case .threatSelfAsSaved = item.aliasHandling, item.peer.id == item.context.accountPeerId {
|
||||
@ -932,6 +933,9 @@ public class ItemListPeerItemNode: ItemListRevealOptionsItemNode, ItemListItemNo
|
||||
credibilityIcon = .text(color: item.presentationData.theme.chat.message.incoming.scamColor, string: item.presentationData.strings.Message_FakeAccount.uppercased())
|
||||
} else if let emojiStatus = item.peer.emojiStatus {
|
||||
credibilityIcon = .animation(content: .customEmoji(fileId: emojiStatus.fileId), size: CGSize(width: 20.0, height: 20.0), placeholderColor: item.presentationData.theme.list.mediaPlaceholderColor, themeColor: item.presentationData.theme.list.itemAccentColor, loopMode: .count(2))
|
||||
if let color = emojiStatus.color {
|
||||
credibilityParticleColor = UIColor(rgb: UInt32(bitPattern: color))
|
||||
}
|
||||
} else if item.peer.isPremium && !item.context.isPremiumDisabled {
|
||||
credibilityIcon = .premium(color: item.presentationData.theme.list.itemAccentColor)
|
||||
}
|
||||
@ -1504,6 +1508,7 @@ public class ItemListPeerItemNode: ItemListRevealOptionsItemNode, ItemListItemNo
|
||||
animationCache: animationCache,
|
||||
animationRenderer: animationRenderer,
|
||||
content: credibilityIcon,
|
||||
particleColor: credibilityParticleColor,
|
||||
isVisibleForAnimations: strongSelf.visibilityStatus,
|
||||
action: nil,
|
||||
emojiFileUpdated: nil
|
||||
|
@ -2100,7 +2100,7 @@ public class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewI
|
||||
bottomNodeMergeStatus = .Both
|
||||
}
|
||||
|
||||
var currentCredibilityIcon: EmojiStatusComponent.Content?
|
||||
var currentCredibilityIcon: (EmojiStatusComponent.Content, UIColor?)?
|
||||
|
||||
var initialDisplayHeader = true
|
||||
if hidesHeaders || item.message.adAttribute != nil {
|
||||
@ -2163,18 +2163,18 @@ public class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewI
|
||||
|
||||
if case let .peer(peerId) = item.chatLocation, let authorPeerId = item.message.author?.id, authorPeerId == peerId {
|
||||
if effectiveAuthor is TelegramChannel, let emojiStatus = effectiveAuthor.emojiStatus {
|
||||
currentCredibilityIcon = .animation(content: .customEmoji(fileId: emojiStatus.fileId), size: CGSize(width: 20.0, height: 20.0), placeholderColor: incoming ? item.presentationData.theme.theme.chat.message.incoming.mediaPlaceholderColor : item.presentationData.theme.theme.chat.message.outgoing.mediaPlaceholderColor, themeColor: color.withMultipliedAlpha(0.4), loopMode: .count(2))
|
||||
currentCredibilityIcon = (.animation(content: .customEmoji(fileId: emojiStatus.fileId), size: CGSize(width: 20.0, height: 20.0), placeholderColor: incoming ? item.presentationData.theme.theme.chat.message.incoming.mediaPlaceholderColor : item.presentationData.theme.theme.chat.message.outgoing.mediaPlaceholderColor, themeColor: color.withMultipliedAlpha(0.4), loopMode: .count(2)), nil)
|
||||
}
|
||||
} else if effectiveAuthor.isScam {
|
||||
currentCredibilityIcon = .text(color: incoming ? item.presentationData.theme.theme.chat.message.incoming.scamColor : item.presentationData.theme.theme.chat.message.outgoing.scamColor, string: item.presentationData.strings.Message_ScamAccount.uppercased())
|
||||
currentCredibilityIcon = (.text(color: incoming ? item.presentationData.theme.theme.chat.message.incoming.scamColor : item.presentationData.theme.theme.chat.message.outgoing.scamColor, string: item.presentationData.strings.Message_ScamAccount.uppercased()), nil)
|
||||
} else if effectiveAuthor.isFake {
|
||||
currentCredibilityIcon = .text(color: incoming ? item.presentationData.theme.theme.chat.message.incoming.scamColor : item.presentationData.theme.theme.chat.message.outgoing.scamColor, string: item.presentationData.strings.Message_FakeAccount.uppercased())
|
||||
currentCredibilityIcon = (.text(color: incoming ? item.presentationData.theme.theme.chat.message.incoming.scamColor : item.presentationData.theme.theme.chat.message.outgoing.scamColor, string: item.presentationData.strings.Message_FakeAccount.uppercased()), nil)
|
||||
} else if let emojiStatus = effectiveAuthor.emojiStatus {
|
||||
currentCredibilityIcon = .animation(content: .customEmoji(fileId: emojiStatus.fileId), size: CGSize(width: 20.0, height: 20.0), placeholderColor: incoming ? item.presentationData.theme.theme.chat.message.incoming.mediaPlaceholderColor : item.presentationData.theme.theme.chat.message.outgoing.mediaPlaceholderColor, themeColor: color.withMultipliedAlpha(0.4), loopMode: .count(2))
|
||||
currentCredibilityIcon = (.animation(content: .customEmoji(fileId: emojiStatus.fileId), size: CGSize(width: 20.0, height: 20.0), placeholderColor: incoming ? item.presentationData.theme.theme.chat.message.incoming.mediaPlaceholderColor : item.presentationData.theme.theme.chat.message.outgoing.mediaPlaceholderColor, themeColor: color.withMultipliedAlpha(0.4), loopMode: .count(2)), emojiStatus.color.flatMap { UIColor(rgb: UInt32(bitPattern: $0)) })
|
||||
} else if effectiveAuthor.isVerified {
|
||||
currentCredibilityIcon = .verified(fillColor: item.presentationData.theme.theme.list.itemCheckColors.fillColor, foregroundColor: item.presentationData.theme.theme.list.itemCheckColors.foregroundColor, sizeType: .compact)
|
||||
currentCredibilityIcon = (.verified(fillColor: item.presentationData.theme.theme.list.itemCheckColors.fillColor, foregroundColor: item.presentationData.theme.theme.list.itemCheckColors.foregroundColor, sizeType: .compact), nil)
|
||||
} else if effectiveAuthor.isPremium {
|
||||
currentCredibilityIcon = .premium(color: color.withMultipliedAlpha(0.4))
|
||||
currentCredibilityIcon = (.premium(color: color.withMultipliedAlpha(0.4)), nil)
|
||||
}
|
||||
}
|
||||
if let rawAuthorNameColor = authorNameColor {
|
||||
@ -2414,7 +2414,7 @@ public class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewI
|
||||
}
|
||||
|
||||
var credibilityIconWidth: CGFloat = 0.0
|
||||
if let currentCredibilityIcon = currentCredibilityIcon {
|
||||
if let (currentCredibilityIcon, _) = currentCredibilityIcon {
|
||||
credibilityIconWidth += 4.0
|
||||
switch currentCredibilityIcon {
|
||||
case let .text(_, string):
|
||||
@ -3223,7 +3223,7 @@ public class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewI
|
||||
nameNodeOriginY: CGFloat,
|
||||
authorNameColor: UIColor?,
|
||||
layoutConstants: ChatMessageItemLayoutConstants,
|
||||
currentCredibilityIcon: EmojiStatusComponent.Content?,
|
||||
currentCredibilityIcon: (EmojiStatusComponent.Content, UIColor?)?,
|
||||
adminNodeSizeApply: (CGSize, () -> TextNode?),
|
||||
boostNodeSizeApply: (CGSize, () -> TextNode?),
|
||||
contentUpperRightCorner: CGPoint,
|
||||
@ -3428,7 +3428,7 @@ public class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewI
|
||||
nameHighlightNode.image = generateFilledRoundedRectImage(size: CGSize(width: 8.0, height: 8.0), cornerRadius: 4.0, color: nameColor.withAlphaComponent(0.1))?.stretchableImage(withLeftCapWidth: 4, topCapHeight: 4)
|
||||
}
|
||||
|
||||
if let currentCredibilityIcon = currentCredibilityIcon {
|
||||
if let (currentCredibilityIcon, currentParticleColor) = currentCredibilityIcon {
|
||||
let credibilityIconView: ComponentHostView<Empty>
|
||||
if let current = strongSelf.credibilityIconView {
|
||||
credibilityIconView = current
|
||||
@ -3448,6 +3448,7 @@ public class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewI
|
||||
animationCache: item.context.animationCache,
|
||||
animationRenderer: item.context.animationRenderer,
|
||||
content: currentCredibilityIcon,
|
||||
particleColor: currentParticleColor,
|
||||
isVisibleForAnimations: strongSelf.visibilityStatus,
|
||||
action: nil
|
||||
)
|
||||
@ -5767,16 +5768,20 @@ public class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewI
|
||||
|
||||
@objc private func credibilityButtonPressed() {
|
||||
if let item = self.item, let credibilityIconView = self.credibilityIconView, let iconContent = self.credibilityIconContent, let peer = item.message.author {
|
||||
var emojiFileId: Int64?
|
||||
switch iconContent {
|
||||
case let .animation(content, _, _, _, _):
|
||||
emojiFileId = content.fileId.id
|
||||
case .premium:
|
||||
break
|
||||
default:
|
||||
return
|
||||
if case let .starGift(_, _, _, slug, _, _, _, _, _) = peer.emojiStatus?.content {
|
||||
item.controllerInteraction.openUniqueGift(slug)
|
||||
} else {
|
||||
var emojiFileId: Int64?
|
||||
switch iconContent {
|
||||
case let .animation(content, _, _, _, _):
|
||||
emojiFileId = content.fileId.id
|
||||
case .premium:
|
||||
break
|
||||
default:
|
||||
return
|
||||
}
|
||||
item.controllerInteraction.openPremiumStatusInfo(peer.id, credibilityIconView, emojiFileId, peer.nameColor ?? .blue)
|
||||
}
|
||||
item.controllerInteraction.openPremiumStatusInfo(peer.id, credibilityIconView, emojiFileId, peer.nameColor ?? .blue)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -632,8 +632,8 @@ final class ChatRecentActionsControllerNode: ViewControllerTracingNode {
|
||||
}, playMessageEffect: { _ in
|
||||
}, editMessageFactCheck: { _ in
|
||||
}, sendGift: { _ in
|
||||
}, requestMessageUpdate: { _, _ in
|
||||
|
||||
}, openUniqueGift: { _ in
|
||||
}, requestMessageUpdate: { _, _ in
|
||||
}, cancelInteractiveKeyboardGestures: {
|
||||
}, dismissTextInput: {
|
||||
}, scrollToMessageId: { _ in
|
||||
|
@ -489,6 +489,7 @@ public final class ChatSendGroupMediaMessageContextPreview: UIView, ChatSendMess
|
||||
}, playMessageEffect: { _ in
|
||||
}, editMessageFactCheck: { _ in
|
||||
}, sendGift: { _ in
|
||||
}, openUniqueGift: { _ in
|
||||
}, requestMessageUpdate: { _, _ in
|
||||
}, cancelInteractiveKeyboardGestures: {
|
||||
}, dismissTextInput: {
|
||||
|
@ -268,6 +268,7 @@ public final class ChatControllerInteraction: ChatControllerInteractionProtocol
|
||||
public let playMessageEffect: (Message) -> Void
|
||||
public let editMessageFactCheck: (MessageId) -> Void
|
||||
public let sendGift: (EnginePeer.Id) -> Void
|
||||
public let openUniqueGift: (String) -> Void
|
||||
|
||||
public let requestMessageUpdate: (MessageId, Bool) -> Void
|
||||
public let cancelInteractiveKeyboardGestures: () -> Void
|
||||
@ -402,6 +403,7 @@ public final class ChatControllerInteraction: ChatControllerInteractionProtocol
|
||||
playMessageEffect: @escaping (Message) -> Void,
|
||||
editMessageFactCheck: @escaping (MessageId) -> Void,
|
||||
sendGift: @escaping (EnginePeer.Id) -> Void,
|
||||
openUniqueGift: @escaping (String) -> Void,
|
||||
requestMessageUpdate: @escaping (MessageId, Bool) -> Void,
|
||||
cancelInteractiveKeyboardGestures: @escaping () -> Void,
|
||||
dismissTextInput: @escaping () -> Void,
|
||||
@ -515,6 +517,7 @@ public final class ChatControllerInteraction: ChatControllerInteractionProtocol
|
||||
self.playMessageEffect = playMessageEffect
|
||||
self.editMessageFactCheck = editMessageFactCheck
|
||||
self.sendGift = sendGift
|
||||
self.openUniqueGift = openUniqueGift
|
||||
|
||||
self.requestMessageUpdate = requestMessageUpdate
|
||||
self.cancelInteractiveKeyboardGestures = cancelInteractiveKeyboardGestures
|
||||
|
@ -229,7 +229,7 @@ public func makeEditorImageComposition(context: CIContext, postbox: Postbox, inp
|
||||
} else if values.isAvatar {
|
||||
maskImage = rectangleMaskImage(size: CGSize(width: 1080.0, height: 1080.0))
|
||||
} else if let outputDimensions {
|
||||
maskImage = rectangleMaskImage(size: outputDimensions.aspectFitted(CGSize(width: 1080.0, height: 1080.0)))
|
||||
maskImage = rectangleMaskImage(size: outputDimensions.aspectFitted(CGSize(width: 1080.0, height: 1920.0)))
|
||||
}
|
||||
|
||||
if let drawing = values.drawing, let image = CIImage(image: drawing, options: [.colorSpace: colorSpace]) {
|
||||
@ -308,8 +308,7 @@ private func makeEditorImageFrameComposition(context: CIContext, inputImage: CII
|
||||
let scaledSize = CGSize(width: minSize, height: minSize)
|
||||
resultImage = resultImage.transformed(by: CGAffineTransform(translationX: -(dimensions.width - scaledSize.width) / 2.0, y: -(dimensions.height - scaledSize.height) / 2.0)).cropped(to: CGRect(origin: .zero, size: scaledSize))
|
||||
} else if values.isCover, let outputDimensions {
|
||||
let minSize = min(dimensions.width, dimensions.height)
|
||||
let scaledSize = outputDimensions.aspectFitted(CGSize(width: minSize, height: minSize))
|
||||
let scaledSize = outputDimensions.aspectFitted(dimensions)
|
||||
resultImage = resultImage.transformed(by: CGAffineTransform(translationX: -(dimensions.width - scaledSize.width) / 2.0, y: -(dimensions.height - scaledSize.height) / 2.0)).cropped(to: CGRect(origin: .zero, size: scaledSize))
|
||||
} else if values.isStory {
|
||||
resultImage = resultImage.cropped(to: CGRect(origin: .zero, size: dimensions))
|
||||
|
@ -3680,6 +3680,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro
|
||||
}, playMessageEffect: { _ in
|
||||
}, editMessageFactCheck: { _ in
|
||||
}, sendGift: { _ in
|
||||
}, openUniqueGift: { _ in
|
||||
}, requestMessageUpdate: { _, _ in
|
||||
}, cancelInteractiveKeyboardGestures: {
|
||||
}, dismissTextInput: {
|
||||
@ -10970,20 +10971,30 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro
|
||||
giftsContext?.updateFilter(updatedFilter)
|
||||
}
|
||||
|
||||
let switchToFilter: (ProfileGiftsContext.Filters) -> Void = { [weak giftsContext] value in
|
||||
giftsContext?.updateFilter(value)
|
||||
}
|
||||
|
||||
items.append(.action(ContextMenuActionItem(text: strings.PeerInfo_Gifts_Unlimited, icon: { theme in
|
||||
return filter.contains(.unlimited) ? generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Check"), color: theme.contextMenu.primaryColor) : nil
|
||||
}, action: { _, f in
|
||||
toggleFilter(.unlimited)
|
||||
}, longPressAction: { _, f in
|
||||
switchToFilter(.unlimited)
|
||||
})))
|
||||
items.append(.action(ContextMenuActionItem(text: strings.PeerInfo_Gifts_Limited, icon: { theme in
|
||||
return filter.contains(.limited) ? generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Check"), color: theme.contextMenu.primaryColor) : nil
|
||||
}, action: { _, f in
|
||||
toggleFilter(.limited)
|
||||
}, longPressAction: { _, f in
|
||||
switchToFilter(.limited)
|
||||
})))
|
||||
items.append(.action(ContextMenuActionItem(text: strings.PeerInfo_Gifts_Unique, icon: { theme in
|
||||
return filter.contains(.unique) ? generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Check"), color: theme.contextMenu.primaryColor) : nil
|
||||
}, action: { _, f in
|
||||
toggleFilter(.unique)
|
||||
}, longPressAction: { _, f in
|
||||
switchToFilter(.unique)
|
||||
})))
|
||||
|
||||
if channel.hasPermission(.sendSomething) {
|
||||
@ -10993,11 +11004,15 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro
|
||||
return filter.contains(.displayed) ? generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Check"), color: theme.contextMenu.primaryColor) : nil
|
||||
}, action: { _, f in
|
||||
toggleFilter(.displayed)
|
||||
}, longPressAction: { _, f in
|
||||
switchToFilter(.displayed)
|
||||
})))
|
||||
items.append(.action(ContextMenuActionItem(text: strings.PeerInfo_Gifts_Hidden, icon: { theme in
|
||||
return filter.contains(.hidden) ? generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Check"), color: theme.contextMenu.primaryColor) : nil
|
||||
}, action: { _, f in
|
||||
toggleFilter(.hidden)
|
||||
}, longPressAction: { _, f in
|
||||
switchToFilter(.hidden)
|
||||
})))
|
||||
}
|
||||
|
||||
|
@ -835,6 +835,7 @@ public final class PeerListItemComponent: Component {
|
||||
let avatarFrame = CGRect(origin: CGPoint(x: avatarLeftInset, y: floorToScreenPixels((height - verticalInset * 2.0 - avatarSize) / 2.0)), size: CGSize(width: avatarSize, height: avatarSize))
|
||||
|
||||
var statusIcon: EmojiStatusComponent.Content?
|
||||
var particleColor: UIColor?
|
||||
if let peer = component.peer {
|
||||
if peer.isScam {
|
||||
statusIcon = .text(color: component.theme.chat.message.incoming.scamColor, string: component.strings.Message_ScamAccount.uppercased())
|
||||
@ -842,6 +843,9 @@ public final class PeerListItemComponent: Component {
|
||||
statusIcon = .text(color: component.theme.chat.message.incoming.scamColor, string: component.strings.Message_FakeAccount.uppercased())
|
||||
} else if let emojiStatus = peer.emojiStatus {
|
||||
statusIcon = .animation(content: .customEmoji(fileId: emojiStatus.fileId), size: CGSize(width: 20.0, height: 20.0), placeholderColor: component.theme.list.mediaPlaceholderColor, themeColor: component.theme.list.itemAccentColor, loopMode: .count(2))
|
||||
if let color = emojiStatus.color {
|
||||
particleColor = UIColor(rgb: UInt32(bitPattern: color))
|
||||
}
|
||||
} else if peer.isVerified {
|
||||
statusIcon = .verified(fillColor: component.theme.list.itemCheckColors.fillColor, foregroundColor: component.theme.list.itemCheckColors.foregroundColor, sizeType: .compact)
|
||||
} else if peer.isPremium {
|
||||
@ -1086,6 +1090,7 @@ public final class PeerListItemComponent: Component {
|
||||
animationCache: animationCache,
|
||||
animationRenderer: animationRenderer,
|
||||
content: statusIcon,
|
||||
particleColor: particleColor,
|
||||
isVisibleForAnimations: true,
|
||||
action: nil,
|
||||
emojiFileUpdated: nil
|
||||
|
File diff suppressed because one or more lines are too long
@ -4333,6 +4333,7 @@ extension ChatControllerImpl {
|
||||
guard let self, let peerId = self.chatLocation.peerId else {
|
||||
return
|
||||
}
|
||||
|
||||
if peerId.namespace == Namespaces.Peer.CloudUser {
|
||||
self.presentAttachmentMenu(subject: .gift)
|
||||
Queue.mainQueue().after(0.5) {
|
||||
|
@ -4585,6 +4585,11 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
let controller = self.context.sharedContext.makeGiftOptionsController(context: context, peerId: peerId, premiumOptions: premiumOptions, hasBirthday: hasBirthday, completion: nil)
|
||||
self.push(controller)
|
||||
})
|
||||
}, openUniqueGift: { [weak self] slug in
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
self.openUrl("https://t.me/nft/\(slug)", concealed: false)
|
||||
}, requestMessageUpdate: { [weak self] id, scroll in
|
||||
if let self {
|
||||
self.chatDisplayNode.historyNode.requestMessageUpdate(id, andScrollToItem: scroll)
|
||||
|
@ -181,6 +181,7 @@ final class OverlayAudioPlayerControllerNode: ViewControllerTracingNode, ASGestu
|
||||
}, playMessageEffect: { _ in
|
||||
}, editMessageFactCheck: { _ in
|
||||
}, sendGift: { _ in
|
||||
}, openUniqueGift: { _ in
|
||||
}, requestMessageUpdate: { _, _ in
|
||||
}, cancelInteractiveKeyboardGestures: {
|
||||
}, dismissTextInput: {
|
||||
|
@ -1937,6 +1937,7 @@ public final class SharedAccountContextImpl: SharedAccountContext {
|
||||
}, playMessageEffect: { _ in
|
||||
}, editMessageFactCheck: { _ in
|
||||
}, sendGift: { _ in
|
||||
}, openUniqueGift: { _ in
|
||||
}, requestMessageUpdate: { _, _ in
|
||||
}, cancelInteractiveKeyboardGestures: {
|
||||
}, dismissTextInput: {
|
||||
@ -3256,15 +3257,18 @@ private func peerInfoControllerImpl(context: AccountContext, updatedPresentation
|
||||
} else if let _ = peer as? TelegramChannel {
|
||||
var forumTopicThread: ChatReplyThreadMessage?
|
||||
var switchToRecommendedChannels = false
|
||||
var switchToGifts = false
|
||||
switch mode {
|
||||
case let .forumTopic(thread):
|
||||
forumTopicThread = thread
|
||||
case .recommendedChannels:
|
||||
switchToRecommendedChannels = true
|
||||
case .gifts:
|
||||
switchToGifts = true
|
||||
default:
|
||||
break
|
||||
}
|
||||
return PeerInfoScreenImpl(context: context, updatedPresentationData: updatedPresentationData, peerId: peer.id, avatarInitiallyExpanded: avatarInitiallyExpanded, isOpenedFromChat: isOpenedFromChat, nearbyPeerDistance: nil, reactionSourceMessageId: nil, callMessages: [], forumTopicThread: forumTopicThread, switchToRecommendedChannels: switchToRecommendedChannels)
|
||||
return PeerInfoScreenImpl(context: context, updatedPresentationData: updatedPresentationData, peerId: peer.id, avatarInitiallyExpanded: avatarInitiallyExpanded, isOpenedFromChat: isOpenedFromChat, nearbyPeerDistance: nil, reactionSourceMessageId: nil, callMessages: [], forumTopicThread: forumTopicThread, switchToRecommendedChannels: switchToRecommendedChannels, switchToGifts: switchToGifts)
|
||||
} else if peer is TelegramUser {
|
||||
var nearbyPeerDistance: Int32?
|
||||
var reactionSourceMessageId: MessageId?
|
||||
|
Loading…
x
Reference in New Issue
Block a user