mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-15 21:45:19 +00:00
Various improvements
This commit is contained in:
parent
26ff9da7d1
commit
5451053195
@ -13447,3 +13447,77 @@ Sorry for the inconvenience.";
|
|||||||
"StarsTransaction.StarRefReason.Referred" = "Referred User";
|
"StarsTransaction.StarRefReason.Referred" = "Referred User";
|
||||||
|
|
||||||
"Gallery.SaveToGallery.cached" = "cached";
|
"Gallery.SaveToGallery.cached" = "cached";
|
||||||
|
|
||||||
|
"ChatList.Search.Messages.AllChats" = "From All Chats";
|
||||||
|
"ChatList.Search.Messages.PrivateChats" = "From Private Chats";
|
||||||
|
"ChatList.Search.Messages.GroupChats" = "From Group Chats";
|
||||||
|
"ChatList.Search.Messages.Channels" = "From Channels";
|
||||||
|
|
||||||
|
"ChatList.Search.Messages.Menu.AllChats" = "All Chats";
|
||||||
|
"ChatList.Search.Messages.Menu.PrivateChats" = "Private Chats";
|
||||||
|
"ChatList.Search.Messages.Menu.GroupChats" = "Group Chats";
|
||||||
|
"ChatList.Search.Messages.Menu.Channels" = "Channels";
|
||||||
|
|
||||||
|
"MediaEditor.Timeline" = "Timeline";
|
||||||
|
|
||||||
|
"Conversation.ContextMenuSendGiftTo" = "Send Gift to %@";
|
||||||
|
"Conversation.ContextMenuSendAnotherGift" = "Send Another Gift";
|
||||||
|
|
||||||
|
"Gift.View.Status" = "Status";
|
||||||
|
"Gift.View.Status.NonUnique" = "Non-Unique";
|
||||||
|
"Gift.View.Status.Upgrade" = "upgrade";
|
||||||
|
"Gift.View.DisplayedInfoHide" = "The gift is visible on your Page. [Hide >]()";
|
||||||
|
|
||||||
|
"Gift.Upgrade.Title" = "Upgrade Gift";
|
||||||
|
"Gift.Upgrade.Description" = "Turn your gift into a unique collectible that you can transfer or auction.";
|
||||||
|
"Gift.Upgrade.Unique.Title" = "Unique";
|
||||||
|
"Gift.Upgrade.Unique.Description" = "Get a unique number, model backdrop and and symbol for your gift.";
|
||||||
|
"Gift.Upgrade.Transferable.Title" = "Transferable";
|
||||||
|
"Gift.Upgrade.Transferable.Description" = "Send your upgraded gift to any of your friends on Telegram.";
|
||||||
|
"Gift.Upgrade.Tradable.Title" = "Tradable";
|
||||||
|
"Gift.Upgrade.Tradable.Description" = "Sell or auction your gift on third-party NFT marketplaces.";
|
||||||
|
"Gift.Upgrade.Soon" = "SOON";
|
||||||
|
"Gift.Upgrade.AddName" = "Add sender's name";
|
||||||
|
"Gift.Upgrade.AddNameAndComment" = "Add sender's name and comment";
|
||||||
|
"Gift.Upgrade.Upgrade" = "Upgrade";
|
||||||
|
|
||||||
|
"Gift.Upgrade.Succeed.Title" = "The gift is now collectible";
|
||||||
|
"Gift.Upgrade.Succeed.Text" = "You have received a unique number, model, backdrop and symbol for your gift.";
|
||||||
|
|
||||||
|
"Gift.Unique.Collectible" = "Collectible";
|
||||||
|
"Gift.Unique.Owner" = "Owner";
|
||||||
|
"Gift.Unique.Transfer" = "transfer";
|
||||||
|
"Gift.Unique.Model" = "Model";
|
||||||
|
"Gift.Unique.Backdrop" = "Backdrop";
|
||||||
|
"Gift.Unique.Symbol" = "Symbol";
|
||||||
|
"Gift.Unique.Availability" = "Availability";
|
||||||
|
"Gift.Unique.Issued" = "%@ issued";
|
||||||
|
|
||||||
|
"Gift.Unique.AttributeDescription" = "Only %@ of such collectibles have this attribute.";
|
||||||
|
|
||||||
|
"Gift.Transfer.Title" = "Transfer";
|
||||||
|
"Gift.Transfer.SendViaBlockchain" = "Send via Blockchain";
|
||||||
|
"Gift.Transfer.SendUnlocks" = "unlocks in %@";
|
||||||
|
"Gift.Transfer.SendUnlocks.Days_1" = "%@ day";
|
||||||
|
"Gift.Transfer.SendUnlocks.Days_any" = "%@ days";
|
||||||
|
|
||||||
|
"Gift.Transfer.UnlockPending.Title" = "Unlocking In Progress";
|
||||||
|
"Gift.Transfer.UnlockPending.Text" = "In %@, you'll be able to send this collectible to any TON blockchain address outside Telegram for sale or auction.";
|
||||||
|
"Gift.Transfer.UnlockPending.Text.Days_1" = "%@ day";
|
||||||
|
"Gift.Transfer.UnlockPending.Text.Days_any" = "%@ days";
|
||||||
|
|
||||||
|
"Gift.Transfer.UpdateRequired.Title" = "Update Required";
|
||||||
|
"Gift.Transfer.UpdateRequired.Text" = "Please update your Telegram application to the latest version.";
|
||||||
|
|
||||||
|
"Gift.View.KeepUpgradeOrConvertDescription" = "You can keep this gift, upgrade it, or sell it for %@. [More About Stars >]()";
|
||||||
|
|
||||||
|
|
||||||
|
"PeerInfo.VerificationInfo.Custom.User" = "This user is verified by %@.";
|
||||||
|
"PeerInfo.VerificationInfo.Custom.Bot" = "This bot is verified by %@.";
|
||||||
|
"PeerInfo.VerificationInfo.Custom.Channel" = "This channel is verified by %@.";
|
||||||
|
"PeerInfo.VerificationInfo.Custom.Group" = "This group is verified by %@.";
|
||||||
|
|
||||||
|
"PeerInfo.VerificationInfo.Bot" = "This bot is verified as official by the representatives of Telegram.";
|
||||||
|
"PeerInfo.VerificationInfo.Channel" = "This channel is verified as official by the representatives of Telegram.";
|
||||||
|
"PeerInfo.VerificationInfo.Group" = "This group is verified as official by the representatives of Telegram.";
|
||||||
|
"PeerInfo.VerificationInfo.URL" = "https://telegram.org/verify";
|
||||||
|
@ -1050,12 +1050,12 @@ public protocol SharedAccountContext: AnyObject {
|
|||||||
func makePremiumLimitController(context: AccountContext, subject: PremiumLimitSubject, count: Int32, forceDark: Bool, cancel: @escaping () -> Void, action: @escaping () -> Bool) -> ViewController
|
func makePremiumLimitController(context: AccountContext, subject: PremiumLimitSubject, count: Int32, forceDark: Bool, cancel: @escaping () -> Void, action: @escaping () -> Bool) -> ViewController
|
||||||
|
|
||||||
func makeStarsGiftController(context: AccountContext, birthdays: [EnginePeer.Id: TelegramBirthday]?, completion: @escaping (([EnginePeer.Id]) -> Void)) -> ViewController
|
func makeStarsGiftController(context: AccountContext, birthdays: [EnginePeer.Id: TelegramBirthday]?, completion: @escaping (([EnginePeer.Id]) -> Void)) -> ViewController
|
||||||
func makePremiumGiftController(context: AccountContext, source: PremiumGiftSource, completion: (([EnginePeer.Id]) -> Void)?) -> ViewController
|
func makePremiumGiftController(context: AccountContext, source: PremiumGiftSource, transfer: Bool, completion: (([EnginePeer.Id]) -> Void)?) -> ViewController
|
||||||
func makeGiftOptionsController(context: AccountContext, peerId: EnginePeer.Id, premiumOptions: [CachedPremiumGiftOption], hasBirthday: Bool) -> ViewController
|
func makeGiftOptionsController(context: AccountContext, peerId: EnginePeer.Id, premiumOptions: [CachedPremiumGiftOption], hasBirthday: Bool) -> ViewController
|
||||||
func makePremiumPrivacyControllerController(context: AccountContext, subject: PremiumPrivacySubject, peerId: EnginePeer.Id) -> ViewController
|
func makePremiumPrivacyControllerController(context: AccountContext, subject: PremiumPrivacySubject, peerId: EnginePeer.Id) -> ViewController
|
||||||
func makePremiumBoostLevelsController(context: AccountContext, peerId: EnginePeer.Id, subject: BoostSubject, boostStatus: ChannelBoostStatus, myBoostStatus: MyBoostStatus, forceDark: Bool, openStats: (() -> Void)?) -> ViewController
|
func makePremiumBoostLevelsController(context: AccountContext, peerId: EnginePeer.Id, subject: BoostSubject, boostStatus: ChannelBoostStatus, myBoostStatus: MyBoostStatus, forceDark: Bool, openStats: (() -> Void)?) -> ViewController
|
||||||
|
|
||||||
func makeStickerPackScreen(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)?, mainStickerPack: StickerPackReference, stickerPacks: [StickerPackReference], loadedStickerPacks: [LoadedStickerPack], isEditing: Bool, expandIfNeeded: Bool, parentNavigationController: NavigationController?, sendSticker: ((FileMediaReference, UIView, CGRect) -> Bool)?, actionPerformed: ((Bool) -> Void)?) -> ViewController
|
func makeStickerPackScreen(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)?, mainStickerPack: StickerPackReference, stickerPacks: [StickerPackReference], loadedStickerPacks: [LoadedStickerPack], actionTitle: String?, isEditing: Bool, expandIfNeeded: Bool, parentNavigationController: NavigationController?, sendSticker: ((FileMediaReference, UIView, CGRect) -> Bool)?, actionPerformed: ((Bool) -> Void)?) -> ViewController
|
||||||
|
|
||||||
func makeMediaPickerScreen(context: AccountContext, hasSearch: Bool, completion: @escaping (Any) -> Void) -> ViewController
|
func makeMediaPickerScreen(context: AccountContext, hasSearch: Bool, completion: @escaping (Any) -> Void) -> ViewController
|
||||||
|
|
||||||
@ -1066,7 +1066,10 @@ public protocol SharedAccountContext: AnyObject {
|
|||||||
func makeStickerEditorScreen(context: AccountContext, source: Any?, intro: Bool, transitionArguments: (UIView, CGRect, UIImage?)?, completion: @escaping (TelegramMediaFile, [String], @escaping () -> Void) -> Void, cancelled: @escaping () -> Void) -> ViewController
|
func makeStickerEditorScreen(context: AccountContext, source: Any?, intro: Bool, transitionArguments: (UIView, CGRect, UIImage?)?, completion: @escaping (TelegramMediaFile, [String], @escaping () -> Void) -> Void, cancelled: @escaping () -> Void) -> ViewController
|
||||||
|
|
||||||
func makeStickerMediaPickerScreen(context: AccountContext, getSourceRect: @escaping () -> CGRect?, completion: @escaping (Any?, UIView?, CGRect, UIImage?, Bool, @escaping (Bool?) -> (UIView, CGRect)?, @escaping () -> Void) -> Void, dismissed: @escaping () -> Void) -> ViewController
|
func makeStickerMediaPickerScreen(context: AccountContext, getSourceRect: @escaping () -> CGRect?, completion: @escaping (Any?, UIView?, CGRect, UIImage?, Bool, @escaping (Bool?) -> (UIView, CGRect)?, @escaping () -> Void) -> Void, dismissed: @escaping () -> Void) -> ViewController
|
||||||
func makeStoryMediaPickerScreen(context: AccountContext, isDark: Bool, forCollage: Bool, getSourceRect: @escaping () -> CGRect, completion: @escaping (Any, UIView, CGRect, UIImage?, @escaping (Bool?) -> (UIView, CGRect)?, @escaping () -> Void) -> Void, dismissed: @escaping () -> Void, groupsPresented: @escaping () -> Void) -> ViewController
|
|
||||||
|
func makeAvatarMediaPickerScreen(context: AccountContext, getSourceRect: @escaping () -> CGRect?, canDelete: Bool, performDelete: @escaping () -> Void, completion: @escaping (Any?, UIView?, CGRect, UIImage?, Bool, @escaping (Bool?) -> (UIView, CGRect)?, @escaping () -> Void) -> Void, dismissed: @escaping () -> Void) -> ViewController
|
||||||
|
|
||||||
|
func makeStoryMediaPickerScreen(context: AccountContext, isDark: Bool, forCollage: Bool, selectionLimit: Int?, getSourceRect: @escaping () -> CGRect, completion: @escaping (Any, UIView, CGRect, UIImage?, @escaping (Bool?) -> (UIView, CGRect)?, @escaping () -> Void) -> Void, multipleCompletion: @escaping ([Any]) -> Void, dismissed: @escaping () -> Void, groupsPresented: @escaping () -> Void) -> ViewController
|
||||||
|
|
||||||
func makeStickerPickerScreen(context: AccountContext, inputData: Promise<StickerPickerInput>, completion: @escaping (FileMediaReference) -> Void) -> ViewController
|
func makeStickerPickerScreen(context: AccountContext, inputData: Promise<StickerPickerInput>, completion: @escaping (FileMediaReference) -> Void) -> ViewController
|
||||||
|
|
||||||
@ -1108,6 +1111,8 @@ public protocol SharedAccountContext: AnyObject {
|
|||||||
|
|
||||||
func makeAffiliateProgramJoinScreen(context: AccountContext, sourcePeer: EnginePeer, commissionPermille: Int32, programDuration: Int32?, revenuePerUser: Double, mode: JoinAffiliateProgramScreenMode) -> ViewController
|
func makeAffiliateProgramJoinScreen(context: AccountContext, sourcePeer: EnginePeer, commissionPermille: Int32, programDuration: Int32?, revenuePerUser: Double, mode: JoinAffiliateProgramScreenMode) -> ViewController
|
||||||
|
|
||||||
|
func makeGalleryController(context: AccountContext, source: GalleryControllerItemSource, streamSingleVideo: Bool, isPreview: Bool) -> ViewController
|
||||||
|
|
||||||
func makeDebugSettingsController(context: AccountContext?) -> ViewController?
|
func makeDebugSettingsController(context: AccountContext?) -> ViewController?
|
||||||
|
|
||||||
func navigateToCurrentCall()
|
func navigateToCurrentCall()
|
||||||
|
@ -21,19 +21,21 @@ public enum ContactSelectionControllerMode {
|
|||||||
|
|
||||||
public struct ContactListAdditionalOption: Equatable {
|
public struct ContactListAdditionalOption: Equatable {
|
||||||
public let title: String
|
public let title: String
|
||||||
|
public let subtitle: String?
|
||||||
public let icon: ContactListActionItemIcon
|
public let icon: ContactListActionItemIcon
|
||||||
public let action: () -> Void
|
public let action: () -> Void
|
||||||
public let clearHighlightAutomatically: Bool
|
public let clearHighlightAutomatically: Bool
|
||||||
|
|
||||||
public init(title: String, icon: ContactListActionItemIcon, action: @escaping () -> Void, clearHighlightAutomatically: Bool = false) {
|
public init(title: String, subtitle: String? = nil, icon: ContactListActionItemIcon, action: @escaping () -> Void, clearHighlightAutomatically: Bool = false) {
|
||||||
self.title = title
|
self.title = title
|
||||||
|
self.subtitle = subtitle
|
||||||
self.icon = icon
|
self.icon = icon
|
||||||
self.action = action
|
self.action = action
|
||||||
self.clearHighlightAutomatically = clearHighlightAutomatically
|
self.clearHighlightAutomatically = clearHighlightAutomatically
|
||||||
}
|
}
|
||||||
|
|
||||||
public static func ==(lhs: ContactListAdditionalOption, rhs: ContactListAdditionalOption) -> Bool {
|
public static func ==(lhs: ContactListAdditionalOption, rhs: ContactListAdditionalOption) -> Bool {
|
||||||
return lhs.title == rhs.title && lhs.icon == rhs.icon
|
return lhs.title == rhs.title && lhs.subtitle == rhs.subtitle && lhs.icon == rhs.icon
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
import UIKit
|
import UIKit
|
||||||
|
import Display
|
||||||
import Postbox
|
import Postbox
|
||||||
import SwiftSignalKit
|
import SwiftSignalKit
|
||||||
import TelegramCore
|
import TelegramCore
|
||||||
@ -50,6 +51,10 @@ public final class GalleryControllerActionInteraction {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public protocol GalleryControllerProtocol: ViewController {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
public protocol StickerPackScreen {
|
public protocol StickerPackScreen {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -85,7 +85,7 @@ public class AnimatedCountLabelNode: ASDisplayNode {
|
|||||||
super.init()
|
super.init()
|
||||||
}
|
}
|
||||||
|
|
||||||
public func asyncLayout() -> (CGSize, [Segment]) -> (Layout, (Bool) -> Void) {
|
public func asyncLayout() -> (CGSize, UIEdgeInsets, [Segment]) -> (Layout, (Bool) -> Void) {
|
||||||
var segmentLayouts: [ResolvedSegment.Key: (TextNodeLayoutArguments) -> (TextNodeLayout, () -> TextNode)] = [:]
|
var segmentLayouts: [ResolvedSegment.Key: (TextNodeLayoutArguments) -> (TextNodeLayout, () -> TextNode)] = [:]
|
||||||
let wasEmpty = self.resolvedSegments.isEmpty
|
let wasEmpty = self.resolvedSegments.isEmpty
|
||||||
for (segmentKey, segmentAndTextNode) in self.resolvedSegments {
|
for (segmentKey, segmentAndTextNode) in self.resolvedSegments {
|
||||||
@ -94,7 +94,7 @@ public class AnimatedCountLabelNode: ASDisplayNode {
|
|||||||
let reverseAnimationDirection = self.reverseAnimationDirection
|
let reverseAnimationDirection = self.reverseAnimationDirection
|
||||||
let alwaysOneDirection = self.alwaysOneDirection
|
let alwaysOneDirection = self.alwaysOneDirection
|
||||||
|
|
||||||
return { [weak self] size, initialSegments in
|
return { [weak self] size, insets, initialSegments in
|
||||||
var segments: [ResolvedSegment] = []
|
var segments: [ResolvedSegment] = []
|
||||||
loop: for segment in initialSegments {
|
loop: for segment in initialSegments {
|
||||||
switch segment {
|
switch segment {
|
||||||
@ -165,7 +165,7 @@ public class AnimatedCountLabelNode: ASDisplayNode {
|
|||||||
transition = .immediate
|
transition = .immediate
|
||||||
}
|
}
|
||||||
|
|
||||||
var currentOffset = CGPoint()
|
var currentOffset = CGPoint(x: insets.left, y: 0.0)
|
||||||
for segment in segments {
|
for segment in segments {
|
||||||
var animation: (CGFloat, Double)?
|
var animation: (CGFloat, Double)?
|
||||||
if let (currentSegment, currentTextNode) = strongSelf.resolvedSegments[segment.key] {
|
if let (currentSegment, currentTextNode) = strongSelf.resolvedSegments[segment.key] {
|
||||||
@ -254,12 +254,14 @@ public final class ImmediateAnimatedCountLabelNode: AnimatedCountLabelNode {
|
|||||||
public var segments: [AnimatedCountLabelNode.Segment] = []
|
public var segments: [AnimatedCountLabelNode.Segment] = []
|
||||||
|
|
||||||
private var constrainedSize: CGSize?
|
private var constrainedSize: CGSize?
|
||||||
|
private var insets: UIEdgeInsets?
|
||||||
|
|
||||||
public func updateLayout(size: CGSize, animated: Bool) -> CGSize {
|
public func updateLayout(size: CGSize, insets: UIEdgeInsets = .zero, animated: Bool) -> CGSize {
|
||||||
self.constrainedSize = size
|
self.constrainedSize = size
|
||||||
|
self.insets = insets
|
||||||
|
|
||||||
let makeLayout = self.asyncLayout()
|
let makeLayout = self.asyncLayout()
|
||||||
let (layout, apply) = makeLayout(size, self.segments)
|
let (layout, apply) = makeLayout(size, insets, self.segments)
|
||||||
let _ = apply(animated)
|
let _ = apply(animated)
|
||||||
return layout.size
|
return layout.size
|
||||||
}
|
}
|
||||||
@ -282,8 +284,8 @@ public final class ImmediateAnimatedCountLabelNode: AnimatedCountLabelNode {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if let constrainedSize = self.constrainedSize {
|
if let constrainedSize = self.constrainedSize, let insets = self.insets {
|
||||||
let _ = node.updateLayout(size: constrainedSize, animated: false)
|
let _ = node.updateLayout(size: constrainedSize, insets: insets, animated: false)
|
||||||
}
|
}
|
||||||
return node
|
return node
|
||||||
}
|
}
|
||||||
|
@ -1208,7 +1208,18 @@ public class AttachmentController: ViewController, MinimizableController {
|
|||||||
|
|
||||||
public var shouldMinimizeOnSwipe: ((AttachmentButtonType?) -> Bool)?
|
public var shouldMinimizeOnSwipe: ((AttachmentButtonType?) -> Bool)?
|
||||||
|
|
||||||
public init(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)? = nil, chatLocation: ChatLocation?, isScheduledMessages: Bool = false, buttons: [AttachmentButtonType], initialButton: AttachmentButtonType = .gallery, fromMenu: Bool = false, hasTextInput: Bool = true, isFullSize: Bool = false, makeEntityInputView: @escaping () -> AttachmentTextInputPanelInputView? = { return nil}) {
|
public init(
|
||||||
|
context: AccountContext,
|
||||||
|
updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)? = nil,
|
||||||
|
chatLocation: ChatLocation?,
|
||||||
|
isScheduledMessages: Bool = false,
|
||||||
|
buttons: [AttachmentButtonType],
|
||||||
|
initialButton: AttachmentButtonType = .gallery,
|
||||||
|
fromMenu: Bool = false,
|
||||||
|
hasTextInput: Bool = true,
|
||||||
|
isFullSize: Bool = false,
|
||||||
|
makeEntityInputView: @escaping () -> AttachmentTextInputPanelInputView? = { return nil })
|
||||||
|
{
|
||||||
self.context = context
|
self.context = context
|
||||||
self.updatedPresentationData = updatedPresentationData
|
self.updatedPresentationData = updatedPresentationData
|
||||||
self.chatLocation = chatLocation
|
self.chatLocation = chatLocation
|
||||||
|
@ -64,6 +64,20 @@ public struct CameraCode: Equatable {
|
|||||||
return CGRect.null
|
return CGRect.null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public var rotation: CGFloat {
|
||||||
|
guard self.corners.count == 4 else {
|
||||||
|
return 0.0
|
||||||
|
}
|
||||||
|
|
||||||
|
let topLeft = self.corners[1]
|
||||||
|
let topRight = self.corners[2]
|
||||||
|
|
||||||
|
let dx = topRight.x - topLeft.x
|
||||||
|
let dy = topRight.y - topLeft.y
|
||||||
|
|
||||||
|
return atan2(dy, dx) - .pi / 2.0
|
||||||
|
}
|
||||||
|
|
||||||
public static func == (lhs: CameraCode, rhs: CameraCode) -> Bool {
|
public static func == (lhs: CameraCode, rhs: CameraCode) -> Bool {
|
||||||
if lhs.type != rhs.type {
|
if lhs.type != rhs.type {
|
||||||
return false
|
return false
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
import UIKit
|
import UIKit
|
||||||
|
import AsyncDisplayKit
|
||||||
import Display
|
import Display
|
||||||
import TelegramPresentationData
|
import TelegramPresentationData
|
||||||
import ListSectionHeaderNode
|
import ListSectionHeaderNode
|
||||||
@ -209,11 +210,11 @@ public final class ChatListSearchItemHeader: ListViewItemHeader {
|
|||||||
public let theme: PresentationTheme
|
public let theme: PresentationTheme
|
||||||
public let strings: PresentationStrings
|
public let strings: PresentationStrings
|
||||||
public let actionTitle: String?
|
public let actionTitle: String?
|
||||||
public let action: (() -> Void)?
|
public let action: ((ASDisplayNode) -> Void)?
|
||||||
|
|
||||||
public let height: CGFloat = 28.0
|
public let height: CGFloat = 28.0
|
||||||
|
|
||||||
public init(type: ChatListSearchItemHeaderType, theme: PresentationTheme, strings: PresentationStrings, actionTitle: String? = nil, action: (() -> Void)? = nil) {
|
public init(type: ChatListSearchItemHeaderType, theme: PresentationTheme, strings: PresentationStrings, actionTitle: String? = nil, action: ((ASDisplayNode) -> Void)? = nil) {
|
||||||
self.type = type
|
self.type = type
|
||||||
self.id = ListViewItemNode.HeaderId(space: 0, id: Int64(self.type.id.hashValue))
|
self.id = ListViewItemNode.HeaderId(space: 0, id: Int64(self.type.id.hashValue))
|
||||||
self.theme = theme
|
self.theme = theme
|
||||||
@ -244,13 +245,13 @@ public final class ChatListSearchItemHeaderNode: ListViewItemHeaderNode {
|
|||||||
private var theme: PresentationTheme
|
private var theme: PresentationTheme
|
||||||
private var strings: PresentationStrings
|
private var strings: PresentationStrings
|
||||||
private var actionTitle: String?
|
private var actionTitle: String?
|
||||||
private var action: (() -> Void)?
|
private var action: ((ASDisplayNode) -> Void)?
|
||||||
|
|
||||||
private var validLayout: (size: CGSize, leftInset: CGFloat, rightInset: CGFloat)?
|
private var validLayout: (size: CGSize, leftInset: CGFloat, rightInset: CGFloat)?
|
||||||
|
|
||||||
private let sectionHeaderNode: ListSectionHeaderNode
|
private let sectionHeaderNode: ListSectionHeaderNode
|
||||||
|
|
||||||
public init(type: ChatListSearchItemHeaderType, theme: PresentationTheme, strings: PresentationStrings, actionTitle: String?, action: (() -> Void)?) {
|
public init(type: ChatListSearchItemHeaderType, theme: PresentationTheme, strings: PresentationStrings, actionTitle: String?, action: ((ASDisplayNode) -> Void)?) {
|
||||||
self.type = type
|
self.type = type
|
||||||
self.theme = theme
|
self.theme = theme
|
||||||
self.strings = strings
|
self.strings = strings
|
||||||
@ -273,7 +274,7 @@ public final class ChatListSearchItemHeaderNode: ListViewItemHeaderNode {
|
|||||||
self.sectionHeaderNode.updateTheme(theme: theme)
|
self.sectionHeaderNode.updateTheme(theme: theme)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func update(type: ChatListSearchItemHeaderType, actionTitle: String?, action: (() -> Void)?) {
|
public func update(type: ChatListSearchItemHeaderType, actionTitle: String?, action: ((ASDisplayNode) -> Void)?) {
|
||||||
self.actionTitle = actionTitle
|
self.actionTitle = actionTitle
|
||||||
self.action = action
|
self.action = action
|
||||||
|
|
||||||
|
@ -109,6 +109,7 @@ swift_library(
|
|||||||
"//submodules/TelegramUI/Components/ChatEntityKeyboardInputNode",
|
"//submodules/TelegramUI/Components/ChatEntityKeyboardInputNode",
|
||||||
"//submodules/ComposePollUI",
|
"//submodules/ComposePollUI",
|
||||||
"//submodules/ChatPresentationInterfaceState",
|
"//submodules/ChatPresentationInterfaceState",
|
||||||
|
"//submodules/ShimmerEffect:ShimmerEffect",
|
||||||
],
|
],
|
||||||
visibility = [
|
visibility = [
|
||||||
"//visibility:public",
|
"//visibility:public",
|
||||||
|
@ -1395,6 +1395,8 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
|||||||
}
|
}
|
||||||
|
|
||||||
switch item.content {
|
switch item.content {
|
||||||
|
case .loading:
|
||||||
|
break
|
||||||
case let .groupReference(groupReference):
|
case let .groupReference(groupReference):
|
||||||
let chatListController = ChatListControllerImpl(context: strongSelf.context, location: .chatList(groupId: groupReference.groupId), controlsHistoryPreload: false, hideNetworkActivityStatus: true, previewing: true, enableDebugActions: false)
|
let chatListController = ChatListControllerImpl(context: strongSelf.context, location: .chatList(groupId: groupReference.groupId), controlsHistoryPreload: false, hideNetworkActivityStatus: true, previewing: true, enableDebugActions: false)
|
||||||
chatListController.navigationPresentation = .master
|
chatListController.navigationPresentation = .master
|
||||||
|
@ -261,7 +261,7 @@ private enum ChatListRecentEntry: Comparable, Identifiable {
|
|||||||
header = ChatListSearchItemHeader(type: .text(presentationData.strings.ChatList_Search_SectionRecommendedChannels, 1), theme: theme, strings: strings)
|
header = ChatListSearchItemHeader(type: .text(presentationData.strings.ChatList_Search_SectionRecommendedChannels, 1), theme: theme, strings: strings)
|
||||||
} else {
|
} else {
|
||||||
if let isChannelsTabExpanded {
|
if let isChannelsTabExpanded {
|
||||||
header = ChatListSearchItemHeader(type: .text(presentationData.strings.ChatList_Search_SectionLocalChannels, 0), theme: theme, strings: strings, actionTitle: isChannelsTabExpanded ? presentationData.strings.ChatList_Search_SectionActionShowLess : presentationData.strings.ChatList_Search_SectionActionShowMore, action: {
|
header = ChatListSearchItemHeader(type: .text(presentationData.strings.ChatList_Search_SectionLocalChannels, 0), theme: theme, strings: strings, actionTitle: isChannelsTabExpanded ? presentationData.strings.ChatList_Search_SectionActionShowLess : presentationData.strings.ChatList_Search_SectionActionShowMore, action: { _ in
|
||||||
toggleChannelsTabExpanded()
|
toggleChannelsTabExpanded()
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
@ -273,7 +273,7 @@ private enum ChatListRecentEntry: Comparable, Identifiable {
|
|||||||
header = ChatListSearchItemHeader(type: .text(presentationData.strings.ChatList_Search_SectionPopularApps, 1), theme: theme, strings: strings)
|
header = ChatListSearchItemHeader(type: .text(presentationData.strings.ChatList_Search_SectionPopularApps, 1), theme: theme, strings: strings)
|
||||||
} else {
|
} else {
|
||||||
if let isChannelsTabExpanded {
|
if let isChannelsTabExpanded {
|
||||||
header = ChatListSearchItemHeader(type: .text(presentationData.strings.ChatList_Search_SectionRecentApps, 0), theme: theme, strings: strings, actionTitle: isChannelsTabExpanded ? presentationData.strings.ChatList_Search_SectionActionShowLess : presentationData.strings.ChatList_Search_SectionActionShowMore, action: {
|
header = ChatListSearchItemHeader(type: .text(presentationData.strings.ChatList_Search_SectionRecentApps, 0), theme: theme, strings: strings, actionTitle: isChannelsTabExpanded ? presentationData.strings.ChatList_Search_SectionActionShowLess : presentationData.strings.ChatList_Search_SectionActionShowMore, action: { _ in
|
||||||
toggleChannelsTabExpanded()
|
toggleChannelsTabExpanded()
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
@ -281,7 +281,7 @@ private enum ChatListRecentEntry: Comparable, Identifiable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
header = ChatListSearchItemHeader(type: .recentPeers, theme: theme, strings: strings, actionTitle: strings.WebSearch_RecentSectionClear, action: {
|
header = ChatListSearchItemHeader(type: .recentPeers, theme: theme, strings: strings, actionTitle: strings.WebSearch_RecentSectionClear, action: { _ in
|
||||||
clearRecentlySearchedPeers()
|
clearRecentlySearchedPeers()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -379,6 +379,7 @@ public enum ChatListSearchEntryStableId: Hashable {
|
|||||||
case localPeerId(EnginePeer.Id)
|
case localPeerId(EnginePeer.Id)
|
||||||
case globalPeerId(EnginePeer.Id)
|
case globalPeerId(EnginePeer.Id)
|
||||||
case messageId(EngineMessage.Id, ChatListSearchEntry.MessageSection)
|
case messageId(EngineMessage.Id, ChatListSearchEntry.MessageSection)
|
||||||
|
case messagePlaceholder(Int32)
|
||||||
case addContact
|
case addContact
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -439,7 +440,8 @@ public enum ChatListSearchEntry: Comparable, Identifiable {
|
|||||||
case recentlySearchedPeer(EnginePeer, EnginePeer?, (Int32, Bool)?, Int, PresentationTheme, PresentationStrings, PresentationPersonNameOrder, PresentationPersonNameOrder, PeerStoryStats?, Bool)
|
case recentlySearchedPeer(EnginePeer, EnginePeer?, (Int32, Bool)?, Int, PresentationTheme, PresentationStrings, PresentationPersonNameOrder, PresentationPersonNameOrder, PeerStoryStats?, Bool)
|
||||||
case localPeer(EnginePeer, EnginePeer?, (Int32, Bool)?, Int, PresentationTheme, PresentationStrings, PresentationPersonNameOrder, PresentationPersonNameOrder, ChatListSearchSectionExpandType, PeerStoryStats?, Bool)
|
case localPeer(EnginePeer, EnginePeer?, (Int32, Bool)?, Int, PresentationTheme, PresentationStrings, PresentationPersonNameOrder, PresentationPersonNameOrder, ChatListSearchSectionExpandType, PeerStoryStats?, Bool)
|
||||||
case globalPeer(FoundPeer, (Int32, Bool)?, Int, PresentationTheme, PresentationStrings, PresentationPersonNameOrder, PresentationPersonNameOrder, ChatListSearchSectionExpandType, PeerStoryStats?, Bool, String?)
|
case globalPeer(FoundPeer, (Int32, Bool)?, Int, PresentationTheme, PresentationStrings, PresentationPersonNameOrder, PresentationPersonNameOrder, ChatListSearchSectionExpandType, PeerStoryStats?, Bool, String?)
|
||||||
case message(EngineMessage, EngineRenderedPeer, EnginePeerReadCounters?, EngineMessageHistoryThread.Info?, ChatListPresentationData, Int32, Bool?, Bool, MessageOrderingKey, (id: String, size: Int64, isFirstInList: Bool)?, MessageSection, Bool, PeerStoryStats?, Bool)
|
case message(EngineMessage, EngineRenderedPeer, EnginePeerReadCounters?, EngineMessageHistoryThread.Info?, ChatListPresentationData, Int32, Bool?, Bool, MessageOrderingKey, (id: String, size: Int64, isFirstInList: Bool)?, MessageSection, Bool, PeerStoryStats?, Bool, TelegramSearchPeersScope)
|
||||||
|
case messagePlaceholder(Int32, ChatListPresentationData, TelegramSearchPeersScope)
|
||||||
case addContact(String, PresentationTheme, PresentationStrings)
|
case addContact(String, PresentationTheme, PresentationStrings)
|
||||||
|
|
||||||
public var stableId: ChatListSearchEntryStableId {
|
public var stableId: ChatListSearchEntryStableId {
|
||||||
@ -452,8 +454,10 @@ public enum ChatListSearchEntry: Comparable, Identifiable {
|
|||||||
return .localPeerId(peer.id)
|
return .localPeerId(peer.id)
|
||||||
case let .globalPeer(peer, _, _, _, _, _, _, _, _, _, _):
|
case let .globalPeer(peer, _, _, _, _, _, _, _, _, _, _):
|
||||||
return .globalPeerId(peer.peer.id)
|
return .globalPeerId(peer.peer.id)
|
||||||
case let .message(message, _, _, _, _, _, _, _, _, _, section, _, _, _):
|
case let .message(message, _, _, _, _, _, _, _, _, _, section, _, _, _, _):
|
||||||
return .messageId(message.id, section)
|
return .messageId(message.id, section)
|
||||||
|
case let .messagePlaceholder(index, _, _):
|
||||||
|
return .messagePlaceholder(index)
|
||||||
case .addContact:
|
case .addContact:
|
||||||
return .addContact
|
return .addContact
|
||||||
}
|
}
|
||||||
@ -485,8 +489,8 @@ public enum ChatListSearchEntry: Comparable, Identifiable {
|
|||||||
} else {
|
} else {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
case let .message(lhsMessage, lhsPeer, lhsCombinedPeerReadState, lhsThreadInfo, lhsPresentationData, lhsTotalCount, lhsSelected, lhsDisplayCustomHeader, lhsKey, lhsResourceId, lhsSection, lhsAllPaused, lhsStoryStats, lhsRequiresPremiumForMessaging):
|
case let .message(lhsMessage, lhsPeer, lhsCombinedPeerReadState, lhsThreadInfo, lhsPresentationData, lhsTotalCount, lhsSelected, lhsDisplayCustomHeader, lhsKey, lhsResourceId, lhsSection, lhsAllPaused, lhsStoryStats, lhsRequiresPremiumForMessaging, lhsSearchScope):
|
||||||
if case let .message(rhsMessage, rhsPeer, rhsCombinedPeerReadState, rhsThreadInfo, rhsPresentationData, rhsTotalCount, rhsSelected, rhsDisplayCustomHeader, rhsKey, rhsResourceId, rhsSection, rhsAllPaused, rhsStoryStats, rhsRequiresPremiumForMessaging) = rhs {
|
if case let .message(rhsMessage, rhsPeer, rhsCombinedPeerReadState, rhsThreadInfo, rhsPresentationData, rhsTotalCount, rhsSelected, rhsDisplayCustomHeader, rhsKey, rhsResourceId, rhsSection, rhsAllPaused, rhsStoryStats, rhsRequiresPremiumForMessaging, rhsSearchScope) = rhs {
|
||||||
if lhsMessage.id != rhsMessage.id {
|
if lhsMessage.id != rhsMessage.id {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@ -535,6 +539,24 @@ public enum ChatListSearchEntry: Comparable, Identifiable {
|
|||||||
if lhsRequiresPremiumForMessaging != rhsRequiresPremiumForMessaging {
|
if lhsRequiresPremiumForMessaging != rhsRequiresPremiumForMessaging {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
if lhsSearchScope != rhsSearchScope {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
case let .messagePlaceholder(lhsIndex, lhsPresentationData, lhsSearchScope):
|
||||||
|
if case let .messagePlaceholder(rhsIndex, rhsPresentationData, rhsSearchScope) = rhs {
|
||||||
|
if lhsIndex != rhsIndex {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if lhsPresentationData !== rhsPresentationData {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if lhsSearchScope != rhsSearchScope {
|
||||||
|
return false
|
||||||
|
}
|
||||||
return true
|
return true
|
||||||
} else {
|
} else {
|
||||||
return false
|
return false
|
||||||
@ -579,7 +601,7 @@ public enum ChatListSearchEntry: Comparable, Identifiable {
|
|||||||
return false
|
return false
|
||||||
case let .localPeer(_, _, _, rhsIndex, _, _, _, _, _, _, _):
|
case let .localPeer(_, _, _, rhsIndex, _, _, _, _, _, _, _):
|
||||||
return lhsIndex <= rhsIndex
|
return lhsIndex <= rhsIndex
|
||||||
case .globalPeer, .message, .addContact:
|
case .globalPeer, .message, .messagePlaceholder, .addContact:
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
case let .globalPeer(_, _, lhsIndex, _, _, _, _, _, _, _, _):
|
case let .globalPeer(_, _, lhsIndex, _, _, _, _, _, _, _, _):
|
||||||
@ -588,12 +610,22 @@ public enum ChatListSearchEntry: Comparable, Identifiable {
|
|||||||
return false
|
return false
|
||||||
case let .globalPeer(_, _, rhsIndex, _, _, _, _, _, _, _, _):
|
case let .globalPeer(_, _, rhsIndex, _, _, _, _, _, _, _, _):
|
||||||
return lhsIndex <= rhsIndex
|
return lhsIndex <= rhsIndex
|
||||||
case .message, .addContact:
|
case .message, .messagePlaceholder, .addContact:
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
case let .message(_, _, _, _, _, _, _, _, lhsKey, _, _, _, _, _):
|
case let .message(_, _, _, _, _, _, _, _, lhsKey, _, _, _, _, _, _):
|
||||||
if case let .message(_, _, _, _, _, _, _, _, rhsKey, _, _, _, _, _) = rhs {
|
if case let .message(_, _, _, _, _, _, _, _, rhsKey, _, _, _, _, _, _) = rhs {
|
||||||
return lhsKey < rhsKey
|
return lhsKey < rhsKey
|
||||||
|
} else if case .messagePlaceholder = rhs {
|
||||||
|
return true
|
||||||
|
} else if case .addContact = rhs {
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
case let .messagePlaceholder(lhsIndex, _, _):
|
||||||
|
if case let .messagePlaceholder(rhsIndex, _, _) = rhs {
|
||||||
|
return lhsIndex < rhsIndex
|
||||||
} else if case .addContact = rhs {
|
} else if case .addContact = rhs {
|
||||||
return true
|
return true
|
||||||
} else {
|
} else {
|
||||||
@ -604,7 +636,30 @@ public enum ChatListSearchEntry: Comparable, Identifiable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public func item(context: AccountContext, presentationData: PresentationData, enableHeaders: Bool, filter: ChatListNodePeersFilter, requestPeerType: [ReplyMarkupButtonRequestPeerType]?, location: ChatListControllerLocation, key: ChatListSearchPaneKey, tagMask: EngineMessage.Tags?, interaction: ChatListNodeInteraction, listInteraction: ListMessageItemInteraction, peerContextAction: ((EnginePeer, ChatListSearchContextActionSource, ASDisplayNode, ContextGesture?, CGPoint?) -> Void)?, toggleExpandLocalResults: @escaping () -> Void, toggleExpandGlobalResults: @escaping () -> Void, searchPeer: @escaping (EnginePeer) -> Void, searchQuery: String?, searchOptions: ChatListSearchOptions?, messageContextAction: ((EngineMessage, ASDisplayNode?, CGRect?, UIGestureRecognizer?, ChatListSearchPaneKey, (id: String, size: Int64, isFirstInList: Bool)?) -> Void)?, openClearRecentlyDownloaded: @escaping () -> Void, toggleAllPaused: @escaping () -> Void, openStories: @escaping (EnginePeer.Id, AvatarNode) -> Void, openPublicPosts: @escaping () -> Void) -> ListViewItem {
|
public func item(
|
||||||
|
context: AccountContext,
|
||||||
|
presentationData: PresentationData,
|
||||||
|
enableHeaders: Bool,
|
||||||
|
filter: ChatListNodePeersFilter,
|
||||||
|
requestPeerType: [ReplyMarkupButtonRequestPeerType]?,
|
||||||
|
location: ChatListControllerLocation,
|
||||||
|
key: ChatListSearchPaneKey,
|
||||||
|
tagMask: EngineMessage.Tags?,
|
||||||
|
interaction: ChatListNodeInteraction,
|
||||||
|
listInteraction: ListMessageItemInteraction,
|
||||||
|
peerContextAction: ((EnginePeer, ChatListSearchContextActionSource, ASDisplayNode, ContextGesture?, CGPoint?) -> Void)?,
|
||||||
|
toggleExpandLocalResults: @escaping () -> Void,
|
||||||
|
toggleExpandGlobalResults: @escaping () -> Void,
|
||||||
|
searchPeer: @escaping (EnginePeer) -> Void,
|
||||||
|
searchQuery: String?,
|
||||||
|
searchOptions: ChatListSearchOptions?,
|
||||||
|
messageContextAction: ((EngineMessage, ASDisplayNode?, CGRect?, UIGestureRecognizer?, ChatListSearchPaneKey, (id: String, size: Int64, isFirstInList: Bool)?) -> Void)?,
|
||||||
|
openClearRecentlyDownloaded: @escaping () -> Void,
|
||||||
|
toggleAllPaused: @escaping () -> Void,
|
||||||
|
openStories: @escaping (EnginePeer.Id, AvatarNode) -> Void,
|
||||||
|
openPublicPosts: @escaping () -> Void,
|
||||||
|
openMessagesFilter: @escaping (ASDisplayNode) -> Void
|
||||||
|
) -> ListViewItem {
|
||||||
switch self {
|
switch self {
|
||||||
case let .topic(peer, threadInfo, _, theme, strings, expandType):
|
case let .topic(peer, threadInfo, _, theme, strings, expandType):
|
||||||
let actionTitle: String?
|
let actionTitle: String?
|
||||||
@ -616,7 +671,7 @@ public enum ChatListSearchEntry: Comparable, Identifiable {
|
|||||||
case .collapse:
|
case .collapse:
|
||||||
actionTitle = strings.ChatList_Search_ShowLess
|
actionTitle = strings.ChatList_Search_ShowLess
|
||||||
}
|
}
|
||||||
let header = ChatListSearchItemHeader(type: .topics, theme: theme, strings: strings, actionTitle: actionTitle, action: actionTitle == nil ? nil : {
|
let header = ChatListSearchItemHeader(type: .topics, theme: theme, strings: strings, actionTitle: actionTitle, action: actionTitle == nil ? nil : { _ in
|
||||||
toggleExpandGlobalResults()
|
toggleExpandGlobalResults()
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -803,7 +858,7 @@ public enum ChatListSearchEntry: Comparable, Identifiable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
header = ChatListSearchItemHeader(type: headerType, theme: theme, strings: strings, actionTitle: actionTitle, action: actionTitle == nil ? nil : {
|
header = ChatListSearchItemHeader(type: headerType, theme: theme, strings: strings, actionTitle: actionTitle, action: actionTitle == nil ? nil : { _ in
|
||||||
toggleExpandLocalResults()
|
toggleExpandLocalResults()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -907,7 +962,7 @@ public enum ChatListSearchEntry: Comparable, Identifiable {
|
|||||||
case .collapse:
|
case .collapse:
|
||||||
actionTitle = strings.ChatList_Search_ShowLess
|
actionTitle = strings.ChatList_Search_ShowLess
|
||||||
}
|
}
|
||||||
header = ChatListSearchItemHeader(type: .globalPeers, theme: theme, strings: strings, actionTitle: actionTitle, action: actionTitle == nil ? nil : {
|
header = ChatListSearchItemHeader(type: .globalPeers, theme: theme, strings: strings, actionTitle: actionTitle, action: actionTitle == nil ? nil : { _ in
|
||||||
toggleExpandGlobalResults()
|
toggleExpandGlobalResults()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -935,21 +990,21 @@ public enum ChatListSearchEntry: Comparable, Identifiable {
|
|||||||
openStories(peer.id, sourceNode.avatarNode)
|
openStories(peer.id, sourceNode.avatarNode)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
case let .message(message, peer, readState, threadInfo, presentationData, _, selected, displayCustomHeader, orderingKey, _, section, allPaused, storyStats, requiresPremiumForMessaging):
|
case let .message(message, peer, readState, threadInfo, presentationData, _, selected, displayCustomHeader, orderingKey, _, section, allPaused, storyStats, requiresPremiumForMessaging, searchScope):
|
||||||
let header: ChatListSearchItemHeader
|
let header: ChatListSearchItemHeader
|
||||||
switch orderingKey {
|
switch orderingKey {
|
||||||
case .downloading:
|
case .downloading:
|
||||||
if allPaused {
|
if allPaused {
|
||||||
header = ChatListSearchItemHeader(type: .downloading, theme: presentationData.theme, strings: presentationData.strings, actionTitle: presentationData.strings.DownloadList_ResumeAll, action: {
|
header = ChatListSearchItemHeader(type: .downloading, theme: presentationData.theme, strings: presentationData.strings, actionTitle: presentationData.strings.DownloadList_ResumeAll, action: { _ in
|
||||||
toggleAllPaused()
|
toggleAllPaused()
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
header = ChatListSearchItemHeader(type: .downloading, theme: presentationData.theme, strings: presentationData.strings, actionTitle: presentationData.strings.DownloadList_PauseAll, action: {
|
header = ChatListSearchItemHeader(type: .downloading, theme: presentationData.theme, strings: presentationData.strings, actionTitle: presentationData.strings.DownloadList_PauseAll, action: { _ in
|
||||||
toggleAllPaused()
|
toggleAllPaused()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
case .downloaded:
|
case .downloaded:
|
||||||
header = ChatListSearchItemHeader(type: .recentDownloads, theme: presentationData.theme, strings: presentationData.strings, actionTitle: presentationData.strings.DownloadList_Clear, action: {
|
header = ChatListSearchItemHeader(type: .recentDownloads, theme: presentationData.theme, strings: presentationData.strings, actionTitle: presentationData.strings.DownloadList_Clear, action: { _ in
|
||||||
openClearRecentlyDownloaded()
|
openClearRecentlyDownloaded()
|
||||||
})
|
})
|
||||||
case .index:
|
case .index:
|
||||||
@ -957,7 +1012,7 @@ public enum ChatListSearchEntry: Comparable, Identifiable {
|
|||||||
if case .publicPosts = key {
|
if case .publicPosts = key {
|
||||||
header = ChatListSearchItemHeader(type: .publicPosts, theme: presentationData.theme, strings: presentationData.strings, actionTitle: nil, action: nil)
|
header = ChatListSearchItemHeader(type: .publicPosts, theme: presentationData.theme, strings: presentationData.strings, actionTitle: nil, action: nil)
|
||||||
} else {
|
} else {
|
||||||
header = ChatListSearchItemHeader(type: .publicPosts, theme: presentationData.theme, strings: presentationData.strings, actionTitle: "\(presentationData.strings.ChatList_Search_ShowMore) >", action: {
|
header = ChatListSearchItemHeader(type: .publicPosts, theme: presentationData.theme, strings: presentationData.strings, actionTitle: "\(presentationData.strings.ChatList_Search_ShowMore) >", action: { _ in
|
||||||
openPublicPosts()
|
openPublicPosts()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -966,7 +1021,24 @@ public enum ChatListSearchEntry: Comparable, Identifiable {
|
|||||||
if case let .forum(peerId) = location, let peer = peer.peer, peer.id == peerId {
|
if case let .forum(peerId) = location, let peer = peer.peer, peer.id == peerId {
|
||||||
headerType = .messages(location: peer.compactDisplayTitle)
|
headerType = .messages(location: peer.compactDisplayTitle)
|
||||||
}
|
}
|
||||||
header = ChatListSearchItemHeader(type: headerType, theme: presentationData.theme, strings: presentationData.strings, actionTitle: nil, action: nil)
|
var actionTitle: String?
|
||||||
|
if case .generic = section {
|
||||||
|
let filterTitle: String
|
||||||
|
switch searchScope {
|
||||||
|
case .everywhere:
|
||||||
|
filterTitle = presentationData.strings.ChatList_Search_Messages_AllChats
|
||||||
|
case .channels:
|
||||||
|
filterTitle = presentationData.strings.ChatList_Search_Messages_Channels
|
||||||
|
case .groups:
|
||||||
|
filterTitle = presentationData.strings.ChatList_Search_Messages_GroupChats
|
||||||
|
case .privateChats:
|
||||||
|
filterTitle = presentationData.strings.ChatList_Search_Messages_PrivateChats
|
||||||
|
}
|
||||||
|
actionTitle = "\(filterTitle) <"
|
||||||
|
}
|
||||||
|
header = ChatListSearchItemHeader(type: headerType, theme: presentationData.theme, strings: presentationData.strings, actionTitle: actionTitle, action: { sourceNode in
|
||||||
|
openMessagesFilter(sourceNode)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let selection: ChatHistoryMessageSelection = selected.flatMap { .selectable(selected: $0) } ?? .none
|
let selection: ChatHistoryMessageSelection = selected.flatMap { .selectable(selected: $0) } ?? .none
|
||||||
@ -1037,6 +1109,25 @@ public enum ChatListSearchEntry: Comparable, Identifiable {
|
|||||||
tags: []
|
tags: []
|
||||||
)), editing: false, hasActiveRevealControls: false, selected: false, header: tagMask == nil ? header : nil, enableContextActions: false, hiddenOffset: false, interaction: interaction)
|
)), editing: false, hasActiveRevealControls: false, selected: false, header: tagMask == nil ? header : nil, enableContextActions: false, hiddenOffset: false, interaction: interaction)
|
||||||
}
|
}
|
||||||
|
case let .messagePlaceholder(_, presentationData, searchScope):
|
||||||
|
var actionTitle: String?
|
||||||
|
let filterTitle: String
|
||||||
|
switch searchScope {
|
||||||
|
case .everywhere:
|
||||||
|
filterTitle = presentationData.strings.ChatList_Search_Messages_AllChats
|
||||||
|
case .channels:
|
||||||
|
filterTitle = presentationData.strings.ChatList_Search_Messages_Channels
|
||||||
|
case .groups:
|
||||||
|
filterTitle = presentationData.strings.ChatList_Search_Messages_GroupChats
|
||||||
|
case .privateChats:
|
||||||
|
filterTitle = presentationData.strings.ChatList_Search_Messages_PrivateChats
|
||||||
|
}
|
||||||
|
actionTitle = "\(filterTitle) <"
|
||||||
|
|
||||||
|
let header = ChatListSearchItemHeader(type: .messages(location: nil), theme: presentationData.theme, strings: presentationData.strings, actionTitle: actionTitle, action: { sourceNode in
|
||||||
|
openMessagesFilter(sourceNode)
|
||||||
|
})
|
||||||
|
return ChatListItem(presentationData: presentationData, context: context, chatListLocation: location, filterData: nil, index: EngineChatList.Item.Index.chatList(ChatListIndex(pinningIndex: nil, messageIndex: MessageIndex(id: MessageId(peerId: PeerId(0), namespace: Namespaces.Message.Cloud, id: 0), timestamp: 0))), content: .loading, editing: false, hasActiveRevealControls: false, selected: false, header: header, enableContextActions: false, hiddenOffset: false, interaction: interaction)
|
||||||
case let .addContact(phoneNumber, theme, strings):
|
case let .addContact(phoneNumber, theme, strings):
|
||||||
return ContactsAddItem(context: context, theme: theme, strings: strings, phoneNumber: phoneNumber, header: ChatListSearchItemHeader(type: .phoneNumber, theme: theme, strings: strings, actionTitle: nil, action: nil), action: {
|
return ContactsAddItem(context: context, theme: theme, strings: strings, phoneNumber: phoneNumber, header: ChatListSearchItemHeader(type: .phoneNumber, theme: theme, strings: strings, actionTitle: nil, action: nil), action: {
|
||||||
interaction.addContact(phoneNumber)
|
interaction.addContact(phoneNumber)
|
||||||
@ -1110,12 +1201,12 @@ private func chatListSearchContainerPreparedRecentTransition(
|
|||||||
return ChatListSearchContainerRecentTransition(deletions: deletions, insertions: insertions, updates: updates, isEmpty: isEmpty)
|
return ChatListSearchContainerRecentTransition(deletions: deletions, insertions: insertions, updates: updates, isEmpty: isEmpty)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func chatListSearchContainerPreparedTransition(from fromEntries: [ChatListSearchEntry], to toEntries: [ChatListSearchEntry], displayingResults: Bool, isEmpty: Bool, isLoading: Bool, animated: Bool, context: AccountContext, presentationData: PresentationData, enableHeaders: Bool, filter: ChatListNodePeersFilter, requestPeerType: [ReplyMarkupButtonRequestPeerType]?, location: ChatListControllerLocation, key: ChatListSearchPaneKey, tagMask: EngineMessage.Tags?, interaction: ChatListNodeInteraction, listInteraction: ListMessageItemInteraction, peerContextAction: ((EnginePeer, ChatListSearchContextActionSource, ASDisplayNode, ContextGesture?, CGPoint?) -> Void)?, toggleExpandLocalResults: @escaping () -> Void, toggleExpandGlobalResults: @escaping () -> Void, searchPeer: @escaping (EnginePeer) -> Void, searchQuery: String?, searchOptions: ChatListSearchOptions?, messageContextAction: ((EngineMessage, ASDisplayNode?, CGRect?, UIGestureRecognizer?, ChatListSearchPaneKey, (id: String, size: Int64, isFirstInList: Bool)?) -> Void)?, openClearRecentlyDownloaded: @escaping () -> Void, toggleAllPaused: @escaping () -> Void, openStories: @escaping (EnginePeer.Id, AvatarNode) -> Void, openPublicPosts: @escaping () -> Void) -> ChatListSearchContainerTransition {
|
public func chatListSearchContainerPreparedTransition(from fromEntries: [ChatListSearchEntry], to toEntries: [ChatListSearchEntry], displayingResults: Bool, isEmpty: Bool, isLoading: Bool, animated: Bool, context: AccountContext, presentationData: PresentationData, enableHeaders: Bool, filter: ChatListNodePeersFilter, requestPeerType: [ReplyMarkupButtonRequestPeerType]?, location: ChatListControllerLocation, key: ChatListSearchPaneKey, tagMask: EngineMessage.Tags?, interaction: ChatListNodeInteraction, listInteraction: ListMessageItemInteraction, peerContextAction: ((EnginePeer, ChatListSearchContextActionSource, ASDisplayNode, ContextGesture?, CGPoint?) -> Void)?, toggleExpandLocalResults: @escaping () -> Void, toggleExpandGlobalResults: @escaping () -> Void, searchPeer: @escaping (EnginePeer) -> Void, searchQuery: String?, searchOptions: ChatListSearchOptions?, messageContextAction: ((EngineMessage, ASDisplayNode?, CGRect?, UIGestureRecognizer?, ChatListSearchPaneKey, (id: String, size: Int64, isFirstInList: Bool)?) -> Void)?, openClearRecentlyDownloaded: @escaping () -> Void, toggleAllPaused: @escaping () -> Void, openStories: @escaping (EnginePeer.Id, AvatarNode) -> Void, openPublicPosts: @escaping () -> Void, openMessagesFilter: @escaping (ASDisplayNode) -> Void) -> ChatListSearchContainerTransition {
|
||||||
let (deleteIndices, indicesAndItems, updateIndices) = mergeListsStableWithUpdates(leftList: fromEntries, rightList: toEntries)
|
let (deleteIndices, indicesAndItems, updateIndices) = mergeListsStableWithUpdates(leftList: fromEntries, rightList: toEntries)
|
||||||
|
|
||||||
let deletions = deleteIndices.map { ListViewDeleteItem(index: $0, directionHint: nil) }
|
let deletions = deleteIndices.map { ListViewDeleteItem(index: $0, directionHint: nil) }
|
||||||
let insertions = indicesAndItems.map { ListViewInsertItem(index: $0.0, previousIndex: $0.2, item: $0.1.item(context: context, presentationData: presentationData, enableHeaders: enableHeaders, filter: filter, requestPeerType: requestPeerType, location: location, key: key, tagMask: tagMask, interaction: interaction, listInteraction: listInteraction, peerContextAction: peerContextAction, toggleExpandLocalResults: toggleExpandLocalResults, toggleExpandGlobalResults: toggleExpandGlobalResults, searchPeer: searchPeer, searchQuery: searchQuery, searchOptions: searchOptions, messageContextAction: messageContextAction, openClearRecentlyDownloaded: openClearRecentlyDownloaded, toggleAllPaused: toggleAllPaused, openStories: openStories, openPublicPosts: openPublicPosts), directionHint: nil) }
|
let insertions = indicesAndItems.map { ListViewInsertItem(index: $0.0, previousIndex: $0.2, item: $0.1.item(context: context, presentationData: presentationData, enableHeaders: enableHeaders, filter: filter, requestPeerType: requestPeerType, location: location, key: key, tagMask: tagMask, interaction: interaction, listInteraction: listInteraction, peerContextAction: peerContextAction, toggleExpandLocalResults: toggleExpandLocalResults, toggleExpandGlobalResults: toggleExpandGlobalResults, searchPeer: searchPeer, searchQuery: searchQuery, searchOptions: searchOptions, messageContextAction: messageContextAction, openClearRecentlyDownloaded: openClearRecentlyDownloaded, toggleAllPaused: toggleAllPaused, openStories: openStories, openPublicPosts: openPublicPosts, openMessagesFilter: openMessagesFilter), directionHint: nil) }
|
||||||
let updates = updateIndices.map { ListViewUpdateItem(index: $0.0, previousIndex: $0.2, item: $0.1.item(context: context, presentationData: presentationData, enableHeaders: enableHeaders, filter: filter, requestPeerType: requestPeerType, location: location, key: key, tagMask: tagMask, interaction: interaction, listInteraction: listInteraction, peerContextAction: peerContextAction, toggleExpandLocalResults: toggleExpandLocalResults, toggleExpandGlobalResults: toggleExpandGlobalResults, searchPeer: searchPeer, searchQuery: searchQuery, searchOptions: searchOptions, messageContextAction: messageContextAction, openClearRecentlyDownloaded: openClearRecentlyDownloaded, toggleAllPaused: toggleAllPaused, openStories: openStories, openPublicPosts: openPublicPosts), directionHint: nil) }
|
let updates = updateIndices.map { ListViewUpdateItem(index: $0.0, previousIndex: $0.2, item: $0.1.item(context: context, presentationData: presentationData, enableHeaders: enableHeaders, filter: filter, requestPeerType: requestPeerType, location: location, key: key, tagMask: tagMask, interaction: interaction, listInteraction: listInteraction, peerContextAction: peerContextAction, toggleExpandLocalResults: toggleExpandLocalResults, toggleExpandGlobalResults: toggleExpandGlobalResults, searchPeer: searchPeer, searchQuery: searchQuery, searchOptions: searchOptions, messageContextAction: messageContextAction, openClearRecentlyDownloaded: openClearRecentlyDownloaded, toggleAllPaused: toggleAllPaused, openStories: openStories, openPublicPosts: openPublicPosts, openMessagesFilter: openMessagesFilter), directionHint: nil) }
|
||||||
|
|
||||||
return ChatListSearchContainerTransition(deletions: deletions, insertions: insertions, updates: updates, displayingResults: displayingResults, isEmpty: isEmpty, isLoading: isLoading, query: searchQuery, animated: animated)
|
return ChatListSearchContainerTransition(deletions: deletions, insertions: insertions, updates: updates, displayingResults: displayingResults, isEmpty: isEmpty, isLoading: isLoading, query: searchQuery, animated: animated)
|
||||||
}
|
}
|
||||||
@ -1215,9 +1306,9 @@ private struct DownloadItem: Equatable {
|
|||||||
|
|
||||||
private func filteredPeerSearchQueryResults(value: ([FoundPeer], [FoundPeer]), scope: TelegramSearchPeersScope) -> ([FoundPeer], [FoundPeer]) {
|
private func filteredPeerSearchQueryResults(value: ([FoundPeer], [FoundPeer]), scope: TelegramSearchPeersScope) -> ([FoundPeer], [FoundPeer]) {
|
||||||
switch scope {
|
switch scope {
|
||||||
case .everywhere, .privateChats:
|
case .everywhere, .privateChats, .groups:
|
||||||
return value
|
return value
|
||||||
case .channels, .groups:
|
case .channels:
|
||||||
return (
|
return (
|
||||||
value.0.filter { peer in
|
value.0.filter { peer in
|
||||||
if let channel = peer.peer as? TelegramChannel, case .broadcast = channel.info {
|
if let channel = peer.peer as? TelegramChannel, case .broadcast = channel.info {
|
||||||
@ -1422,6 +1513,8 @@ final class ChatListSearchListPaneNode: ASDisplayNode, ChatListSearchPaneNode {
|
|||||||
private var searchQueryDisposable: Disposable?
|
private var searchQueryDisposable: Disposable?
|
||||||
private var searchOptionsDisposable: Disposable?
|
private var searchOptionsDisposable: Disposable?
|
||||||
|
|
||||||
|
private let searchScopePromise = ValuePromise<TelegramSearchPeersScope>(.everywhere)
|
||||||
|
|
||||||
init(context: AccountContext, animationCache: AnimationCache, animationRenderer: MultiAnimationRenderer, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)? = nil, interaction: ChatListSearchInteraction, key: ChatListSearchPaneKey, peersFilter: ChatListNodePeersFilter, requestPeerType: [ReplyMarkupButtonRequestPeerType]?, location: ChatListControllerLocation, searchQuery: Signal<String?, NoError>, searchOptions: Signal<ChatListSearchOptions?, NoError>, navigationController: NavigationController?, parentController: ViewController?, globalPeerSearchContext: GlobalPeerSearchContext?) {
|
init(context: AccountContext, animationCache: AnimationCache, animationRenderer: MultiAnimationRenderer, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)? = nil, interaction: ChatListSearchInteraction, key: ChatListSearchPaneKey, peersFilter: ChatListNodePeersFilter, requestPeerType: [ReplyMarkupButtonRequestPeerType]?, location: ChatListControllerLocation, searchQuery: Signal<String?, NoError>, searchOptions: Signal<ChatListSearchOptions?, NoError>, navigationController: NavigationController?, parentController: ViewController?, globalPeerSearchContext: GlobalPeerSearchContext?) {
|
||||||
self.context = context
|
self.context = context
|
||||||
self.animationCache = animationCache
|
self.animationCache = animationCache
|
||||||
@ -1708,8 +1801,8 @@ final class ChatListSearchListPaneNode: ASDisplayNode, ChatListSearchPaneNode {
|
|||||||
}
|
}
|
||||||
let previousRecentlySearchedPeersState = Atomic<SearchedPeersState?>(value: nil)
|
let previousRecentlySearchedPeersState = Atomic<SearchedPeersState?>(value: nil)
|
||||||
|
|
||||||
let foundItems: Signal<([ChatListSearchEntry], Bool)?, NoError> = combineLatest(queue: .mainQueue(), searchQuery, searchOptions, downloadItems)
|
let foundItems: Signal<([ChatListSearchEntry], Bool)?, NoError> = combineLatest(queue: .mainQueue(), searchQuery, searchOptions, self.searchScopePromise.get(), downloadItems)
|
||||||
|> mapToSignal { [weak self] query, options, downloadItems -> Signal<([ChatListSearchEntry], Bool)?, NoError> in
|
|> mapToSignal { [weak self] query, options, searchScope, downloadItems -> Signal<([ChatListSearchEntry], Bool)?, NoError> in
|
||||||
if query == nil && options == nil && [.chats, .topics, .channels, .apps].contains(key) {
|
if query == nil && options == nil && [.chats, .topics, .channels, .apps].contains(key) {
|
||||||
let _ = currentRemotePeers.swap(nil)
|
let _ = currentRemotePeers.swap(nil)
|
||||||
return .single(nil)
|
return .single(nil)
|
||||||
@ -1774,7 +1867,7 @@ final class ChatListSearchListPaneNode: ASDisplayNode, ChatListSearchPaneNode {
|
|||||||
resource = (resourceValue.id.stringRepresentation, size, entries.isEmpty)
|
resource = (resourceValue.id.stringRepresentation, size, entries.isEmpty)
|
||||||
}
|
}
|
||||||
|
|
||||||
entries.append(.message(message, peer, nil, nil, presentationData, 1, nil, false, .downloading(item.priority), resource, .downloading, allPaused, nil, false))
|
entries.append(.message(message, peer, nil, nil, presentationData, 1, nil, false, .downloading(item.priority), resource, .downloading, allPaused, nil, false, .everywhere))
|
||||||
}
|
}
|
||||||
for item in downloadItems.doneItems.sorted(by: { ChatListSearchEntry.MessageOrderingKey.downloaded(timestamp: $0.timestamp, index: $0.message.index) < ChatListSearchEntry.MessageOrderingKey.downloaded(timestamp: $1.timestamp, index: $1.message.index) }) {
|
for item in downloadItems.doneItems.sorted(by: { ChatListSearchEntry.MessageOrderingKey.downloaded(timestamp: $0.timestamp, index: $0.message.index) < ChatListSearchEntry.MessageOrderingKey.downloaded(timestamp: $1.timestamp, index: $1.message.index) }) {
|
||||||
if !item.isSeen {
|
if !item.isSeen {
|
||||||
@ -1802,7 +1895,7 @@ final class ChatListSearchListPaneNode: ASDisplayNode, ChatListSearchPaneNode {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
entries.append(.message(message, peer, nil, nil, presentationData, 1, selectionState?.contains(message.id), false, .downloaded(timestamp: item.timestamp, index: message.index), (item.resourceId, item.size, false), .recentlyDownloaded, false, nil, false))
|
entries.append(.message(message, peer, nil, nil, presentationData, 1, selectionState?.contains(message.id), false, .downloaded(timestamp: item.timestamp, index: message.index), (item.resourceId, item.size, false), .recentlyDownloaded, false, nil, false, .everywhere))
|
||||||
}
|
}
|
||||||
return (entries.sorted(), false)
|
return (entries.sorted(), false)
|
||||||
}
|
}
|
||||||
@ -2188,7 +2281,7 @@ final class ChatListSearchListPaneNode: ASDisplayNode, ChatListSearchPaneNode {
|
|||||||
if case let .chatList(groupId) = location, case .archive = groupId {
|
if case let .chatList(groupId) = location, case .archive = groupId {
|
||||||
searchLocations = [.group(groupId: groupId._asGroup(), tags: tagMask, minDate: options.date?.0, maxDate: options.date?.1)]
|
searchLocations = [.group(groupId: groupId._asGroup(), tags: tagMask, minDate: options.date?.0, maxDate: options.date?.1)]
|
||||||
} else {
|
} else {
|
||||||
searchLocations = [.general(scope: .everywhere, tags: tagMask, minDate: options.date?.0, maxDate: options.date?.1)]
|
searchLocations = [.general(scope: searchScope, tags: tagMask, minDate: options.date?.0, maxDate: options.date?.1)]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -2199,7 +2292,7 @@ final class ChatListSearchListPaneNode: ASDisplayNode, ChatListSearchPaneNode {
|
|||||||
} else if case let .chatList(groupId) = location, case .archive = groupId {
|
} else if case let .chatList(groupId) = location, case .archive = groupId {
|
||||||
searchLocations = [.group(groupId: groupId._asGroup(), tags: tagMask, minDate: nil, maxDate: nil)]
|
searchLocations = [.group(groupId: groupId._asGroup(), tags: tagMask, minDate: nil, maxDate: nil)]
|
||||||
} else {
|
} else {
|
||||||
searchLocations = [.general(scope: .everywhere, tags: tagMask, minDate: nil, maxDate: nil)]
|
searchLocations = [.general(scope: searchScope, tags: tagMask, minDate: nil, maxDate: nil)]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2787,7 +2880,7 @@ final class ChatListSearchListPaneNode: ASDisplayNode, ChatListSearchPaneNode {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
//TODO:requiresPremiumForMessaging
|
//TODO:requiresPremiumForMessaging
|
||||||
entries.append(.message(message, peer, nil, nil, presentationData, 1, nil, true, .index(message.index), nil, .generic, false, nil, false))
|
entries.append(.message(message, peer, nil, nil, presentationData, 1, nil, true, .index(message.index), nil, .generic, false, nil, false, .everywhere))
|
||||||
index += 1
|
index += 1
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2807,39 +2900,46 @@ final class ChatListSearchListPaneNode: ASDisplayNode, ChatListSearchPaneNode {
|
|||||||
firstHeaderId = headerId
|
firstHeaderId = headerId
|
||||||
}
|
}
|
||||||
let peer = EngineRenderedPeer(message: message)
|
let peer = EngineRenderedPeer(message: message)
|
||||||
entries.append(.message(message, peer, foundPublicMessageSet.readCounters[message.id.peerId], foundPublicMessageSet.threadsData[message.id]?.info, presentationData, foundPublicMessageSet.totalCount, nil, headerId == firstHeaderId, .index(message.index), nil, .publicPosts, false, nil, false))
|
entries.append(.message(message, peer, foundPublicMessageSet.readCounters[message.id.peerId], foundPublicMessageSet.threadsData[message.id]?.info, presentationData, foundPublicMessageSet.totalCount, nil, headerId == firstHeaderId, .index(message.index), nil, .publicPosts, false, nil, false, .everywhere))
|
||||||
index += 1
|
index += 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var existingMessageIds = Set<MessageId>()
|
var existingMessageIds = Set<MessageId>()
|
||||||
for foundRemoteMessageSet in foundRemoteMessages.0 {
|
if foundRemoteMessages.1 && searchScope != .everywhere {
|
||||||
for message in foundRemoteMessageSet.messages {
|
for i in 0 ..< 5 {
|
||||||
if existingMessageIds.contains(message.id) {
|
entries.append(.messagePlaceholder(Int32(i), presentationData, searchScope))
|
||||||
continue
|
|
||||||
}
|
|
||||||
existingMessageIds.insert(message.id)
|
|
||||||
|
|
||||||
if searchState.deletedMessageIds.contains(message.id) {
|
|
||||||
continue
|
|
||||||
} else if message.id.namespace == Namespaces.Message.Cloud && searchState.deletedGlobalMessageIds.contains(message.id.id) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
let headerId = listMessageDateHeaderId(timestamp: message.timestamp)
|
|
||||||
if firstHeaderId == nil {
|
|
||||||
firstHeaderId = headerId
|
|
||||||
}
|
|
||||||
var peer = EngineRenderedPeer(message: message)
|
|
||||||
if let group = message.peers[message.id.peerId] as? TelegramGroup, let migrationReference = group.migrationReference {
|
|
||||||
if let channelPeer = message.peers[migrationReference.peerId] {
|
|
||||||
peer = EngineRenderedPeer(peer: EnginePeer(channelPeer))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//TODO:requiresPremiumForMessaging
|
|
||||||
entries.append(.message(message, peer, foundRemoteMessageSet.readCounters[message.id.peerId], foundRemoteMessageSet.threadsData[message.id]?.info, presentationData, foundRemoteMessageSet.totalCount, selectionState?.contains(message.id), headerId == firstHeaderId, .index(message.index), nil, .generic, false, nil, false))
|
|
||||||
index += 1
|
index += 1
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
for foundRemoteMessageSet in foundRemoteMessages.0 {
|
||||||
|
for message in foundRemoteMessageSet.messages {
|
||||||
|
if existingMessageIds.contains(message.id) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
existingMessageIds.insert(message.id)
|
||||||
|
|
||||||
|
if searchState.deletedMessageIds.contains(message.id) {
|
||||||
|
continue
|
||||||
|
} else if message.id.namespace == Namespaces.Message.Cloud && searchState.deletedGlobalMessageIds.contains(message.id.id) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
let headerId = listMessageDateHeaderId(timestamp: message.timestamp)
|
||||||
|
if firstHeaderId == nil {
|
||||||
|
firstHeaderId = headerId
|
||||||
|
}
|
||||||
|
var peer = EngineRenderedPeer(message: message)
|
||||||
|
if let group = message.peers[message.id.peerId] as? TelegramGroup, let migrationReference = group.migrationReference {
|
||||||
|
if let channelPeer = message.peers[migrationReference.peerId] {
|
||||||
|
peer = EngineRenderedPeer(peer: EnginePeer(channelPeer))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO:requiresPremiumForMessaging
|
||||||
|
entries.append(.message(message, peer, foundRemoteMessageSet.readCounters[message.id.peerId], foundRemoteMessageSet.threadsData[message.id]?.info, presentationData, foundRemoteMessageSet.totalCount, selectionState?.contains(message.id), headerId == firstHeaderId, .index(message.index), nil, .generic, false, nil, false, searchScope))
|
||||||
|
index += 1
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2985,6 +3085,8 @@ final class ChatListSearchListPaneNode: ASDisplayNode, ChatListSearchPaneNode {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
switch item.content {
|
switch item.content {
|
||||||
|
case .loading:
|
||||||
|
break
|
||||||
case let .peer(peerData):
|
case let .peer(peerData):
|
||||||
if let peer = peerData.peer.peer, let message = peerData.messages.first {
|
if let peer = peerData.peer.peer, let message = peerData.messages.first {
|
||||||
peerContextAction(peer, .search(message.id), node, gesture, location)
|
peerContextAction(peer, .search(message.id), node, gesture, location)
|
||||||
@ -3096,7 +3198,7 @@ final class ChatListSearchListPaneNode: ASDisplayNode, ChatListSearchPaneNode {
|
|||||||
var fetchResourceId: (id: String, size: Int64, isFirstInList: Bool)?
|
var fetchResourceId: (id: String, size: Int64, isFirstInList: Bool)?
|
||||||
for entry in currentEntries {
|
for entry in currentEntries {
|
||||||
switch entry {
|
switch entry {
|
||||||
case let .message(m, _, _, _, _, _, _, _, _, resource, _, _, _, _):
|
case let .message(m, _, _, _, _, _, _, _, _, resource, _, _, _, _, _):
|
||||||
if m.id == message.id {
|
if m.id == message.id {
|
||||||
fetchResourceId = resource
|
fetchResourceId = resource
|
||||||
}
|
}
|
||||||
@ -3165,7 +3267,7 @@ final class ChatListSearchListPaneNode: ASDisplayNode, ChatListSearchPaneNode {
|
|||||||
if let user = foundPeer.peer as? TelegramUser, user.flags.contains(.requirePremium) {
|
if let user = foundPeer.peer as? TelegramUser, user.flags.contains(.requirePremium) {
|
||||||
requiresPremiumForMessagingPeerIds.append(foundPeer.peer.id)
|
requiresPremiumForMessagingPeerIds.append(foundPeer.peer.id)
|
||||||
}
|
}
|
||||||
case let .message(_, peer, _, _, _, _, _, _, _, _, _, _, _, _):
|
case let .message(_, peer, _, _, _, _, _, _, _, _, _, _, _, _, _):
|
||||||
if let peer = peer.peer {
|
if let peer = peer.peer {
|
||||||
storyStatsIds.append(peer.id)
|
storyStatsIds.append(peer.id)
|
||||||
if case let .user(user) = peer, user.flags.contains(.requirePremium) {
|
if case let .user(user) = peer, user.flags.contains(.requirePremium) {
|
||||||
@ -3203,8 +3305,8 @@ final class ChatListSearchListPaneNode: ASDisplayNode, ChatListSearchPaneNode {
|
|||||||
mappedItems[i] = .localPeer(peer, associatedPeer, unreadBadge, index, theme, strings, sortOrder, displayOrder, expandType, stats[peer.id] ?? nil, requiresPremiumForMessaging[peer.id] ?? false)
|
mappedItems[i] = .localPeer(peer, associatedPeer, unreadBadge, index, theme, strings, sortOrder, displayOrder, expandType, stats[peer.id] ?? nil, requiresPremiumForMessaging[peer.id] ?? false)
|
||||||
case let .globalPeer(peer, unreadBadge, index, theme, strings, sortOrder, displayOrder, expandType, _, _, searchQuery):
|
case let .globalPeer(peer, unreadBadge, index, theme, strings, sortOrder, displayOrder, expandType, _, _, searchQuery):
|
||||||
mappedItems[i] = .globalPeer(peer, unreadBadge, index, theme, strings, sortOrder, displayOrder, expandType, stats[peer.peer.id] ?? nil, requiresPremiumForMessaging[peer.peer.id] ?? false, searchQuery)
|
mappedItems[i] = .globalPeer(peer, unreadBadge, index, theme, strings, sortOrder, displayOrder, expandType, stats[peer.peer.id] ?? nil, requiresPremiumForMessaging[peer.peer.id] ?? false, searchQuery)
|
||||||
case let .message(message, peer, combinedPeerReadState, threadInfo, presentationData, totalCount, selected, displayCustomHeader, key, resourceId, section, allPaused, _, _):
|
case let .message(message, peer, combinedPeerReadState, threadInfo, presentationData, totalCount, selected, displayCustomHeader, key, resourceId, section, allPaused, _, _, searchScope):
|
||||||
mappedItems[i] = .message(message, peer, combinedPeerReadState, threadInfo, presentationData, totalCount, selected, displayCustomHeader, key, resourceId, section, allPaused, stats[peer.peerId] ?? nil, requiresPremiumForMessaging[peer.peerId] ?? false)
|
mappedItems[i] = .message(message, peer, combinedPeerReadState, threadInfo, presentationData, totalCount, selected, displayCustomHeader, key, resourceId, section, allPaused, stats[peer.peerId] ?? nil, requiresPremiumForMessaging[peer.peerId] ?? false, searchScope)
|
||||||
default:
|
default:
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
@ -3340,6 +3442,8 @@ final class ChatListSearchListPaneNode: ASDisplayNode, ChatListSearchPaneNode {
|
|||||||
strongSelf.interaction.openStories?(peerId, avatarNode)
|
strongSelf.interaction.openStories?(peerId, avatarNode)
|
||||||
}, openPublicPosts: {
|
}, openPublicPosts: {
|
||||||
strongSelf.interaction.switchToFilter(.publicPosts)
|
strongSelf.interaction.switchToFilter(.publicPosts)
|
||||||
|
}, openMessagesFilter: { sourceNode in
|
||||||
|
strongSelf.openMessagesFilter(sourceNode: sourceNode)
|
||||||
})
|
})
|
||||||
strongSelf.currentEntries = newEntries
|
strongSelf.currentEntries = newEntries
|
||||||
if strongSelf.key == .downloads {
|
if strongSelf.key == .downloads {
|
||||||
@ -3351,7 +3455,7 @@ final class ChatListSearchListPaneNode: ASDisplayNode, ChatListSearchPaneNode {
|
|||||||
|
|
||||||
var messages: [EngineMessage] = []
|
var messages: [EngineMessage] = []
|
||||||
for entry in newEntries {
|
for entry in newEntries {
|
||||||
if case let .message(message, _, _, _, _, _, _, _, _, _, _, _, _, _) = entry {
|
if case let .message(message, _, _, _, _, _, _, _, _, _, _, _, _, _, _) = entry {
|
||||||
messages.append(message)
|
messages.append(message)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -4767,14 +4871,65 @@ final class ChatListSearchListPaneNode: ASDisplayNode, ChatListSearchPaneNode {
|
|||||||
bounds = selectedItemNode.bounds
|
bounds = selectedItemNode.bounds
|
||||||
}
|
}
|
||||||
switch item.content {
|
switch item.content {
|
||||||
case let .peer(peerData):
|
case .loading:
|
||||||
return (selectedItemNode.view, bounds, peerData.messages.last?.id ?? peerData.peer.peerId)
|
return nil
|
||||||
case let .groupReference(groupReference):
|
case let .peer(peerData):
|
||||||
return (selectedItemNode.view, bounds, groupReference.groupId)
|
return (selectedItemNode.view, bounds, peerData.messages.last?.id ?? peerData.peer.peerId)
|
||||||
|
case let .groupReference(groupReference):
|
||||||
|
return (selectedItemNode.view, bounds, groupReference.groupId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func openMessagesFilter(sourceNode: ASDisplayNode) {
|
||||||
|
self.interaction.dismissInput()
|
||||||
|
let _ = (self.searchScopePromise.get()
|
||||||
|
|> take(1)).start(next: { [weak self] scope in
|
||||||
|
guard let self else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
var items: [ContextMenuItem] = []
|
||||||
|
items.append(.action(ContextMenuActionItem(text: self.presentationData.strings.ChatList_Search_Messages_Menu_AllChats, icon: { theme in
|
||||||
|
return scope == .everywhere ? generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Check"), color: theme.contextMenu.primaryColor) : nil
|
||||||
|
}, action: { [weak self] _, f in
|
||||||
|
guard let self else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
f(.default)
|
||||||
|
self.searchScopePromise.set(.everywhere)
|
||||||
|
})))
|
||||||
|
items.append(.action(ContextMenuActionItem(text: self.presentationData.strings.ChatList_Search_Messages_Menu_PrivateChats, icon: { theme in
|
||||||
|
return scope == .privateChats ? generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Check"), color: theme.contextMenu.primaryColor) : nil
|
||||||
|
}, action: { [weak self] _, f in
|
||||||
|
guard let self else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
f(.default)
|
||||||
|
self.searchScopePromise.set(.privateChats)
|
||||||
|
})))
|
||||||
|
items.append(.action(ContextMenuActionItem(text: self.presentationData.strings.ChatList_Search_Messages_Menu_GroupChats, icon: { theme in
|
||||||
|
return scope == .groups ? generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Check"), color: theme.contextMenu.primaryColor) : nil
|
||||||
|
}, action: { [weak self] _, f in
|
||||||
|
guard let self else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
f(.default)
|
||||||
|
self.searchScopePromise.set(.groups)
|
||||||
|
})))
|
||||||
|
items.append(.action(ContextMenuActionItem(text: self.presentationData.strings.ChatList_Search_Messages_Menu_Channels, icon: { theme in
|
||||||
|
return scope == .channels ? generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Check"), color: theme.contextMenu.primaryColor) : nil
|
||||||
|
}, action: { [weak self] _, f in
|
||||||
|
guard let self else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
f(.default)
|
||||||
|
self.searchScopePromise.set(.channels)
|
||||||
|
})))
|
||||||
|
let contextController = ContextController(presentationData: self.presentationData, source: .reference(ChatListSearchReferenceContentSource(sourceNode: sourceNode)), items: .single(ContextController.Items(content: .list(items))), gesture: nil)
|
||||||
|
self.interaction.present(contextController, nil)
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private final class SearchShimmerEffectNode: ASDisplayNode {
|
private final class SearchShimmerEffectNode: ASDisplayNode {
|
||||||
@ -5276,3 +5431,18 @@ public final class ChatListSearchShimmerNode: ASDisplayNode {
|
|||||||
transition.updateFrame(node: self.effectNode, frame: CGRect(origin: CGPoint(x: 0.0, y: 0.0), size: size))
|
transition.updateFrame(node: self.effectNode, frame: CGRect(origin: CGPoint(x: 0.0, y: 0.0), size: size))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private final class ChatListSearchReferenceContentSource: ContextReferenceContentSource {
|
||||||
|
private let sourceNode: ASDisplayNode
|
||||||
|
var keepInPlace: Bool {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
init(sourceNode: ASDisplayNode) {
|
||||||
|
self.sourceNode = sourceNode
|
||||||
|
}
|
||||||
|
|
||||||
|
func transitionInfo() -> ContextControllerReferenceViewInfo? {
|
||||||
|
return ContextControllerReferenceViewInfo(referenceView: self.sourceNode.view, contentAreaInScreenSpace: UIScreen.main.bounds, actionsPosition: .bottom)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -702,7 +702,7 @@ final class ChatListSearchMediaNode: ASDisplayNode, ASScrollViewDelegate {
|
|||||||
var index: UInt32 = 0
|
var index: UInt32 = 0
|
||||||
if let entries = entries {
|
if let entries = entries {
|
||||||
for entry in entries {
|
for entry in entries {
|
||||||
if case let .message(message, _, _, _, _, _, _, _, _, _, _, _, _, _) = entry {
|
if case let .message(message, _, _, _, _, _, _, _, _, _, _, _, _, _, _) = entry {
|
||||||
self.mediaItems.append(VisualMediaItem(message: message._asMessage(), index: nil))
|
self.mediaItems.append(VisualMediaItem(message: message._asMessage(), index: nil))
|
||||||
}
|
}
|
||||||
index += 1
|
index += 1
|
||||||
|
@ -8,7 +8,7 @@ import AnimationCache
|
|||||||
import MultiAnimationRenderer
|
import MultiAnimationRenderer
|
||||||
import TelegramCore
|
import TelegramCore
|
||||||
|
|
||||||
final class ShimmerEffectNode: ASDisplayNode {
|
private final class ShimmerEffectNode: ASDisplayNode {
|
||||||
private var currentBackgroundColor: UIColor?
|
private var currentBackgroundColor: UIColor?
|
||||||
private var currentForegroundColor: UIColor?
|
private var currentForegroundColor: UIColor?
|
||||||
private let imageNodeContainer: ASDisplayNode
|
private let imageNodeContainer: ASDisplayNode
|
||||||
|
@ -254,7 +254,7 @@ class ChatListSectionHeaderNode: ListViewItemNode {
|
|||||||
if item.hide != nil {
|
if item.hide != nil {
|
||||||
headerNode.action = item.strings.ChatList_EmptyListContactsHeaderHide
|
headerNode.action = item.strings.ChatList_EmptyListContactsHeaderHide
|
||||||
headerNode.actionType = .generic
|
headerNode.actionType = .generic
|
||||||
headerNode.activateAction = {
|
headerNode.activateAction = { _ in
|
||||||
guard let self else {
|
guard let self else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -28,6 +28,7 @@ import EmojiStatusComponent
|
|||||||
import AvatarVideoNode
|
import AvatarVideoNode
|
||||||
import AppBundle
|
import AppBundle
|
||||||
import MultilineTextComponent
|
import MultilineTextComponent
|
||||||
|
import ShimmerEffect
|
||||||
|
|
||||||
public enum ChatListItemContent {
|
public enum ChatListItemContent {
|
||||||
public struct ThreadInfo: Equatable {
|
public struct ThreadInfo: Equatable {
|
||||||
@ -210,11 +211,14 @@ public enum ChatListItemContent {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case loading
|
||||||
case peer(PeerData)
|
case peer(PeerData)
|
||||||
case groupReference(GroupReferenceData)
|
case groupReference(GroupReferenceData)
|
||||||
|
|
||||||
public var chatLocation: ChatLocation? {
|
public var chatLocation: ChatLocation? {
|
||||||
switch self {
|
switch self {
|
||||||
|
case .loading:
|
||||||
|
return nil
|
||||||
case let .peer(peerData):
|
case let .peer(peerData):
|
||||||
return .peer(id: peerData.peer.peerId)
|
return .peer(id: peerData.peer.peerId)
|
||||||
case .groupReference:
|
case .groupReference:
|
||||||
@ -492,6 +496,8 @@ public class ChatListItem: ListViewItem, ChatListSearchItemNeighbour {
|
|||||||
|
|
||||||
public func selected(listView: ListView) {
|
public func selected(listView: ListView) {
|
||||||
switch self.content {
|
switch self.content {
|
||||||
|
case .loading:
|
||||||
|
break
|
||||||
case let .peer(peerData):
|
case let .peer(peerData):
|
||||||
if let message = peerData.messages.last, let peer = peerData.peer.peer {
|
if let message = peerData.messages.last, let peer = peerData.peer.peer {
|
||||||
var threadId: Int64?
|
var threadId: Int64?
|
||||||
@ -1234,6 +1240,9 @@ public class ChatListItemNode: ItemListRevealOptionsItemNode {
|
|||||||
var actionButtonBackgroundView: UIImageView?
|
var actionButtonBackgroundView: UIImageView?
|
||||||
var actionButtonNode: HighlightableButtonNode?
|
var actionButtonNode: HighlightableButtonNode?
|
||||||
|
|
||||||
|
private var placeholderNode: ShimmerEffectNode?
|
||||||
|
private var absoluteLocation: (CGRect, CGSize)?
|
||||||
|
|
||||||
private var hierarchyTrackingLayer: HierarchyTrackingLayer?
|
private var hierarchyTrackingLayer: HierarchyTrackingLayer?
|
||||||
private var cachedDataDisposable = MetaDisposable()
|
private var cachedDataDisposable = MetaDisposable()
|
||||||
|
|
||||||
@ -1293,6 +1302,8 @@ public class ChatListItemNode: ItemListRevealOptionsItemNode {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
switch item.content {
|
switch item.content {
|
||||||
|
case .loading:
|
||||||
|
return nil
|
||||||
case let .groupReference(groupReferenceData):
|
case let .groupReference(groupReferenceData):
|
||||||
var result = item.presentationData.strings.ChatList_ArchivedChatsTitle
|
var result = item.presentationData.strings.ChatList_ArchivedChatsTitle
|
||||||
let allCount = groupReferenceData.unreadCount
|
let allCount = groupReferenceData.unreadCount
|
||||||
@ -1325,6 +1336,8 @@ public class ChatListItemNode: ItemListRevealOptionsItemNode {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
switch item.content {
|
switch item.content {
|
||||||
|
case .loading:
|
||||||
|
return nil
|
||||||
case let .groupReference(groupReferenceData):
|
case let .groupReference(groupReferenceData):
|
||||||
let peers = groupReferenceData.peers
|
let peers = groupReferenceData.peers
|
||||||
let messageValue = groupReferenceData.message
|
let messageValue = groupReferenceData.message
|
||||||
@ -1619,6 +1632,9 @@ public class ChatListItemNode: ItemListRevealOptionsItemNode {
|
|||||||
var displayAsMessage = false
|
var displayAsMessage = false
|
||||||
var enablePreview = true
|
var enablePreview = true
|
||||||
switch item.content {
|
switch item.content {
|
||||||
|
case .loading:
|
||||||
|
displayAsMessage = true
|
||||||
|
enablePreview = false
|
||||||
case let .peer(peerData):
|
case let .peer(peerData):
|
||||||
displayAsMessage = peerData.displayAsMessage
|
displayAsMessage = peerData.displayAsMessage
|
||||||
if displayAsMessage, case let .user(author) = peerData.messages.last?.author {
|
if displayAsMessage, case let .user(author) = peerData.messages.last?.author {
|
||||||
@ -1934,6 +1950,22 @@ public class ChatListItemNode: ItemListRevealOptionsItemNode {
|
|||||||
var groupHiddenByDefault = false
|
var groupHiddenByDefault = false
|
||||||
|
|
||||||
switch item.content {
|
switch item.content {
|
||||||
|
case .loading:
|
||||||
|
messages = []
|
||||||
|
contentPeer = .group([])
|
||||||
|
combinedReadState = nil
|
||||||
|
unreadCount = (0, false, false, nil, false)
|
||||||
|
isRemovedFromTotalUnreadCount = false
|
||||||
|
peerPresence = nil
|
||||||
|
draftState = nil
|
||||||
|
mediaDraftContentType = nil
|
||||||
|
hasUnseenMentions = false
|
||||||
|
hasUnseenReactions = false
|
||||||
|
inputActivities = nil
|
||||||
|
isPeerGroup = false
|
||||||
|
promoInfo = nil
|
||||||
|
displayAsMessage = true
|
||||||
|
hasFailedMessages = false
|
||||||
case let .peer(peerData):
|
case let .peer(peerData):
|
||||||
let messagesValue = peerData.messages
|
let messagesValue = peerData.messages
|
||||||
let peerValue = peerData.peer
|
let peerValue = peerData.peer
|
||||||
@ -2078,6 +2110,7 @@ public class ChatListItemNode: ItemListRevealOptionsItemNode {
|
|||||||
var currentForwardedIcon: UIImage?
|
var currentForwardedIcon: UIImage?
|
||||||
var currentStoryIcon: UIImage?
|
var currentStoryIcon: UIImage?
|
||||||
var currentGiftIcon: UIImage?
|
var currentGiftIcon: UIImage?
|
||||||
|
var currentLocationIcon: UIImage?
|
||||||
|
|
||||||
var selectableControlSizeAndApply: (CGFloat, (CGSize, Bool) -> ItemListSelectableControlNode)?
|
var selectableControlSizeAndApply: (CGFloat, (CGSize, Bool) -> ItemListSelectableControlNode)?
|
||||||
var reorderControlSizeAndApply: (CGFloat, (CGFloat, Bool, ContainedViewLayoutTransition) -> ItemListEditableReorderControlNode)?
|
var reorderControlSizeAndApply: (CGFloat, (CGFloat, Bool, ContainedViewLayoutTransition) -> ItemListEditableReorderControlNode)?
|
||||||
@ -2252,6 +2285,7 @@ public class ChatListItemNode: ItemListRevealOptionsItemNode {
|
|||||||
var displayForwardedIcon = false
|
var displayForwardedIcon = false
|
||||||
var displayStoryReplyIcon = false
|
var displayStoryReplyIcon = false
|
||||||
var displayGiftIcon = false
|
var displayGiftIcon = false
|
||||||
|
var displayLocationIcon = false
|
||||||
var ignoreForwardedIcon = false
|
var ignoreForwardedIcon = false
|
||||||
|
|
||||||
switch contentData {
|
switch contentData {
|
||||||
@ -2562,7 +2596,9 @@ public class ChatListItemNode: ItemListRevealOptionsItemNode {
|
|||||||
displayStoryReplyIcon = true
|
displayStoryReplyIcon = true
|
||||||
} else {
|
} else {
|
||||||
for media in message.media {
|
for media in message.media {
|
||||||
if let action = media as? TelegramMediaAction {
|
if let _ = media as? TelegramMediaMap {
|
||||||
|
displayLocationIcon = true
|
||||||
|
} else if let action = media as? TelegramMediaAction {
|
||||||
switch action.action {
|
switch action.action {
|
||||||
case .giftPremium, .giftStars, .starGift:
|
case .giftPremium, .giftStars, .starGift:
|
||||||
displayGiftIcon = true
|
displayGiftIcon = true
|
||||||
@ -2737,6 +2773,10 @@ public class ChatListItemNode: ItemListRevealOptionsItemNode {
|
|||||||
currentGiftIcon = PresentationResourcesChatList.giftIcon(item.presentationData.theme)
|
currentGiftIcon = PresentationResourcesChatList.giftIcon(item.presentationData.theme)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if displayLocationIcon {
|
||||||
|
currentLocationIcon = PresentationResourcesChatList.locationIcon(item.presentationData.theme)
|
||||||
|
}
|
||||||
|
|
||||||
if let currentForwardedIcon {
|
if let currentForwardedIcon {
|
||||||
textLeftCutout += currentForwardedIcon.size.width
|
textLeftCutout += currentForwardedIcon.size.width
|
||||||
if !contentImageSpecs.isEmpty {
|
if !contentImageSpecs.isEmpty {
|
||||||
@ -2764,6 +2804,15 @@ public class ChatListItemNode: ItemListRevealOptionsItemNode {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let currentLocationIcon {
|
||||||
|
textLeftCutout += currentLocationIcon.size.width
|
||||||
|
if !contentImageSpecs.isEmpty {
|
||||||
|
textLeftCutout += forwardedIconSpacing
|
||||||
|
} else {
|
||||||
|
textLeftCutout += contentImageTrailingSpace
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for i in 0 ..< contentImageSpecs.count {
|
for i in 0 ..< contentImageSpecs.count {
|
||||||
if i != 0 {
|
if i != 0 {
|
||||||
textLeftCutout += contentImageSpacing
|
textLeftCutout += contentImageSpacing
|
||||||
@ -2824,6 +2873,8 @@ public class ChatListItemNode: ItemListRevealOptionsItemNode {
|
|||||||
let dateText: String
|
let dateText: String
|
||||||
var topIndex: MessageIndex?
|
var topIndex: MessageIndex?
|
||||||
switch item.content {
|
switch item.content {
|
||||||
|
case .loading:
|
||||||
|
break
|
||||||
case let .groupReference(groupReferenceData):
|
case let .groupReference(groupReferenceData):
|
||||||
topIndex = groupReferenceData.message?.index
|
topIndex = groupReferenceData.message?.index
|
||||||
case let .peer(peerData):
|
case let .peer(peerData):
|
||||||
@ -2996,6 +3047,7 @@ public class ChatListItemNode: ItemListRevealOptionsItemNode {
|
|||||||
if case let .chatList(index) = item.index, index.messageIndex.id.peerId == item.context.account.peerId {
|
if case let .chatList(index) = item.index, index.messageIndex.id.peerId == item.context.account.peerId {
|
||||||
isAccountPeer = true
|
isAccountPeer = true
|
||||||
}
|
}
|
||||||
|
|
||||||
if !isPeerGroup && !isAccountPeer && threadInfo == nil {
|
if !isPeerGroup && !isAccountPeer && threadInfo == nil {
|
||||||
if displayAsMessage {
|
if displayAsMessage {
|
||||||
switch item.content {
|
switch item.content {
|
||||||
@ -3010,16 +3062,16 @@ public class ChatListItemNode: ItemListRevealOptionsItemNode {
|
|||||||
} else if peer.isFake {
|
} else if peer.isFake {
|
||||||
currentCredibilityIconContent = .text(color: item.presentationData.theme.chat.message.incoming.scamColor, string: item.presentationData.strings.Message_FakeAccount.uppercased())
|
currentCredibilityIconContent = .text(color: item.presentationData.theme.chat.message.incoming.scamColor, string: item.presentationData.strings.Message_FakeAccount.uppercased())
|
||||||
} else if let emojiStatus = peer.emojiStatus, !premiumConfiguration.isPremiumDisabled {
|
} else if let emojiStatus = peer.emojiStatus, !premiumConfiguration.isPremiumDisabled {
|
||||||
if case .channel = peer, peer.isVerified {
|
|
||||||
currentVerifiedIconContent = .verified(fillColor: item.presentationData.theme.list.itemCheckColors.fillColor, foregroundColor: item.presentationData.theme.list.itemCheckColors.foregroundColor, sizeType: .compact)
|
|
||||||
}
|
|
||||||
|
|
||||||
currentCredibilityIconContent = .animation(content: .customEmoji(fileId: emojiStatus.fileId), size: CGSize(width: 32.0, height: 32.0), placeholderColor: item.presentationData.theme.list.mediaPlaceholderColor, themeColor: item.presentationData.theme.list.itemAccentColor, loopMode: .count(2))
|
currentCredibilityIconContent = .animation(content: .customEmoji(fileId: emojiStatus.fileId), size: CGSize(width: 32.0, height: 32.0), placeholderColor: item.presentationData.theme.list.mediaPlaceholderColor, themeColor: item.presentationData.theme.list.itemAccentColor, loopMode: .count(2))
|
||||||
} else if peer.isVerified {
|
|
||||||
currentCredibilityIconContent = .verified(fillColor: item.presentationData.theme.list.itemCheckColors.fillColor, foregroundColor: item.presentationData.theme.list.itemCheckColors.foregroundColor, sizeType: .compact)
|
|
||||||
} else if peer.isPremium && !premiumConfiguration.isPremiumDisabled {
|
} else if peer.isPremium && !premiumConfiguration.isPremiumDisabled {
|
||||||
currentCredibilityIconContent = .premium(color: item.presentationData.theme.list.itemAccentColor)
|
currentCredibilityIconContent = .premium(color: item.presentationData.theme.list.itemAccentColor)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if peer.isVerified {
|
||||||
|
currentVerifiedIconContent = .verified(fillColor: item.presentationData.theme.list.itemCheckColors.fillColor, foregroundColor: item.presentationData.theme.list.itemCheckColors.foregroundColor, sizeType: .compact)
|
||||||
|
} else if let verification = peer.verification {
|
||||||
|
currentVerifiedIconContent = .animation(content: .customEmoji(fileId: verification.iconFileId), size: CGSize(width: 32.0, height: 32.0), placeholderColor: item.presentationData.theme.list.mediaPlaceholderColor, themeColor: item.presentationData.theme.list.itemAccentColor, loopMode: .count(0))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
break
|
break
|
||||||
@ -3037,23 +3089,28 @@ public class ChatListItemNode: ItemListRevealOptionsItemNode {
|
|||||||
} else if peer.isFake {
|
} else if peer.isFake {
|
||||||
currentCredibilityIconContent = .text(color: item.presentationData.theme.chat.message.incoming.scamColor, string: item.presentationData.strings.Message_FakeAccount.uppercased())
|
currentCredibilityIconContent = .text(color: item.presentationData.theme.chat.message.incoming.scamColor, string: item.presentationData.strings.Message_FakeAccount.uppercased())
|
||||||
} else if let emojiStatus = peer.emojiStatus, !premiumConfiguration.isPremiumDisabled {
|
} else if let emojiStatus = peer.emojiStatus, !premiumConfiguration.isPremiumDisabled {
|
||||||
if case .channel = peer, peer.isVerified {
|
|
||||||
currentVerifiedIconContent = .verified(fillColor: item.presentationData.theme.list.itemCheckColors.fillColor, foregroundColor: item.presentationData.theme.list.itemCheckColors.foregroundColor, sizeType: .compact)
|
|
||||||
}
|
|
||||||
|
|
||||||
currentCredibilityIconContent = .animation(content: .customEmoji(fileId: emojiStatus.fileId), size: CGSize(width: 32.0, height: 32.0), placeholderColor: item.presentationData.theme.list.mediaPlaceholderColor, themeColor: item.presentationData.theme.list.itemAccentColor, loopMode: .count(2))
|
currentCredibilityIconContent = .animation(content: .customEmoji(fileId: emojiStatus.fileId), size: CGSize(width: 32.0, height: 32.0), placeholderColor: item.presentationData.theme.list.mediaPlaceholderColor, themeColor: item.presentationData.theme.list.itemAccentColor, loopMode: .count(2))
|
||||||
} else if peer.isVerified {
|
|
||||||
currentCredibilityIconContent = .verified(fillColor: item.presentationData.theme.list.itemCheckColors.fillColor, foregroundColor: item.presentationData.theme.list.itemCheckColors.foregroundColor, sizeType: .compact)
|
|
||||||
} else if peer.isPremium && !premiumConfiguration.isPremiumDisabled {
|
} else if peer.isPremium && !premiumConfiguration.isPremiumDisabled {
|
||||||
currentCredibilityIconContent = .premium(color: item.presentationData.theme.list.itemAccentColor)
|
currentCredibilityIconContent = .premium(color: item.presentationData.theme.list.itemAccentColor)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if peer.isVerified {
|
||||||
|
currentVerifiedIconContent = .verified(fillColor: item.presentationData.theme.list.itemCheckColors.fillColor, foregroundColor: item.presentationData.theme.list.itemCheckColors.foregroundColor, sizeType: .compact)
|
||||||
|
} else if let verification = peer.verification {
|
||||||
|
currentVerifiedIconContent = .animation(content: .customEmoji(fileId: verification.iconFileId), size: CGSize(width: 32.0, height: 32.0), placeholderColor: item.presentationData.theme.list.mediaPlaceholderColor, themeColor: item.presentationData.theme.list.itemAccentColor, loopMode: .count(0))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if let currentSecretIconImage = currentSecretIconImage {
|
if let currentSecretIconImage = currentSecretIconImage {
|
||||||
titleIconsWidth += currentSecretIconImage.size.width + 2.0
|
titleIconsWidth += currentSecretIconImage.size.width + 2.0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var titleLeftOffset: CGFloat = 0.0
|
||||||
if let currentVerifiedIconContent {
|
if let currentVerifiedIconContent {
|
||||||
|
if titleLeftOffset.isZero, currentVerifiedIconContent != .none {
|
||||||
|
titleLeftOffset += 20.0
|
||||||
|
}
|
||||||
|
|
||||||
if titleIconsWidth.isZero {
|
if titleIconsWidth.isZero {
|
||||||
titleIconsWidth += 4.0
|
titleIconsWidth += 4.0
|
||||||
} else {
|
} else {
|
||||||
@ -3070,6 +3127,10 @@ public class ChatListItemNode: ItemListRevealOptionsItemNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if let currentCredibilityIconContent {
|
if let currentCredibilityIconContent {
|
||||||
|
if titleLeftOffset.isZero, case .verified = currentCredibilityIconContent {
|
||||||
|
titleLeftOffset += 20.0
|
||||||
|
}
|
||||||
|
|
||||||
if titleIconsWidth.isZero {
|
if titleIconsWidth.isZero {
|
||||||
titleIconsWidth += 4.0
|
titleIconsWidth += 4.0
|
||||||
} else {
|
} else {
|
||||||
@ -3257,6 +3318,9 @@ public class ChatListItemNode: ItemListRevealOptionsItemNode {
|
|||||||
var peerRevealOptions: [ItemListRevealOption]
|
var peerRevealOptions: [ItemListRevealOption]
|
||||||
var peerLeftRevealOptions: [ItemListRevealOption]
|
var peerLeftRevealOptions: [ItemListRevealOption]
|
||||||
switch item.content {
|
switch item.content {
|
||||||
|
case .loading:
|
||||||
|
peerRevealOptions = []
|
||||||
|
peerLeftRevealOptions = []
|
||||||
case let .peer(peerData):
|
case let .peer(peerData):
|
||||||
let renderedPeer = peerData.peer
|
let renderedPeer = peerData.peer
|
||||||
let presence = peerData.presence
|
let presence = peerData.presence
|
||||||
@ -3948,7 +4012,7 @@ public class ChatListItemNode: ItemListRevealOptionsItemNode {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var titleOffset: CGFloat = 0.0
|
var titleOffset: CGFloat = titleLeftOffset
|
||||||
if let currentSecretIconImage = currentSecretIconImage {
|
if let currentSecretIconImage = currentSecretIconImage {
|
||||||
let iconNode: ASImageNode
|
let iconNode: ASImageNode
|
||||||
if let current = strongSelf.secretIconNode {
|
if let current = strongSelf.secretIconNode {
|
||||||
@ -4293,6 +4357,9 @@ public class ChatListItemNode: ItemListRevealOptionsItemNode {
|
|||||||
} else if let currentGiftIcon {
|
} else if let currentGiftIcon {
|
||||||
messageTypeIcon = currentGiftIcon
|
messageTypeIcon = currentGiftIcon
|
||||||
messageTypeIconOffset.y -= 2.0 - UIScreenPixel
|
messageTypeIconOffset.y -= 2.0 - UIScreenPixel
|
||||||
|
} else if let currentLocationIcon {
|
||||||
|
messageTypeIcon = currentLocationIcon
|
||||||
|
messageTypeIconOffset.y -= 2.0 - UIScreenPixel
|
||||||
}
|
}
|
||||||
|
|
||||||
if let messageTypeIcon {
|
if let messageTypeIcon {
|
||||||
@ -4422,7 +4489,7 @@ public class ChatListItemNode: ItemListRevealOptionsItemNode {
|
|||||||
strongSelf.credibilityIconView = credibilityIconView
|
strongSelf.credibilityIconView = credibilityIconView
|
||||||
strongSelf.mainContentContainerNode.view.addSubview(credibilityIconView)
|
strongSelf.mainContentContainerNode.view.addSubview(credibilityIconView)
|
||||||
}
|
}
|
||||||
|
|
||||||
let credibilityIconComponent = EmojiStatusComponent(
|
let credibilityIconComponent = EmojiStatusComponent(
|
||||||
context: item.context,
|
context: item.context,
|
||||||
animationCache: item.interaction.animationCache,
|
animationCache: item.interaction.animationCache,
|
||||||
@ -4433,14 +4500,22 @@ public class ChatListItemNode: ItemListRevealOptionsItemNode {
|
|||||||
)
|
)
|
||||||
strongSelf.credibilityIconComponent = credibilityIconComponent
|
strongSelf.credibilityIconComponent = credibilityIconComponent
|
||||||
|
|
||||||
|
var iconOrigin: CGFloat = nextTitleIconOrigin
|
||||||
|
let containerSize = CGSize(width: 20.0, height: 20.0)
|
||||||
|
if case .verified = currentCredibilityIconContent {
|
||||||
|
iconOrigin = contentRect.origin.x
|
||||||
|
}
|
||||||
let iconSize = credibilityIconView.update(
|
let iconSize = credibilityIconView.update(
|
||||||
transition: .immediate,
|
transition: .immediate,
|
||||||
component: AnyComponent(credibilityIconComponent),
|
component: AnyComponent(credibilityIconComponent),
|
||||||
environment: {},
|
environment: {},
|
||||||
containerSize: CGSize(width: 20.0, height: 20.0)
|
containerSize: containerSize
|
||||||
)
|
)
|
||||||
transition.updateFrame(view: credibilityIconView, frame: CGRect(origin: CGPoint(x: nextTitleIconOrigin, y: floorToScreenPixels(titleFrame.maxY - lastLineRect.height * 0.5 - iconSize.height / 2.0) - UIScreenPixel), size: iconSize))
|
transition.updateFrame(view: credibilityIconView, frame: CGRect(origin: CGPoint(x: iconOrigin, y: floorToScreenPixels(titleFrame.maxY - lastLineRect.height * 0.5 - iconSize.height / 2.0) - UIScreenPixel), size: iconSize))
|
||||||
nextTitleIconOrigin += credibilityIconView.bounds.width + 4.0
|
if case .verified = currentCredibilityIconContent {
|
||||||
|
} else {
|
||||||
|
nextTitleIconOrigin += credibilityIconView.bounds.width + 4.0
|
||||||
|
}
|
||||||
} else if let credibilityIconView = strongSelf.credibilityIconView {
|
} else if let credibilityIconView = strongSelf.credibilityIconView {
|
||||||
strongSelf.credibilityIconView = nil
|
strongSelf.credibilityIconView = nil
|
||||||
credibilityIconView.removeFromSuperview()
|
credibilityIconView.removeFromSuperview()
|
||||||
@ -4466,14 +4541,16 @@ public class ChatListItemNode: ItemListRevealOptionsItemNode {
|
|||||||
)
|
)
|
||||||
strongSelf.verifiedIconComponent = verifiedIconComponent
|
strongSelf.verifiedIconComponent = verifiedIconComponent
|
||||||
|
|
||||||
|
let iconOrigin = contentRect.origin.x
|
||||||
|
let containerSize = CGSize(width: 16.0, height: 16.0)
|
||||||
|
|
||||||
let iconSize = verifiedIconView.update(
|
let iconSize = verifiedIconView.update(
|
||||||
transition: .immediate,
|
transition: .immediate,
|
||||||
component: AnyComponent(verifiedIconComponent),
|
component: AnyComponent(verifiedIconComponent),
|
||||||
environment: {},
|
environment: {},
|
||||||
containerSize: CGSize(width: 20.0, height: 20.0)
|
containerSize: containerSize
|
||||||
)
|
)
|
||||||
transition.updateFrame(view: verifiedIconView, frame: CGRect(origin: CGPoint(x: nextTitleIconOrigin, y: floorToScreenPixels(titleFrame.maxY - lastLineRect.height * 0.5 - iconSize.height / 2.0) - UIScreenPixel), size: iconSize))
|
transition.updateFrame(view: verifiedIconView, frame: CGRect(origin: CGPoint(x: iconOrigin, y: floorToScreenPixels(titleFrame.maxY - lastLineRect.height * 0.5 - iconSize.height / 2.0) - UIScreenPixel), size: iconSize))
|
||||||
nextTitleIconOrigin += verifiedIconView.bounds.width + 4.0
|
|
||||||
} else if let verifiedIconView = strongSelf.verifiedIconView {
|
} else if let verifiedIconView = strongSelf.verifiedIconView {
|
||||||
strongSelf.verifiedIconView = nil
|
strongSelf.verifiedIconView = nil
|
||||||
verifiedIconView.removeFromSuperview()
|
verifiedIconView.removeFromSuperview()
|
||||||
@ -4577,11 +4654,60 @@ public class ChatListItemNode: ItemListRevealOptionsItemNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
strongSelf.avatarTapRecognizer?.isEnabled = item.interaction.inlineNavigationLocation == nil
|
strongSelf.avatarTapRecognizer?.isEnabled = item.interaction.inlineNavigationLocation == nil
|
||||||
|
|
||||||
|
if case .loading = item.content {
|
||||||
|
let shimmerNode: ShimmerEffectNode
|
||||||
|
if let current = strongSelf.placeholderNode {
|
||||||
|
shimmerNode = current
|
||||||
|
} else {
|
||||||
|
shimmerNode = ShimmerEffectNode()
|
||||||
|
strongSelf.placeholderNode = shimmerNode
|
||||||
|
strongSelf.addSubnode(shimmerNode)
|
||||||
|
}
|
||||||
|
shimmerNode.frame = CGRect(origin: CGPoint(), size: CGSize(width: layout.contentSize.width, height: layout.contentSize.height - 1.0))
|
||||||
|
if let (rect, size) = strongSelf.absoluteLocation {
|
||||||
|
shimmerNode.updateAbsoluteRect(rect, within: size)
|
||||||
|
}
|
||||||
|
|
||||||
|
var shapes: [ShimmerEffectNode.Shape] = []
|
||||||
|
|
||||||
|
let titleLineWidth: CGFloat = 180.0
|
||||||
|
let dateLineWidth: CGFloat = 36.0
|
||||||
|
let textFirstLineWidth: CGFloat = 240.0
|
||||||
|
let textSecondLineWidth: CGFloat = 200.0
|
||||||
|
let lineDiameter: CGFloat = 10.0
|
||||||
|
|
||||||
|
shapes.append(.circle(avatarFrame))
|
||||||
|
|
||||||
|
let titleFrame = strongSelf.titleNode.frame
|
||||||
|
shapes.append(.roundedRectLine(startPoint: CGPoint(x: titleFrame.minX, y: titleFrame.minY + floor((titleFrame.height - lineDiameter) / 2.0)), width: titleLineWidth, diameter: lineDiameter))
|
||||||
|
|
||||||
|
let textFrame = strongSelf.textNode.textNode.frame
|
||||||
|
shapes.append(.roundedRectLine(startPoint: CGPoint(x: textFrame.minX, y: textFrame.minY + 7.0), width: textFirstLineWidth, diameter: lineDiameter))
|
||||||
|
shapes.append(.roundedRectLine(startPoint: CGPoint(x: textFrame.minX, y: textFrame.minY + 7.0 + lineDiameter + 9.0), width: textSecondLineWidth, diameter: lineDiameter))
|
||||||
|
|
||||||
|
let dateFrame = strongSelf.dateNode.frame
|
||||||
|
shapes.append(.roundedRectLine(startPoint: CGPoint(x: dateFrame.maxX - dateLineWidth, y: dateFrame.minY + 3.0), width: dateLineWidth, diameter: lineDiameter))
|
||||||
|
|
||||||
|
shimmerNode.update(backgroundColor: item.presentationData.theme.list.itemBlocksBackgroundColor, foregroundColor: item.presentationData.theme.list.mediaPlaceholderColor, shimmeringColor: item.presentationData.theme.list.itemBlocksBackgroundColor.withAlphaComponent(0.4), shapes: shapes, size: shimmerNode.frame.size)
|
||||||
|
} else if let shimmerNode = strongSelf.placeholderNode {
|
||||||
|
strongSelf.placeholderNode = nil
|
||||||
|
shimmerNode.removeFromSupernode()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override public func updateAbsoluteRect(_ rect: CGRect, within containerSize: CGSize) {
|
||||||
|
var rect = rect
|
||||||
|
rect.origin.y += self.insets.top
|
||||||
|
self.absoluteLocation = (rect, containerSize)
|
||||||
|
if let shimmerNode = self.placeholderNode {
|
||||||
|
shimmerNode.updateAbsoluteRect(rect, within: containerSize)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@objc private func compoundTextButtonPressed() {
|
@objc private func compoundTextButtonPressed() {
|
||||||
guard let item else {
|
guard let item else {
|
||||||
return
|
return
|
||||||
@ -4686,6 +4812,8 @@ public class ChatListItemNode: ItemListRevealOptionsItemNode {
|
|||||||
switch option.key {
|
switch option.key {
|
||||||
case RevealOptionKey.pin.rawValue:
|
case RevealOptionKey.pin.rawValue:
|
||||||
switch item.content {
|
switch item.content {
|
||||||
|
case .loading:
|
||||||
|
break
|
||||||
case .peer:
|
case .peer:
|
||||||
let itemId: EngineChatList.PinnedItem.Id = .peer(index.messageIndex.id.peerId)
|
let itemId: EngineChatList.PinnedItem.Id = .peer(index.messageIndex.id.peerId)
|
||||||
item.interaction.setItemPinned(itemId, true)
|
item.interaction.setItemPinned(itemId, true)
|
||||||
@ -4694,6 +4822,8 @@ public class ChatListItemNode: ItemListRevealOptionsItemNode {
|
|||||||
}
|
}
|
||||||
case RevealOptionKey.unpin.rawValue:
|
case RevealOptionKey.unpin.rawValue:
|
||||||
switch item.content {
|
switch item.content {
|
||||||
|
case .loading:
|
||||||
|
break
|
||||||
case .peer:
|
case .peer:
|
||||||
let itemId: EngineChatList.PinnedItem.Id = .peer(index.messageIndex.id.peerId)
|
let itemId: EngineChatList.PinnedItem.Id = .peer(index.messageIndex.id.peerId)
|
||||||
item.interaction.setItemPinned(itemId, false)
|
item.interaction.setItemPinned(itemId, false)
|
||||||
@ -4892,6 +5022,8 @@ public class ChatListItemNode: ItemListRevealOptionsItemNode {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
switch item.content {
|
switch item.content {
|
||||||
|
case .loading:
|
||||||
|
break
|
||||||
case let .peer(peerData):
|
case let .peer(peerData):
|
||||||
item.interaction.openStories(.peer(peerData.peer.peerId), self)
|
item.interaction.openStories(.peer(peerData.peer.peerId), self)
|
||||||
case .groupReference:
|
case .groupReference:
|
||||||
|
@ -1747,7 +1747,7 @@ public final class ChatListNode: ListView {
|
|||||||
self.push?(controller)
|
self.push?(controller)
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
let controller = self.context.sharedContext.makePremiumGiftController(context: self.context, source: .chatList(birthdays), completion: nil)
|
let controller = self.context.sharedContext.makePremiumGiftController(context: self.context, source: .chatList(birthdays), transfer: false, completion: nil)
|
||||||
controller.navigationPresentation = .modal
|
controller.navigationPresentation = .modal
|
||||||
self.push?(controller)
|
self.push?(controller)
|
||||||
}
|
}
|
||||||
@ -3629,6 +3629,8 @@ public final class ChatListNode: ListView {
|
|||||||
for item in transition.insertItems {
|
for item in transition.insertItems {
|
||||||
if let item = item.item as? ChatListItem {
|
if let item = item.item as? ChatListItem {
|
||||||
switch item.content {
|
switch item.content {
|
||||||
|
case .loading:
|
||||||
|
break
|
||||||
case let .peer(peerData):
|
case let .peer(peerData):
|
||||||
insertedPeerIds.append(peerData.peer.peerId)
|
insertedPeerIds.append(peerData.peer.peerId)
|
||||||
case .groupReference:
|
case .groupReference:
|
||||||
|
@ -532,6 +532,7 @@ public final class ChatPresentationInterfaceState: Equatable {
|
|||||||
public let businessIntro: TelegramBusinessIntro?
|
public let businessIntro: TelegramBusinessIntro?
|
||||||
public let hasBirthdayToday: Bool
|
public let hasBirthdayToday: Bool
|
||||||
public let adMessage: Message?
|
public let adMessage: Message?
|
||||||
|
public let displayVerificationDescription: Bool
|
||||||
|
|
||||||
public init(chatWallpaper: TelegramWallpaper, theme: PresentationTheme, strings: PresentationStrings, dateTimeFormat: PresentationDateTimeFormat, nameDisplayOrder: PresentationPersonNameOrder, limitsConfiguration: LimitsConfiguration, fontSize: PresentationFontSize, bubbleCorners: PresentationChatBubbleCorners, accountPeerId: PeerId, mode: ChatControllerPresentationMode, chatLocation: ChatLocation, subject: ChatControllerSubject?, peerNearbyData: ChatPeerNearbyData?, greetingData: ChatGreetingData?, pendingUnpinnedAllMessages: Bool, activeGroupCallInfo: ChatActiveGroupCallInfo?, hasActiveGroupCall: Bool, importState: ChatPresentationImportState?, threadData: ThreadData?, isGeneralThreadClosed: Bool?, replyMessage: Message?, accountPeerColor: AccountPeerColor?, businessIntro: TelegramBusinessIntro?) {
|
public init(chatWallpaper: TelegramWallpaper, theme: PresentationTheme, strings: PresentationStrings, dateTimeFormat: PresentationDateTimeFormat, nameDisplayOrder: PresentationPersonNameOrder, limitsConfiguration: LimitsConfiguration, fontSize: PresentationFontSize, bubbleCorners: PresentationChatBubbleCorners, accountPeerId: PeerId, mode: ChatControllerPresentationMode, chatLocation: ChatLocation, subject: ChatControllerSubject?, peerNearbyData: ChatPeerNearbyData?, greetingData: ChatGreetingData?, pendingUnpinnedAllMessages: Bool, activeGroupCallInfo: ChatActiveGroupCallInfo?, hasActiveGroupCall: Bool, importState: ChatPresentationImportState?, threadData: ThreadData?, isGeneralThreadClosed: Bool?, replyMessage: Message?, accountPeerColor: AccountPeerColor?, businessIntro: TelegramBusinessIntro?) {
|
||||||
self.interfaceState = ChatInterfaceState()
|
self.interfaceState = ChatInterfaceState()
|
||||||
@ -617,9 +618,10 @@ public final class ChatPresentationInterfaceState: Equatable {
|
|||||||
self.businessIntro = businessIntro
|
self.businessIntro = businessIntro
|
||||||
self.hasBirthdayToday = false
|
self.hasBirthdayToday = false
|
||||||
self.adMessage = nil
|
self.adMessage = nil
|
||||||
|
self.displayVerificationDescription = false
|
||||||
}
|
}
|
||||||
|
|
||||||
public init(interfaceState: ChatInterfaceState, chatLocation: ChatLocation, renderedPeer: RenderedPeer?, isNotAccessible: Bool, explicitelyCanPinMessages: Bool, contactStatus: ChatContactStatus?, hasBots: Bool, isArchived: Bool, inputTextPanelState: ChatTextInputPanelState, editMessageState: ChatEditInterfaceMessageState?, inputQueryResults: [ChatPresentationInputQueryKind: ChatPresentationInputQueryResult], inputMode: ChatInputMode, titlePanelContexts: [ChatTitlePanelContext], keyboardButtonsMessage: Message?, pinnedMessageId: MessageId?, pinnedMessage: ChatPinnedMessage?, peerIsBlocked: Bool, peerIsMuted: Bool, peerDiscussionId: PeerId?, peerGeoLocation: PeerGeoLocation?, callsAvailable: Bool, callsPrivate: Bool, slowmodeState: ChatSlowmodeState?, chatHistoryState: ChatHistoryNodeHistoryState?, botStartPayload: String?, urlPreview: UrlPreview?, editingUrlPreview: UrlPreview?, search: ChatSearchData?, searchQuerySuggestionResult: ChatPresentationInputQueryResult?, historyFilter: HistoryFilter?, displayHistoryFilterAsList: Bool, presentationReady: Bool, chatWallpaper: TelegramWallpaper, theme: PresentationTheme, strings: PresentationStrings, dateTimeFormat: PresentationDateTimeFormat, nameDisplayOrder: PresentationPersonNameOrder, limitsConfiguration: LimitsConfiguration, fontSize: PresentationFontSize, bubbleCorners: PresentationChatBubbleCorners, accountPeerId: PeerId, mode: ChatControllerPresentationMode, hasScheduledMessages: Bool, autoremoveTimeout: Int32?, subject: ChatControllerSubject?, peerNearbyData: ChatPeerNearbyData?, greetingData: ChatGreetingData?, pendingUnpinnedAllMessages: Bool, activeGroupCallInfo: ChatActiveGroupCallInfo?, hasActiveGroupCall: Bool, importState: ChatPresentationImportState?, reportReason: (String, Data, String?)?, showCommands: Bool, hasBotCommands: Bool, showSendAsPeers: Bool, sendAsPeers: [SendAsPeer]?, botMenuButton: BotMenuButton, showWebView: Bool, currentSendAsPeerId: PeerId?, copyProtectionEnabled: Bool, hasAtLeast3Messages: Bool, hasPlentyOfMessages: Bool, isPremium: Bool, premiumGiftOptions: [CachedPremiumGiftOption], suggestPremiumGift: Bool, forceInputCommandsHidden: Bool, voiceMessagesAvailable: Bool, customEmojiAvailable: Bool, threadData: ThreadData?, forumTopicData: ThreadData?, isGeneralThreadClosed: Bool?, translationState: ChatPresentationTranslationState?, replyMessage: Message?, accountPeerColor: AccountPeerColor?, savedMessagesTopicPeer: EnginePeer?, hasSearchTags: Bool, isPremiumRequiredForMessaging: Bool, hasSavedChats: Bool, appliedBoosts: Int32?, boostsToUnrestrict: Int32?, businessIntro: TelegramBusinessIntro?, hasBirthdayToday: Bool, adMessage: Message?) {
|
public init(interfaceState: ChatInterfaceState, chatLocation: ChatLocation, renderedPeer: RenderedPeer?, isNotAccessible: Bool, explicitelyCanPinMessages: Bool, contactStatus: ChatContactStatus?, hasBots: Bool, isArchived: Bool, inputTextPanelState: ChatTextInputPanelState, editMessageState: ChatEditInterfaceMessageState?, inputQueryResults: [ChatPresentationInputQueryKind: ChatPresentationInputQueryResult], inputMode: ChatInputMode, titlePanelContexts: [ChatTitlePanelContext], keyboardButtonsMessage: Message?, pinnedMessageId: MessageId?, pinnedMessage: ChatPinnedMessage?, peerIsBlocked: Bool, peerIsMuted: Bool, peerDiscussionId: PeerId?, peerGeoLocation: PeerGeoLocation?, callsAvailable: Bool, callsPrivate: Bool, slowmodeState: ChatSlowmodeState?, chatHistoryState: ChatHistoryNodeHistoryState?, botStartPayload: String?, urlPreview: UrlPreview?, editingUrlPreview: UrlPreview?, search: ChatSearchData?, searchQuerySuggestionResult: ChatPresentationInputQueryResult?, historyFilter: HistoryFilter?, displayHistoryFilterAsList: Bool, presentationReady: Bool, chatWallpaper: TelegramWallpaper, theme: PresentationTheme, strings: PresentationStrings, dateTimeFormat: PresentationDateTimeFormat, nameDisplayOrder: PresentationPersonNameOrder, limitsConfiguration: LimitsConfiguration, fontSize: PresentationFontSize, bubbleCorners: PresentationChatBubbleCorners, accountPeerId: PeerId, mode: ChatControllerPresentationMode, hasScheduledMessages: Bool, autoremoveTimeout: Int32?, subject: ChatControllerSubject?, peerNearbyData: ChatPeerNearbyData?, greetingData: ChatGreetingData?, pendingUnpinnedAllMessages: Bool, activeGroupCallInfo: ChatActiveGroupCallInfo?, hasActiveGroupCall: Bool, importState: ChatPresentationImportState?, reportReason: (String, Data, String?)?, showCommands: Bool, hasBotCommands: Bool, showSendAsPeers: Bool, sendAsPeers: [SendAsPeer]?, botMenuButton: BotMenuButton, showWebView: Bool, currentSendAsPeerId: PeerId?, copyProtectionEnabled: Bool, hasAtLeast3Messages: Bool, hasPlentyOfMessages: Bool, isPremium: Bool, premiumGiftOptions: [CachedPremiumGiftOption], suggestPremiumGift: Bool, forceInputCommandsHidden: Bool, voiceMessagesAvailable: Bool, customEmojiAvailable: Bool, threadData: ThreadData?, forumTopicData: ThreadData?, isGeneralThreadClosed: Bool?, translationState: ChatPresentationTranslationState?, replyMessage: Message?, accountPeerColor: AccountPeerColor?, savedMessagesTopicPeer: EnginePeer?, hasSearchTags: Bool, isPremiumRequiredForMessaging: Bool, hasSavedChats: Bool, appliedBoosts: Int32?, boostsToUnrestrict: Int32?, businessIntro: TelegramBusinessIntro?, hasBirthdayToday: Bool, adMessage: Message?, displayVerificationDescription: Bool) {
|
||||||
self.interfaceState = interfaceState
|
self.interfaceState = interfaceState
|
||||||
self.chatLocation = chatLocation
|
self.chatLocation = chatLocation
|
||||||
self.renderedPeer = renderedPeer
|
self.renderedPeer = renderedPeer
|
||||||
@ -703,6 +705,7 @@ public final class ChatPresentationInterfaceState: Equatable {
|
|||||||
self.businessIntro = businessIntro
|
self.businessIntro = businessIntro
|
||||||
self.hasBirthdayToday = hasBirthdayToday
|
self.hasBirthdayToday = hasBirthdayToday
|
||||||
self.adMessage = adMessage
|
self.adMessage = adMessage
|
||||||
|
self.displayVerificationDescription = displayVerificationDescription
|
||||||
}
|
}
|
||||||
|
|
||||||
public static func ==(lhs: ChatPresentationInterfaceState, rhs: ChatPresentationInterfaceState) -> Bool {
|
public static func ==(lhs: ChatPresentationInterfaceState, rhs: ChatPresentationInterfaceState) -> Bool {
|
||||||
@ -961,35 +964,38 @@ public final class ChatPresentationInterfaceState: Equatable {
|
|||||||
if lhs.adMessage?.id != rhs.adMessage?.id {
|
if lhs.adMessage?.id != rhs.adMessage?.id {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
if lhs.displayVerificationDescription != rhs.displayVerificationDescription {
|
||||||
|
return false
|
||||||
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
public func updatedInterfaceState(_ f: (ChatInterfaceState) -> ChatInterfaceState) -> ChatPresentationInterfaceState {
|
public func updatedInterfaceState(_ f: (ChatInterfaceState) -> ChatInterfaceState) -> ChatPresentationInterfaceState {
|
||||||
return ChatPresentationInterfaceState(interfaceState: f(self.interfaceState), chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage)
|
return ChatPresentationInterfaceState(interfaceState: f(self.interfaceState), chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, displayVerificationDescription: self.displayVerificationDescription)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func updatedPeer(_ f: (RenderedPeer?) -> RenderedPeer?) -> ChatPresentationInterfaceState {
|
public func updatedPeer(_ f: (RenderedPeer?) -> RenderedPeer?) -> ChatPresentationInterfaceState {
|
||||||
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: f(self.renderedPeer), isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage)
|
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: f(self.renderedPeer), isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, displayVerificationDescription: self.displayVerificationDescription)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func updatedIsNotAccessible(_ isNotAccessible: Bool) -> ChatPresentationInterfaceState {
|
public func updatedIsNotAccessible(_ isNotAccessible: Bool) -> ChatPresentationInterfaceState {
|
||||||
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage)
|
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, displayVerificationDescription: self.displayVerificationDescription)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func updatedExplicitelyCanPinMessages(_ explicitelyCanPinMessages: Bool) -> ChatPresentationInterfaceState {
|
public func updatedExplicitelyCanPinMessages(_ explicitelyCanPinMessages: Bool) -> ChatPresentationInterfaceState {
|
||||||
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage)
|
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, displayVerificationDescription: self.displayVerificationDescription)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func updatedContactStatus(_ contactStatus: ChatContactStatus?) -> ChatPresentationInterfaceState {
|
public func updatedContactStatus(_ contactStatus: ChatContactStatus?) -> ChatPresentationInterfaceState {
|
||||||
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage)
|
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, displayVerificationDescription: self.displayVerificationDescription)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func updatedHasBots(_ hasBots: Bool) -> ChatPresentationInterfaceState {
|
public func updatedHasBots(_ hasBots: Bool) -> ChatPresentationInterfaceState {
|
||||||
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage)
|
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, displayVerificationDescription: self.displayVerificationDescription)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func updatedIsArchived(_ isArchived: Bool) -> ChatPresentationInterfaceState {
|
public func updatedIsArchived(_ isArchived: Bool) -> ChatPresentationInterfaceState {
|
||||||
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage)
|
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, displayVerificationDescription: self.displayVerificationDescription)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func updatedInputQueryResult(queryKind: ChatPresentationInputQueryKind, _ f: (ChatPresentationInputQueryResult?) -> ChatPresentationInputQueryResult?) -> ChatPresentationInterfaceState {
|
public func updatedInputQueryResult(queryKind: ChatPresentationInputQueryKind, _ f: (ChatPresentationInputQueryResult?) -> ChatPresentationInputQueryResult?) -> ChatPresentationInterfaceState {
|
||||||
@ -1001,279 +1007,283 @@ public final class ChatPresentationInterfaceState: Equatable {
|
|||||||
inputQueryResults.removeValue(forKey: queryKind)
|
inputQueryResults.removeValue(forKey: queryKind)
|
||||||
}
|
}
|
||||||
|
|
||||||
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage)
|
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, displayVerificationDescription: self.displayVerificationDescription)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func updatedInputTextPanelState(_ f: (ChatTextInputPanelState) -> ChatTextInputPanelState) -> ChatPresentationInterfaceState {
|
public func updatedInputTextPanelState(_ f: (ChatTextInputPanelState) -> ChatTextInputPanelState) -> ChatPresentationInterfaceState {
|
||||||
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: f(self.inputTextPanelState), editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage)
|
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: f(self.inputTextPanelState), editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, displayVerificationDescription: self.displayVerificationDescription)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func updatedEditMessageState(_ editMessageState: ChatEditInterfaceMessageState?) -> ChatPresentationInterfaceState {
|
public func updatedEditMessageState(_ editMessageState: ChatEditInterfaceMessageState?) -> ChatPresentationInterfaceState {
|
||||||
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage)
|
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, displayVerificationDescription: self.displayVerificationDescription)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func updatedInputMode(_ f: (ChatInputMode) -> ChatInputMode) -> ChatPresentationInterfaceState {
|
public func updatedInputMode(_ f: (ChatInputMode) -> ChatInputMode) -> ChatPresentationInterfaceState {
|
||||||
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: f(self.inputMode), titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage)
|
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: f(self.inputMode), titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, displayVerificationDescription: self.displayVerificationDescription)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func updatedTitlePanelContext(_ f: ([ChatTitlePanelContext]) -> [ChatTitlePanelContext]) -> ChatPresentationInterfaceState {
|
public func updatedTitlePanelContext(_ f: ([ChatTitlePanelContext]) -> [ChatTitlePanelContext]) -> ChatPresentationInterfaceState {
|
||||||
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: f(self.titlePanelContexts), keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage)
|
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: f(self.titlePanelContexts), keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, displayVerificationDescription: self.displayVerificationDescription)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func updatedKeyboardButtonsMessage(_ message: Message?) -> ChatPresentationInterfaceState {
|
public func updatedKeyboardButtonsMessage(_ message: Message?) -> ChatPresentationInterfaceState {
|
||||||
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: message, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage)
|
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: message, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, displayVerificationDescription: self.displayVerificationDescription)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func updatedPinnedMessageId(_ pinnedMessageId: MessageId?) -> ChatPresentationInterfaceState {
|
public func updatedPinnedMessageId(_ pinnedMessageId: MessageId?) -> ChatPresentationInterfaceState {
|
||||||
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage)
|
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, displayVerificationDescription: self.displayVerificationDescription)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func updatedPinnedMessage(_ pinnedMessage: ChatPinnedMessage?) -> ChatPresentationInterfaceState {
|
public func updatedPinnedMessage(_ pinnedMessage: ChatPinnedMessage?) -> ChatPresentationInterfaceState {
|
||||||
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage)
|
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, displayVerificationDescription: self.displayVerificationDescription)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func updatedPeerIsBlocked(_ peerIsBlocked: Bool) -> ChatPresentationInterfaceState {
|
public func updatedPeerIsBlocked(_ peerIsBlocked: Bool) -> ChatPresentationInterfaceState {
|
||||||
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage)
|
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, displayVerificationDescription: self.displayVerificationDescription)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func updatedPeerIsMuted(_ peerIsMuted: Bool) -> ChatPresentationInterfaceState {
|
public func updatedPeerIsMuted(_ peerIsMuted: Bool) -> ChatPresentationInterfaceState {
|
||||||
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage)
|
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, displayVerificationDescription: self.displayVerificationDescription)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func updatedPeerDiscussionId(_ peerDiscussionId: PeerId?) -> ChatPresentationInterfaceState {
|
public func updatedPeerDiscussionId(_ peerDiscussionId: PeerId?) -> ChatPresentationInterfaceState {
|
||||||
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage)
|
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, displayVerificationDescription: self.displayVerificationDescription)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func updatedPeerGeoLocation(_ peerGeoLocation: PeerGeoLocation?) -> ChatPresentationInterfaceState {
|
public func updatedPeerGeoLocation(_ peerGeoLocation: PeerGeoLocation?) -> ChatPresentationInterfaceState {
|
||||||
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage)
|
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, displayVerificationDescription: self.displayVerificationDescription)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func updatedCallsAvailable(_ callsAvailable: Bool) -> ChatPresentationInterfaceState {
|
public func updatedCallsAvailable(_ callsAvailable: Bool) -> ChatPresentationInterfaceState {
|
||||||
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage)
|
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, displayVerificationDescription: self.displayVerificationDescription)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func updatedCallsPrivate(_ callsPrivate: Bool) -> ChatPresentationInterfaceState {
|
public func updatedCallsPrivate(_ callsPrivate: Bool) -> ChatPresentationInterfaceState {
|
||||||
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage)
|
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, displayVerificationDescription: self.displayVerificationDescription)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func updatedSlowmodeState(_ slowmodeState: ChatSlowmodeState?) -> ChatPresentationInterfaceState {
|
public func updatedSlowmodeState(_ slowmodeState: ChatSlowmodeState?) -> ChatPresentationInterfaceState {
|
||||||
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage)
|
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, displayVerificationDescription: self.displayVerificationDescription)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func updatedBotStartPayload(_ botStartPayload: String?) -> ChatPresentationInterfaceState {
|
public func updatedBotStartPayload(_ botStartPayload: String?) -> ChatPresentationInterfaceState {
|
||||||
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage)
|
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, displayVerificationDescription: self.displayVerificationDescription)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func updatedChatHistoryState(_ chatHistoryState: ChatHistoryNodeHistoryState?) -> ChatPresentationInterfaceState {
|
public func updatedChatHistoryState(_ chatHistoryState: ChatHistoryNodeHistoryState?) -> ChatPresentationInterfaceState {
|
||||||
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage)
|
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, displayVerificationDescription: self.displayVerificationDescription)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func updatedUrlPreview(_ urlPreview: UrlPreview?) -> ChatPresentationInterfaceState {
|
public func updatedUrlPreview(_ urlPreview: UrlPreview?) -> ChatPresentationInterfaceState {
|
||||||
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage)
|
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, displayVerificationDescription: self.displayVerificationDescription)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func updatedEditingUrlPreview(_ editingUrlPreview: UrlPreview?) -> ChatPresentationInterfaceState {
|
public func updatedEditingUrlPreview(_ editingUrlPreview: UrlPreview?) -> ChatPresentationInterfaceState {
|
||||||
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage)
|
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, displayVerificationDescription: self.displayVerificationDescription)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func updatedSearch(_ search: ChatSearchData?) -> ChatPresentationInterfaceState {
|
public func updatedSearch(_ search: ChatSearchData?) -> ChatPresentationInterfaceState {
|
||||||
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage)
|
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, displayVerificationDescription: self.displayVerificationDescription)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func updatedSearchQuerySuggestionResult(_ f: (ChatPresentationInputQueryResult?) -> ChatPresentationInputQueryResult?) -> ChatPresentationInterfaceState {
|
public func updatedSearchQuerySuggestionResult(_ f: (ChatPresentationInputQueryResult?) -> ChatPresentationInputQueryResult?) -> ChatPresentationInterfaceState {
|
||||||
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: f(self.searchQuerySuggestionResult), historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage)
|
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: f(self.searchQuerySuggestionResult), historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, displayVerificationDescription: self.displayVerificationDescription)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func updatedHistoryFilter(_ historyFilter: HistoryFilter?) -> ChatPresentationInterfaceState {
|
public func updatedHistoryFilter(_ historyFilter: HistoryFilter?) -> ChatPresentationInterfaceState {
|
||||||
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage)
|
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, displayVerificationDescription: self.displayVerificationDescription)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func updatedDisplayHistoryFilterAsList(_ displayHistoryFilterAsList: Bool) -> ChatPresentationInterfaceState {
|
public func updatedDisplayHistoryFilterAsList(_ displayHistoryFilterAsList: Bool) -> ChatPresentationInterfaceState {
|
||||||
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage)
|
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, displayVerificationDescription: self.displayVerificationDescription)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func updatedMode(_ mode: ChatControllerPresentationMode) -> ChatPresentationInterfaceState {
|
public func updatedMode(_ mode: ChatControllerPresentationMode) -> ChatPresentationInterfaceState {
|
||||||
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage)
|
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, displayVerificationDescription: self.displayVerificationDescription)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func updatedPresentationReady(_ presentationReady: Bool) -> ChatPresentationInterfaceState {
|
public func updatedPresentationReady(_ presentationReady: Bool) -> ChatPresentationInterfaceState {
|
||||||
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage)
|
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, displayVerificationDescription: self.displayVerificationDescription)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func updatedTheme(_ theme: PresentationTheme) -> ChatPresentationInterfaceState {
|
public func updatedTheme(_ theme: PresentationTheme) -> ChatPresentationInterfaceState {
|
||||||
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage)
|
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, displayVerificationDescription: self.displayVerificationDescription)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func updatedStrings(_ strings: PresentationStrings) -> ChatPresentationInterfaceState {
|
public func updatedStrings(_ strings: PresentationStrings) -> ChatPresentationInterfaceState {
|
||||||
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage)
|
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, displayVerificationDescription: self.displayVerificationDescription)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func updatedDateTimeFormat(_ dateTimeFormat: PresentationDateTimeFormat) -> ChatPresentationInterfaceState {
|
public func updatedDateTimeFormat(_ dateTimeFormat: PresentationDateTimeFormat) -> ChatPresentationInterfaceState {
|
||||||
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage)
|
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, displayVerificationDescription: self.displayVerificationDescription)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func updatedChatWallpaper(_ chatWallpaper: TelegramWallpaper) -> ChatPresentationInterfaceState {
|
public func updatedChatWallpaper(_ chatWallpaper: TelegramWallpaper) -> ChatPresentationInterfaceState {
|
||||||
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage)
|
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, displayVerificationDescription: self.displayVerificationDescription)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func updatedBubbleCorners(_ bubbleCorners: PresentationChatBubbleCorners) -> ChatPresentationInterfaceState {
|
public func updatedBubbleCorners(_ bubbleCorners: PresentationChatBubbleCorners) -> ChatPresentationInterfaceState {
|
||||||
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage)
|
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, displayVerificationDescription: self.displayVerificationDescription)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func updatedHasScheduledMessages(_ hasScheduledMessages: Bool) -> ChatPresentationInterfaceState {
|
public func updatedHasScheduledMessages(_ hasScheduledMessages: Bool) -> ChatPresentationInterfaceState {
|
||||||
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage)
|
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, displayVerificationDescription: self.displayVerificationDescription)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func updatedSubject(_ subject: ChatControllerSubject?) -> ChatPresentationInterfaceState {
|
public func updatedSubject(_ subject: ChatControllerSubject?) -> ChatPresentationInterfaceState {
|
||||||
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage)
|
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, displayVerificationDescription: self.displayVerificationDescription)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func updatedAutoremoveTimeout(_ autoremoveTimeout: Int32?) -> ChatPresentationInterfaceState {
|
public func updatedAutoremoveTimeout(_ autoremoveTimeout: Int32?) -> ChatPresentationInterfaceState {
|
||||||
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage)
|
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, displayVerificationDescription: self.displayVerificationDescription)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func updatedPendingUnpinnedAllMessages(_ pendingUnpinnedAllMessages: Bool) -> ChatPresentationInterfaceState {
|
public func updatedPendingUnpinnedAllMessages(_ pendingUnpinnedAllMessages: Bool) -> ChatPresentationInterfaceState {
|
||||||
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage)
|
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, displayVerificationDescription: self.displayVerificationDescription)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func updatedActiveGroupCallInfo(_ activeGroupCallInfo: ChatActiveGroupCallInfo?) -> ChatPresentationInterfaceState {
|
public func updatedActiveGroupCallInfo(_ activeGroupCallInfo: ChatActiveGroupCallInfo?) -> ChatPresentationInterfaceState {
|
||||||
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage)
|
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, displayVerificationDescription: self.displayVerificationDescription)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func updatedHasActiveGroupCall(_ hasActiveGroupCall: Bool) -> ChatPresentationInterfaceState {
|
public func updatedHasActiveGroupCall(_ hasActiveGroupCall: Bool) -> ChatPresentationInterfaceState {
|
||||||
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage)
|
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, displayVerificationDescription: self.displayVerificationDescription)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func updatedImportState(_ importState: ChatPresentationImportState?) -> ChatPresentationInterfaceState {
|
public func updatedImportState(_ importState: ChatPresentationImportState?) -> ChatPresentationInterfaceState {
|
||||||
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage)
|
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, displayVerificationDescription: self.displayVerificationDescription)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func updatedReportReason(_ reportReason: (String, Data, String?)?) -> ChatPresentationInterfaceState {
|
public func updatedReportReason(_ reportReason: (String, Data, String?)?) -> ChatPresentationInterfaceState {
|
||||||
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage)
|
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, displayVerificationDescription: self.displayVerificationDescription)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func updatedShowCommands(_ showCommands: Bool) -> ChatPresentationInterfaceState {
|
public func updatedShowCommands(_ showCommands: Bool) -> ChatPresentationInterfaceState {
|
||||||
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage)
|
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, displayVerificationDescription: self.displayVerificationDescription)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func updatedHasBotCommands(_ hasBotCommands: Bool) -> ChatPresentationInterfaceState {
|
public func updatedHasBotCommands(_ hasBotCommands: Bool) -> ChatPresentationInterfaceState {
|
||||||
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage)
|
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, displayVerificationDescription: self.displayVerificationDescription)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func updatedShowSendAsPeers(_ showSendAsPeers: Bool) -> ChatPresentationInterfaceState {
|
public func updatedShowSendAsPeers(_ showSendAsPeers: Bool) -> ChatPresentationInterfaceState {
|
||||||
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage)
|
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, displayVerificationDescription: self.displayVerificationDescription)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func updatedSendAsPeers(_ sendAsPeers: [SendAsPeer]?) -> ChatPresentationInterfaceState {
|
public func updatedSendAsPeers(_ sendAsPeers: [SendAsPeer]?) -> ChatPresentationInterfaceState {
|
||||||
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage)
|
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, displayVerificationDescription: self.displayVerificationDescription)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func updatedCurrentSendAsPeerId(_ currentSendAsPeerId: PeerId?) -> ChatPresentationInterfaceState {
|
public func updatedCurrentSendAsPeerId(_ currentSendAsPeerId: PeerId?) -> ChatPresentationInterfaceState {
|
||||||
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage)
|
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, displayVerificationDescription: self.displayVerificationDescription)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func updatedBotMenuButton(_ botMenuButton: BotMenuButton) -> ChatPresentationInterfaceState {
|
public func updatedBotMenuButton(_ botMenuButton: BotMenuButton) -> ChatPresentationInterfaceState {
|
||||||
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage)
|
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, displayVerificationDescription: self.displayVerificationDescription)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func updatedShowWebView(_ showWebView: Bool) -> ChatPresentationInterfaceState {
|
public func updatedShowWebView(_ showWebView: Bool) -> ChatPresentationInterfaceState {
|
||||||
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage)
|
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, displayVerificationDescription: self.displayVerificationDescription)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func updatedCopyProtectionEnabled(_ copyProtectionEnabled: Bool) -> ChatPresentationInterfaceState {
|
public func updatedCopyProtectionEnabled(_ copyProtectionEnabled: Bool) -> ChatPresentationInterfaceState {
|
||||||
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage)
|
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, displayVerificationDescription: self.displayVerificationDescription)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func updatedHasAtLeast3Messages(_ hasAtLeast3Messages: Bool) -> ChatPresentationInterfaceState {
|
public func updatedHasAtLeast3Messages(_ hasAtLeast3Messages: Bool) -> ChatPresentationInterfaceState {
|
||||||
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage)
|
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, displayVerificationDescription: self.displayVerificationDescription)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func updatedHasPlentyOfMessages(_ hasPlentyOfMessages: Bool) -> ChatPresentationInterfaceState {
|
public func updatedHasPlentyOfMessages(_ hasPlentyOfMessages: Bool) -> ChatPresentationInterfaceState {
|
||||||
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage)
|
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, displayVerificationDescription: self.displayVerificationDescription)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func updatedIsPremium(_ isPremium: Bool) -> ChatPresentationInterfaceState {
|
public func updatedIsPremium(_ isPremium: Bool) -> ChatPresentationInterfaceState {
|
||||||
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage)
|
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, displayVerificationDescription: self.displayVerificationDescription)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func updatedPremiumGiftOptions(_ premiumGiftOptions: [CachedPremiumGiftOption]) -> ChatPresentationInterfaceState {
|
public func updatedPremiumGiftOptions(_ premiumGiftOptions: [CachedPremiumGiftOption]) -> ChatPresentationInterfaceState {
|
||||||
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage)
|
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, displayVerificationDescription: self.displayVerificationDescription)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func updatedSuggestPremiumGift(_ suggestPremiumGift: Bool) -> ChatPresentationInterfaceState {
|
public func updatedSuggestPremiumGift(_ suggestPremiumGift: Bool) -> ChatPresentationInterfaceState {
|
||||||
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage)
|
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, displayVerificationDescription: self.displayVerificationDescription)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func updatedForceInputCommandsHidden(_ forceInputCommandsHidden: Bool) -> ChatPresentationInterfaceState {
|
public func updatedForceInputCommandsHidden(_ forceInputCommandsHidden: Bool) -> ChatPresentationInterfaceState {
|
||||||
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage)
|
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, displayVerificationDescription: self.displayVerificationDescription)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func updatedVoiceMessagesAvailable(_ voiceMessagesAvailable: Bool) -> ChatPresentationInterfaceState {
|
public func updatedVoiceMessagesAvailable(_ voiceMessagesAvailable: Bool) -> ChatPresentationInterfaceState {
|
||||||
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage)
|
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, displayVerificationDescription: self.displayVerificationDescription)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func updatedCustomEmojiAvailable(_ customEmojiAvailable: Bool) -> ChatPresentationInterfaceState {
|
public func updatedCustomEmojiAvailable(_ customEmojiAvailable: Bool) -> ChatPresentationInterfaceState {
|
||||||
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage)
|
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, displayVerificationDescription: self.displayVerificationDescription)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func updatedThreadData(_ threadData: ThreadData?) -> ChatPresentationInterfaceState {
|
public func updatedThreadData(_ threadData: ThreadData?) -> ChatPresentationInterfaceState {
|
||||||
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage)
|
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, displayVerificationDescription: self.displayVerificationDescription)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func updatedForumTopicData(_ forumTopicData: ThreadData?) -> ChatPresentationInterfaceState {
|
public func updatedForumTopicData(_ forumTopicData: ThreadData?) -> ChatPresentationInterfaceState {
|
||||||
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage)
|
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, displayVerificationDescription: self.displayVerificationDescription)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func updatedIsGeneralThreadClosed(_ isGeneralThreadClosed: Bool?) -> ChatPresentationInterfaceState {
|
public func updatedIsGeneralThreadClosed(_ isGeneralThreadClosed: Bool?) -> ChatPresentationInterfaceState {
|
||||||
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage)
|
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, displayVerificationDescription: self.displayVerificationDescription)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func updatedTranslationState(_ translationState: ChatPresentationTranslationState?) -> ChatPresentationInterfaceState {
|
public func updatedTranslationState(_ translationState: ChatPresentationTranslationState?) -> ChatPresentationInterfaceState {
|
||||||
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage)
|
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, displayVerificationDescription: self.displayVerificationDescription)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func updatedReplyMessage(_ replyMessage: Message?) -> ChatPresentationInterfaceState {
|
public func updatedReplyMessage(_ replyMessage: Message?) -> ChatPresentationInterfaceState {
|
||||||
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage)
|
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, displayVerificationDescription: self.displayVerificationDescription)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func updatedAccountPeerColor(_ accountPeerColor: AccountPeerColor?) -> ChatPresentationInterfaceState {
|
public func updatedAccountPeerColor(_ accountPeerColor: AccountPeerColor?) -> ChatPresentationInterfaceState {
|
||||||
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage)
|
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, displayVerificationDescription: self.displayVerificationDescription)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func updatedSavedMessagesTopicPeer(_ savedMessagesTopicPeer: EnginePeer?) -> ChatPresentationInterfaceState {
|
public func updatedSavedMessagesTopicPeer(_ savedMessagesTopicPeer: EnginePeer?) -> ChatPresentationInterfaceState {
|
||||||
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage)
|
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, displayVerificationDescription: self.displayVerificationDescription)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func updatedHasSearchTags(_ hasSearchTags: Bool) -> ChatPresentationInterfaceState {
|
public func updatedHasSearchTags(_ hasSearchTags: Bool) -> ChatPresentationInterfaceState {
|
||||||
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage)
|
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, displayVerificationDescription: self.displayVerificationDescription)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func updatedIsPremiumRequiredForMessaging(_ isPremiumRequiredForMessaging: Bool) -> ChatPresentationInterfaceState {
|
public func updatedIsPremiumRequiredForMessaging(_ isPremiumRequiredForMessaging: Bool) -> ChatPresentationInterfaceState {
|
||||||
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: isPremiumRequiredForMessaging, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage)
|
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: isPremiumRequiredForMessaging, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, displayVerificationDescription: self.displayVerificationDescription)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func updatedHasSavedChats(_ hasSavedChats: Bool) -> ChatPresentationInterfaceState {
|
public func updatedHasSavedChats(_ hasSavedChats: Bool) -> ChatPresentationInterfaceState {
|
||||||
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, hasSavedChats: hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage)
|
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, hasSavedChats: hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, displayVerificationDescription: self.displayVerificationDescription)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func updatedAppliedBoosts(_ appliedBoosts: Int32?) -> ChatPresentationInterfaceState {
|
public func updatedAppliedBoosts(_ appliedBoosts: Int32?) -> ChatPresentationInterfaceState {
|
||||||
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, hasSavedChats: self.hasSavedChats, appliedBoosts: appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage)
|
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, hasSavedChats: self.hasSavedChats, appliedBoosts: appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, displayVerificationDescription: self.displayVerificationDescription)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func updatedBoostsToUnrestrict(_ boostsToUnrestrict: Int32?) -> ChatPresentationInterfaceState {
|
public func updatedBoostsToUnrestrict(_ boostsToUnrestrict: Int32?) -> ChatPresentationInterfaceState {
|
||||||
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage)
|
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, displayVerificationDescription: self.displayVerificationDescription)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func updatedBusinessIntro(_ businessIntro: TelegramBusinessIntro?) -> ChatPresentationInterfaceState {
|
public func updatedBusinessIntro(_ businessIntro: TelegramBusinessIntro?) -> ChatPresentationInterfaceState {
|
||||||
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage)
|
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, displayVerificationDescription: self.displayVerificationDescription)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func updatedHasBirthdayToday(_ hasBirthdayToday: Bool) -> ChatPresentationInterfaceState {
|
public func updatedHasBirthdayToday(_ hasBirthdayToday: Bool) -> ChatPresentationInterfaceState {
|
||||||
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: hasBirthdayToday, adMessage: self.adMessage)
|
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: hasBirthdayToday, adMessage: self.adMessage, displayVerificationDescription: self.displayVerificationDescription)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func updatedAdMessage(_ adMessage: Message?) -> ChatPresentationInterfaceState {
|
public func updatedAdMessage(_ adMessage: Message?) -> ChatPresentationInterfaceState {
|
||||||
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: adMessage)
|
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: adMessage, displayVerificationDescription: self.displayVerificationDescription)
|
||||||
|
}
|
||||||
|
|
||||||
|
public func updatedDisplayVerificationDescription(_ displayVerificationDescription: Bool) -> ChatPresentationInterfaceState {
|
||||||
|
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, displayVerificationDescription: displayVerificationDescription)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,12 +22,14 @@ public final class LottieAnimationComponent: Component {
|
|||||||
public var name: String
|
public var name: String
|
||||||
public var mode: Mode
|
public var mode: Mode
|
||||||
public var range: (CGFloat, CGFloat)?
|
public var range: (CGFloat, CGFloat)?
|
||||||
|
public var speed: CGFloat
|
||||||
public var waitForCompletion: Bool
|
public var waitForCompletion: Bool
|
||||||
|
|
||||||
public init(name: String, mode: Mode, range: (CGFloat, CGFloat)? = nil, waitForCompletion: Bool = true) {
|
public init(name: String, mode: Mode, range: (CGFloat, CGFloat)? = nil, speed: CGFloat = 1.0, waitForCompletion: Bool = true) {
|
||||||
self.name = name
|
self.name = name
|
||||||
self.mode = mode
|
self.mode = mode
|
||||||
self.range = range
|
self.range = range
|
||||||
|
self.speed = speed
|
||||||
self.waitForCompletion = waitForCompletion
|
self.waitForCompletion = waitForCompletion
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -38,6 +40,9 @@ public final class LottieAnimationComponent: Component {
|
|||||||
if lhs.mode != rhs.mode {
|
if lhs.mode != rhs.mode {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
if lhs.speed != rhs.speed {
|
||||||
|
return false
|
||||||
|
}
|
||||||
if let lhsRange = lhs.range, let rhsRange = rhs.range, lhsRange != rhsRange {
|
if let lhsRange = lhs.range, let rhsRange = rhs.range, lhsRange != rhsRange {
|
||||||
return false
|
return false
|
||||||
} else if (lhs.range == nil) != (rhs.range == nil) {
|
} else if (lhs.range == nil) != (rhs.range == nil) {
|
||||||
@ -203,7 +208,7 @@ public final class LottieAnimationComponent: Component {
|
|||||||
view.loopMode = .playOnce
|
view.loopMode = .playOnce
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
view.animationSpeed = 1.0
|
view.animationSpeed = component.animation.speed
|
||||||
view.backgroundColor = .clear
|
view.backgroundColor = .clear
|
||||||
view.isOpaque = false
|
view.isOpaque = false
|
||||||
|
|
||||||
|
@ -17,6 +17,7 @@ public enum ContactListActionItemHighlight {
|
|||||||
public class ContactListActionItem: ListViewItem, ListViewItemWithHeader {
|
public class ContactListActionItem: ListViewItem, ListViewItemWithHeader {
|
||||||
let presentationData: ItemListPresentationData
|
let presentationData: ItemListPresentationData
|
||||||
let title: String
|
let title: String
|
||||||
|
let subtitle: String?
|
||||||
let icon: ContactListActionItemIcon
|
let icon: ContactListActionItemIcon
|
||||||
let highlight: ContactListActionItemHighlight
|
let highlight: ContactListActionItemHighlight
|
||||||
let clearHighlightAutomatically: Bool
|
let clearHighlightAutomatically: Bool
|
||||||
@ -24,9 +25,10 @@ public class ContactListActionItem: ListViewItem, ListViewItemWithHeader {
|
|||||||
let action: () -> Void
|
let action: () -> Void
|
||||||
public let header: ListViewItemHeader?
|
public let header: ListViewItemHeader?
|
||||||
|
|
||||||
public init(presentationData: ItemListPresentationData, title: String, icon: ContactListActionItemIcon, highlight: ContactListActionItemHighlight = .cell, clearHighlightAutomatically: Bool = true, accessible: Bool = true, header: ListViewItemHeader?, action: @escaping () -> Void) {
|
public init(presentationData: ItemListPresentationData, title: String, subtitle: String? = nil, icon: ContactListActionItemIcon, highlight: ContactListActionItemHighlight = .cell, clearHighlightAutomatically: Bool = true, accessible: Bool = true, header: ListViewItemHeader?, action: @escaping () -> Void) {
|
||||||
self.presentationData = presentationData
|
self.presentationData = presentationData
|
||||||
self.title = title
|
self.title = title
|
||||||
|
self.subtitle = subtitle
|
||||||
self.icon = icon
|
self.icon = icon
|
||||||
self.highlight = highlight
|
self.highlight = highlight
|
||||||
self.header = header
|
self.header = header
|
||||||
@ -204,7 +206,11 @@ class ContactListActionItemNode: ListViewItemNode {
|
|||||||
strongSelf.backgroundNode.backgroundColor = item.presentationData.theme.list.plainBackgroundColor
|
strongSelf.backgroundNode.backgroundColor = item.presentationData.theme.list.plainBackgroundColor
|
||||||
strongSelf.highlightedBackgroundNode.backgroundColor = item.presentationData.theme.list.itemHighlightedBackgroundColor
|
strongSelf.highlightedBackgroundNode.backgroundColor = item.presentationData.theme.list.itemHighlightedBackgroundColor
|
||||||
|
|
||||||
strongSelf.iconNode.image = generateTintedImage(image: item.icon.image, color: item.presentationData.theme.list.itemAccentColor)
|
if item.subtitle != nil {
|
||||||
|
strongSelf.iconNode.image = item.icon.image
|
||||||
|
} else {
|
||||||
|
strongSelf.iconNode.image = generateTintedImage(image: item.icon.image, color: item.presentationData.theme.list.itemAccentColor)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if item.accessible && strongSelf.activateArea.supernode == nil {
|
if item.accessible && strongSelf.activateArea.supernode == nil {
|
||||||
|
@ -144,7 +144,7 @@ private enum ContactListNodeEntry: Comparable, Identifiable {
|
|||||||
interaction.authorize()
|
interaction.authorize()
|
||||||
})
|
})
|
||||||
case let .option(_, option, header, _, _):
|
case let .option(_, option, header, _, _):
|
||||||
return ContactListActionItem(presentationData: ItemListPresentationData(presentationData), title: option.title, icon: option.icon, clearHighlightAutomatically: option.clearHighlightAutomatically, header: header, action: option.action)
|
return ContactListActionItem(presentationData: ItemListPresentationData(presentationData), title: option.title, subtitle: option.subtitle, icon: option.icon, clearHighlightAutomatically: option.clearHighlightAutomatically, header: header, action: option.action)
|
||||||
case let .peer(_, peer, presence, header, selection, _, strings, dateTimeFormat, nameSortOrder, nameDisplayOrder, displayCallIcons, hasMoreButton, enabled, storyData, requiresPremiumForMessaging):
|
case let .peer(_, peer, presence, header, selection, _, strings, dateTimeFormat, nameSortOrder, nameDisplayOrder, displayCallIcons, hasMoreButton, enabled, storyData, requiresPremiumForMessaging):
|
||||||
var status: ContactsPeerItemStatus
|
var status: ContactsPeerItemStatus
|
||||||
let itemPeer: ContactsPeerItemPeer
|
let itemPeer: ContactsPeerItemPeer
|
||||||
@ -541,7 +541,7 @@ private func contactListNodeEntries(accountPeer: EnginePeer?, peers: [ContactLis
|
|||||||
if !topPeers.isEmpty {
|
if !topPeers.isEmpty {
|
||||||
let hasDeselectAll = !(selectionState?.selectedPeerIndices ?? [:]).isEmpty
|
let hasDeselectAll = !(selectionState?.selectedPeerIndices ?? [:]).isEmpty
|
||||||
|
|
||||||
let header: ListViewItemHeader? = ChatListSearchItemHeader(type: .text(strings.Premium_Gift_ContactSelection_FrequentContacts.uppercased(), AnyHashable(hasDeselectAll ? 1 : 0)), theme: theme, strings: strings, actionTitle: hasDeselectAll ? strings.Premium_Gift_ContactSelection_DeselectAll.uppercased() : nil, action: {
|
let header: ListViewItemHeader? = ChatListSearchItemHeader(type: .text(strings.Premium_Gift_ContactSelection_FrequentContacts.uppercased(), AnyHashable(hasDeselectAll ? 1 : 0)), theme: theme, strings: strings, actionTitle: hasDeselectAll ? strings.Premium_Gift_ContactSelection_DeselectAll.uppercased() : nil, action: { _ in
|
||||||
interaction.deselectAll()
|
interaction.deselectAll()
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -585,7 +585,7 @@ private func contactListNodeEntries(accountPeer: EnginePeer?, peers: [ContactLis
|
|||||||
if peerIds.count > 1 {
|
if peerIds.count > 1 {
|
||||||
actionTitle = allSelected ? strings.Premium_Gift_ContactSelection_DeselectAll.uppercased() : strings.Premium_Gift_ContactSelection_SelectAll.uppercased()
|
actionTitle = allSelected ? strings.Premium_Gift_ContactSelection_DeselectAll.uppercased() : strings.Premium_Gift_ContactSelection_SelectAll.uppercased()
|
||||||
}
|
}
|
||||||
let header: ListViewItemHeader? = ChatListSearchItemHeader(type: .text(title.uppercased(), AnyHashable(10 * sectionId + (allSelected ? 1 : 0))), theme: theme, strings: strings, actionTitle: actionTitle, action: {
|
let header: ListViewItemHeader? = ChatListSearchItemHeader(type: .text(title.uppercased(), AnyHashable(10 * sectionId + (allSelected ? 1 : 0))), theme: theme, strings: strings, actionTitle: actionTitle, action: { _ in
|
||||||
var existingPeerIds = Set<EnginePeer.Id>()
|
var existingPeerIds = Set<EnginePeer.Id>()
|
||||||
var peers: [EnginePeer] = []
|
var peers: [EnginePeer] = []
|
||||||
for peer in topPeers {
|
for peer in topPeers {
|
||||||
@ -645,7 +645,7 @@ private func contactListNodeEntries(accountPeer: EnginePeer?, peers: [ContactLis
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let header: ListViewItemHeader? = ChatListSearchItemHeader(type: .text(strings.Premium_Gift_ContactSelection_FrequentContacts.uppercased(), AnyHashable(hasDeselectAll ? 1 : 0)), theme: theme, strings: strings, actionTitle: hasDeselectAll ? strings.Premium_Gift_ContactSelection_DeselectAll.uppercased() : nil, action: {
|
let header: ListViewItemHeader? = ChatListSearchItemHeader(type: .text(strings.Premium_Gift_ContactSelection_FrequentContacts.uppercased(), AnyHashable(hasDeselectAll ? 1 : 0)), theme: theme, strings: strings, actionTitle: hasDeselectAll ? strings.Premium_Gift_ContactSelection_DeselectAll.uppercased() : nil, action: { _ in
|
||||||
interaction.deselectAll()
|
interaction.deselectAll()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -789,15 +789,16 @@ public class ContactsPeerItemNode: ItemListRevealOptionsItemNode {
|
|||||||
} else if peer.isFake {
|
} else if peer.isFake {
|
||||||
credibilityIcon = .text(color: item.presentationData.theme.chat.message.incoming.scamColor, string: item.presentationData.strings.Message_FakeAccount.uppercased())
|
credibilityIcon = .text(color: item.presentationData.theme.chat.message.incoming.scamColor, string: item.presentationData.strings.Message_FakeAccount.uppercased())
|
||||||
} else if let emojiStatus = peer.emojiStatus {
|
} else if let emojiStatus = peer.emojiStatus {
|
||||||
if case .channel = peer, peer.isVerified {
|
|
||||||
verifiedIcon = .verified(fillColor: item.presentationData.theme.list.itemCheckColors.fillColor, foregroundColor: item.presentationData.theme.list.itemCheckColors.foregroundColor, sizeType: .compact)
|
|
||||||
}
|
|
||||||
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))
|
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))
|
||||||
} else if peer.isVerified {
|
|
||||||
credibilityIcon = .verified(fillColor: item.presentationData.theme.list.itemCheckColors.fillColor, foregroundColor: item.presentationData.theme.list.itemCheckColors.foregroundColor, sizeType: .compact)
|
|
||||||
} else if peer.isPremium && !premiumConfiguration.isPremiumDisabled {
|
} else if peer.isPremium && !premiumConfiguration.isPremiumDisabled {
|
||||||
credibilityIcon = .premium(color: item.presentationData.theme.list.itemAccentColor)
|
credibilityIcon = .premium(color: item.presentationData.theme.list.itemAccentColor)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if peer.isVerified {
|
||||||
|
verifiedIcon = .verified(fillColor: item.presentationData.theme.list.itemCheckColors.fillColor, foregroundColor: item.presentationData.theme.list.itemCheckColors.foregroundColor, sizeType: .compact)
|
||||||
|
} else if let verification = peer.verification {
|
||||||
|
verifiedIcon = .animation(content: .customEmoji(fileId: verification.iconFileId), size: CGSize(width: 32.0, height: 32.0), placeholderColor: item.presentationData.theme.list.mediaPlaceholderColor, themeColor: item.presentationData.theme.list.itemAccentColor, loopMode: .count(0))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
case .deviceContact:
|
case .deviceContact:
|
||||||
break
|
break
|
||||||
@ -1349,7 +1350,48 @@ public class ContactsPeerItemNode: ItemListRevealOptionsItemNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let _ = titleApply()
|
let _ = titleApply()
|
||||||
let titleFrame = titleFrame.offsetBy(dx: revealOffset, dy: 0.0)
|
|
||||||
|
var titleLeftOffset: CGFloat = 0.0
|
||||||
|
if let verifiedIcon {
|
||||||
|
let animationCache = item.context.animationCache
|
||||||
|
let animationRenderer = item.context.animationRenderer
|
||||||
|
|
||||||
|
let verifiedIconView: ComponentHostView<Empty>
|
||||||
|
if let current = strongSelf.verifiedIconView {
|
||||||
|
verifiedIconView = current
|
||||||
|
} else {
|
||||||
|
verifiedIconView = ComponentHostView<Empty>()
|
||||||
|
strongSelf.offsetContainerNode.view.addSubview(verifiedIconView)
|
||||||
|
strongSelf.verifiedIconView = verifiedIconView
|
||||||
|
}
|
||||||
|
|
||||||
|
let verifiedIconComponent = EmojiStatusComponent(
|
||||||
|
context: item.context,
|
||||||
|
animationCache: animationCache,
|
||||||
|
animationRenderer: animationRenderer,
|
||||||
|
content: verifiedIcon,
|
||||||
|
isVisibleForAnimations: strongSelf.visibilityStatus,
|
||||||
|
action: nil,
|
||||||
|
emojiFileUpdated: nil
|
||||||
|
)
|
||||||
|
strongSelf.verifiedIconComponent = verifiedIconComponent
|
||||||
|
|
||||||
|
let iconSize = verifiedIconView.update(
|
||||||
|
transition: .immediate,
|
||||||
|
component: AnyComponent(verifiedIconComponent),
|
||||||
|
environment: {},
|
||||||
|
containerSize: CGSize(width: 16.0, height: 16.0)
|
||||||
|
)
|
||||||
|
|
||||||
|
transition.updateFrame(view: verifiedIconView, frame: CGRect(origin: CGPoint(x: titleFrame.minX, y: floorToScreenPixels(titleFrame.midY - iconSize.height / 2.0)), size: iconSize))
|
||||||
|
|
||||||
|
titleLeftOffset += iconSize.width + 4.0
|
||||||
|
} else if let verifiedIconView = strongSelf.verifiedIconView {
|
||||||
|
strongSelf.verifiedIconView = nil
|
||||||
|
verifiedIconView.removeFromSuperview()
|
||||||
|
}
|
||||||
|
|
||||||
|
let titleFrame = titleFrame.offsetBy(dx: revealOffset + titleLeftOffset, dy: 0.0)
|
||||||
transition.updateFrame(node: strongSelf.titleNode, frame: titleFrame)
|
transition.updateFrame(node: strongSelf.titleNode, frame: titleFrame)
|
||||||
|
|
||||||
strongSelf.titleNode.alpha = item.enabled ? 1.0 : 0.4
|
strongSelf.titleNode.alpha = item.enabled ? 1.0 : 0.4
|
||||||
@ -1421,46 +1463,7 @@ public class ContactsPeerItemNode: ItemListRevealOptionsItemNode {
|
|||||||
strongSelf.credibilityIconView = nil
|
strongSelf.credibilityIconView = nil
|
||||||
credibilityIconView.removeFromSuperview()
|
credibilityIconView.removeFromSuperview()
|
||||||
}
|
}
|
||||||
|
|
||||||
if let verifiedIcon {
|
|
||||||
let animationCache = item.context.animationCache
|
|
||||||
let animationRenderer = item.context.animationRenderer
|
|
||||||
|
|
||||||
let verifiedIconView: ComponentHostView<Empty>
|
|
||||||
if let current = strongSelf.verifiedIconView {
|
|
||||||
verifiedIconView = current
|
|
||||||
} else {
|
|
||||||
verifiedIconView = ComponentHostView<Empty>()
|
|
||||||
strongSelf.offsetContainerNode.view.addSubview(verifiedIconView)
|
|
||||||
strongSelf.verifiedIconView = verifiedIconView
|
|
||||||
}
|
|
||||||
|
|
||||||
let verifiedIconComponent = EmojiStatusComponent(
|
|
||||||
context: item.context,
|
|
||||||
animationCache: animationCache,
|
|
||||||
animationRenderer: animationRenderer,
|
|
||||||
content: verifiedIcon,
|
|
||||||
isVisibleForAnimations: strongSelf.visibilityStatus,
|
|
||||||
action: nil,
|
|
||||||
emojiFileUpdated: nil
|
|
||||||
)
|
|
||||||
strongSelf.verifiedIconComponent = verifiedIconComponent
|
|
||||||
|
|
||||||
let iconSize = verifiedIconView.update(
|
|
||||||
transition: .immediate,
|
|
||||||
component: AnyComponent(verifiedIconComponent),
|
|
||||||
environment: {},
|
|
||||||
containerSize: CGSize(width: 20.0, height: 20.0)
|
|
||||||
)
|
|
||||||
|
|
||||||
nextIconX += 4.0
|
|
||||||
transition.updateFrame(view: verifiedIconView, frame: CGRect(origin: CGPoint(x: nextIconX, y: floorToScreenPixels(titleFrame.midY - iconSize.height / 2.0)), size: iconSize))
|
|
||||||
nextIconX += iconSize.width
|
|
||||||
} else if let verifiedIconView = strongSelf.verifiedIconView {
|
|
||||||
strongSelf.verifiedIconView = nil
|
|
||||||
verifiedIconView.removeFromSuperview()
|
|
||||||
}
|
|
||||||
|
|
||||||
var additionalRightInset: CGFloat = 0.0
|
var additionalRightInset: CGFloat = 0.0
|
||||||
if let (titleLayout, titleApply) = actionButtonTitleLayoutAndApply {
|
if let (titleLayout, titleApply) = actionButtonTitleLayoutAndApply {
|
||||||
let actionButtonTitleNode = titleApply()
|
let actionButtonTitleNode = titleApply()
|
||||||
|
@ -1495,8 +1495,32 @@ final class ContextControllerExtractedPresentationNode: ASDisplayNode, ContextCo
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let completeWithActionStack = itemContentNode == nil && controllerContentNode == nil
|
var restoreOverlayViews: [() -> Void] = []
|
||||||
|
if let overlayViews = self.getController()?.getOverlayViews?(), !overlayViews.isEmpty, let itemContentNode, let contentNodeSupernode = itemContentNode.supernode {
|
||||||
|
for view in overlayViews {
|
||||||
|
let originalFrame = view.frame
|
||||||
|
let originalSuperview = view.superview
|
||||||
|
let originalIndex = view.superview?.subviews.firstIndex(of: view)
|
||||||
|
let originalGroupOpacity = view.layer.allowsGroupOpacity
|
||||||
|
|
||||||
|
contentNodeSupernode.view.insertSubview(view, aboveSubview: itemContentNode.view)
|
||||||
|
view.frame = view.convert(view.bounds, to: contentNodeSupernode.view)
|
||||||
|
view.layer.allowsGroupOpacity = true
|
||||||
|
view.layer.animateAlpha(from: 0.0, to: view.alpha, duration: 0.2)
|
||||||
|
|
||||||
|
restoreOverlayViews.append({
|
||||||
|
view.frame = originalFrame
|
||||||
|
view.layer.allowsGroupOpacity = originalGroupOpacity
|
||||||
|
if let originalIndex {
|
||||||
|
originalSuperview?.insertSubview(view, at: originalIndex)
|
||||||
|
} else {
|
||||||
|
originalSuperview?.addSubview(view)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let completeWithActionStack = itemContentNode == nil && controllerContentNode == nil
|
||||||
if let contentNode = itemContentNode {
|
if let contentNode = itemContentNode {
|
||||||
contentNode.containingItem.willUpdateIsExtractedToContextPreview?(false, transition)
|
contentNode.containingItem.willUpdateIsExtractedToContextPreview?(false, transition)
|
||||||
|
|
||||||
@ -1542,7 +1566,6 @@ final class ContextControllerExtractedPresentationNode: ASDisplayNode, ContextCo
|
|||||||
additive: true,
|
additive: true,
|
||||||
completion: { [weak self] _ in
|
completion: { [weak self] _ in
|
||||||
Queue.mainQueue().after(reactionContextNodeIsAnimatingOut ? 0.2 * UIView.animationDurationFactor() : 0.0, {
|
Queue.mainQueue().after(reactionContextNodeIsAnimatingOut ? 0.2 * UIView.animationDurationFactor() : 0.0, {
|
||||||
|
|
||||||
if let strongSelf = self, let contentNode = strongSelf.itemContentNode {
|
if let strongSelf = self, let contentNode = strongSelf.itemContentNode {
|
||||||
switch contentNode.containingItem {
|
switch contentNode.containingItem {
|
||||||
case let .node(containingNode):
|
case let .node(containingNode):
|
||||||
@ -1555,6 +1578,7 @@ final class ContextControllerExtractedPresentationNode: ASDisplayNode, ContextCo
|
|||||||
contentNode.containingItem.isExtractedToContextPreview = false
|
contentNode.containingItem.isExtractedToContextPreview = false
|
||||||
contentNode.containingItem.isExtractedToContextPreviewUpdated?(false)
|
contentNode.containingItem.isExtractedToContextPreviewUpdated?(false)
|
||||||
|
|
||||||
|
restoreOverlayViews.forEach({ $0() })
|
||||||
completion()
|
completion()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -1595,6 +1619,7 @@ final class ContextControllerExtractedPresentationNode: ASDisplayNode, ContextCo
|
|||||||
}
|
}
|
||||||
|
|
||||||
contentNode.layer.animateAlpha(from: 1.0, to: 0.0, duration: duration * 0.8, removeOnCompletion: false, completion: { _ in
|
contentNode.layer.animateAlpha(from: 1.0, to: 0.0, duration: duration * 0.8, removeOnCompletion: false, completion: { _ in
|
||||||
|
restoreOverlayViews.forEach({ $0() })
|
||||||
completion()
|
completion()
|
||||||
})
|
})
|
||||||
contentNode.layer.animate(
|
contentNode.layer.animate(
|
||||||
@ -1630,6 +1655,7 @@ final class ContextControllerExtractedPresentationNode: ASDisplayNode, ContextCo
|
|||||||
removeOnCompletion: false,
|
removeOnCompletion: false,
|
||||||
completion: { _ in
|
completion: { _ in
|
||||||
if completeWithActionStack {
|
if completeWithActionStack {
|
||||||
|
restoreOverlayViews.forEach({ $0() })
|
||||||
completion()
|
completion()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1657,18 +1683,6 @@ final class ContextControllerExtractedPresentationNode: ASDisplayNode, ContextCo
|
|||||||
if let reactionContextNode = self.reactionContextNode {
|
if let reactionContextNode = self.reactionContextNode {
|
||||||
reactionContextNode.animateOut(to: currentContentScreenFrame, animatingOutToReaction: self.reactionContextNodeIsAnimatingOut)
|
reactionContextNode.animateOut(to: currentContentScreenFrame, animatingOutToReaction: self.reactionContextNodeIsAnimatingOut)
|
||||||
}
|
}
|
||||||
|
|
||||||
if let overlayViews = self.getController()?.getOverlayViews?(), !overlayViews.isEmpty {
|
|
||||||
for view in overlayViews {
|
|
||||||
if let snapshotView = view.snapshotView(afterScreenUpdates: false) {
|
|
||||||
snapshotView.frame = view.convert(view.bounds, to: nil)
|
|
||||||
self.view.addSubview(snapshotView)
|
|
||||||
snapshotView.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2, removeOnCompletion: false, completion: { [weak snapshotView] _ in
|
|
||||||
snapshotView?.removeFromSuperview()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case .none:
|
case .none:
|
||||||
if animateReactionsIn, let reactionContextNode = self.reactionContextNode {
|
if animateReactionsIn, let reactionContextNode = self.reactionContextNode {
|
||||||
reactionContextNode.animateIn(from: contentRect)
|
reactionContextNode.animateIn(from: contentRect)
|
||||||
|
@ -142,13 +142,14 @@ private final class TextNodeLine {
|
|||||||
let range: NSRange?
|
let range: NSRange?
|
||||||
let isRTL: Bool
|
let isRTL: Bool
|
||||||
var strikethroughs: [TextNodeStrikethrough]
|
var strikethroughs: [TextNodeStrikethrough]
|
||||||
|
var underlines: [TextNodeStrikethrough]
|
||||||
var spoilers: [TextNodeSpoiler]
|
var spoilers: [TextNodeSpoiler]
|
||||||
var spoilerWords: [TextNodeSpoiler]
|
var spoilerWords: [TextNodeSpoiler]
|
||||||
var embeddedItems: [TextNodeEmbeddedItem]
|
var embeddedItems: [TextNodeEmbeddedItem]
|
||||||
var attachments: [TextNodeAttachment]
|
var attachments: [TextNodeAttachment]
|
||||||
let additionalTrailingLine: (CTLine, Double)?
|
let additionalTrailingLine: (CTLine, Double)?
|
||||||
|
|
||||||
init(line: CTLine, frame: CGRect, ascent: CGFloat, descent: CGFloat, range: NSRange?, isRTL: Bool, strikethroughs: [TextNodeStrikethrough], spoilers: [TextNodeSpoiler], spoilerWords: [TextNodeSpoiler], embeddedItems: [TextNodeEmbeddedItem], attachments: [TextNodeAttachment], additionalTrailingLine: (CTLine, Double)?) {
|
init(line: CTLine, frame: CGRect, ascent: CGFloat, descent: CGFloat, range: NSRange?, isRTL: Bool, strikethroughs: [TextNodeStrikethrough], underlines: [TextNodeStrikethrough], spoilers: [TextNodeSpoiler], spoilerWords: [TextNodeSpoiler], embeddedItems: [TextNodeEmbeddedItem], attachments: [TextNodeAttachment], additionalTrailingLine: (CTLine, Double)?) {
|
||||||
self.line = line
|
self.line = line
|
||||||
self.frame = frame
|
self.frame = frame
|
||||||
self.ascent = ascent
|
self.ascent = ascent
|
||||||
@ -156,6 +157,7 @@ private final class TextNodeLine {
|
|||||||
self.range = range
|
self.range = range
|
||||||
self.isRTL = isRTL
|
self.isRTL = isRTL
|
||||||
self.strikethroughs = strikethroughs
|
self.strikethroughs = strikethroughs
|
||||||
|
self.underlines = underlines
|
||||||
self.spoilers = spoilers
|
self.spoilers = spoilers
|
||||||
self.spoilerWords = spoilerWords
|
self.spoilerWords = spoilerWords
|
||||||
self.embeddedItems = embeddedItems
|
self.embeddedItems = embeddedItems
|
||||||
@ -200,6 +202,14 @@ public struct TextNodeCutout: Equatable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private let drawUnderlinesManually: Bool = {
|
||||||
|
if #available(iOS 18.0, *) {
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
private func displayLineFrame(frame: CGRect, isRTL: Bool, boundingRect: CGRect, cutout: TextNodeCutout?) -> CGRect {
|
private func displayLineFrame(frame: CGRect, isRTL: Bool, boundingRect: CGRect, cutout: TextNodeCutout?) -> CGRect {
|
||||||
if frame.width.isEqual(to: boundingRect.width) {
|
if frame.width.isEqual(to: boundingRect.width) {
|
||||||
return frame
|
return frame
|
||||||
@ -1439,6 +1449,7 @@ open class TextNode: ASDisplayNode, TextNodeProtocol {
|
|||||||
range: nil,
|
range: nil,
|
||||||
isRTL: false,
|
isRTL: false,
|
||||||
strikethroughs: [],
|
strikethroughs: [],
|
||||||
|
underlines: [],
|
||||||
spoilers: [],
|
spoilers: [],
|
||||||
spoilerWords: [],
|
spoilerWords: [],
|
||||||
embeddedItems: [],
|
embeddedItems: [],
|
||||||
@ -1476,6 +1487,7 @@ open class TextNode: ASDisplayNode, TextNodeProtocol {
|
|||||||
range: NSRange(location: currentLineStartIndex, length: lineCharacterCount),
|
range: NSRange(location: currentLineStartIndex, length: lineCharacterCount),
|
||||||
isRTL: isRTL && segment.blockQuote == nil,
|
isRTL: isRTL && segment.blockQuote == nil,
|
||||||
strikethroughs: [],
|
strikethroughs: [],
|
||||||
|
underlines: [],
|
||||||
spoilers: [],
|
spoilers: [],
|
||||||
spoilerWords: [],
|
spoilerWords: [],
|
||||||
embeddedItems: [],
|
embeddedItems: [],
|
||||||
@ -1746,6 +1758,7 @@ open class TextNode: ASDisplayNode, TextNodeProtocol {
|
|||||||
var first = true
|
var first = true
|
||||||
while true {
|
while true {
|
||||||
var strikethroughs: [TextNodeStrikethrough] = []
|
var strikethroughs: [TextNodeStrikethrough] = []
|
||||||
|
var underlines: [TextNodeStrikethrough] = []
|
||||||
var spoilers: [TextNodeSpoiler] = []
|
var spoilers: [TextNodeSpoiler] = []
|
||||||
var spoilerWords: [TextNodeSpoiler] = []
|
var spoilerWords: [TextNodeSpoiler] = []
|
||||||
var embeddedItems: [TextNodeEmbeddedItem] = []
|
var embeddedItems: [TextNodeEmbeddedItem] = []
|
||||||
@ -2017,6 +2030,11 @@ open class TextNode: ASDisplayNode, TextNodeProtocol {
|
|||||||
let upperX = ceil(CTLineGetOffsetForStringIndex(coreTextLine, range.location + range.length, nil))
|
let upperX = ceil(CTLineGetOffsetForStringIndex(coreTextLine, range.location + range.length, nil))
|
||||||
let x = lowerX < upperX ? lowerX : upperX
|
let x = lowerX < upperX ? lowerX : upperX
|
||||||
strikethroughs.append(TextNodeStrikethrough(range: range, frame: CGRect(x: x, y: 0.0, width: abs(upperX - lowerX), height: fontLineHeight)))
|
strikethroughs.append(TextNodeStrikethrough(range: range, frame: CGRect(x: x, y: 0.0, width: abs(upperX - lowerX), height: fontLineHeight)))
|
||||||
|
} else if let _ = attributes[NSAttributedString.Key.underlineStyle] {
|
||||||
|
let lowerX = floor(CTLineGetOffsetForStringIndex(coreTextLine, range.location, nil))
|
||||||
|
let upperX = ceil(CTLineGetOffsetForStringIndex(coreTextLine, range.location + range.length, nil))
|
||||||
|
let x = lowerX < upperX ? lowerX : upperX
|
||||||
|
underlines.append(TextNodeStrikethrough(range: range, frame: CGRect(x: x, y: 0.0, width: abs(upperX - lowerX), height: fontLineHeight)))
|
||||||
} else if let paragraphStyle = attributes[NSAttributedString.Key.paragraphStyle] as? NSParagraphStyle {
|
} else if let paragraphStyle = attributes[NSAttributedString.Key.paragraphStyle] as? NSParagraphStyle {
|
||||||
headIndent = paragraphStyle.headIndent
|
headIndent = paragraphStyle.headIndent
|
||||||
}
|
}
|
||||||
@ -2070,6 +2088,7 @@ open class TextNode: ASDisplayNode, TextNodeProtocol {
|
|||||||
range: NSMakeRange(effectiveLineRange.location, effectiveLineRange.length),
|
range: NSMakeRange(effectiveLineRange.location, effectiveLineRange.length),
|
||||||
isRTL: isRTL,
|
isRTL: isRTL,
|
||||||
strikethroughs: strikethroughs,
|
strikethroughs: strikethroughs,
|
||||||
|
underlines: underlines,
|
||||||
spoilers: spoilers,
|
spoilers: spoilers,
|
||||||
spoilerWords: spoilerWords,
|
spoilerWords: spoilerWords,
|
||||||
embeddedItems: embeddedItems,
|
embeddedItems: embeddedItems,
|
||||||
@ -2132,6 +2151,11 @@ open class TextNode: ASDisplayNode, TextNodeProtocol {
|
|||||||
let upperX = ceil(CTLineGetOffsetForStringIndex(coreTextLine, range.location + range.length, nil))
|
let upperX = ceil(CTLineGetOffsetForStringIndex(coreTextLine, range.location + range.length, nil))
|
||||||
let x = lowerX < upperX ? lowerX : upperX
|
let x = lowerX < upperX ? lowerX : upperX
|
||||||
strikethroughs.append(TextNodeStrikethrough(range: range, frame: CGRect(x: x, y: 0.0, width: abs(upperX - lowerX), height: fontLineHeight)))
|
strikethroughs.append(TextNodeStrikethrough(range: range, frame: CGRect(x: x, y: 0.0, width: abs(upperX - lowerX), height: fontLineHeight)))
|
||||||
|
} else if let _ = attributes[NSAttributedString.Key.underlineStyle] {
|
||||||
|
let lowerX = floor(CTLineGetOffsetForStringIndex(coreTextLine, range.location, nil))
|
||||||
|
let upperX = ceil(CTLineGetOffsetForStringIndex(coreTextLine, range.location + range.length, nil))
|
||||||
|
let x = lowerX < upperX ? lowerX : upperX
|
||||||
|
underlines.append(TextNodeStrikethrough(range: range, frame: CGRect(x: x, y: 0.0, width: abs(upperX - lowerX), height: fontLineHeight)))
|
||||||
} else if let paragraphStyle = attributes[NSAttributedString.Key.paragraphStyle] as? NSParagraphStyle {
|
} else if let paragraphStyle = attributes[NSAttributedString.Key.paragraphStyle] as? NSParagraphStyle {
|
||||||
headIndent = paragraphStyle.headIndent
|
headIndent = paragraphStyle.headIndent
|
||||||
}
|
}
|
||||||
@ -2179,6 +2203,7 @@ open class TextNode: ASDisplayNode, TextNodeProtocol {
|
|||||||
range: NSMakeRange(lineRange.location, lineRange.length),
|
range: NSMakeRange(lineRange.location, lineRange.length),
|
||||||
isRTL: isRTL,
|
isRTL: isRTL,
|
||||||
strikethroughs: strikethroughs,
|
strikethroughs: strikethroughs,
|
||||||
|
underlines: underlines,
|
||||||
spoilers: spoilers,
|
spoilers: spoilers,
|
||||||
spoilerWords: spoilerWords,
|
spoilerWords: spoilerWords,
|
||||||
embeddedItems: embeddedItems,
|
embeddedItems: embeddedItems,
|
||||||
@ -2552,6 +2577,26 @@ open class TextNode: ASDisplayNode, TextNodeProtocol {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if drawUnderlinesManually {
|
||||||
|
if !line.underlines.isEmpty {
|
||||||
|
for strikethrough in line.underlines {
|
||||||
|
guard let lineRange = line.range else {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
var textColor: UIColor?
|
||||||
|
layout.attributedString?.enumerateAttributes(in: NSMakeRange(lineRange.location, lineRange.length), options: []) { attributes, range, _ in
|
||||||
|
if range == strikethrough.range, let color = attributes[NSAttributedString.Key.foregroundColor] as? UIColor {
|
||||||
|
textColor = color
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if let textColor = textColor {
|
||||||
|
context.setFillColor(textColor.cgColor)
|
||||||
|
}
|
||||||
|
let frame = strikethrough.frame.offsetBy(dx: lineFrame.minX, dy: lineFrame.minY)
|
||||||
|
context.fill(CGRect(x: frame.minX, y: frame.minY + 1.0, width: frame.width, height: 1.0))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
if !line.strikethroughs.isEmpty {
|
if !line.strikethroughs.isEmpty {
|
||||||
for strikethrough in line.strikethroughs {
|
for strikethrough in line.strikethroughs {
|
||||||
guard let lineRange = line.range else {
|
guard let lineRange = line.range else {
|
||||||
|
@ -95,7 +95,6 @@ swift_library(
|
|||||||
"//submodules/FastBlur:FastBlur",
|
"//submodules/FastBlur:FastBlur",
|
||||||
"//submodules/TelegramUI/Components/MediaEditor",
|
"//submodules/TelegramUI/Components/MediaEditor",
|
||||||
"//submodules/ChatPresentationInterfaceState:ChatPresentationInterfaceState",
|
"//submodules/ChatPresentationInterfaceState:ChatPresentationInterfaceState",
|
||||||
"//submodules/StickerPackPreviewUI:StickerPackPreviewUI",
|
|
||||||
"//submodules/TelegramUI/Components/LottieComponent",
|
"//submodules/TelegramUI/Components/LottieComponent",
|
||||||
"//submodules/TelegramUI/Components/LottieComponentResourceContent",
|
"//submodules/TelegramUI/Components/LottieComponentResourceContent",
|
||||||
"//submodules/ImageTransparency",
|
"//submodules/ImageTransparency",
|
||||||
|
@ -19,7 +19,6 @@ swift_library(
|
|||||||
"//submodules/TelegramPresentationData:TelegramPresentationData",
|
"//submodules/TelegramPresentationData:TelegramPresentationData",
|
||||||
"//submodules/TelegramUIPreferences:TelegramUIPreferences",
|
"//submodules/TelegramUIPreferences:TelegramUIPreferences",
|
||||||
"//submodules/MergeLists:MergeLists",
|
"//submodules/MergeLists:MergeLists",
|
||||||
"//submodules/StickerPackPreviewUI:StickerPackPreviewUI",
|
|
||||||
"//submodules/StickerPeekUI:StickerPeekUI",
|
"//submodules/StickerPeekUI:StickerPeekUI",
|
||||||
"//submodules/OverlayStatusController:OverlayStatusController",
|
"//submodules/OverlayStatusController:OverlayStatusController",
|
||||||
"//submodules/PresentationDataUtils:PresentationDataUtils",
|
"//submodules/PresentationDataUtils:PresentationDataUtils",
|
||||||
@ -33,6 +32,7 @@ swift_library(
|
|||||||
"//submodules/TelegramAnimatedStickerNode:TelegramAnimatedStickerNode",
|
"//submodules/TelegramAnimatedStickerNode:TelegramAnimatedStickerNode",
|
||||||
"//submodules/TelegramUI/Components/EmojiTextAttachmentView",
|
"//submodules/TelegramUI/Components/EmojiTextAttachmentView",
|
||||||
"//submodules/TextFormat",
|
"//submodules/TextFormat",
|
||||||
|
"//submodules/ListSectionHeaderNode",
|
||||||
],
|
],
|
||||||
visibility = [
|
visibility = [
|
||||||
"//visibility:public",
|
"//visibility:public",
|
||||||
|
@ -9,9 +9,9 @@ import TelegramPresentationData
|
|||||||
import MergeLists
|
import MergeLists
|
||||||
import OverlayStatusController
|
import OverlayStatusController
|
||||||
import AccountContext
|
import AccountContext
|
||||||
import StickerPackPreviewUI
|
|
||||||
import PresentationDataUtils
|
import PresentationDataUtils
|
||||||
import UndoUI
|
import UndoUI
|
||||||
|
import StickerResources
|
||||||
|
|
||||||
public final class TrendingPaneInteraction {
|
public final class TrendingPaneInteraction {
|
||||||
public let installPack: (ItemCollectionInfo) -> Void
|
public let installPack: (ItemCollectionInfo) -> Void
|
||||||
@ -355,13 +355,26 @@ public final class ChatMediaInputTrendingPane: ChatMediaInputPane {
|
|||||||
let presentationData = strongSelf.context.sharedContext.currentPresentationData.with { $0 }.withUpdated(theme: forceTheme)
|
let presentationData = strongSelf.context.sharedContext.currentPresentationData.with { $0 }.withUpdated(theme: forceTheme)
|
||||||
updatedPresentationData = (presentationData, .single(presentationData))
|
updatedPresentationData = (presentationData, .single(presentationData))
|
||||||
}
|
}
|
||||||
let controller = StickerPackScreen(context: strongSelf.context, updatedPresentationData: updatedPresentationData, mainStickerPack: packReference, stickerPacks: [packReference], actionTitle: strongSelf.stickerActionTitle, parentNavigationController: strongSelf.interaction.getNavigationController(), sendSticker: { fileReference, sourceNode, sourceRect in
|
|
||||||
if let strongSelf = self {
|
let controller = strongSelf.context.sharedContext.makeStickerPackScreen(
|
||||||
return strongSelf.interaction.sendSticker(fileReference, false, false, nil, false, sourceNode, sourceRect, nil, [])
|
context: strongSelf.context,
|
||||||
} else {
|
updatedPresentationData: updatedPresentationData,
|
||||||
return false
|
mainStickerPack: packReference,
|
||||||
}
|
stickerPacks: [packReference],
|
||||||
})
|
loadedStickerPacks: [],
|
||||||
|
actionTitle: strongSelf.stickerActionTitle,
|
||||||
|
isEditing: false,
|
||||||
|
expandIfNeeded: false,
|
||||||
|
parentNavigationController: strongSelf.interaction.getNavigationController(),
|
||||||
|
sendSticker: { fileReference, sourceNode, sourceRect in
|
||||||
|
if let strongSelf = self {
|
||||||
|
return strongSelf.interaction.sendSticker(fileReference, false, false, nil, false, sourceNode, sourceRect, nil, [])
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
actionPerformed: nil
|
||||||
|
)
|
||||||
strongSelf.interaction.presentController(controller, nil)
|
strongSelf.interaction.presentController(controller, nil)
|
||||||
}
|
}
|
||||||
}, getItemIsPreviewed: self.getItemIsPreviewed,
|
}, getItemIsPreviewed: self.getItemIsPreviewed,
|
||||||
|
@ -9,7 +9,6 @@ import AccountContext
|
|||||||
import TelegramPresentationData
|
import TelegramPresentationData
|
||||||
import TelegramUIPreferences
|
import TelegramUIPreferences
|
||||||
import MergeLists
|
import MergeLists
|
||||||
import StickerPackPreviewUI
|
|
||||||
import StickerPeekUI
|
import StickerPeekUI
|
||||||
import OverlayStatusController
|
import OverlayStatusController
|
||||||
import PresentationDataUtils
|
import PresentationDataUtils
|
||||||
@ -319,13 +318,25 @@ private final class FeaturedStickersScreenNode: ViewControllerTracingNode {
|
|||||||
if let strongSelf = self, let info = info as? StickerPackCollectionInfo {
|
if let strongSelf = self, let info = info as? StickerPackCollectionInfo {
|
||||||
strongSelf.view.window?.endEditing(true)
|
strongSelf.view.window?.endEditing(true)
|
||||||
let packReference: StickerPackReference = .id(id: info.id.id, accessHash: info.accessHash)
|
let packReference: StickerPackReference = .id(id: info.id.id, accessHash: info.accessHash)
|
||||||
let controller = StickerPackScreen(context: strongSelf.context, updatedPresentationData: strongSelf.updatedPresentationData, mainStickerPack: packReference, stickerPacks: [packReference], actionTitle: strongSelf.controller?.stickerActionTitle, parentNavigationController: strongSelf.controller?.navigationController as? NavigationController, sendSticker: { fileReference, sourceNode, sourceRect in
|
let controller = strongSelf.context.sharedContext.makeStickerPackScreen(
|
||||||
if let strongSelf = self {
|
context: strongSelf.context,
|
||||||
return strongSelf.sendSticker?(fileReference, sourceNode, sourceRect) ?? false
|
updatedPresentationData: strongSelf.updatedPresentationData,
|
||||||
} else {
|
mainStickerPack: packReference,
|
||||||
return false
|
stickerPacks: [packReference],
|
||||||
}
|
loadedStickerPacks: [],
|
||||||
})
|
actionTitle: strongSelf.controller?.stickerActionTitle,
|
||||||
|
isEditing: false,
|
||||||
|
expandIfNeeded: false,
|
||||||
|
parentNavigationController: strongSelf.controller?.navigationController as? NavigationController,
|
||||||
|
sendSticker: { file, sourceNode, sourceRect in
|
||||||
|
if let strongSelf = self {
|
||||||
|
return strongSelf.sendSticker?(file, sourceNode, sourceRect) ?? false
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
actionPerformed: nil
|
||||||
|
)
|
||||||
strongSelf.controller?.present(controller, in: .window(.root))
|
strongSelf.controller?.present(controller, in: .window(.root))
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -552,14 +563,25 @@ private final class FeaturedStickersScreenNode: ViewControllerTracingNode {
|
|||||||
switch attribute {
|
switch attribute {
|
||||||
case let .Sticker(_, packReference, _):
|
case let .Sticker(_, packReference, _):
|
||||||
if let packReference = packReference {
|
if let packReference = packReference {
|
||||||
let controller = StickerPackScreen(context: strongSelf.context, updatedPresentationData: strongSelf.updatedPresentationData, mainStickerPack: packReference, stickerPacks: [packReference], actionTitle: strongSelf.controller?.stickerActionTitle, parentNavigationController: strongSelf.controller?.navigationController as? NavigationController, sendSticker: { file, sourceNode, sourceRect in
|
let controller = strongSelf.context.sharedContext.makeStickerPackScreen(
|
||||||
if let strongSelf = self {
|
context: strongSelf.context,
|
||||||
return strongSelf.sendSticker?(file, sourceNode, sourceRect) ?? false
|
updatedPresentationData: strongSelf.updatedPresentationData,
|
||||||
} else {
|
mainStickerPack: packReference,
|
||||||
return false
|
stickerPacks: [packReference],
|
||||||
}
|
loadedStickerPacks: [],
|
||||||
})
|
actionTitle: strongSelf.controller?.stickerActionTitle,
|
||||||
|
isEditing: false,
|
||||||
|
expandIfNeeded: false,
|
||||||
|
parentNavigationController: strongSelf.controller?.navigationController as? NavigationController,
|
||||||
|
sendSticker: { file, sourceNode, sourceRect in
|
||||||
|
if let strongSelf = self {
|
||||||
|
return strongSelf.sendSticker?(file, sourceNode, sourceRect) ?? false
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
actionPerformed: nil
|
||||||
|
)
|
||||||
strongSelf.controller?.view.endEditing(true)
|
strongSelf.controller?.view.endEditing(true)
|
||||||
strongSelf.controller?.present(controller, in: .window(.root))
|
strongSelf.controller?.present(controller, in: .window(.root))
|
||||||
}
|
}
|
||||||
@ -640,14 +662,25 @@ private final class FeaturedStickersScreenNode: ViewControllerTracingNode {
|
|||||||
switch attribute {
|
switch attribute {
|
||||||
case let .Sticker(_, packReference, _):
|
case let .Sticker(_, packReference, _):
|
||||||
if let packReference = packReference {
|
if let packReference = packReference {
|
||||||
let controller = StickerPackScreen(context: strongSelf.context, updatedPresentationData: strongSelf.updatedPresentationData, mainStickerPack: packReference, stickerPacks: [packReference], actionTitle: strongSelf.controller?.stickerActionTitle, parentNavigationController: strongSelf.controller?.navigationController as? NavigationController, sendSticker: { file, sourceNode, sourceRect in
|
let controller = strongSelf.context.sharedContext.makeStickerPackScreen(
|
||||||
if let strongSelf = self {
|
context: strongSelf.context,
|
||||||
return strongSelf.sendSticker?(file, sourceNode, sourceRect) ?? false
|
updatedPresentationData: strongSelf.updatedPresentationData,
|
||||||
} else {
|
mainStickerPack: packReference,
|
||||||
return false
|
stickerPacks: [packReference],
|
||||||
}
|
loadedStickerPacks: [],
|
||||||
})
|
actionTitle: strongSelf.controller?.stickerActionTitle,
|
||||||
|
isEditing: false,
|
||||||
|
expandIfNeeded: false,
|
||||||
|
parentNavigationController: strongSelf.controller?.navigationController as? NavigationController,
|
||||||
|
sendSticker: { file, sourceNode, sourceRect in
|
||||||
|
if let strongSelf = self {
|
||||||
|
return strongSelf.sendSticker?(file, sourceNode, sourceRect) ?? false
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
actionPerformed: nil
|
||||||
|
)
|
||||||
strongSelf.controller?.view.endEditing(true)
|
strongSelf.controller?.view.endEditing(true)
|
||||||
strongSelf.controller?.present(controller, in: .window(.root))
|
strongSelf.controller?.present(controller, in: .window(.root))
|
||||||
}
|
}
|
||||||
@ -1192,13 +1225,26 @@ private final class FeaturedPaneSearchContentNode: ASDisplayNode {
|
|||||||
if let strongSelf = self {
|
if let strongSelf = self {
|
||||||
strongSelf.view.window?.endEditing(true)
|
strongSelf.view.window?.endEditing(true)
|
||||||
let packReference: StickerPackReference = .id(id: info.id.id, accessHash: info.accessHash)
|
let packReference: StickerPackReference = .id(id: info.id.id, accessHash: info.accessHash)
|
||||||
let controller = StickerPackScreen(context: strongSelf.context, updatedPresentationData: strongSelf.updatedPresentationData, mainStickerPack: packReference, stickerPacks: [packReference], actionTitle: strongSelf.controller?.stickerActionTitle, parentNavigationController: strongSelf.controller?.navigationController as? NavigationController, sendSticker: { [weak self] fileReference, sourceNode, sourceRect in
|
|
||||||
if let strongSelf = self {
|
let controller = strongSelf.context.sharedContext.makeStickerPackScreen(
|
||||||
return strongSelf.sendSticker?(fileReference, sourceNode, sourceRect) ?? false
|
context: strongSelf.context,
|
||||||
} else {
|
updatedPresentationData: strongSelf.updatedPresentationData,
|
||||||
return false
|
mainStickerPack: packReference,
|
||||||
}
|
stickerPacks: [packReference],
|
||||||
})
|
loadedStickerPacks: [],
|
||||||
|
actionTitle: strongSelf.controller?.stickerActionTitle,
|
||||||
|
isEditing: false,
|
||||||
|
expandIfNeeded: false,
|
||||||
|
parentNavigationController: strongSelf.controller?.navigationController as? NavigationController,
|
||||||
|
sendSticker: { file, sourceNode, sourceRect in
|
||||||
|
if let strongSelf = self {
|
||||||
|
return strongSelf.sendSticker?(file, sourceNode, sourceRect) ?? false
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
actionPerformed: nil
|
||||||
|
)
|
||||||
strongSelf.controller?.present(controller, in: .window(.root))
|
strongSelf.controller?.present(controller, in: .window(.root))
|
||||||
}
|
}
|
||||||
}, install: { [weak self] info, items, install in
|
}, install: { [weak self] info, items, install in
|
||||||
|
@ -6,9 +6,9 @@ import TelegramCore
|
|||||||
import SwiftSignalKit
|
import SwiftSignalKit
|
||||||
import Postbox
|
import Postbox
|
||||||
import TelegramPresentationData
|
import TelegramPresentationData
|
||||||
import StickerPackPreviewUI
|
|
||||||
import ListSectionHeaderNode
|
import ListSectionHeaderNode
|
||||||
import AccountContext
|
import AccountContext
|
||||||
|
import StickerResources
|
||||||
|
|
||||||
final class StickerPaneSearchGlobalSection: GridSection {
|
final class StickerPaneSearchGlobalSection: GridSection {
|
||||||
let title: String?
|
let title: String?
|
||||||
|
@ -566,7 +566,7 @@ private func galleryEntriesForMessageHistoryEntries(_ entries: [MessageHistoryEn
|
|||||||
return results
|
return results
|
||||||
}
|
}
|
||||||
|
|
||||||
public class GalleryController: ViewController, StandalonePresentableController, KeyShortcutResponder {
|
public class GalleryController: ViewController, StandalonePresentableController, KeyShortcutResponder, GalleryControllerProtocol {
|
||||||
public static let darkNavigationTheme = NavigationBarTheme(buttonColor: .white, disabledButtonColor: UIColor(rgb: 0x525252), primaryTextColor: .white, backgroundColor: UIColor(white: 0.0, alpha: 0.6), enableBackgroundBlur: false, separatorColor: UIColor(white: 0.0, alpha: 0.8), badgeBackgroundColor: .clear, badgeStrokeColor: .clear, badgeTextColor: .clear)
|
public static let darkNavigationTheme = NavigationBarTheme(buttonColor: .white, disabledButtonColor: UIColor(rgb: 0x525252), primaryTextColor: .white, backgroundColor: UIColor(white: 0.0, alpha: 0.6), enableBackgroundBlur: false, separatorColor: UIColor(white: 0.0, alpha: 0.8), badgeBackgroundColor: .clear, badgeStrokeColor: .clear, badgeTextColor: .clear)
|
||||||
public static let lightNavigationTheme = NavigationBarTheme(buttonColor: UIColor(rgb: 0x007aff), disabledButtonColor: UIColor(rgb: 0xd0d0d0), primaryTextColor: .black, backgroundColor: UIColor(red: 0.968626451, green: 0.968626451, blue: 0.968626451, alpha: 1.0), enableBackgroundBlur: false, separatorColor: UIColor(red: 0.6953125, green: 0.6953125, blue: 0.6953125, alpha: 1.0), badgeBackgroundColor: .clear, badgeStrokeColor: .clear, badgeTextColor: .clear)
|
public static let lightNavigationTheme = NavigationBarTheme(buttonColor: UIColor(rgb: 0x007aff), disabledButtonColor: UIColor(rgb: 0xd0d0d0), primaryTextColor: .black, backgroundColor: UIColor(red: 0.968626451, green: 0.968626451, blue: 0.968626451, alpha: 1.0), enableBackgroundBlur: false, separatorColor: UIColor(red: 0.6953125, green: 0.6953125, blue: 0.6953125, alpha: 1.0), badgeBackgroundColor: .clear, badgeStrokeColor: .clear, badgeTextColor: .clear)
|
||||||
|
|
||||||
|
@ -735,6 +735,8 @@ public class ItemListPeerItemNode: ItemListRevealOptionsItemNode, ItemListItemNo
|
|||||||
private let statusNode: TextNode
|
private let statusNode: TextNode
|
||||||
private var credibilityIconComponent: EmojiStatusComponent?
|
private var credibilityIconComponent: EmojiStatusComponent?
|
||||||
private var credibilityIconView: ComponentHostView<Empty>?
|
private var credibilityIconView: ComponentHostView<Empty>?
|
||||||
|
private var verifiedIconComponent: EmojiStatusComponent?
|
||||||
|
private var verifiedIconView: ComponentHostView<Empty>?
|
||||||
private var switchNode: SwitchNode?
|
private var switchNode: SwitchNode?
|
||||||
private var checkNode: ASImageNode?
|
private var checkNode: ASImageNode?
|
||||||
private var leftCheckNode: CheckNode?
|
private var leftCheckNode: CheckNode?
|
||||||
@ -775,6 +777,14 @@ public class ItemListPeerItemNode: ItemListRevealOptionsItemNode, ItemListItemNo
|
|||||||
containerSize: credibilityIconView.bounds.size
|
containerSize: credibilityIconView.bounds.size
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
if let verifiedIconView = self.verifiedIconView, let verifiedIconComponent = self.verifiedIconComponent {
|
||||||
|
let _ = verifiedIconView.update(
|
||||||
|
transition: .immediate,
|
||||||
|
component: AnyComponent(verifiedIconComponent.withVisibleForAnimations(self.visibilityStatus)),
|
||||||
|
environment: {},
|
||||||
|
containerSize: verifiedIconView.bounds.size
|
||||||
|
)
|
||||||
|
}
|
||||||
if let avatarIconView = self.avatarIconView, let avatarIconComponentView = avatarIconView.view, let avatarIconComponent = self.avatarIconComponent {
|
if let avatarIconView = self.avatarIconView, let avatarIconComponentView = avatarIconView.view, let avatarIconComponent = self.avatarIconComponent {
|
||||||
let _ = avatarIconView.update(
|
let _ = avatarIconView.update(
|
||||||
transition: .immediate,
|
transition: .immediate,
|
||||||
@ -912,6 +922,7 @@ public class ItemListPeerItemNode: ItemListRevealOptionsItemNode, ItemListItemNo
|
|||||||
|
|
||||||
var updatedLabelBadgeImage: UIImage?
|
var updatedLabelBadgeImage: UIImage?
|
||||||
var credibilityIcon: EmojiStatusComponent.Content?
|
var credibilityIcon: EmojiStatusComponent.Content?
|
||||||
|
var verifiedIcon: EmojiStatusComponent.Content?
|
||||||
|
|
||||||
if case .threatSelfAsSaved = item.aliasHandling, item.peer.id == item.context.accountPeerId {
|
if case .threatSelfAsSaved = item.aliasHandling, item.peer.id == item.context.accountPeerId {
|
||||||
} else {
|
} else {
|
||||||
@ -921,14 +932,29 @@ public class ItemListPeerItemNode: ItemListRevealOptionsItemNode, ItemListItemNo
|
|||||||
credibilityIcon = .text(color: item.presentationData.theme.chat.message.incoming.scamColor, string: item.presentationData.strings.Message_FakeAccount.uppercased())
|
credibilityIcon = .text(color: item.presentationData.theme.chat.message.incoming.scamColor, string: item.presentationData.strings.Message_FakeAccount.uppercased())
|
||||||
} else if let emojiStatus = item.peer.emojiStatus {
|
} 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))
|
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))
|
||||||
} else if item.peer.isVerified {
|
|
||||||
credibilityIcon = .verified(fillColor: item.presentationData.theme.list.itemCheckColors.fillColor, foregroundColor: item.presentationData.theme.list.itemCheckColors.foregroundColor, sizeType: .compact)
|
|
||||||
} else if item.peer.isPremium && !item.context.isPremiumDisabled {
|
} else if item.peer.isPremium && !item.context.isPremiumDisabled {
|
||||||
credibilityIcon = .premium(color: item.presentationData.theme.list.itemAccentColor)
|
credibilityIcon = .premium(color: item.presentationData.theme.list.itemAccentColor)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if item.peer.isVerified {
|
||||||
|
verifiedIcon = .verified(fillColor: item.presentationData.theme.list.itemCheckColors.fillColor, foregroundColor: item.presentationData.theme.list.itemCheckColors.foregroundColor, sizeType: .compact)
|
||||||
|
} else if let verification = item.peer.verification {
|
||||||
|
verifiedIcon = .animation(content: .customEmoji(fileId: verification.iconFileId), size: CGSize(width: 32.0, height: 32.0), placeholderColor: item.presentationData.theme.list.mediaPlaceholderColor, themeColor: item.presentationData.theme.list.itemAccentColor, loopMode: .count(0))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var titleIconsWidth: CGFloat = 0.0
|
var titleIconsWidth: CGFloat = 0.0
|
||||||
|
if let verifiedIcon = verifiedIcon {
|
||||||
|
titleIconsWidth += 4.0
|
||||||
|
switch verifiedIcon {
|
||||||
|
case let .text(_, string):
|
||||||
|
let textString = NSAttributedString(string: string, font: Font.bold(10.0), textColor: .black, paragraphAlignment: .center)
|
||||||
|
let stringRect = textString.boundingRect(with: CGSize(width: 100.0, height: 16.0), options: .usesLineFragmentOrigin, context: nil)
|
||||||
|
titleIconsWidth += floor(stringRect.width) + 11.0
|
||||||
|
default:
|
||||||
|
titleIconsWidth += 16.0
|
||||||
|
}
|
||||||
|
}
|
||||||
if let credibilityIcon = credibilityIcon {
|
if let credibilityIcon = credibilityIcon {
|
||||||
titleIconsWidth += 4.0
|
titleIconsWidth += 4.0
|
||||||
switch credibilityIcon {
|
switch credibilityIcon {
|
||||||
@ -1407,7 +1433,50 @@ public class ItemListPeerItemNode: ItemListRevealOptionsItemNode, ItemListItemNo
|
|||||||
transition.updateFrame(node: strongSelf.topStripeNode, frame: CGRect(origin: CGPoint(x: 0.0, y: -min(insets.top, separatorHeight)), size: CGSize(width: layoutSize.width, height: separatorHeight)))
|
transition.updateFrame(node: strongSelf.topStripeNode, frame: CGRect(origin: CGPoint(x: 0.0, y: -min(insets.top, separatorHeight)), size: CGSize(width: layoutSize.width, height: separatorHeight)))
|
||||||
transition.updateFrame(node: strongSelf.bottomStripeNode, frame: CGRect(origin: CGPoint(x: bottomStripeInset, y: contentSize.height + bottomStripeOffset), size: CGSize(width: layoutSize.width - bottomStripeInset, height: separatorHeight)))
|
transition.updateFrame(node: strongSelf.bottomStripeNode, frame: CGRect(origin: CGPoint(x: bottomStripeInset, y: contentSize.height + bottomStripeOffset), size: CGSize(width: layoutSize.width - bottomStripeInset, height: separatorHeight)))
|
||||||
|
|
||||||
let titleFrame = CGRect(origin: CGPoint(x: leftInset + revealOffset + editingOffset, y: verticalInset + verticalOffset), size: titleLayout.size)
|
var titleFrame = CGRect(origin: CGPoint(x: leftInset + revealOffset + editingOffset, y: verticalInset + verticalOffset), size: titleLayout.size)
|
||||||
|
|
||||||
|
var titleLeftOffset: CGFloat = 0.0
|
||||||
|
if let verifiedIcon = verifiedIcon {
|
||||||
|
let animationCache = item.context.animationCache
|
||||||
|
let animationRenderer = item.context.animationRenderer
|
||||||
|
|
||||||
|
let verifiedIconView: ComponentHostView<Empty>
|
||||||
|
if let current = strongSelf.verifiedIconView {
|
||||||
|
verifiedIconView = current
|
||||||
|
} else {
|
||||||
|
verifiedIconView = ComponentHostView<Empty>()
|
||||||
|
strongSelf.containerNode.view.addSubview(verifiedIconView)
|
||||||
|
strongSelf.verifiedIconView = verifiedIconView
|
||||||
|
}
|
||||||
|
|
||||||
|
let verifiedIconComponent = EmojiStatusComponent(
|
||||||
|
postbox: item.context.postbox,
|
||||||
|
energyUsageSettings: item.context.energyUsageSettings,
|
||||||
|
resolveInlineStickers: item.context.resolveInlineStickers,
|
||||||
|
animationCache: animationCache,
|
||||||
|
animationRenderer: animationRenderer,
|
||||||
|
content: verifiedIcon,
|
||||||
|
isVisibleForAnimations: strongSelf.visibilityStatus,
|
||||||
|
action: nil,
|
||||||
|
emojiFileUpdated: nil
|
||||||
|
)
|
||||||
|
strongSelf.verifiedIconComponent = verifiedIconComponent
|
||||||
|
let iconSize = verifiedIconView.update(
|
||||||
|
transition: .immediate,
|
||||||
|
component: AnyComponent(verifiedIconComponent),
|
||||||
|
environment: {},
|
||||||
|
containerSize: CGSize(width: 20.0, height: 20.0)
|
||||||
|
)
|
||||||
|
|
||||||
|
transition.updateFrame(view: verifiedIconView, frame: CGRect(origin: CGPoint(x: titleFrame.maxX + 4.0, y: floorToScreenPixels(titleFrame.midY - iconSize.height / 2.0)), size: iconSize))
|
||||||
|
|
||||||
|
titleLeftOffset += iconSize.width + 4.0
|
||||||
|
} else if let verifiedIconView = strongSelf.verifiedIconView {
|
||||||
|
strongSelf.verifiedIconView = nil
|
||||||
|
verifiedIconView.removeFromSuperview()
|
||||||
|
}
|
||||||
|
titleFrame = titleFrame.offsetBy(dx: titleLeftOffset, dy: 0.0)
|
||||||
|
|
||||||
transition.updateFrame(node: strongSelf.titleNode, frame: titleFrame)
|
transition.updateFrame(node: strongSelf.titleNode, frame: titleFrame)
|
||||||
transition.updateFrame(node: strongSelf.statusNode, frame: CGRect(origin: CGPoint(x: leftInset + revealOffset + editingOffset, y: strongSelf.titleNode.frame.maxY + titleSpacing), size: statusLayout.size))
|
transition.updateFrame(node: strongSelf.statusNode, frame: CGRect(origin: CGPoint(x: leftInset + revealOffset + editingOffset, y: strongSelf.titleNode.frame.maxY + titleSpacing), size: statusLayout.size))
|
||||||
|
|
||||||
@ -1843,7 +1912,13 @@ public class ItemListPeerItemNode: ItemListRevealOptionsItemNode, ItemListItemNo
|
|||||||
editingOffset = 0.0
|
editingOffset = 0.0
|
||||||
}
|
}
|
||||||
|
|
||||||
transition.updateFrame(node: self.titleNode, frame: CGRect(origin: CGPoint(x: leftInset + revealOffset + editingOffset, y: self.titleNode.frame.minY), size: self.titleNode.bounds.size))
|
var titleLeftOffset: CGFloat = 0.0
|
||||||
|
if let verifiedIconView = self.verifiedIconView {
|
||||||
|
transition.updateFrame(view: verifiedIconView, frame: CGRect(origin: CGPoint(x: leftInset + revealOffset + editingOffset, y: verifiedIconView.frame.minY), size: verifiedIconView.bounds.size))
|
||||||
|
titleLeftOffset += verifiedIconView.bounds.size.width + 4.0
|
||||||
|
}
|
||||||
|
|
||||||
|
transition.updateFrame(node: self.titleNode, frame: CGRect(origin: CGPoint(x: leftInset + revealOffset + editingOffset + titleLeftOffset, y: self.titleNode.frame.minY), size: self.titleNode.bounds.size))
|
||||||
transition.updateFrame(node: self.statusNode, frame: CGRect(origin: CGPoint(x: leftInset + revealOffset + editingOffset, y: self.statusNode.frame.minY), size: self.statusNode.bounds.size))
|
transition.updateFrame(node: self.statusNode, frame: CGRect(origin: CGPoint(x: leftInset + revealOffset + editingOffset, y: self.statusNode.frame.minY), size: self.statusNode.bounds.size))
|
||||||
|
|
||||||
if let credibilityIconView = self.credibilityIconView {
|
if let credibilityIconView = self.credibilityIconView {
|
||||||
|
@ -77,7 +77,7 @@ public final class ListSectionHeaderNode: ASDisplayNode {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public var activateAction: (() -> Void)?
|
public var activateAction: ((ASDisplayNode) -> Void)?
|
||||||
|
|
||||||
public init(theme: PresentationTheme) {
|
public init(theme: PresentationTheme) {
|
||||||
self.theme = theme
|
self.theme = theme
|
||||||
@ -120,6 +120,10 @@ public final class ListSectionHeaderNode: ASDisplayNode {
|
|||||||
actionColor = self.theme.list.itemDestructiveColor
|
actionColor = self.theme.list.itemDestructiveColor
|
||||||
}
|
}
|
||||||
let attributedText = NSMutableAttributedString(string: action, font: actionFont, textColor: actionColor)
|
let attributedText = NSMutableAttributedString(string: action, font: actionFont, textColor: actionColor)
|
||||||
|
if let range = attributedText.string.range(of: "<"), let arrowImage = UIImage(bundleImageName: "Item List/HeaderContextDisclosureArrow") {
|
||||||
|
attributedText.addAttribute(.attachment, value: arrowImage, range: NSRange(range, in: attributedText.string))
|
||||||
|
attributedText.addAttribute(.baselineOffset, value: 2.0, range: NSRange(range, in: attributedText.string))
|
||||||
|
}
|
||||||
if let range = attributedText.string.range(of: ">"), let arrowImage = UIImage(bundleImageName: "Item List/InlineTextRightArrow") {
|
if let range = attributedText.string.range(of: ">"), let arrowImage = UIImage(bundleImageName: "Item List/InlineTextRightArrow") {
|
||||||
attributedText.addAttribute(.attachment, value: arrowImage, range: NSRange(range, in: attributedText.string))
|
attributedText.addAttribute(.attachment, value: arrowImage, range: NSRange(range, in: attributedText.string))
|
||||||
attributedText.addAttribute(.baselineOffset, value: 1.0, range: NSRange(range, in: attributedText.string))
|
attributedText.addAttribute(.baselineOffset, value: 1.0, range: NSRange(range, in: attributedText.string))
|
||||||
@ -158,6 +162,8 @@ public final class ListSectionHeaderNode: ASDisplayNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@objc private func actionButtonPressed() {
|
@objc private func actionButtonPressed() {
|
||||||
self.activateAction?()
|
if let actionButton = self.actionButton {
|
||||||
|
self.activateAction?(actionButton)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -52,6 +52,8 @@ swift_library(
|
|||||||
"//submodules/Components/ComponentDisplayAdapters",
|
"//submodules/Components/ComponentDisplayAdapters",
|
||||||
"//submodules/AnimatedCountLabelNode",
|
"//submodules/AnimatedCountLabelNode",
|
||||||
"//submodules/TelegramUI/Components/MediaAssetsContext",
|
"//submodules/TelegramUI/Components/MediaAssetsContext",
|
||||||
|
"//submodules/TelegramUI/Components/AvatarBackground",
|
||||||
|
"//submodules/TelegramUI/Components/EmojiTextAttachmentView",
|
||||||
],
|
],
|
||||||
visibility = [
|
visibility = [
|
||||||
"//visibility:public",
|
"//visibility:public",
|
||||||
|
191
submodules/MediaPickerUI/Sources/AvatarEditorPreviewView.swift
Normal file
191
submodules/MediaPickerUI/Sources/AvatarEditorPreviewView.swift
Normal file
@ -0,0 +1,191 @@
|
|||||||
|
import Foundation
|
||||||
|
import UIKit
|
||||||
|
import Display
|
||||||
|
import SwiftSignalKit
|
||||||
|
import TelegramCore
|
||||||
|
import Postbox
|
||||||
|
import AvatarBackground
|
||||||
|
import AccountContext
|
||||||
|
import EmojiTextAttachmentView
|
||||||
|
import TextFormat
|
||||||
|
import ComponentFlow
|
||||||
|
import MultilineTextComponent
|
||||||
|
|
||||||
|
final class AvatarEditorPreviewView: UIView {
|
||||||
|
private let context: AccountContext
|
||||||
|
private var disposable: Disposable?
|
||||||
|
private var files: [TelegramMediaFile] = []
|
||||||
|
private var currentIndex = 0
|
||||||
|
private var currentBackgroundIndex = 0
|
||||||
|
private var switchingToNext = false
|
||||||
|
|
||||||
|
private let backgroundView = UIImageView()
|
||||||
|
private let label = ComponentView<Empty>()
|
||||||
|
private var animationLayer: InlineStickerItemLayer?
|
||||||
|
private var preloadDisposableSet = DisposableSet()
|
||||||
|
|
||||||
|
private var timer: SwiftSignalKit.Timer?
|
||||||
|
|
||||||
|
private var currentSize: CGSize?
|
||||||
|
|
||||||
|
var tapped: () -> Void = {}
|
||||||
|
|
||||||
|
init(context: AccountContext) {
|
||||||
|
self.context = context
|
||||||
|
|
||||||
|
super.init(frame: .zero)
|
||||||
|
|
||||||
|
self.addSubview(self.backgroundView)
|
||||||
|
|
||||||
|
let stickersKey: PostboxViewKey = .orderedItemList(id: Namespaces.OrderedItemList.CloudFeaturedProfilePhotoEmoji)
|
||||||
|
self.disposable = (context.account.postbox.combinedView(keys: [stickersKey])
|
||||||
|
|> runOn(Queue.concurrentDefaultQueue())
|
||||||
|
|> deliverOnMainQueue).start(next: { [weak self] views in
|
||||||
|
guard let self else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if let view = views.views[stickersKey] as? OrderedItemListView {
|
||||||
|
var files: [TelegramMediaFile] = []
|
||||||
|
for item in view.items.prefix(8) {
|
||||||
|
if let mediaItem = item.contents.get(RecentMediaItem.self) {
|
||||||
|
let file = mediaItem.media
|
||||||
|
files.append(file)
|
||||||
|
|
||||||
|
self.preloadDisposableSet.add(freeMediaFileResourceInteractiveFetched(account: context.account, userLocation: .other, fileReference: .standalone(media: file), resource: file.resource).start())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self.files = files
|
||||||
|
if let size = self.currentSize {
|
||||||
|
self.updateLayout(size: size)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
let tapRecognizer = UITapGestureRecognizer(target: self, action: #selector(self.handleTap))
|
||||||
|
self.addGestureRecognizer(tapRecognizer)
|
||||||
|
}
|
||||||
|
|
||||||
|
required init?(coder: NSCoder) {
|
||||||
|
preconditionFailure()
|
||||||
|
}
|
||||||
|
|
||||||
|
deinit {
|
||||||
|
self.disposable?.dispose()
|
||||||
|
self.preloadDisposableSet.dispose()
|
||||||
|
self.timer?.invalidate()
|
||||||
|
}
|
||||||
|
|
||||||
|
@objc private func handleTap() {
|
||||||
|
self.tapped()
|
||||||
|
}
|
||||||
|
|
||||||
|
func updateLayout(size: CGSize) {
|
||||||
|
self.currentSize = size
|
||||||
|
self.backgroundView.frame = CGRect(origin: .zero, size: size)
|
||||||
|
|
||||||
|
//TODO:localize
|
||||||
|
let labelSize = self.label.update(
|
||||||
|
transition: .immediate,
|
||||||
|
component: AnyComponent(
|
||||||
|
MultilineTextComponent(
|
||||||
|
text: .plain(NSAttributedString(
|
||||||
|
string: "Use an Emoji",
|
||||||
|
font: Font.semibold(14.0),
|
||||||
|
textColor: .white
|
||||||
|
)),
|
||||||
|
textShadowColor: UIColor(white: 0.0, alpha: 0.4),
|
||||||
|
textShadowBlur: 4.0
|
||||||
|
)
|
||||||
|
),
|
||||||
|
environment: {},
|
||||||
|
containerSize: size
|
||||||
|
)
|
||||||
|
if let view = self.label.view {
|
||||||
|
if view.superview == nil {
|
||||||
|
self.addSubview(view)
|
||||||
|
}
|
||||||
|
view.frame = CGRect(origin: CGPoint(x: floor((size.width - labelSize.width) / 2.0), y: size.height - labelSize.height - 20.0), size: labelSize)
|
||||||
|
}
|
||||||
|
|
||||||
|
guard !self.files.isEmpty else {
|
||||||
|
if self.backgroundView.image == nil {
|
||||||
|
self.backgroundView.image = AvatarBackground.defaultBackgrounds[self.currentBackgroundIndex].generateImage(size: size)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if self.timer == nil {
|
||||||
|
self.timer = SwiftSignalKit.Timer(timeout: 2.0, repeat: true, completion: { [weak self] in
|
||||||
|
guard let self else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
self.switchingToNext = true
|
||||||
|
if let size = self.currentSize {
|
||||||
|
self.updateLayout(size: size)
|
||||||
|
}
|
||||||
|
}, queue: Queue.mainQueue())
|
||||||
|
self.timer?.start()
|
||||||
|
}
|
||||||
|
|
||||||
|
let iconSize = CGSize(width: 64.0, height: 64.0)
|
||||||
|
let animationLayer: InlineStickerItemLayer
|
||||||
|
var disappearingAnimationLayer: InlineStickerItemLayer?
|
||||||
|
if let current = self.animationLayer, !self.switchingToNext {
|
||||||
|
animationLayer = current
|
||||||
|
} else {
|
||||||
|
if self.switchingToNext {
|
||||||
|
self.currentIndex = (self.currentIndex + 1) % self.files.count
|
||||||
|
self.currentBackgroundIndex = (self.currentBackgroundIndex + 1) % AvatarBackground.defaultBackgrounds.count
|
||||||
|
disappearingAnimationLayer = self.animationLayer
|
||||||
|
self.switchingToNext = false
|
||||||
|
}
|
||||||
|
|
||||||
|
if let image = self.backgroundView.image {
|
||||||
|
let snapshotView = UIImageView(image: image)
|
||||||
|
self.insertSubview(snapshotView, aboveSubview: self.backgroundView)
|
||||||
|
snapshotView.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.2, removeOnCompletion: false, completion: { _ in
|
||||||
|
snapshotView.removeFromSuperview()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
self.backgroundView.image = AvatarBackground.defaultBackgrounds[self.currentBackgroundIndex].generateImage(size: size)
|
||||||
|
|
||||||
|
let file = self.files[self.currentIndex]
|
||||||
|
let emoji = ChatTextInputTextCustomEmojiAttribute(
|
||||||
|
interactivelySelectedFromPackId: nil,
|
||||||
|
fileId: file.fileId.id,
|
||||||
|
file: file
|
||||||
|
)
|
||||||
|
animationLayer = InlineStickerItemLayer(
|
||||||
|
context: .account(self.context),
|
||||||
|
userLocation: .other,
|
||||||
|
attemptSynchronousLoad: false,
|
||||||
|
emoji: emoji,
|
||||||
|
file: file,
|
||||||
|
cache: self.context.animationCache,
|
||||||
|
renderer: self.context.animationRenderer,
|
||||||
|
unique: true,
|
||||||
|
placeholderColor: UIColor(white: 1.0, alpha: 0.1),
|
||||||
|
pointSize: iconSize,
|
||||||
|
loopCount: 1
|
||||||
|
)
|
||||||
|
animationLayer.isVisibleForAnimations = true
|
||||||
|
self.layer.addSublayer(animationLayer)
|
||||||
|
self.animationLayer = animationLayer
|
||||||
|
|
||||||
|
animationLayer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2)
|
||||||
|
animationLayer.animatePosition(from: CGPoint(x: 0.0, y: 10.0), to: .zero, duration: 0.2, additive: true)
|
||||||
|
animationLayer.animateScale(from: 0.01, to: 1.0, duration: 0.2)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
animationLayer.frame = CGRect(origin: CGPoint(x: floor((size.width - iconSize.width) / 2.0), y: floor((size.height - iconSize.height) / 2.0) - 10.0), size: iconSize)
|
||||||
|
|
||||||
|
if let disappearingAnimationLayer {
|
||||||
|
disappearingAnimationLayer.animateAlpha(from: 1.0, to: 0.0, duration: 0.2, removeOnCompletion: false, completion: { _ in
|
||||||
|
disappearingAnimationLayer.removeFromSuperlayer()
|
||||||
|
})
|
||||||
|
disappearingAnimationLayer.animatePosition(from: .zero, to: CGPoint(x: 0.0, y: -10.0), duration: 0.2, removeOnCompletion: false, additive: true)
|
||||||
|
disappearingAnimationLayer.animateScale(from: 1.0, to: 0.01, duration: 0.2, removeOnCompletion: false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -241,7 +241,7 @@ final class MediaPickerGridItemNode: GridItemNode {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func updateSelectionState(animated: Bool = false) {
|
func updateSelectionState(isFirstTime: Bool = false, animated: Bool = false) {
|
||||||
if self.checkNode == nil, let _ = self.interaction?.selectionState, self.selectable, let theme = self.theme {
|
if self.checkNode == nil, let _ = self.interaction?.selectionState, self.selectable, let theme = self.theme {
|
||||||
let checkNode = InteractiveCheckNode(theme: CheckNodeTheme(theme: theme, style: .overlay))
|
let checkNode = InteractiveCheckNode(theme: CheckNodeTheme(theme: theme, style: .overlay))
|
||||||
checkNode.valueChanged = { [weak self] value in
|
checkNode.valueChanged = { [weak self] value in
|
||||||
@ -254,6 +254,11 @@ final class MediaPickerGridItemNode: GridItemNode {
|
|||||||
self.addSubnode(checkNode)
|
self.addSubnode(checkNode)
|
||||||
self.checkNode = checkNode
|
self.checkNode = checkNode
|
||||||
self.setNeedsLayout()
|
self.setNeedsLayout()
|
||||||
|
|
||||||
|
if !isFirstTime {
|
||||||
|
checkNode.layer.animateScale(from: 0.2, to: 1.0, duration: 0.5, timingFunction: kCAMediaTimingFunctionSpring)
|
||||||
|
checkNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.5, timingFunction: kCAMediaTimingFunctionSpring)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let interaction = self.interaction, let selectionState = interaction.selectionState {
|
if let interaction = self.interaction, let selectionState = interaction.selectionState {
|
||||||
@ -429,6 +434,8 @@ final class MediaPickerGridItemNode: GridItemNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func setup(interaction: MediaPickerInteraction, fetchResult: PHFetchResult<PHAsset>, index: Int, theme: PresentationTheme, selectable: Bool, enableAnimations: Bool, stories: Bool) {
|
func setup(interaction: MediaPickerInteraction, fetchResult: PHFetchResult<PHAsset>, index: Int, theme: PresentationTheme, selectable: Bool, enableAnimations: Bool, stories: Bool) {
|
||||||
|
let isFirstTime = self.currentAssetState == nil
|
||||||
|
|
||||||
self.interaction = interaction
|
self.interaction = interaction
|
||||||
self.theme = theme
|
self.theme = theme
|
||||||
self.selectable = selectable
|
self.selectable = selectable
|
||||||
@ -639,7 +646,7 @@ final class MediaPickerGridItemNode: GridItemNode {
|
|||||||
self.setNeedsLayout()
|
self.setNeedsLayout()
|
||||||
}
|
}
|
||||||
|
|
||||||
self.updateSelectionState()
|
self.updateSelectionState(isFirstTime: isFirstTime)
|
||||||
self.updateHiddenMedia()
|
self.updateHiddenMedia()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -161,6 +161,7 @@ public final class MediaPickerScreenImpl: ViewController, MediaPickerScreen, Att
|
|||||||
case story
|
case story
|
||||||
case addImage
|
case addImage
|
||||||
case createSticker
|
case createSticker
|
||||||
|
case createAvatar
|
||||||
}
|
}
|
||||||
|
|
||||||
case assets(PHAssetCollection?, AssetsMode)
|
case assets(PHAssetCollection?, AssetsMode)
|
||||||
@ -183,8 +184,11 @@ public final class MediaPickerScreenImpl: ViewController, MediaPickerScreen, Att
|
|||||||
private let canBoostToUnrestrict: Bool
|
private let canBoostToUnrestrict: Bool
|
||||||
fileprivate let paidMediaAllowed: Bool
|
fileprivate let paidMediaAllowed: Bool
|
||||||
private let subject: Subject
|
private let subject: Subject
|
||||||
|
fileprivate let forCollage: Bool
|
||||||
private let saveEditedPhotos: Bool
|
private let saveEditedPhotos: Bool
|
||||||
|
|
||||||
|
private var explicitMultipleSelection = false
|
||||||
|
|
||||||
private let titleView: MediaPickerTitleView
|
private let titleView: MediaPickerTitleView
|
||||||
private let cancelButtonNode: WebAppCancelButtonNode
|
private let cancelButtonNode: WebAppCancelButtonNode
|
||||||
private let moreButtonNode: MoreButtonNode
|
private let moreButtonNode: MoreButtonNode
|
||||||
@ -203,6 +207,7 @@ public final class MediaPickerScreenImpl: ViewController, MediaPickerScreen, Att
|
|||||||
|
|
||||||
public var createFromScratch: () -> Void = {}
|
public var createFromScratch: () -> Void = {}
|
||||||
public var presentFilePicker: () -> Void = {}
|
public var presentFilePicker: () -> Void = {}
|
||||||
|
public var openAvatarEditor: () -> Void = {}
|
||||||
|
|
||||||
private var completed = false
|
private var completed = false
|
||||||
public var legacyCompletion: (_ signals: [Any], _ silently: Bool, _ scheduleTime: Int32?, ChatSendMessageActionSheetController.SendParameters?, @escaping (String) -> UIView?, @escaping () -> Void) -> Void = { _, _, _, _, _, _ in }
|
public var legacyCompletion: (_ signals: [Any], _ silently: Bool, _ scheduleTime: Int32?, ChatSendMessageActionSheetController.SendParameters?, @escaping (String) -> UIView?, @escaping () -> Void) -> Void = { _, _, _, _, _, _ in }
|
||||||
@ -260,6 +265,8 @@ public final class MediaPickerScreenImpl: ViewController, MediaPickerScreen, Att
|
|||||||
fileprivate var modernCameraView: CameraSimplePreviewView?
|
fileprivate var modernCameraView: CameraSimplePreviewView?
|
||||||
fileprivate var modernCameraTapGestureRecognizer: UITapGestureRecognizer?
|
fileprivate var modernCameraTapGestureRecognizer: UITapGestureRecognizer?
|
||||||
|
|
||||||
|
fileprivate var avatarEditorPreviewView: AvatarEditorPreviewView?
|
||||||
|
|
||||||
private var cameraActivateAreaNode: AccessibilityAreaNode
|
private var cameraActivateAreaNode: AccessibilityAreaNode
|
||||||
private var placeholderNode: MediaPickerPlaceholderNode?
|
private var placeholderNode: MediaPickerPlaceholderNode?
|
||||||
private var manageNode: MediaPickerManageNode?
|
private var manageNode: MediaPickerManageNode?
|
||||||
@ -271,7 +278,7 @@ public final class MediaPickerScreenImpl: ViewController, MediaPickerScreen, Att
|
|||||||
private var nextStableId: Int = 1
|
private var nextStableId: Int = 1
|
||||||
private var currentEntries: [MediaPickerGridEntry] = []
|
private var currentEntries: [MediaPickerGridEntry] = []
|
||||||
private var enqueuedTransactions: [MediaPickerGridTransaction] = []
|
private var enqueuedTransactions: [MediaPickerGridTransaction] = []
|
||||||
private var state: State?
|
fileprivate var state: State?
|
||||||
|
|
||||||
private var preloadPromise = ValuePromise<Bool>(true)
|
private var preloadPromise = ValuePromise<Bool>(true)
|
||||||
|
|
||||||
@ -515,7 +522,7 @@ public final class MediaPickerScreenImpl: ViewController, MediaPickerScreen, Att
|
|||||||
self.gridNode.scrollView.alwaysBounceVertical = true
|
self.gridNode.scrollView.alwaysBounceVertical = true
|
||||||
self.gridNode.scrollView.showsVerticalScrollIndicator = false
|
self.gridNode.scrollView.showsVerticalScrollIndicator = false
|
||||||
|
|
||||||
if case let .assets(_, mode) = controller.subject, [.wallpaper, .story, .addImage, .createSticker].contains(mode) {
|
if case let .assets(_, mode) = controller.subject, [.wallpaper, .story, .addImage, .createSticker, .createAvatar].contains(mode) {
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
let selectionGesture = MediaPickerGridSelectionGesture<TGMediaSelectableItem>()
|
let selectionGesture = MediaPickerGridSelectionGesture<TGMediaSelectableItem>()
|
||||||
@ -602,7 +609,24 @@ public final class MediaPickerScreenImpl: ViewController, MediaPickerScreen, Att
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
if let controller = self.controller, case .assets(nil, .default) = controller.subject {
|
if case .assets(nil, .createAvatar) = controller.subject {
|
||||||
|
let avatarEditorPreviewView = AvatarEditorPreviewView(context: controller.context)
|
||||||
|
avatarEditorPreviewView.tapped = { [weak self] in
|
||||||
|
self?.controller?.openAvatarEditor()
|
||||||
|
}
|
||||||
|
self.gridNode.view.addSubview(avatarEditorPreviewView)
|
||||||
|
self.avatarEditorPreviewView = avatarEditorPreviewView
|
||||||
|
}
|
||||||
|
|
||||||
|
var useLegacyCamera = false
|
||||||
|
var useModernCamera = false
|
||||||
|
if case .assets(nil, .default) = controller.subject {
|
||||||
|
useLegacyCamera = true
|
||||||
|
} else if case .assets(nil, let mode) = controller.subject, [.createSticker, .createAvatar].contains(mode) {
|
||||||
|
useModernCamera = true
|
||||||
|
}
|
||||||
|
|
||||||
|
if useLegacyCamera {
|
||||||
let enableAnimations = self.controller?.context.sharedContext.energyUsageSettings.fullTranslucency ?? true
|
let enableAnimations = self.controller?.context.sharedContext.energyUsageSettings.fullTranslucency ?? true
|
||||||
|
|
||||||
let cameraView = TGAttachmentCameraView(forSelfPortrait: false, videoModeByDefault: controller.bannedSendPhotos != nil && controller.bannedSendVideos == nil)!
|
let cameraView = TGAttachmentCameraView(forSelfPortrait: false, videoModeByDefault: controller.bannedSendPhotos != nil && controller.bannedSendVideos == nil)!
|
||||||
@ -626,9 +650,14 @@ public final class MediaPickerScreenImpl: ViewController, MediaPickerScreen, Att
|
|||||||
|
|
||||||
self.gridNode.scrollView.addSubview(cameraView)
|
self.gridNode.scrollView.addSubview(cameraView)
|
||||||
self.gridNode.addSubnode(self.cameraActivateAreaNode)
|
self.gridNode.addSubnode(self.cameraActivateAreaNode)
|
||||||
} else if let controller = self.controller, case .assets(nil, .createSticker) = controller.subject, !Camera.isIpad {
|
} else if useModernCamera, !Camera.isIpad {
|
||||||
|
var cameraPosition: Camera.Position = .back
|
||||||
|
if case .assets(nil, .createAvatar) = controller.subject {
|
||||||
|
cameraPosition = .front
|
||||||
|
}
|
||||||
|
|
||||||
let cameraPreviewView = CameraSimplePreviewView(frame: .zero, main: true)
|
let cameraPreviewView = CameraSimplePreviewView(frame: .zero, main: true)
|
||||||
cameraPreviewView.resetPlaceholder(front: false)
|
cameraPreviewView.resetPlaceholder(front: cameraPosition == .front)
|
||||||
self.modernCameraView = cameraPreviewView
|
self.modernCameraView = cameraPreviewView
|
||||||
|
|
||||||
let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(self.cameraTapped))
|
let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(self.cameraTapped))
|
||||||
@ -650,21 +679,30 @@ public final class MediaPickerScreenImpl: ViewController, MediaPickerScreen, Att
|
|||||||
|
|
||||||
self.cameraWrapperView.addSubview(cameraPreviewView)
|
self.cameraWrapperView.addSubview(cameraPreviewView)
|
||||||
|
|
||||||
let camera = Camera(
|
let setupCamera = {
|
||||||
configuration: Camera.Configuration(
|
let camera = Camera(
|
||||||
preset: .hd1920x1080,
|
configuration: Camera.Configuration(
|
||||||
position: .back,
|
preset: .hd1920x1080,
|
||||||
isDualEnabled: false,
|
position: cameraPosition,
|
||||||
audio: false,
|
isDualEnabled: false,
|
||||||
photo: true,
|
audio: false,
|
||||||
metadata: false
|
photo: true,
|
||||||
),
|
metadata: false
|
||||||
previewView: cameraPreviewView,
|
),
|
||||||
secondaryPreviewView: nil
|
previewView: cameraPreviewView,
|
||||||
)
|
secondaryPreviewView: nil
|
||||||
self.modernCamera = camera
|
)
|
||||||
|
self.modernCamera = camera
|
||||||
|
camera.startCapture()
|
||||||
|
}
|
||||||
|
|
||||||
camera.startCapture()
|
if case .assets(nil, .createAvatar) = controller.subject {
|
||||||
|
Queue.mainQueue().after(0.4, {
|
||||||
|
setupCamera()
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
setupCamera()
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
self.containerNode.clipsToBounds = true
|
self.containerNode.clipsToBounds = true
|
||||||
}
|
}
|
||||||
@ -767,7 +805,7 @@ public final class MediaPickerScreenImpl: ViewController, MediaPickerScreen, Att
|
|||||||
}
|
}
|
||||||
|
|
||||||
fileprivate var resetOnUpdate = false
|
fileprivate var resetOnUpdate = false
|
||||||
private func updateState(_ state: State) {
|
fileprivate func updateState(_ state: State) {
|
||||||
guard let controller = self.controller, let interaction = controller.interaction else {
|
guard let controller = self.controller, let interaction = controller.interaction else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -783,7 +821,7 @@ public final class MediaPickerScreenImpl: ViewController, MediaPickerScreen, Att
|
|||||||
var stories = false
|
var stories = false
|
||||||
var selectable = true
|
var selectable = true
|
||||||
if case let .assets(_, mode) = controller.subject, mode != .default {
|
if case let .assets(_, mode) = controller.subject, mode != .default {
|
||||||
selectable = false
|
selectable = controller.explicitMultipleSelection
|
||||||
if mode == .story {
|
if mode == .story {
|
||||||
stories = true
|
stories = true
|
||||||
}
|
}
|
||||||
@ -1114,6 +1152,15 @@ public final class MediaPickerScreenImpl: ViewController, MediaPickerScreen, Att
|
|||||||
Queue.mainQueue().justDispatch {
|
Queue.mainQueue().justDispatch {
|
||||||
self.dismissInput()
|
self.dismissInput()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if controller.explicitMultipleSelection {
|
||||||
|
let asset = fetchResult[index]
|
||||||
|
if let selectableItem = TGMediaAsset(phAsset: asset), let selectionContext = interaction.selectionState {
|
||||||
|
let value = !selectionContext.isIdentifierSelected(selectableItem.uniqueIdentifier)
|
||||||
|
let _ = interaction.toggleSelection(selectableItem, value, false)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
if let customSelection = controller.customSelection {
|
if let customSelection = controller.customSelection {
|
||||||
self.openingMedia = true
|
self.openingMedia = true
|
||||||
@ -1489,11 +1536,15 @@ public final class MediaPickerScreenImpl: ViewController, MediaPickerScreen, Att
|
|||||||
let itemSpacing: CGFloat = 1.0
|
let itemSpacing: CGFloat = 1.0
|
||||||
let itemWidth = floorToScreenPixels((width - itemSpacing * CGFloat(itemsPerRow - 1)) / CGFloat(itemsPerRow))
|
let itemWidth = floorToScreenPixels((width - itemSpacing * CGFloat(itemsPerRow - 1)) / CGFloat(itemsPerRow))
|
||||||
|
|
||||||
|
var cutoutRect: CGRect?
|
||||||
var cameraRect: CGRect? = CGRect(origin: CGPoint(x: layout.safeInsets.left, y: 0.0), size: CGSize(width: itemWidth, height: itemWidth * 2.0 + 1.0))
|
var cameraRect: CGRect? = CGRect(origin: CGPoint(x: layout.safeInsets.left, y: 0.0), size: CGSize(width: itemWidth, height: itemWidth * 2.0 + 1.0))
|
||||||
|
if case .assets(nil, .createAvatar) = controller.subject {
|
||||||
|
cameraRect = CGRect(origin: CGPoint(x: layout.safeInsets.left, y: 0.0), size: CGSize(width: itemWidth, height: itemWidth))
|
||||||
|
}
|
||||||
if self.cameraView == nil && self.modernCameraView == nil {
|
if self.cameraView == nil && self.modernCameraView == nil {
|
||||||
cameraRect = nil
|
cameraRect = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
var manageHeight: CGFloat = 0.0
|
var manageHeight: CGFloat = 0.0
|
||||||
if case let .assets(_, _, _, mediaAccess, cameraAccess) = self.state {
|
if case let .assets(_, _, _, mediaAccess, cameraAccess) = self.state {
|
||||||
if cameraAccess == nil {
|
if cameraAccess == nil {
|
||||||
@ -1578,7 +1629,7 @@ public final class MediaPickerScreenImpl: ViewController, MediaPickerScreen, Att
|
|||||||
} else {
|
} else {
|
||||||
cameraRect = nil
|
cameraRect = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
let cleanGridInsets = UIEdgeInsets(top: insets.top, left: layout.safeInsets.left, bottom: layout.intrinsicInsets.bottom, right: layout.safeInsets.right)
|
let cleanGridInsets = UIEdgeInsets(top: insets.top, left: layout.safeInsets.left, bottom: layout.intrinsicInsets.bottom, right: layout.safeInsets.right)
|
||||||
let gridInsets = UIEdgeInsets(top: insets.top + manageHeight, left: layout.safeInsets.left, bottom: layout.intrinsicInsets.bottom, right: layout.safeInsets.right)
|
let gridInsets = UIEdgeInsets(top: insets.top + manageHeight, left: layout.safeInsets.left, bottom: layout.intrinsicInsets.bottom, right: layout.safeInsets.right)
|
||||||
transition.updateFrame(node: self.gridNode, frame: innerBounds)
|
transition.updateFrame(node: self.gridNode, frame: innerBounds)
|
||||||
@ -1589,13 +1640,17 @@ public final class MediaPickerScreenImpl: ViewController, MediaPickerScreen, Att
|
|||||||
|
|
||||||
transition.updateFrame(node: self.containerNode, frame: CGRect(origin: CGPoint(), size: CGSize(width: bounds.width, height: bounds.height)))
|
transition.updateFrame(node: self.containerNode, frame: CGRect(origin: CGPoint(), size: CGSize(width: bounds.width, height: bounds.height)))
|
||||||
|
|
||||||
|
cutoutRect = cameraRect
|
||||||
|
if let _ = self.avatarEditorPreviewView {
|
||||||
|
cutoutRect = CGRect(origin: CGPoint(x: layout.safeInsets.left, y: 0.0), size: CGSize(width: cameraRect != nil ? itemWidth * 2.0 : itemWidth, height: itemWidth))
|
||||||
|
}
|
||||||
|
|
||||||
var itemHeight = itemWidth
|
var itemHeight = itemWidth
|
||||||
if case let .assets(_, mode) = controller.subject, case .story = mode {
|
if case let .assets(_, mode) = controller.subject, case .story = mode {
|
||||||
itemHeight = floor(itemWidth * 1.227)
|
itemHeight = floor(itemWidth * 1.227)
|
||||||
}
|
}
|
||||||
|
|
||||||
let preloadSize: CGFloat = itemHeight// * 3.0
|
let preloadSize: CGFloat = itemHeight// * 3.0
|
||||||
self.gridNode.transaction(GridNodeTransaction(deleteItems: [], insertItems: [], updateItems: [], scrollToItem: nil, updateLayout: GridNodeUpdateLayout(layout: GridNodeLayout(size: bounds.size, insets: gridInsets, scrollIndicatorInsets: nil, preloadSize: preloadSize, type: .fixed(itemSize: CGSize(width: itemWidth, height: itemHeight), fillWidth: true, lineSpacing: itemSpacing, itemSpacing: itemSpacing), cutout: cameraRect), transition: transition), itemTransition: .immediate, stationaryItems: .none, updateFirstIndexInSectionOffset: nil, updateOpaqueState: nil, synchronousLoads: false), completion: { [weak self] _ in
|
self.gridNode.transaction(GridNodeTransaction(deleteItems: [], insertItems: [], updateItems: [], scrollToItem: nil, updateLayout: GridNodeUpdateLayout(layout: GridNodeLayout(size: bounds.size, insets: gridInsets, scrollIndicatorInsets: nil, preloadSize: preloadSize, type: .fixed(itemSize: CGSize(width: itemWidth, height: itemHeight), fillWidth: true, lineSpacing: itemSpacing, itemSpacing: itemSpacing), cutout: cutoutRect), transition: transition), itemTransition: .immediate, stationaryItems: .none, updateFirstIndexInSectionOffset: nil, updateOpaqueState: nil, synchronousLoads: false), completion: { [weak self] _ in
|
||||||
guard let strongSelf = self else {
|
guard let strongSelf = self else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -1612,6 +1667,14 @@ public final class MediaPickerScreenImpl: ViewController, MediaPickerScreen, Att
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
if let avatarEditorPreviewView = self.avatarEditorPreviewView {
|
||||||
|
avatarEditorPreviewView.frame = CGRect(origin: CGPoint(x: cameraRect != nil ? cameraRect!.maxX + itemSpacing : layout.safeInsets.left, y: 0.0), size: CGSize(width: itemWidth, height: itemWidth))
|
||||||
|
avatarEditorPreviewView.updateLayout(size: CGSize(width: itemWidth, height: itemWidth))
|
||||||
|
if self.gridNode.view.subviews.last !== avatarEditorPreviewView {
|
||||||
|
self.gridNode.view.bringSubviewToFront(avatarEditorPreviewView)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if let selectionNode = self.selectionNode, let controller = self.controller {
|
if let selectionNode = self.selectionNode, let controller = self.controller {
|
||||||
let selectedItems = controller.interaction?.selectionState?.selectedItems() as? [TGMediaSelectableItem] ?? []
|
let selectedItems = controller.interaction?.selectionState?.selectedItems() as? [TGMediaSelectableItem] ?? []
|
||||||
let updateSelectionNode = {
|
let updateSelectionNode = {
|
||||||
@ -1642,7 +1705,7 @@ public final class MediaPickerScreenImpl: ViewController, MediaPickerScreen, Att
|
|||||||
|
|
||||||
let screenWidth = min(layout.deviceMetrics.screenSize.width, layout.deviceMetrics.screenSize.height)
|
let screenWidth = min(layout.deviceMetrics.screenSize.width, layout.deviceMetrics.screenSize.height)
|
||||||
let cameraFullSize = CGSize(width: screenWidth, height: floorToScreenPixels(layout.size.width * 1.77778))
|
let cameraFullSize = CGSize(width: screenWidth, height: floorToScreenPixels(layout.size.width * 1.77778))
|
||||||
let cameraScale = cameraRect.height / cameraFullSize.height
|
let cameraScale = max(cameraRect.width / cameraFullSize.width, cameraRect.height / cameraFullSize.height)
|
||||||
|
|
||||||
cameraView.bounds = CGRect(origin: .zero, size: cameraFullSize)
|
cameraView.bounds = CGRect(origin: .zero, size: cameraFullSize)
|
||||||
cameraView.center = CGPoint(x: cameraRect.size.width / 2.0, y: cameraRect.size.height / 2.0)
|
cameraView.center = CGPoint(x: cameraRect.size.width / 2.0, y: cameraRect.size.height / 2.0)
|
||||||
@ -1681,6 +1744,8 @@ public final class MediaPickerScreenImpl: ViewController, MediaPickerScreen, Att
|
|||||||
self.controller?.navigationItem.rightBarButtonItem = nil
|
self.controller?.navigationItem.rightBarButtonItem = nil
|
||||||
} else if case .assets(_, .createSticker) = subject {
|
} else if case .assets(_, .createSticker) = subject {
|
||||||
hasCamera = false
|
hasCamera = false
|
||||||
|
} else if case .assets(_, .createAvatar) = subject {
|
||||||
|
hasCamera = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1743,7 +1808,8 @@ public final class MediaPickerScreenImpl: ViewController, MediaPickerScreen, Att
|
|||||||
|
|
||||||
private var isDismissing = false
|
private var isDismissing = false
|
||||||
|
|
||||||
fileprivate let mainButtonState: AttachmentMainButtonState?
|
fileprivate let mainButtonStatePromise = Promise<AttachmentMainButtonState?>(nil)
|
||||||
|
|
||||||
private let mainButtonAction: (() -> Void)?
|
private let mainButtonAction: (() -> Void)?
|
||||||
|
|
||||||
public init(
|
public init(
|
||||||
@ -1758,6 +1824,7 @@ public final class MediaPickerScreenImpl: ViewController, MediaPickerScreen, Att
|
|||||||
canBoostToUnrestrict: Bool = false,
|
canBoostToUnrestrict: Bool = false,
|
||||||
paidMediaAllowed: Bool = false,
|
paidMediaAllowed: Bool = false,
|
||||||
subject: Subject,
|
subject: Subject,
|
||||||
|
forCollage: Bool = false,
|
||||||
editingContext: TGMediaEditingContext? = nil,
|
editingContext: TGMediaEditingContext? = nil,
|
||||||
selectionContext: TGMediaSelectionContext? = nil,
|
selectionContext: TGMediaSelectionContext? = nil,
|
||||||
saveEditedPhotos: Bool = false,
|
saveEditedPhotos: Bool = false,
|
||||||
@ -1778,8 +1845,9 @@ public final class MediaPickerScreenImpl: ViewController, MediaPickerScreen, Att
|
|||||||
self.canBoostToUnrestrict = canBoostToUnrestrict
|
self.canBoostToUnrestrict = canBoostToUnrestrict
|
||||||
self.paidMediaAllowed = paidMediaAllowed
|
self.paidMediaAllowed = paidMediaAllowed
|
||||||
self.subject = subject
|
self.subject = subject
|
||||||
|
self.forCollage = forCollage
|
||||||
self.saveEditedPhotos = saveEditedPhotos
|
self.saveEditedPhotos = saveEditedPhotos
|
||||||
self.mainButtonState = mainButtonState
|
self.mainButtonStatePromise.set(.single(mainButtonState))
|
||||||
self.mainButtonAction = mainButtonAction
|
self.mainButtonAction = mainButtonAction
|
||||||
|
|
||||||
let selectionContext = selectionContext ?? TGMediaSelectionContext()
|
let selectionContext = selectionContext ?? TGMediaSelectionContext()
|
||||||
@ -1798,6 +1866,11 @@ public final class MediaPickerScreenImpl: ViewController, MediaPickerScreen, Att
|
|||||||
self.titleView.title = presentationData.strings.MediaPicker_Recents
|
self.titleView.title = presentationData.strings.MediaPicker_Recents
|
||||||
self.titleView.subtitle = presentationData.strings.MediaPicker_CreateSticker
|
self.titleView.subtitle = presentationData.strings.MediaPicker_CreateSticker
|
||||||
self.titleView.isEnabled = true
|
self.titleView.isEnabled = true
|
||||||
|
case .createAvatar:
|
||||||
|
//TODO:localize
|
||||||
|
self.titleView.title = presentationData.strings.MediaPicker_Recents
|
||||||
|
self.titleView.subtitle = "Set new profile photo"
|
||||||
|
self.titleView.isEnabled = true
|
||||||
case .story:
|
case .story:
|
||||||
self.titleView.title = presentationData.strings.MediaPicker_Recents
|
self.titleView.title = presentationData.strings.MediaPicker_Recents
|
||||||
self.titleView.isEnabled = true
|
self.titleView.isEnabled = true
|
||||||
@ -1823,7 +1896,7 @@ public final class MediaPickerScreenImpl: ViewController, MediaPickerScreen, Att
|
|||||||
super.init(navigationBarPresentationData: NavigationBarPresentationData(presentationData: presentationData))
|
super.init(navigationBarPresentationData: NavigationBarPresentationData(presentationData: presentationData))
|
||||||
|
|
||||||
self.statusBar.statusBarStyle = .Ignore
|
self.statusBar.statusBarStyle = .Ignore
|
||||||
|
|
||||||
selectionContext.attemptSelectingItem = { [weak self] item in
|
selectionContext.attemptSelectingItem = { [weak self] item in
|
||||||
guard let self else {
|
guard let self else {
|
||||||
return false
|
return false
|
||||||
@ -1908,10 +1981,14 @@ public final class MediaPickerScreenImpl: ViewController, MediaPickerScreen, Att
|
|||||||
} else if collection == nil {
|
} else if collection == nil {
|
||||||
self.navigationItem.leftBarButtonItem = UIBarButtonItem(title: self.presentationData.strings.Common_Cancel, style: .plain, target: self, action: #selector(self.cancelPressed))
|
self.navigationItem.leftBarButtonItem = UIBarButtonItem(title: self.presentationData.strings.Common_Cancel, style: .plain, target: self, action: #selector(self.cancelPressed))
|
||||||
|
|
||||||
if [.createSticker].contains(mode) {
|
if forCollage {
|
||||||
self.navigationItem.rightBarButtonItem = UIBarButtonItem(customDisplayNode: self.moreButtonNode)
|
self.navigationItem.rightBarButtonItem = UIBarButtonItem(backButtonAppearanceWithTitle: self.presentationData.strings.Common_Select, target: self, action: #selector(self.selectPressed))
|
||||||
self.navigationItem.rightBarButtonItem?.action = #selector(self.rightButtonPressed)
|
} else {
|
||||||
self.navigationItem.rightBarButtonItem?.target = self
|
if [.createSticker].contains(mode) {
|
||||||
|
self.navigationItem.rightBarButtonItem = UIBarButtonItem(customDisplayNode: self.moreButtonNode)
|
||||||
|
self.navigationItem.rightBarButtonItem?.action = #selector(self.rightButtonPressed)
|
||||||
|
self.navigationItem.rightBarButtonItem?.target = self
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
self.navigationItem.leftBarButtonItem = UIBarButtonItem(backButtonAppearanceWithTitle: self.presentationData.strings.Common_Back, target: self, action: #selector(self.backPressed))
|
self.navigationItem.leftBarButtonItem = UIBarButtonItem(backButtonAppearanceWithTitle: self.presentationData.strings.Common_Back, target: self, action: #selector(self.backPressed))
|
||||||
@ -1923,8 +2000,6 @@ public final class MediaPickerScreenImpl: ViewController, MediaPickerScreen, Att
|
|||||||
self.navigationItem.leftBarButtonItem = UIBarButtonItem(customDisplayNode: self.cancelButtonNode)
|
self.navigationItem.leftBarButtonItem = UIBarButtonItem(customDisplayNode: self.cancelButtonNode)
|
||||||
self.navigationItem.leftBarButtonItem?.action = #selector(self.cancelPressed)
|
self.navigationItem.leftBarButtonItem?.action = #selector(self.cancelPressed)
|
||||||
self.navigationItem.leftBarButtonItem?.target = self
|
self.navigationItem.leftBarButtonItem?.target = self
|
||||||
|
|
||||||
// self.navigationItem.leftBarButtonItem = UIBarButtonItem(title: self.presentationData.strings.Common_Cancel, style: .plain, target: self, action: #selector(self.cancelPressed))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.bannedSendPhotos != nil && self.bannedSendVideos != nil {
|
if self.bannedSendPhotos != nil && self.bannedSendVideos != nil {
|
||||||
@ -2286,6 +2361,11 @@ public final class MediaPickerScreenImpl: ViewController, MediaPickerScreen, Att
|
|||||||
|
|
||||||
transition.updateAlpha(node: self.moreButtonNode.iconNode, alpha: moreIsVisible ? 1.0 : 0.0)
|
transition.updateAlpha(node: self.moreButtonNode.iconNode, alpha: moreIsVisible ? 1.0 : 0.0)
|
||||||
transition.updateTransformScale(node: self.moreButtonNode.iconNode, scale: moreIsVisible ? 1.0 : 0.1)
|
transition.updateTransformScale(node: self.moreButtonNode.iconNode, scale: moreIsVisible ? 1.0 : 0.1)
|
||||||
|
|
||||||
|
//if self. {
|
||||||
|
//TODO:localize
|
||||||
|
self.mainButtonStatePromise.set(.single(AttachmentMainButtonState(text: "Add", badge: "\(count)", font: .bold, background: .color(self.presentationData.theme.actionSheet.controlAccentColor), textColor: self.presentationData.theme.list.itemCheckColors.foregroundColor, isVisible: count > 0, progress: .none, isEnabled: true, hasShimmer: false)))
|
||||||
|
//}
|
||||||
}
|
}
|
||||||
|
|
||||||
private func updateThemeAndStrings() {
|
private func updateThemeAndStrings() {
|
||||||
@ -2458,6 +2538,15 @@ public final class MediaPickerScreenImpl: ViewController, MediaPickerScreen, Att
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@objc private func selectPressed() {
|
||||||
|
self.navigationItem.setRightBarButton(nil, animated: true)
|
||||||
|
self.explicitMultipleSelection = true
|
||||||
|
|
||||||
|
if let state = self.controllerNode.state {
|
||||||
|
self.controllerNode.updateState(state)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@objc private func selectedPressed() {
|
@objc private func selectedPressed() {
|
||||||
self.controllerNode.updateDisplayMode(.selected, animated: true)
|
self.controllerNode.updateDisplayMode(.selected, animated: true)
|
||||||
}
|
}
|
||||||
@ -2689,14 +2778,18 @@ final class MediaPickerContext: AttachmentMediaPickerContext {
|
|||||||
private weak var controller: MediaPickerScreenImpl?
|
private weak var controller: MediaPickerScreenImpl?
|
||||||
|
|
||||||
var selectionCount: Signal<Int, NoError> {
|
var selectionCount: Signal<Int, NoError> {
|
||||||
return Signal { [weak self] subscriber in
|
//if self.controller?.forCollage == true {
|
||||||
let disposable = self?.controller?.interaction?.selectionState?.selectionChangedSignal().start(next: { [weak self] value in
|
return .single(0)
|
||||||
subscriber.putNext(Int(self?.controller?.interaction?.selectionState?.count() ?? 0))
|
// } else {
|
||||||
}, error: { _ in }, completed: { })
|
// return Signal { [weak self] subscriber in
|
||||||
return ActionDisposable {
|
// let disposable = self?.controller?.interaction?.selectionState?.selectionChangedSignal().start(next: { [weak self] value in
|
||||||
disposable?.dispose()
|
// subscriber.putNext(Int(self?.controller?.interaction?.selectionState?.count() ?? 0))
|
||||||
}
|
// }, error: { _ in }, completed: { })
|
||||||
}
|
// return ActionDisposable {
|
||||||
|
// disposable?.dispose()
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
var caption: Signal<NSAttributedString?, NoError> {
|
var caption: Signal<NSAttributedString?, NoError> {
|
||||||
@ -2820,7 +2913,7 @@ final class MediaPickerContext: AttachmentMediaPickerContext {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public var mainButtonState: Signal<AttachmentMainButtonState?, NoError> {
|
public var mainButtonState: Signal<AttachmentMainButtonState?, NoError> {
|
||||||
return .single(self.controller?.mainButtonState)
|
return self.controller?.mainButtonStatePromise.get() ?? .single(nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
init(controller: MediaPickerScreenImpl) {
|
init(controller: MediaPickerScreenImpl) {
|
||||||
@ -3026,8 +3119,10 @@ public func storyMediaPickerController(
|
|||||||
context: AccountContext,
|
context: AccountContext,
|
||||||
isDark: Bool,
|
isDark: Bool,
|
||||||
forCollage: Bool,
|
forCollage: Bool,
|
||||||
|
selectionLimit: Int?,
|
||||||
getSourceRect: @escaping () -> CGRect,
|
getSourceRect: @escaping () -> CGRect,
|
||||||
completion: @escaping (Any, UIView, CGRect, UIImage?, @escaping (Bool?) -> (UIView, CGRect)?, @escaping () -> Void) -> Void,
|
completion: @escaping (Any, UIView, CGRect, UIImage?, @escaping (Bool?) -> (UIView, CGRect)?, @escaping () -> Void) -> Void,
|
||||||
|
multipleCompletion: @escaping ([Any]) -> Void,
|
||||||
dismissed: @escaping () -> Void,
|
dismissed: @escaping () -> Void,
|
||||||
groupsPresented: @escaping () -> Void
|
groupsPresented: @escaping () -> Void
|
||||||
) -> ViewController {
|
) -> ViewController {
|
||||||
@ -3036,13 +3131,46 @@ public func storyMediaPickerController(
|
|||||||
presentationData = presentationData.withUpdated(theme: defaultDarkColorPresentationTheme)
|
presentationData = presentationData.withUpdated(theme: defaultDarkColorPresentationTheme)
|
||||||
}
|
}
|
||||||
let updatedPresentationData: (PresentationData, Signal<PresentationData, NoError>) = (presentationData, .single(presentationData))
|
let updatedPresentationData: (PresentationData, Signal<PresentationData, NoError>) = (presentationData, .single(presentationData))
|
||||||
|
|
||||||
|
var selectionContext: TGMediaSelectionContext?
|
||||||
|
if let selectionLimit {
|
||||||
|
selectionContext = TGMediaSelectionContext()
|
||||||
|
selectionContext?.selectionLimit = Int32(selectionLimit)
|
||||||
|
selectionContext?.selectionLimitExceeded = {
|
||||||
|
HapticFeedback().error()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let controller = AttachmentController(context: context, updatedPresentationData: updatedPresentationData, chatLocation: nil, buttons: [.standalone], initialButton: .standalone, fromMenu: false, hasTextInput: false, makeEntityInputView: {
|
let controller = AttachmentController(context: context, updatedPresentationData: updatedPresentationData, chatLocation: nil, buttons: [.standalone], initialButton: .standalone, fromMenu: false, hasTextInput: false, makeEntityInputView: {
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
controller.forceSourceRect = true
|
controller.forceSourceRect = true
|
||||||
controller.getSourceRect = getSourceRect
|
controller.getSourceRect = getSourceRect
|
||||||
controller.requestController = { _, present in
|
controller.requestController = { _, present in
|
||||||
let mediaPickerController = MediaPickerScreenImpl(context: context, updatedPresentationData: updatedPresentationData, peer: nil, threadTitle: nil, chatLocation: nil, bannedSendPhotos: nil, bannedSendVideos: nil, subject: .assets(nil, .story), mainButtonState: nil, mainButtonAction: nil)
|
let mediaPickerController = MediaPickerScreenImpl(
|
||||||
|
context: context,
|
||||||
|
updatedPresentationData: updatedPresentationData,
|
||||||
|
peer: nil,
|
||||||
|
threadTitle: nil,
|
||||||
|
chatLocation: nil,
|
||||||
|
bannedSendPhotos: nil,
|
||||||
|
bannedSendVideos: nil,
|
||||||
|
subject: .assets(nil, .story),
|
||||||
|
forCollage: forCollage,
|
||||||
|
selectionContext: selectionContext,
|
||||||
|
mainButtonState: nil,
|
||||||
|
mainButtonAction: { [weak selectionContext] in
|
||||||
|
if let selectionContext, let selectedItems = selectionContext.selectedItems() {
|
||||||
|
var results: [Any] = []
|
||||||
|
for item in selectedItems {
|
||||||
|
if let item = item as? TGMediaAsset, let asset = item.backingAsset {
|
||||||
|
results.append(asset)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
multipleCompletion(results)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
mediaPickerController.groupsPresented = groupsPresented
|
mediaPickerController.groupsPresented = groupsPresented
|
||||||
mediaPickerController.customSelection = { controller, result in
|
mediaPickerController.customSelection = { controller, result in
|
||||||
if let result = result as? MediaEditorDraft {
|
if let result = result as? MediaEditorDraft {
|
||||||
@ -3093,8 +3221,9 @@ public func storyMediaPickerController(
|
|||||||
}
|
}
|
||||||
present(mediaPickerController, mediaPickerController.mediaPickerContext)
|
present(mediaPickerController, mediaPickerController.mediaPickerContext)
|
||||||
}
|
}
|
||||||
controller.willDismiss = {
|
controller.willDismiss = { [weak selectionContext] in
|
||||||
dismissed()
|
dismissed()
|
||||||
|
selectionContext?.clear()
|
||||||
}
|
}
|
||||||
controller.navigationPresentation = .flatModal
|
controller.navigationPresentation = .flatModal
|
||||||
controller.supportedOrientations = ViewControllerSupportedOrientations(regularSize: .all, compactSize: .portrait)
|
controller.supportedOrientations = ViewControllerSupportedOrientations(regularSize: .all, compactSize: .portrait)
|
||||||
@ -3228,6 +3357,124 @@ public func stickerMediaPickerController(
|
|||||||
return controller
|
return controller
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public func avatarMediaPickerController(
|
||||||
|
context: AccountContext,
|
||||||
|
getSourceRect: @escaping () -> CGRect?,
|
||||||
|
canDelete: Bool,
|
||||||
|
performDelete: @escaping () -> Void,
|
||||||
|
completion: @escaping (Any?, UIView?, CGRect, UIImage?, Bool, @escaping (Bool?) -> (UIView, CGRect)?, @escaping () -> Void) -> Void,
|
||||||
|
dismissed: @escaping () -> Void
|
||||||
|
) -> ViewController {
|
||||||
|
let presentationData = context.sharedContext.currentPresentationData.with({ $0 })
|
||||||
|
let updatedPresentationData: (PresentationData, Signal<PresentationData, NoError>) = (presentationData, .single(presentationData))
|
||||||
|
let controller = AttachmentController(context: context, updatedPresentationData: updatedPresentationData, chatLocation: nil, buttons: [.standalone], initialButton: .standalone, fromMenu: false, hasTextInput: false, makeEntityInputView: {
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
controller.forceSourceRect = true
|
||||||
|
controller.getSourceRect = getSourceRect
|
||||||
|
controller.requestController = { [weak controller] _, present in
|
||||||
|
|
||||||
|
var mainButtonState: AttachmentMainButtonState?
|
||||||
|
|
||||||
|
if canDelete {
|
||||||
|
//TODO:localize
|
||||||
|
mainButtonState = AttachmentMainButtonState(text: "Remove Photo", font: .regular, background: .color(.clear), textColor: presentationData.theme.actionSheet.destructiveActionTextColor, isVisible: true, progress: .none, isEnabled: true, hasShimmer: false)
|
||||||
|
}
|
||||||
|
|
||||||
|
let mediaPickerController = MediaPickerScreenImpl(
|
||||||
|
context: context,
|
||||||
|
updatedPresentationData: updatedPresentationData,
|
||||||
|
peer: nil,
|
||||||
|
threadTitle: nil,
|
||||||
|
chatLocation: nil,
|
||||||
|
bannedSendPhotos: nil,
|
||||||
|
bannedSendVideos: nil,
|
||||||
|
subject: .assets(nil, .createAvatar),
|
||||||
|
mainButtonState: mainButtonState,
|
||||||
|
mainButtonAction: { [weak controller] in
|
||||||
|
controller?.dismiss(animated: true)
|
||||||
|
performDelete()
|
||||||
|
}
|
||||||
|
)
|
||||||
|
mediaPickerController.customSelection = { controller, result in
|
||||||
|
if let result = result as? PHAsset {
|
||||||
|
controller.updateHiddenMediaId(result.localIdentifier)
|
||||||
|
if let transitionView = controller.transitionView(for: result.localIdentifier, snapshot: false) {
|
||||||
|
let transitionOut: (Bool?) -> (UIView, CGRect)? = { isNew in
|
||||||
|
if let isNew {
|
||||||
|
if isNew {
|
||||||
|
controller.updateHiddenMediaId(nil)
|
||||||
|
if let transitionView = controller.defaultTransitionView() {
|
||||||
|
return (transitionView, transitionView.bounds)
|
||||||
|
}
|
||||||
|
} else if let transitionView = controller.transitionView(for: result.localIdentifier, snapshot: false) {
|
||||||
|
return (transitionView, transitionView.bounds)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
completion(result, transitionView, transitionView.bounds, controller.transitionImage(for: result.localIdentifier), false, transitionOut, { [weak controller] in
|
||||||
|
controller?.updateHiddenMediaId(nil)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mediaPickerController.openAvatarEditor = { [weak controller] in
|
||||||
|
completion(nil, nil, .zero, nil, false, { _ in return nil }, {
|
||||||
|
})
|
||||||
|
controller?.dismiss(animated: true)
|
||||||
|
}
|
||||||
|
mediaPickerController.openCamera = { [weak controller] cameraHolder in
|
||||||
|
guard let cameraHolder = cameraHolder as? CameraHolder else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var returnToCameraImpl: (() -> Void)?
|
||||||
|
let cameraScreen = CameraScreenImpl(
|
||||||
|
context: context,
|
||||||
|
mode: .avatar,
|
||||||
|
holder: cameraHolder,
|
||||||
|
transitionIn: CameraScreenImpl.TransitionIn(
|
||||||
|
sourceView: cameraHolder.parentView,
|
||||||
|
sourceRect: cameraHolder.parentView.bounds,
|
||||||
|
sourceCornerRadius: 0.0
|
||||||
|
),
|
||||||
|
transitionOut: { _ in
|
||||||
|
return CameraScreenImpl.TransitionOut(
|
||||||
|
destinationView: cameraHolder.parentView,
|
||||||
|
destinationRect: cameraHolder.parentView.bounds,
|
||||||
|
destinationCornerRadius: 0.0
|
||||||
|
)
|
||||||
|
},
|
||||||
|
completion: { result, _, commit in
|
||||||
|
completion(result, nil, .zero, nil, true, { _ in return nil }, {
|
||||||
|
returnToCameraImpl?()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
)
|
||||||
|
cameraScreen.transitionedOut = { [weak cameraHolder] in
|
||||||
|
if let cameraHolder {
|
||||||
|
cameraHolder.restore()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
controller?.push(cameraScreen)
|
||||||
|
|
||||||
|
returnToCameraImpl = { [weak cameraScreen] in
|
||||||
|
if let cameraScreen {
|
||||||
|
cameraScreen.returnFromEditor()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
present(mediaPickerController, mediaPickerController.mediaPickerContext)
|
||||||
|
}
|
||||||
|
controller.willDismiss = {
|
||||||
|
dismissed()
|
||||||
|
}
|
||||||
|
controller.navigationPresentation = .flatModal
|
||||||
|
controller.supportedOrientations = ViewControllerSupportedOrientations(regularSize: .all, compactSize: .portrait)
|
||||||
|
return controller
|
||||||
|
}
|
||||||
|
|
||||||
private class SelectedButtonNode: HighlightableButtonNode {
|
private class SelectedButtonNode: HighlightableButtonNode {
|
||||||
private let background = ASImageNode()
|
private let background = ASImageNode()
|
||||||
private let icon = ASImageNode()
|
private let icon = ASImageNode()
|
||||||
|
@ -2413,7 +2413,7 @@ public class PremiumBoostLevelsScreen: ViewController {
|
|||||||
controller?.dismiss(animated: true, completion: nil)
|
controller?.dismiss(animated: true, completion: nil)
|
||||||
|
|
||||||
Queue.mainQueue().after(0.4) {
|
Queue.mainQueue().after(0.4) {
|
||||||
let giftController = context.sharedContext.makePremiumGiftController(context: context, source: .channelBoost, completion: nil)
|
let giftController = context.sharedContext.makePremiumGiftController(context: context, source: .channelBoost, transfer: false, completion: nil)
|
||||||
navigationController.pushViewController(giftController, animated: true)
|
navigationController.pushViewController(giftController, animated: true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -239,7 +239,7 @@ public func PremiumBoostScreen(
|
|||||||
dismissImpl?()
|
dismissImpl?()
|
||||||
|
|
||||||
Queue.mainQueue().after(0.4) {
|
Queue.mainQueue().after(0.4) {
|
||||||
let controller = context.sharedContext.makePremiumGiftController(context: context, source: .channelBoost, completion: nil)
|
let controller = context.sharedContext.makePremiumGiftController(context: context, source: .channelBoost, transfer: false, completion: nil)
|
||||||
pushController(controller)
|
pushController(controller)
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
|
@ -3417,7 +3417,7 @@ private final class PremiumIntroScreenComponent: CombinedComponent {
|
|||||||
loadedPack = .result(info: info, items: items, installed: updatedInstalled ?? installed)
|
loadedPack = .result(info: info, items: items, installed: updatedInstalled ?? installed)
|
||||||
}
|
}
|
||||||
|
|
||||||
let controller = accountContext.sharedContext.makeStickerPackScreen(context: accountContext, updatedPresentationData: nil, mainStickerPack: packReference, stickerPacks: [packReference], loadedStickerPacks: loadedPack.flatMap { [$0] } ?? [], isEditing: false, expandIfNeeded: false, parentNavigationController: navigationController, sendSticker: { _, _, _ in
|
let controller = accountContext.sharedContext.makeStickerPackScreen(context: accountContext, updatedPresentationData: nil, mainStickerPack: packReference, stickerPacks: [packReference], loadedStickerPacks: loadedPack.flatMap { [$0] } ?? [], actionTitle: nil, isEditing: false, expandIfNeeded: false, parentNavigationController: navigationController, sendSticker: { _, _, _ in
|
||||||
return false
|
return false
|
||||||
}, actionPerformed: { added in
|
}, actionPerformed: { added in
|
||||||
updatedInstalled = added
|
updatedInstalled = added
|
||||||
|
@ -882,7 +882,7 @@ public class ReplaceBoostScreen: ViewController {
|
|||||||
}
|
}
|
||||||
let navigationController = self.navigationController
|
let navigationController = self.navigationController
|
||||||
self.dismiss(animated: true, completion: {
|
self.dismiss(animated: true, completion: {
|
||||||
let giftController = context.sharedContext.makePremiumGiftController(context: context, source: .channelBoost, completion: nil)
|
let giftController = context.sharedContext.makePremiumGiftController(context: context, source: .channelBoost, transfer: false, completion: nil)
|
||||||
navigationController?.pushViewController(giftController, animated: true)
|
navigationController?.pushViewController(giftController, animated: true)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -47,7 +47,7 @@ public final class PremiumStarsNode: ASDisplayNode {
|
|||||||
if self.frame.width > 0.0 {
|
if self.frame.width > 0.0 {
|
||||||
size = self.frame.size
|
size = self.frame.size
|
||||||
} else {
|
} else {
|
||||||
size = CGSize(width: 32.0, height: 32.0)
|
size = CGSize(width: 72.0, height: 32.0)
|
||||||
}
|
}
|
||||||
let starSize = CGSize(width: 6.0, height: 8.0)
|
let starSize = CGSize(width: 6.0, height: 8.0)
|
||||||
|
|
||||||
|
@ -456,7 +456,7 @@ public final class SettingsSearchContainerNode: SearchDisplayControllerContentNo
|
|||||||
self.recentDisposable = (combineLatest(recentSearchItems, faqItems.get(), self.presentationDataPromise.get())
|
self.recentDisposable = (combineLatest(recentSearchItems, faqItems.get(), self.presentationDataPromise.get())
|
||||||
|> deliverOnMainQueue).start(next: { [weak self] recentSearchItems, faqItems, presentationData in
|
|> deliverOnMainQueue).start(next: { [weak self] recentSearchItems, faqItems, presentationData in
|
||||||
if let strongSelf = self {
|
if let strongSelf = self {
|
||||||
let recentHeader = ChatListSearchItemHeader(type: .recentPeers, theme: presentationData.theme, strings: presentationData.strings, actionTitle: presentationData.strings.WebSearch_RecentSectionClear, action: {
|
let recentHeader = ChatListSearchItemHeader(type: .recentPeers, theme: presentationData.theme, strings: presentationData.strings, actionTitle: presentationData.strings.WebSearch_RecentSectionClear, action: { _ in
|
||||||
clearRecentSettingsSearchItems(engine: context.engine)
|
clearRecentSettingsSearchItems(engine: context.engine)
|
||||||
})
|
})
|
||||||
let faqHeader = ChatListSearchItemHeader(type: .faq, theme: presentationData.theme, strings: presentationData.strings)
|
let faqHeader = ChatListSearchItemHeader(type: .faq, theme: presentationData.theme, strings: presentationData.strings)
|
||||||
@ -470,7 +470,6 @@ public final class SettingsSearchContainerNode: SearchDisplayControllerContentNo
|
|||||||
entries.append(.faq(i, faqItems[i], faqHeader))
|
entries.append(.faq(i, faqItems[i], faqHeader))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
let previousEntries = previousRecentItems.swap(entries)
|
let previousEntries = previousRecentItems.swap(entries)
|
||||||
let transition = preparedSettingsSearchContainerRecentTransition(from: previousEntries ?? [], to: entries, account: context.account, theme: presentationData.theme, strings: presentationData.strings, interaction: interaction)
|
let transition = preparedSettingsSearchContainerRecentTransition(from: previousEntries ?? [], to: entries, account: context.account, theme: presentationData.theme, strings: presentationData.strings, interaction: interaction)
|
||||||
strongSelf.enqueueRecentTransition(transition, firstTime: previousEntries == nil)
|
strongSelf.enqueueRecentTransition(transition, firstTime: previousEntries == nil)
|
||||||
|
@ -43,6 +43,7 @@ swift_library(
|
|||||||
"//submodules/Components/MultilineTextComponent",
|
"//submodules/Components/MultilineTextComponent",
|
||||||
"//submodules/Components/BundleIconComponent",
|
"//submodules/Components/BundleIconComponent",
|
||||||
"//submodules/TelegramUI/Components/LottieComponent",
|
"//submodules/TelegramUI/Components/LottieComponent",
|
||||||
|
#"//submodules/TelegramUI/Components/MessageInputPanelComponent",
|
||||||
],
|
],
|
||||||
visibility = [
|
visibility = [
|
||||||
"//visibility:public",
|
"//visibility:public",
|
||||||
|
@ -291,78 +291,3 @@ public final class StickerPackPreviewController: ViewController, StandalonePrese
|
|||||||
self.controllerNode.containerLayoutUpdated(layout, navigationBarHeight: self.navigationLayout(layout: layout).navigationFrame.maxY, transition: transition)
|
self.controllerNode.containerLayoutUpdated(layout, navigationBarHeight: self.navigationLayout(layout: layout).navigationFrame.maxY, transition: transition)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public func preloadedStickerPackThumbnail(account: Account, info: StickerPackCollectionInfo, items: [ItemCollectionItem]) -> Signal<Bool, NoError> {
|
|
||||||
if let thumbnail = info.thumbnail {
|
|
||||||
let signal = Signal<Bool, NoError> { subscriber in
|
|
||||||
let fetched = fetchedMediaResource(mediaBox: account.postbox.mediaBox, userLocation: .other, userContentType: .sticker, reference: .stickerPackThumbnail(stickerPack: .id(id: info.id.id, accessHash: info.accessHash), resource: thumbnail.resource)).start()
|
|
||||||
let dataDisposable: Disposable
|
|
||||||
if thumbnail.typeHint != .generic {
|
|
||||||
dataDisposable = chatMessageAnimationData(mediaBox: account.postbox.mediaBox, resource: thumbnail.resource, isVideo: thumbnail.typeHint == .video, width: 80, height: 80, synchronousLoad: false).start(next: { data in
|
|
||||||
if data.complete {
|
|
||||||
subscriber.putNext(true)
|
|
||||||
subscriber.putCompletion()
|
|
||||||
} else {
|
|
||||||
subscriber.putNext(false)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
dataDisposable = account.postbox.mediaBox.resourceData(thumbnail.resource, option: .incremental(waitUntilFetchStatus: false)).start(next: { data in
|
|
||||||
if data.complete {
|
|
||||||
subscriber.putNext(true)
|
|
||||||
subscriber.putCompletion()
|
|
||||||
} else {
|
|
||||||
subscriber.putNext(false)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
return ActionDisposable {
|
|
||||||
fetched.dispose()
|
|
||||||
dataDisposable.dispose()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return signal
|
|
||||||
}
|
|
||||||
|
|
||||||
if let item = items.first as? StickerPackItem {
|
|
||||||
if item.file.isAnimatedSticker {
|
|
||||||
let signal = Signal<Bool, NoError> { subscriber in
|
|
||||||
let fetched = fetchedMediaResource(mediaBox: account.postbox.mediaBox, userLocation: .other, userContentType: .sticker, reference: FileMediaReference.standalone(media: item.file).resourceReference(item.file.resource)).start()
|
|
||||||
let data = account.postbox.mediaBox.resourceData(item.file.resource).start()
|
|
||||||
let dimensions = item.file.dimensions ?? PixelDimensions(width: 512, height: 512)
|
|
||||||
let fetchedRepresentation = chatMessageAnimatedStickerDatas(postbox: account.postbox, userLocation: .other, file: item.file, small: false, size: dimensions.cgSize.aspectFitted(CGSize(width: 160.0, height: 160.0)), fetched: true, onlyFullSize: false, synchronousLoad: false).start(next: { next in
|
|
||||||
let hasContent = next._0 != nil || next._1 != nil
|
|
||||||
subscriber.putNext(hasContent)
|
|
||||||
if hasContent {
|
|
||||||
subscriber.putCompletion()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
return ActionDisposable {
|
|
||||||
fetched.dispose()
|
|
||||||
data.dispose()
|
|
||||||
fetchedRepresentation.dispose()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return signal
|
|
||||||
} else {
|
|
||||||
let signal = Signal<Bool, NoError> { subscriber in
|
|
||||||
let data = account.postbox.mediaBox.resourceData(item.file.resource).start()
|
|
||||||
let dimensions = item.file.dimensions ?? PixelDimensions(width: 512, height: 512)
|
|
||||||
let fetchedRepresentation = chatMessageAnimatedStickerDatas(postbox: account.postbox, userLocation: .other, file: item.file, small: true, size: dimensions.cgSize.aspectFitted(CGSize(width: 160.0, height: 160.0)), fetched: true, onlyFullSize: false, synchronousLoad: false).start(next: { next in
|
|
||||||
let hasContent = next._0 != nil || next._1 != nil
|
|
||||||
subscriber.putNext(hasContent)
|
|
||||||
if hasContent {
|
|
||||||
subscriber.putCompletion()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
return ActionDisposable {
|
|
||||||
data.dispose()
|
|
||||||
fetchedRepresentation.dispose()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return signal
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return .single(true)
|
|
||||||
}
|
|
||||||
|
@ -585,3 +585,78 @@ public func chatMessageAnimatedSticker(postbox: Postbox, userLocation: MediaReso
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public func preloadedStickerPackThumbnail(account: Account, info: StickerPackCollectionInfo, items: [ItemCollectionItem]) -> Signal<Bool, NoError> {
|
||||||
|
if let thumbnail = info.thumbnail {
|
||||||
|
let signal = Signal<Bool, NoError> { subscriber in
|
||||||
|
let fetched = fetchedMediaResource(mediaBox: account.postbox.mediaBox, userLocation: .other, userContentType: .sticker, reference: .stickerPackThumbnail(stickerPack: .id(id: info.id.id, accessHash: info.accessHash), resource: thumbnail.resource)).start()
|
||||||
|
let dataDisposable: Disposable
|
||||||
|
if thumbnail.typeHint != .generic {
|
||||||
|
dataDisposable = chatMessageAnimationData(mediaBox: account.postbox.mediaBox, resource: thumbnail.resource, isVideo: thumbnail.typeHint == .video, width: 80, height: 80, synchronousLoad: false).start(next: { data in
|
||||||
|
if data.complete {
|
||||||
|
subscriber.putNext(true)
|
||||||
|
subscriber.putCompletion()
|
||||||
|
} else {
|
||||||
|
subscriber.putNext(false)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
dataDisposable = account.postbox.mediaBox.resourceData(thumbnail.resource, option: .incremental(waitUntilFetchStatus: false)).start(next: { data in
|
||||||
|
if data.complete {
|
||||||
|
subscriber.putNext(true)
|
||||||
|
subscriber.putCompletion()
|
||||||
|
} else {
|
||||||
|
subscriber.putNext(false)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return ActionDisposable {
|
||||||
|
fetched.dispose()
|
||||||
|
dataDisposable.dispose()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return signal
|
||||||
|
}
|
||||||
|
|
||||||
|
if let item = items.first as? StickerPackItem {
|
||||||
|
if item.file.isAnimatedSticker {
|
||||||
|
let signal = Signal<Bool, NoError> { subscriber in
|
||||||
|
let fetched = fetchedMediaResource(mediaBox: account.postbox.mediaBox, userLocation: .other, userContentType: .sticker, reference: FileMediaReference.standalone(media: item.file).resourceReference(item.file.resource)).start()
|
||||||
|
let data = account.postbox.mediaBox.resourceData(item.file.resource).start()
|
||||||
|
let dimensions = item.file.dimensions ?? PixelDimensions(width: 512, height: 512)
|
||||||
|
let fetchedRepresentation = chatMessageAnimatedStickerDatas(postbox: account.postbox, userLocation: .other, file: item.file, small: false, size: dimensions.cgSize.aspectFitted(CGSize(width: 160.0, height: 160.0)), fetched: true, onlyFullSize: false, synchronousLoad: false).start(next: { next in
|
||||||
|
let hasContent = next._0 != nil || next._1 != nil
|
||||||
|
subscriber.putNext(hasContent)
|
||||||
|
if hasContent {
|
||||||
|
subscriber.putCompletion()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return ActionDisposable {
|
||||||
|
fetched.dispose()
|
||||||
|
data.dispose()
|
||||||
|
fetchedRepresentation.dispose()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return signal
|
||||||
|
} else {
|
||||||
|
let signal = Signal<Bool, NoError> { subscriber in
|
||||||
|
let data = account.postbox.mediaBox.resourceData(item.file.resource).start()
|
||||||
|
let dimensions = item.file.dimensions ?? PixelDimensions(width: 512, height: 512)
|
||||||
|
let fetchedRepresentation = chatMessageAnimatedStickerDatas(postbox: account.postbox, userLocation: .other, file: item.file, small: true, size: dimensions.cgSize.aspectFitted(CGSize(width: 160.0, height: 160.0)), fetched: true, onlyFullSize: false, synchronousLoad: false).start(next: { next in
|
||||||
|
let hasContent = next._0 != nil || next._1 != nil
|
||||||
|
subscriber.putNext(hasContent)
|
||||||
|
if hasContent {
|
||||||
|
subscriber.putCompletion()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return ActionDisposable {
|
||||||
|
data.dispose()
|
||||||
|
fetchedRepresentation.dispose()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return signal
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return .single(true)
|
||||||
|
}
|
||||||
|
@ -235,6 +235,7 @@ private struct ApplicationSpecificNoticeKeys {
|
|||||||
private static let dismissedPremiumGiftNamespace: Int32 = 9
|
private static let dismissedPremiumGiftNamespace: Int32 = 9
|
||||||
private static let groupEmojiPackNamespace: Int32 = 9
|
private static let groupEmojiPackNamespace: Int32 = 9
|
||||||
private static let dismissedBirthdayPremiumGiftTipNamespace: Int32 = 10
|
private static let dismissedBirthdayPremiumGiftTipNamespace: Int32 = 10
|
||||||
|
private static let displayedPeerVerificationNamespace: Int32 = 11
|
||||||
|
|
||||||
static func inlineBotLocationRequestNotice(peerId: PeerId) -> NoticeEntryKey {
|
static func inlineBotLocationRequestNotice(peerId: PeerId) -> NoticeEntryKey {
|
||||||
return NoticeEntryKey(namespace: noticeNamespace(namespace: inlineBotLocationRequestNamespace), key: noticeKey(peerId: peerId, key: 0))
|
return NoticeEntryKey(namespace: noticeNamespace(namespace: inlineBotLocationRequestNamespace), key: noticeKey(peerId: peerId, key: 0))
|
||||||
@ -516,6 +517,10 @@ private struct ApplicationSpecificNoticeKeys {
|
|||||||
return NoticeEntryKey(namespace: noticeNamespace(namespace: dismissedBirthdayPremiumGiftTipNamespace), key: noticeKey(peerId: peerId, key: 0))
|
return NoticeEntryKey(namespace: noticeNamespace(namespace: dismissedBirthdayPremiumGiftTipNamespace), key: noticeKey(peerId: peerId, key: 0))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static func displayedPeerVerification(peerId: PeerId) -> NoticeEntryKey {
|
||||||
|
return NoticeEntryKey(namespace: noticeNamespace(namespace: displayedPeerVerificationNamespace), key: noticeKey(peerId: peerId, key: 0))
|
||||||
|
}
|
||||||
|
|
||||||
static func monetizationIntroDismissed() -> NoticeEntryKey {
|
static func monetizationIntroDismissed() -> NoticeEntryKey {
|
||||||
return NoticeEntryKey(namespace: noticeNamespace(namespace: globalNamespace), key: ApplicationSpecificGlobalNotice.monetizationIntroDismissed.key)
|
return NoticeEntryKey(namespace: noticeNamespace(namespace: globalNamespace), key: ApplicationSpecificGlobalNotice.monetizationIntroDismissed.key)
|
||||||
}
|
}
|
||||||
@ -2141,6 +2146,26 @@ public struct ApplicationSpecificNotice {
|
|||||||
|> ignoreValues
|
|> ignoreValues
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static func displayedPeerVerification(accountManager: AccountManager<TelegramAccountManagerTypes>, peerId: PeerId) -> Signal<Bool, NoError> {
|
||||||
|
return accountManager.noticeEntry(key: ApplicationSpecificNoticeKeys.displayedPeerVerification(peerId: peerId))
|
||||||
|
|> map { view -> Bool in
|
||||||
|
if let _ = view.value?.get(ApplicationSpecificBoolNotice.self) {
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static func setDisplayedPeerVerification(accountManager: AccountManager<TelegramAccountManagerTypes>, peerId: PeerId) -> Signal<Never, NoError> {
|
||||||
|
return accountManager.transaction { transaction -> Void in
|
||||||
|
if let entry = CodableEntry(ApplicationSpecificBoolNotice()) {
|
||||||
|
transaction.setNotice(ApplicationSpecificNoticeKeys.displayedPeerVerification(peerId: peerId), entry)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|> ignoreValues
|
||||||
|
}
|
||||||
|
|
||||||
public static func setMonetizationIntroDismissed(accountManager: AccountManager<TelegramAccountManagerTypes>) -> Signal<Never, NoError> {
|
public static func setMonetizationIntroDismissed(accountManager: AccountManager<TelegramAccountManagerTypes>) -> Signal<Never, NoError> {
|
||||||
return accountManager.transaction { transaction -> Void in
|
return accountManager.transaction { transaction -> Void in
|
||||||
if let entry = CodableEntry(ApplicationSpecificBoolNotice()) {
|
if let entry = CodableEntry(ApplicationSpecificBoolNotice()) {
|
||||||
|
@ -120,6 +120,7 @@ public enum PresentationResourceKey: Int32 {
|
|||||||
case chatListForwardedIcon
|
case chatListForwardedIcon
|
||||||
case chatListStoryReplyIcon
|
case chatListStoryReplyIcon
|
||||||
case chatListGiftIcon
|
case chatListGiftIcon
|
||||||
|
case chatListLocationIcon
|
||||||
|
|
||||||
case chatListGeneralTopicIcon
|
case chatListGeneralTopicIcon
|
||||||
case chatListGeneralTopicSmallIcon
|
case chatListGeneralTopicSmallIcon
|
||||||
|
@ -265,6 +265,24 @@ public struct PresentationResourcesChatList {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static func locationIcon(_ theme: PresentationTheme) -> UIImage? {
|
||||||
|
return theme.image(PresentationResourceKey.chatListLocationIcon.rawValue, { theme in
|
||||||
|
if let image = UIImage(bundleImageName: "Chat/Attach Menu/Location") {
|
||||||
|
return generateImage(image.size, contextGenerator: { size, context in
|
||||||
|
if let cgImage = image.cgImage {
|
||||||
|
context.clear(CGRect(origin: CGPoint(), size: size))
|
||||||
|
|
||||||
|
context.clip(to: CGRect(origin: .zero, size: size).insetBy(dx: 5.0, dy: 5.0), mask: cgImage)
|
||||||
|
context.setFillColor(theme.chatList.muteIconColor.cgColor)
|
||||||
|
context.fill(CGRect(origin: CGPoint(), size: size))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
public static func verifiedIcon(_ theme: PresentationTheme) -> UIImage? {
|
public static func verifiedIcon(_ theme: PresentationTheme) -> UIImage? {
|
||||||
return theme.image(PresentationResourceKey.chatListVerifiedIcon.rawValue, { theme in
|
return theme.image(PresentationResourceKey.chatListVerifiedIcon.rawValue, { theme in
|
||||||
if let backgroundImage = UIImage(bundleImageName: "Chat List/PeerVerifiedIconBackground"), let foregroundImage = UIImage(bundleImageName: "Chat List/PeerVerifiedIconForeground") {
|
if let backgroundImage = UIImage(bundleImageName: "Chat List/PeerVerifiedIconBackground"), let foregroundImage = UIImage(bundleImageName: "Chat List/PeerVerifiedIconForeground") {
|
||||||
|
20
submodules/TelegramUI/Components/AvatarBackground/BUILD
Normal file
20
submodules/TelegramUI/Components/AvatarBackground/BUILD
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
load("@build_bazel_rules_swift//swift:swift.bzl", "swift_library")
|
||||||
|
|
||||||
|
swift_library(
|
||||||
|
name = "AvatarBackground",
|
||||||
|
module_name = "AvatarBackground",
|
||||||
|
srcs = glob([
|
||||||
|
"Sources/**/*.swift",
|
||||||
|
]),
|
||||||
|
copts = [
|
||||||
|
"-warnings-as-errors",
|
||||||
|
],
|
||||||
|
deps = [
|
||||||
|
"//submodules/AsyncDisplayKit:AsyncDisplayKit",
|
||||||
|
"//submodules/Display:Display",
|
||||||
|
"//submodules/GradientBackground:GradientBackground",
|
||||||
|
],
|
||||||
|
visibility = [
|
||||||
|
"//visibility:public",
|
||||||
|
],
|
||||||
|
)
|
@ -0,0 +1,57 @@
|
|||||||
|
import Foundation
|
||||||
|
import UIKit
|
||||||
|
import Display
|
||||||
|
import GradientBackground
|
||||||
|
|
||||||
|
public enum AvatarBackground: Equatable {
|
||||||
|
public static let defaultBackgrounds: [AvatarBackground] = [
|
||||||
|
.gradient([0xFF5A7FFF, 0xFF2CA0F2, 0xFF4DFF89, 0xFF6BFCEB]),
|
||||||
|
.gradient([0xFFFF011D, 0xFFFF530D, 0xFFFE64DC, 0xFFFFDC61]),
|
||||||
|
.gradient([0xFFFE64DC, 0xFFFF6847, 0xFFFFDD02, 0xFFFFAE10]),
|
||||||
|
.gradient([0xFF84EC00, 0xFF00B7C2, 0xFF00C217, 0xFFFFE600]),
|
||||||
|
.gradient([0xFF86B0FF, 0xFF35FFCF, 0xFF69FFFF, 0xFF76DEFF]),
|
||||||
|
.gradient([0xFFFAE100, 0xFFFF54EE, 0xFFFC2B78, 0xFFFF52D9]),
|
||||||
|
.gradient([0xFF73A4FF, 0xFF5F55FF, 0xFFFF49F8, 0xFFEC76FF]),
|
||||||
|
]
|
||||||
|
|
||||||
|
case gradient([UInt32])
|
||||||
|
|
||||||
|
public var colors: [UInt32] {
|
||||||
|
switch self {
|
||||||
|
case let .gradient(colors):
|
||||||
|
return colors
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public var isLight: Bool {
|
||||||
|
switch self {
|
||||||
|
case let .gradient(colors):
|
||||||
|
if colors.count == 1 {
|
||||||
|
return UIColor(rgb: colors.first!).lightness > 0.99
|
||||||
|
} else if colors.count == 2 {
|
||||||
|
return UIColor(rgb: colors.first!).lightness > 0.99 || UIColor(rgb: colors.last!).lightness > 0.99
|
||||||
|
} else {
|
||||||
|
var lightCount = 0
|
||||||
|
for color in colors {
|
||||||
|
if UIColor(rgb: color).lightness > 0.99 {
|
||||||
|
lightCount += 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return lightCount >= 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public func generateImage(size: CGSize) -> UIImage {
|
||||||
|
switch self {
|
||||||
|
case let .gradient(colors):
|
||||||
|
if colors.count == 1 {
|
||||||
|
return generateSingleColorImage(size: size, color: UIColor(rgb: colors.first!))!
|
||||||
|
} else if colors.count == 2 {
|
||||||
|
return generateGradientImage(size: size, colors: colors.map { UIColor(rgb: $0) }, locations: [0.0, 1.0])!
|
||||||
|
} else {
|
||||||
|
return GradientBackgroundNode.generatePreview(size: size, colors: colors.map { UIColor(rgb: $0) })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -39,6 +39,7 @@ swift_library(
|
|||||||
"//submodules/TelegramUI/Components/AnimationCache:AnimationCache",
|
"//submodules/TelegramUI/Components/AnimationCache:AnimationCache",
|
||||||
"//submodules/TelegramUI/Components/EmojiTextAttachmentView:EmojiTextAttachmentView",
|
"//submodules/TelegramUI/Components/EmojiTextAttachmentView:EmojiTextAttachmentView",
|
||||||
"//submodules/TelegramUI/Components/MediaEditor",
|
"//submodules/TelegramUI/Components/MediaEditor",
|
||||||
|
"//submodules/TelegramUI/Components/AvatarBackground",
|
||||||
],
|
],
|
||||||
visibility = [
|
visibility = [
|
||||||
"//visibility:public",
|
"//visibility:public",
|
||||||
|
@ -24,59 +24,7 @@ import SolidRoundedButtonComponent
|
|||||||
import AnimationCache
|
import AnimationCache
|
||||||
import EmojiTextAttachmentView
|
import EmojiTextAttachmentView
|
||||||
import MediaEditor
|
import MediaEditor
|
||||||
|
import AvatarBackground
|
||||||
enum AvatarBackground: Equatable {
|
|
||||||
case gradient([UInt32])
|
|
||||||
|
|
||||||
var colors: [UInt32] {
|
|
||||||
switch self {
|
|
||||||
case let .gradient(colors):
|
|
||||||
return colors
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var isLight: Bool {
|
|
||||||
switch self {
|
|
||||||
case let .gradient(colors):
|
|
||||||
if colors.count == 1 {
|
|
||||||
return UIColor(rgb: colors.first!).lightness > 0.99
|
|
||||||
} else if colors.count == 2 {
|
|
||||||
return UIColor(rgb: colors.first!).lightness > 0.99 || UIColor(rgb: colors.last!).lightness > 0.99
|
|
||||||
} else {
|
|
||||||
var lightCount = 0
|
|
||||||
for color in colors {
|
|
||||||
if UIColor(rgb: color).lightness > 0.99 {
|
|
||||||
lightCount += 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return lightCount >= 2
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func generateImage(size: CGSize) -> UIImage {
|
|
||||||
switch self {
|
|
||||||
case let .gradient(colors):
|
|
||||||
if colors.count == 1 {
|
|
||||||
return generateSingleColorImage(size: size, color: UIColor(rgb: colors.first!))!
|
|
||||||
} else if colors.count == 2 {
|
|
||||||
return generateGradientImage(size: size, colors: colors.map { UIColor(rgb: $0) }, locations: [0.0, 1.0])!
|
|
||||||
} else {
|
|
||||||
return GradientBackgroundNode.generatePreview(size: size, colors: colors.map { UIColor(rgb: $0) })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private let defaultBackgrounds: [AvatarBackground] = [
|
|
||||||
.gradient([0xFF5A7FFF, 0xFF2CA0F2, 0xFF4DFF89, 0xFF6BFCEB]),
|
|
||||||
.gradient([0xFFFF011D, 0xFFFF530D, 0xFFFE64DC, 0xFFFFDC61]),
|
|
||||||
.gradient([0xFFFE64DC, 0xFFFF6847, 0xFFFFDD02, 0xFFFFAE10]),
|
|
||||||
.gradient([0xFF84EC00, 0xFF00B7C2, 0xFF00C217, 0xFFFFE600]),
|
|
||||||
.gradient([0xFF86B0FF, 0xFF35FFCF, 0xFF69FFFF, 0xFF76DEFF]),
|
|
||||||
.gradient([0xFFFAE100, 0xFFFF54EE, 0xFFFC2B78, 0xFFFF52D9]),
|
|
||||||
.gradient([0xFF73A4FF, 0xFF5F55FF, 0xFFFF49F8, 0xFFEC76FF]),
|
|
||||||
]
|
|
||||||
|
|
||||||
public struct AvatarKeyboardInputData: Equatable {
|
public struct AvatarKeyboardInputData: Equatable {
|
||||||
var emoji: EmojiPagerContentComponent
|
var emoji: EmojiPagerContentComponent
|
||||||
@ -147,7 +95,7 @@ final class AvatarEditorScreenComponent: Component {
|
|||||||
self.context = context
|
self.context = context
|
||||||
self.ready = ready
|
self.ready = ready
|
||||||
|
|
||||||
self.selectedBackground = defaultBackgrounds.first!
|
self.selectedBackground = AvatarBackground.defaultBackgrounds.first!
|
||||||
self.previousColor = self.selectedBackground
|
self.previousColor = self.selectedBackground
|
||||||
|
|
||||||
super.init()
|
super.init()
|
||||||
@ -181,7 +129,7 @@ final class AvatarEditorScreenComponent: Component {
|
|||||||
self.selectedBackground = .gradient(markup.backgroundColors.map { UInt32(bitPattern: $0) })
|
self.selectedBackground = .gradient(markup.backgroundColors.map { UInt32(bitPattern: $0) })
|
||||||
self.previousColor = self.selectedBackground
|
self.previousColor = self.selectedBackground
|
||||||
} else {
|
} else {
|
||||||
self.selectedBackground = defaultBackgrounds.first!
|
self.selectedBackground = AvatarBackground.defaultBackgrounds.first!
|
||||||
}
|
}
|
||||||
|
|
||||||
self.previousColor = self.selectedBackground
|
self.previousColor = self.selectedBackground
|
||||||
@ -1046,7 +994,7 @@ final class AvatarEditorScreenComponent: Component {
|
|||||||
transition: transition,
|
transition: transition,
|
||||||
component: AnyComponent(BackgroundColorComponent(
|
component: AnyComponent(BackgroundColorComponent(
|
||||||
theme: environment.theme,
|
theme: environment.theme,
|
||||||
values: defaultBackgrounds,
|
values: AvatarBackground.defaultBackgrounds,
|
||||||
selectedValue: state.selectedBackground,
|
selectedValue: state.selectedBackground,
|
||||||
customValue: state.customColor,
|
customValue: state.customColor,
|
||||||
updateValue: { [weak state] value in
|
updateValue: { [weak state] value in
|
||||||
|
@ -15,6 +15,7 @@ import Postbox
|
|||||||
import AnimatedStickerNode
|
import AnimatedStickerNode
|
||||||
import TelegramAnimatedStickerNode
|
import TelegramAnimatedStickerNode
|
||||||
import StickerResources
|
import StickerResources
|
||||||
|
import AvatarBackground
|
||||||
|
|
||||||
final class AvatarPreviewComponent: Component {
|
final class AvatarPreviewComponent: Component {
|
||||||
typealias EnvironmentType = Empty
|
typealias EnvironmentType = Empty
|
||||||
|
@ -6,6 +6,7 @@ import ComponentFlow
|
|||||||
import ViewControllerComponent
|
import ViewControllerComponent
|
||||||
import ComponentDisplayAdapters
|
import ComponentDisplayAdapters
|
||||||
import TelegramPresentationData
|
import TelegramPresentationData
|
||||||
|
import AvatarBackground
|
||||||
|
|
||||||
final class BackgroundColorComponent: Component {
|
final class BackgroundColorComponent: Component {
|
||||||
let theme: PresentationTheme
|
let theme: PresentationTheme
|
||||||
|
@ -85,7 +85,7 @@ swift_library(
|
|||||||
"//submodules/TelegramUI/Components/MediaAssetsContext",
|
"//submodules/TelegramUI/Components/MediaAssetsContext",
|
||||||
"//submodules/UndoUI",
|
"//submodules/UndoUI",
|
||||||
"//submodules/ContextUI",
|
"//submodules/ContextUI",
|
||||||
|
"//submodules/AvatarNode",
|
||||||
],
|
],
|
||||||
visibility = [
|
visibility = [
|
||||||
"//visibility:public",
|
"//visibility:public",
|
||||||
|
@ -0,0 +1,177 @@
|
|||||||
|
import Foundation
|
||||||
|
import UIKit
|
||||||
|
import Display
|
||||||
|
import ComponentFlow
|
||||||
|
import Camera
|
||||||
|
|
||||||
|
final class CameraCodeFrameView: UIView {
|
||||||
|
private var cornerLayers: [SimpleShapeLayer] = []
|
||||||
|
private let cornerRadius: CGFloat = 12.0
|
||||||
|
private let focusedCornerRadius: CGFloat = 6.0
|
||||||
|
private let cornerShort: CGFloat = 16.0
|
||||||
|
|
||||||
|
private var currentSize: CGSize?
|
||||||
|
private var currentRect: CGRect?
|
||||||
|
|
||||||
|
override init(frame: CGRect) {
|
||||||
|
super.init(frame: frame)
|
||||||
|
|
||||||
|
self.isUserInteractionEnabled = false
|
||||||
|
|
||||||
|
for _ in 0..<4 {
|
||||||
|
let layer = SimpleShapeLayer()
|
||||||
|
layer.fillColor = UIColor.clear.cgColor
|
||||||
|
layer.strokeColor = UIColor.white.cgColor
|
||||||
|
layer.lineWidth = 2.0
|
||||||
|
layer.lineCap = .round
|
||||||
|
layer.lineJoin = .round
|
||||||
|
self.layer.addSublayer(layer)
|
||||||
|
self.cornerLayers.append(layer)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
required init?(coder: NSCoder) {
|
||||||
|
preconditionFailure()
|
||||||
|
}
|
||||||
|
|
||||||
|
func update(size: CGSize, code: CameraCode?) {
|
||||||
|
let isFirstTime = self.currentSize == nil
|
||||||
|
self.currentSize = size
|
||||||
|
|
||||||
|
var duration: Double = 0.0
|
||||||
|
|
||||||
|
let bounds = CGRect(origin: .zero, size: size)
|
||||||
|
let rect: CGRect
|
||||||
|
if let code {
|
||||||
|
let codeRect = code.boundingBox
|
||||||
|
let side = max(codeRect.width * bounds.width, codeRect.height * bounds.height) * 0.7
|
||||||
|
let center = CGPoint(x: (1.0 - codeRect.center.y) * bounds.width, y: codeRect.center.x * bounds.height)
|
||||||
|
rect = CGSize(width: side, height: side).centered(around: center)
|
||||||
|
|
||||||
|
if !isFirstTime {
|
||||||
|
if let currentRect = self.currentRect {
|
||||||
|
if rect.center.distance(to: currentRect.center) > 40.0 || abs(rect.size.width - currentRect.size.width) > 40.0 {
|
||||||
|
duration = 0.35
|
||||||
|
} else {
|
||||||
|
duration = 0.2
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
duration = 0.4
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self.currentRect = rect
|
||||||
|
} else {
|
||||||
|
rect = bounds.insetBy(dx: -2.0, dy: -2.0)
|
||||||
|
if !isFirstTime {
|
||||||
|
duration = 0.4
|
||||||
|
}
|
||||||
|
self.currentRect = nil
|
||||||
|
}
|
||||||
|
|
||||||
|
let focused = code != nil
|
||||||
|
self.applyPaths(to: self.cornerPaths(for: rect, focused: focused, rotation: 0.0), focused: focused, duration: duration)
|
||||||
|
}
|
||||||
|
|
||||||
|
private func cornerPaths(for rect: CGRect, focused: Bool, rotation: Double) -> [UIBezierPath] {
|
||||||
|
let effectiveCornerRadius = focused ? self.focusedCornerRadius : self.cornerRadius
|
||||||
|
let center = CGPoint(x: rect.midX, y: rect.midY)
|
||||||
|
let transform = CGAffineTransform(translationX: center.x, y: center.y).rotated(by: rotation).translatedBy(x: -center.x, y: -center.y)
|
||||||
|
|
||||||
|
let topLeftPath = UIBezierPath()
|
||||||
|
topLeftPath.move(to: CGPoint(x: rect.minX, y: focused ? rect.minY + self.cornerShort : rect.midY))
|
||||||
|
topLeftPath.addLine(to: CGPoint(x: rect.minX, y: rect.minY + effectiveCornerRadius))
|
||||||
|
topLeftPath.addQuadCurve(
|
||||||
|
to: CGPoint(x: rect.minX + effectiveCornerRadius, y: rect.minY),
|
||||||
|
controlPoint: CGPoint(x: rect.minX, y: rect.minY)
|
||||||
|
)
|
||||||
|
topLeftPath.addLine(to: CGPoint(x: focused ? rect.minX + self.cornerShort : rect.midX, y: rect.minY))
|
||||||
|
topLeftPath.apply(transform)
|
||||||
|
|
||||||
|
let topRightPath = UIBezierPath()
|
||||||
|
topRightPath.move(to: CGPoint(x: rect.maxX, y: focused ? rect.minY + self.cornerShort : rect.midY))
|
||||||
|
topRightPath.addLine(to: CGPoint(x: rect.maxX, y: rect.minY + effectiveCornerRadius))
|
||||||
|
topRightPath.addQuadCurve(
|
||||||
|
to: CGPoint(x: rect.maxX - effectiveCornerRadius, y: rect.minY),
|
||||||
|
controlPoint: CGPoint(x: rect.maxX, y: rect.minY)
|
||||||
|
)
|
||||||
|
topRightPath.addLine(to: CGPoint(x: focused ? rect.maxX - self.cornerShort : rect.midX, y: rect.minY))
|
||||||
|
topRightPath.apply(transform)
|
||||||
|
|
||||||
|
let bottomRightPath = UIBezierPath()
|
||||||
|
bottomRightPath.move(to: CGPoint(x: rect.maxX, y: focused ? rect.maxY - self.cornerShort : rect.midY))
|
||||||
|
bottomRightPath.addLine(to: CGPoint(x: rect.maxX, y: rect.maxY - effectiveCornerRadius))
|
||||||
|
bottomRightPath.addQuadCurve(
|
||||||
|
to: CGPoint(x: rect.maxX - effectiveCornerRadius, y: rect.maxY),
|
||||||
|
controlPoint: CGPoint(x: rect.maxX, y: rect.maxY)
|
||||||
|
)
|
||||||
|
bottomRightPath.addLine(to: CGPoint(x: focused ? rect.maxX - self.cornerShort : rect.midX, y: rect.maxY))
|
||||||
|
bottomRightPath.apply(transform)
|
||||||
|
|
||||||
|
let bottomLeftPath = UIBezierPath()
|
||||||
|
bottomLeftPath.move(to: CGPoint(x: rect.minX, y: focused ? rect.maxY - self.cornerShort : rect.midY))
|
||||||
|
bottomLeftPath.addLine(to: CGPoint(x: rect.minX, y: rect.maxY - effectiveCornerRadius))
|
||||||
|
bottomLeftPath.addQuadCurve(
|
||||||
|
to: CGPoint(x: rect.minX + effectiveCornerRadius, y: rect.maxY),
|
||||||
|
controlPoint: CGPoint(x: rect.minX, y: rect.maxY)
|
||||||
|
)
|
||||||
|
bottomLeftPath.addLine(to: CGPoint(x: focused ? rect.minX + self.cornerShort : rect.midX, y: rect.maxY))
|
||||||
|
bottomLeftPath.apply(transform)
|
||||||
|
|
||||||
|
return [topLeftPath, topRightPath, bottomRightPath, bottomLeftPath]
|
||||||
|
}
|
||||||
|
|
||||||
|
private var animatingAppearance = false
|
||||||
|
private func applyPaths(to paths: [UIBezierPath], focused: Bool, duration: Double) {
|
||||||
|
let animatingAppearance = self.animatingAppearance
|
||||||
|
for (index, path) in paths.enumerated() {
|
||||||
|
let layer = self.cornerLayers[index]
|
||||||
|
let previousPath = layer.path
|
||||||
|
let previousAlpha = layer.opacity
|
||||||
|
let previousColor = layer.strokeColor ?? UIColor.clear.cgColor
|
||||||
|
let previousLineWidth = layer.lineWidth
|
||||||
|
|
||||||
|
if duration > 0.0 && !focused {
|
||||||
|
|
||||||
|
} else {
|
||||||
|
layer.path = path.cgPath
|
||||||
|
}
|
||||||
|
layer.opacity = focused ? 1.0 : 0.0
|
||||||
|
layer.strokeColor = focused ? UIColor(rgb: 0xf8d74a).cgColor : UIColor.white.cgColor
|
||||||
|
layer.lineWidth = focused ? 5.0 : 2.0
|
||||||
|
layer.shadowOffset = .zero
|
||||||
|
layer.shadowRadius = 1.0
|
||||||
|
layer.shadowColor = UIColor.black.cgColor
|
||||||
|
layer.shadowOpacity = 0.2
|
||||||
|
|
||||||
|
if duration > 0.0 && !animatingAppearance {
|
||||||
|
if focused && previousAlpha.isZero && index == 0 {
|
||||||
|
self.animatingAppearance = true
|
||||||
|
}
|
||||||
|
if focused {
|
||||||
|
var currentPath = previousPath
|
||||||
|
var duration = duration
|
||||||
|
if let presentationPath = layer.presentation()?.path {
|
||||||
|
currentPath = presentationPath
|
||||||
|
duration *= 0.5
|
||||||
|
}
|
||||||
|
layer.animate(from: currentPath, to: path.cgPath, keyPath: "path", timingFunction: duration > 0.35 ? kCAMediaTimingFunctionSpring : CAMediaTimingFunctionName.linear.rawValue, duration: duration, completion: { _ in
|
||||||
|
if focused && index == 0 {
|
||||||
|
self.animatingAppearance = false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
layer.animateAlpha(from: CGFloat(previousAlpha), to: CGFloat(layer.opacity), duration: focused ? 0.4 : 0.2, timingFunction: CAMediaTimingFunctionName.easeInEaseOut.rawValue, completion: !focused ? { finished in
|
||||||
|
layer.path = path.cgPath
|
||||||
|
} : nil)
|
||||||
|
layer.animate(from: previousColor, to: layer.strokeColor ?? UIColor.white.cgColor, keyPath: "strokeColor", timingFunction: CAMediaTimingFunctionName.easeInEaseOut.rawValue, duration: 0.3, delay: 0.15)
|
||||||
|
layer.animate(from: previousLineWidth, to: layer.lineWidth, keyPath: "lineWidth", timingFunction: CAMediaTimingFunctionName.easeInEaseOut.rawValue, duration: 0.3)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private extension CGPoint {
|
||||||
|
func distance(to point: CGPoint) -> CGFloat {
|
||||||
|
return sqrt(pow((point.x - self.x), 2) + pow((point.y - self.y), 2))
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,235 @@
|
|||||||
|
import Foundation
|
||||||
|
import UIKit
|
||||||
|
import Display
|
||||||
|
import ComponentFlow
|
||||||
|
import SwiftSignalKit
|
||||||
|
import TelegramCore
|
||||||
|
import MultilineTextComponent
|
||||||
|
import LottieAnimationComponent
|
||||||
|
import AvatarNode
|
||||||
|
import AccountContext
|
||||||
|
|
||||||
|
final class CameraCodeResultComponent: Component {
|
||||||
|
let context: AccountContext
|
||||||
|
let peer: EnginePeer
|
||||||
|
let pressed: (EnginePeer) -> Void
|
||||||
|
|
||||||
|
init(
|
||||||
|
context: AccountContext,
|
||||||
|
peer: EnginePeer,
|
||||||
|
pressed: @escaping (EnginePeer) -> Void
|
||||||
|
) {
|
||||||
|
self.context = context
|
||||||
|
self.peer = peer
|
||||||
|
self.pressed = pressed
|
||||||
|
}
|
||||||
|
|
||||||
|
static func ==(lhs: CameraCodeResultComponent, rhs: CameraCodeResultComponent) -> Bool {
|
||||||
|
if lhs.context !== rhs.context {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if lhs.peer != rhs.peer {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
final class View: UIView {
|
||||||
|
private var component: CameraCodeResultComponent?
|
||||||
|
|
||||||
|
private let wrapperView = UIView()
|
||||||
|
private let backgroundView = BlurredBackgroundView(color: UIColor(rgb: 0x2a2a2a, alpha: 0.65))
|
||||||
|
private let highlightedBackgroundView = UIView()
|
||||||
|
private let contentView = UIView()
|
||||||
|
private let contentWrapperView = UIView()
|
||||||
|
private let avatarNode = AvatarNode(font: avatarPlaceholderFont(size: 14.0))
|
||||||
|
private let title = ComponentView<Empty>()
|
||||||
|
private let subtitle = ComponentView<Empty>()
|
||||||
|
private let button = HighlightTrackingButton()
|
||||||
|
|
||||||
|
private let contentMaskView = UIView()
|
||||||
|
private let animationClippingView = UIView()
|
||||||
|
private let maskAnimation = ComponentView<Empty>()
|
||||||
|
private let maskBackgroundView = UIView()
|
||||||
|
|
||||||
|
init() {
|
||||||
|
self.animationClippingView.clipsToBounds = true
|
||||||
|
self.maskBackgroundView.backgroundColor = .white
|
||||||
|
self.maskBackgroundView.layer.cornerRadius = 12.0
|
||||||
|
|
||||||
|
self.highlightedBackgroundView.alpha = 0.0
|
||||||
|
self.highlightedBackgroundView.backgroundColor = UIColor(rgb: 0xffffff, alpha: 0.5)
|
||||||
|
self.highlightedBackgroundView.isUserInteractionEnabled = false
|
||||||
|
|
||||||
|
super.init(frame: CGRect())
|
||||||
|
|
||||||
|
self.addSubview(self.wrapperView)
|
||||||
|
|
||||||
|
self.wrapperView.mask = self.contentMaskView
|
||||||
|
self.wrapperView.addSubview(self.backgroundView)
|
||||||
|
self.wrapperView.addSubview(self.highlightedBackgroundView)
|
||||||
|
self.wrapperView.addSubview(self.contentView)
|
||||||
|
self.wrapperView.addSubview(self.button)
|
||||||
|
|
||||||
|
self.contentMaskView.addSubview(self.animationClippingView)
|
||||||
|
self.contentMaskView.addSubview(self.maskBackgroundView)
|
||||||
|
|
||||||
|
self.contentView.addSubview(self.contentWrapperView)
|
||||||
|
self.contentWrapperView.addSubview(self.avatarNode.view)
|
||||||
|
|
||||||
|
self.button.highligthedChanged = { [weak self] highlighted in
|
||||||
|
guard let self else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if highlighted {
|
||||||
|
self.highlightedBackgroundView.layer.removeAnimation(forKey: "opacity")
|
||||||
|
self.highlightedBackgroundView.layer.opacity = 1.0
|
||||||
|
} else {
|
||||||
|
self.highlightedBackgroundView.layer.opacity = 0.0
|
||||||
|
self.highlightedBackgroundView.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.2)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self.button.addTarget(self, action: #selector(self.buttonPressed), for: .touchUpInside)
|
||||||
|
}
|
||||||
|
|
||||||
|
required init?(coder aDecoder: NSCoder) {
|
||||||
|
preconditionFailure()
|
||||||
|
}
|
||||||
|
|
||||||
|
@objc private func buttonPressed() {
|
||||||
|
if let component = self.component {
|
||||||
|
component.pressed(component.peer)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func animateIn() {
|
||||||
|
if let view = self.maskAnimation.view as? LottieAnimationComponent.View {
|
||||||
|
view.playOnce()
|
||||||
|
Queue.mainQueue().after(0.016) {
|
||||||
|
view.alpha = 1.0
|
||||||
|
}
|
||||||
|
view.layer.animatePosition(from: CGPoint(x: 0.0, y: 20.0), to: .zero, duration: 0.5, timingFunction: kCAMediaTimingFunctionSpring, additive: true)
|
||||||
|
|
||||||
|
self.maskBackgroundView.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.001, delay: 0.29, completion: { _ in
|
||||||
|
view.alpha = 0.0
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
let overlayLayer = SimpleLayer()
|
||||||
|
overlayLayer.frame = CGRect(origin: .zero, size: self.wrapperView.bounds.size)
|
||||||
|
overlayLayer.backgroundColor = UIColor.white.cgColor
|
||||||
|
overlayLayer.animateAlpha(from: 1.0, to: 0.0, duration: 0.3, delay: 0.15, removeOnCompletion: false, completion: { _ in
|
||||||
|
overlayLayer.removeFromSuperlayer()
|
||||||
|
})
|
||||||
|
self.wrapperView.layer.insertSublayer(overlayLayer, at: 2)
|
||||||
|
|
||||||
|
self.maskBackgroundView.layer.animate(from: 27.5, to: 12.0, keyPath: "cornerRadius", timingFunction: kCAMediaTimingFunctionSpring, duration: 0.4, delay: 0.35)
|
||||||
|
|
||||||
|
self.maskBackgroundView.layer.animateSpring(from: NSValue(cgPoint: CGPoint(x: 0.0, y: 66.0)), to: NSValue(cgPoint: .zero), keyPath: "position", duration: 0.8, delay: 0.2, initialVelocity: 0.0, damping: 64.0, removeOnCompletion: true, additive: true, completion: nil)
|
||||||
|
self.maskBackgroundView.layer.animateSpring(from: 0.1 as NSNumber, to: 1.0 as NSNumber, keyPath: "transform.scale", duration: 1.0, delay: 0.0, initialVelocity: 0.0, damping: 64.0, removeOnCompletion: true, completion: nil)
|
||||||
|
self.maskBackgroundView.layer.animateSpring(from: NSValue(cgRect: CGRect(origin: .zero, size: CGSize(width: 30.0, height: 55.0))), to: NSValue(cgRect: self.maskBackgroundView.bounds), keyPath: "bounds", duration: 0.85, delay: 0.26, initialVelocity: 0.0, damping: 90.0, removeOnCompletion: true, completion: nil)
|
||||||
|
|
||||||
|
self.contentView.layer.animateSpring(from: NSValue(cgPoint: CGPoint(x: 0.0, y: 66.0)), to: NSValue(cgPoint: .zero), keyPath: "position", duration: 0.8, delay: 0.2, initialVelocity: 0.0, damping: 64.0, removeOnCompletion: true, additive: true, completion: nil)
|
||||||
|
self.contentView.layer.animateSpring(from: 0.1 as NSNumber, to: 1.0 as NSNumber, keyPath: "transform.scale", duration: 1.0, delay: 0.0, initialVelocity: 0.0, damping: 64.0, removeOnCompletion: true, completion: nil)
|
||||||
|
|
||||||
|
self.contentWrapperView.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.25, delay: 0.4)
|
||||||
|
self.contentWrapperView.layer.animateScale(from: 0.2, to: 1.0, duration: 0.25, delay: 0.35)
|
||||||
|
}
|
||||||
|
|
||||||
|
func update(component: CameraCodeResultComponent, availableSize: CGSize, transition: ComponentTransition) -> CGSize {
|
||||||
|
self.component = component
|
||||||
|
|
||||||
|
let backgroundSize = CGSize(width: 220.0, height: 55.0)
|
||||||
|
|
||||||
|
let animationSize = self.maskAnimation.update(
|
||||||
|
transition: .immediate,
|
||||||
|
component: AnyComponent(
|
||||||
|
LottieAnimationComponent(
|
||||||
|
animation: LottieAnimationComponent.AnimationItem(
|
||||||
|
name: "UserAvatarMask",
|
||||||
|
mode: .still(position: .end),
|
||||||
|
range: (1.0, 0.0),
|
||||||
|
speed: 30.0
|
||||||
|
),
|
||||||
|
colors: ["__allcolors__": .white],
|
||||||
|
size: CGSize(width: 94.0, height: 120.0)
|
||||||
|
)
|
||||||
|
),
|
||||||
|
environment: {},
|
||||||
|
containerSize: availableSize
|
||||||
|
)
|
||||||
|
if let view = self.maskAnimation.view {
|
||||||
|
if view.superview == nil {
|
||||||
|
view.alpha = 0.0
|
||||||
|
view.transform = CGAffineTransformMakeScale(1.0, -1.0)
|
||||||
|
self.animationClippingView.addSubview(view)
|
||||||
|
}
|
||||||
|
self.animationClippingView.frame = CGRect(origin: CGPoint(x: floor((availableSize.width - animationSize.width) / 2.0), y: 29.0), size: CGSize(width: animationSize.width, height: animationSize.height - 13.0))
|
||||||
|
view.frame = CGRect(origin: .zero, size: animationSize)
|
||||||
|
}
|
||||||
|
|
||||||
|
let presentationData = component.context.sharedContext.currentPresentationData.with { $0 }
|
||||||
|
|
||||||
|
let avatarSize = CGSize(width: 30.0, height: 30.0)
|
||||||
|
self.avatarNode.setPeer(context: component.context, theme: presentationData.theme, peer: component.peer)
|
||||||
|
self.avatarNode.frame = CGRect(origin: CGPoint(x: 12.0, y: floorToScreenPixels((backgroundSize.height - avatarSize.height) / 2.0)), size: avatarSize)
|
||||||
|
|
||||||
|
let titleSize = self.title.update(
|
||||||
|
transition: .immediate,
|
||||||
|
component: AnyComponent(
|
||||||
|
MultilineTextComponent(text: .plain(NSAttributedString(string: component.peer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder), font: Font.regular(17.0), textColor: .white)))
|
||||||
|
),
|
||||||
|
environment: {},
|
||||||
|
containerSize: CGSize(width: 140.0, height: availableSize.height)
|
||||||
|
)
|
||||||
|
if let view = self.title.view {
|
||||||
|
if view.superview == nil {
|
||||||
|
self.contentWrapperView.addSubview(view)
|
||||||
|
}
|
||||||
|
view.frame = CGRect(origin: CGPoint(x: 54.0, y: 9.0), size: titleSize)
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO:localize
|
||||||
|
let subtitleString = NSMutableAttributedString(string: "Open Chat >", font: Font.regular(15.0), textColor: UIColor(rgb: 0xffffff, alpha: 0.7))
|
||||||
|
if let range = subtitleString.string.range(of: ">"), let arrowImage = UIImage(bundleImageName: "Item List/InlineTextRightArrow") {
|
||||||
|
subtitleString.addAttribute(.attachment, value: arrowImage, range: NSRange(range, in: subtitleString.string))
|
||||||
|
subtitleString.addAttribute(.baselineOffset, value: 1.0, range: NSRange(range, in: subtitleString.string))
|
||||||
|
}
|
||||||
|
let subtitleSize = self.subtitle.update(
|
||||||
|
transition: .immediate,
|
||||||
|
component: AnyComponent(
|
||||||
|
MultilineTextComponent(text: .plain(subtitleString))
|
||||||
|
),
|
||||||
|
environment: {},
|
||||||
|
containerSize: CGSize(width: 140.0, height: availableSize.height)
|
||||||
|
)
|
||||||
|
if let view = self.subtitle.view {
|
||||||
|
if view.superview == nil {
|
||||||
|
self.contentWrapperView.addSubview(view)
|
||||||
|
}
|
||||||
|
view.frame = CGRect(origin: CGPoint(x: 54.0, y: 29.0), size: subtitleSize)
|
||||||
|
}
|
||||||
|
|
||||||
|
self.contentView.frame = CGRect(origin: CGPoint(x: floor((availableSize.width - backgroundSize.width) / 2.0), y: 54.0 + UIScreenPixel), size: backgroundSize)
|
||||||
|
self.contentWrapperView.frame = self.contentView.bounds
|
||||||
|
self.maskBackgroundView.frame = self.contentView.frame
|
||||||
|
self.button.frame = self.contentView.frame
|
||||||
|
self.highlightedBackgroundView.frame = self.contentView.frame
|
||||||
|
|
||||||
|
self.wrapperView.frame = CGRect(origin: .zero, size: CGSize(width: availableSize.width, height: animationSize.height + 17.0))
|
||||||
|
self.backgroundView.frame = self.wrapperView.bounds
|
||||||
|
self.backgroundView.update(size: self.wrapperView.bounds.size, transition: .immediate)
|
||||||
|
self.contentMaskView.frame = self.wrapperView.bounds
|
||||||
|
|
||||||
|
return CGSize(width: availableSize.width, height: 120.0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func makeView() -> View {
|
||||||
|
return View()
|
||||||
|
}
|
||||||
|
|
||||||
|
func update(view: View, availableSize: CGSize, state: EmptyComponentState, environment: Environment<Empty>, transition: ComponentTransition) -> CGSize {
|
||||||
|
return view.update(component: self, availableSize: availableSize, transition: transition)
|
||||||
|
}
|
||||||
|
}
|
@ -162,6 +162,9 @@ final class CameraCollage {
|
|||||||
didSet {
|
didSet {
|
||||||
if self.grid != oldValue {
|
if self.grid != oldValue {
|
||||||
self._state.grid = self.grid
|
self._state.grid = self.grid
|
||||||
|
if let cameraIndex = self.cameraIndex, cameraIndex > self.grid.count - 1 {
|
||||||
|
self.cameraIndex = self.grid.count - 1
|
||||||
|
}
|
||||||
self.updateState()
|
self.updateState()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -202,6 +205,19 @@ final class CameraCollage {
|
|||||||
self.updateState()
|
self.updateState()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func addResults(signals: [Signal<CameraScreenImpl.Result, NoError>]) {
|
||||||
|
guard self.results.count < self.grid.count else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
self.results.append(contentsOf: signals.map {
|
||||||
|
CaptureResult(result: $0, snapshotView: nil, contentUpdated: { [weak self] in
|
||||||
|
self?.checkResults()
|
||||||
|
self?.updateState()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
self.updateState()
|
||||||
|
}
|
||||||
|
|
||||||
func moveItem(fromId: Int64, toId: Int64) {
|
func moveItem(fromId: Int64, toId: Int64) {
|
||||||
guard let fromIndex = self.uniqueIds.firstIndex(where: { $0 == fromId }), let toIndex = self.uniqueIds.firstIndex(where: { $0 == toId }), toIndex < self.results.count else {
|
guard let fromIndex = self.uniqueIds.firstIndex(where: { $0 == fromId }), let toIndex = self.uniqueIds.firstIndex(where: { $0 == toId }), toIndex < self.results.count else {
|
||||||
return
|
return
|
||||||
@ -310,7 +326,7 @@ final class CameraCollage {
|
|||||||
return self._state.progress > 1.0 - .ulpOfOne
|
return self._state.progress > 1.0 - .ulpOfOne
|
||||||
}
|
}
|
||||||
|
|
||||||
var result: Signal<CameraScreenImpl.Result, NoError> {
|
func result(itemViews: [Int64 : CameraCollageView.ItemView]) -> Signal<CameraScreenImpl.Result, NoError> {
|
||||||
guard self.isComplete else {
|
guard self.isComplete else {
|
||||||
return .complete()
|
return .complete()
|
||||||
}
|
}
|
||||||
@ -337,6 +353,9 @@ outer: for row in state.rows {
|
|||||||
let columnWidth: CGFloat = floor(size.width / CGFloat(row.items.count))
|
let columnWidth: CGFloat = floor(size.width / CGFloat(row.items.count))
|
||||||
itemFrame = CGRect(origin: itemFrame.origin, size: CGSize(width: columnWidth, height: rowHeight))
|
itemFrame = CGRect(origin: itemFrame.origin, size: CGSize(width: columnWidth, height: rowHeight))
|
||||||
for item in row.items {
|
for item in row.items {
|
||||||
|
let scale = itemViews[item.uniqueId]?.contentScale ?? 1.0
|
||||||
|
let offset = itemViews[item.uniqueId]?.contentOffset ?? .zero
|
||||||
|
|
||||||
let content: CameraScreenImpl.Result.VideoCollage.Item.Content
|
let content: CameraScreenImpl.Result.VideoCollage.Item.Content
|
||||||
switch item.content {
|
switch item.content {
|
||||||
case let .image(image):
|
case let .image(image):
|
||||||
@ -351,7 +370,12 @@ outer: for row in state.rows {
|
|||||||
default:
|
default:
|
||||||
fatalError()
|
fatalError()
|
||||||
}
|
}
|
||||||
items.append(CameraScreenImpl.Result.VideoCollage.Item(content: content, frame: itemFrame))
|
items.append(CameraScreenImpl.Result.VideoCollage.Item(
|
||||||
|
content: content,
|
||||||
|
frame: itemFrame,
|
||||||
|
contentScale: scale,
|
||||||
|
contentOffset: offset
|
||||||
|
))
|
||||||
itemFrame.origin.x += columnWidth
|
itemFrame.origin.x += columnWidth
|
||||||
}
|
}
|
||||||
itemFrame.origin.x = 0.0
|
itemFrame.origin.x = 0.0
|
||||||
@ -362,14 +386,19 @@ outer: for row in state.rows {
|
|||||||
let image = generateImage(size, contextGenerator: { size, context in
|
let image = generateImage(size, contextGenerator: { size, context in
|
||||||
var itemFrame: CGRect = .zero
|
var itemFrame: CGRect = .zero
|
||||||
for row in state.rows {
|
for row in state.rows {
|
||||||
let columnWidth: CGFloat = floor(size.width / CGFloat(row.items.count))
|
let columnWidth: CGFloat = ceil(size.width / CGFloat(row.items.count))
|
||||||
itemFrame = CGRect(origin: itemFrame.origin, size: CGSize(width: columnWidth, height: rowHeight))
|
itemFrame = CGRect(origin: itemFrame.origin, size: CGSize(width: columnWidth, height: rowHeight))
|
||||||
for item in row.items {
|
for item in row.items {
|
||||||
|
let scale = itemViews[item.uniqueId]?.contentScale ?? 1.0
|
||||||
|
let offset = itemViews[item.uniqueId]?.contentOffset ?? .zero
|
||||||
|
|
||||||
let mappedItemFrame = CGRect(origin: CGPoint(x: itemFrame.minX, y: size.height - itemFrame.origin.y - rowHeight), size: CGSize(width: columnWidth, height: rowHeight))
|
let mappedItemFrame = CGRect(origin: CGPoint(x: itemFrame.minX, y: size.height - itemFrame.origin.y - rowHeight), size: CGSize(width: columnWidth, height: rowHeight))
|
||||||
if case let .image(image) = item.content {
|
if case let .image(image) = item.content {
|
||||||
context.clip(to: mappedItemFrame)
|
context.clip(to: mappedItemFrame)
|
||||||
let drawingSize = image.size.aspectFilled(mappedItemFrame.size)
|
let drawingSize = image.size.aspectFilled(mappedItemFrame.size)
|
||||||
let imageFrame = drawingSize.centered(around: mappedItemFrame.center)
|
let center = mappedItemFrame.center.offsetBy(dx: offset.x * mappedItemFrame.width, dy: offset.y * mappedItemFrame.height)
|
||||||
|
|
||||||
|
let imageFrame = CGSize(width: drawingSize.width * scale, height: drawingSize.height * scale).centered(around: center)
|
||||||
if let cgImage = image.cgImage {
|
if let cgImage = image.cgImage {
|
||||||
context.draw(cgImage, in: imageFrame, byTiling: false)
|
context.draw(cgImage, in: imageFrame, byTiling: false)
|
||||||
}
|
}
|
||||||
@ -411,10 +440,12 @@ final class CameraCollageView: UIView, UIGestureRecognizerDelegate {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
final class ItemView: ContextControllerSourceView {
|
final class ItemView: ContextControllerSourceView, UIScrollViewDelegate {
|
||||||
private let extractedContainerView = ContextExtractedContentContainingView()
|
private let extractedContainerView = ContextExtractedContentContainingView()
|
||||||
|
|
||||||
|
private let scrollView = UIScrollView()
|
||||||
private let clippingView = UIView()
|
private let clippingView = UIView()
|
||||||
|
private let contentView = UIView()
|
||||||
private var snapshotView: UIView?
|
private var snapshotView: UIView?
|
||||||
private var cameraContainerView: UIView?
|
private var cameraContainerView: UIView?
|
||||||
private var imageView: UIImageView?
|
private var imageView: UIImageView?
|
||||||
@ -429,6 +460,14 @@ final class CameraCollageView: UIView, UIGestureRecognizerDelegate {
|
|||||||
|
|
||||||
var contextAction: ((Int64, ContextExtractedContentContainingView, ContextGesture?) -> Void)?
|
var contextAction: ((Int64, ContextExtractedContentContainingView, ContextGesture?) -> Void)?
|
||||||
|
|
||||||
|
var contentScale: CGFloat {
|
||||||
|
return self.scrollView.zoomScale
|
||||||
|
}
|
||||||
|
|
||||||
|
var contentOffset: CGPoint {
|
||||||
|
return self.scrollView.offsetFromCenter
|
||||||
|
}
|
||||||
|
|
||||||
var isCamera: Bool {
|
var isCamera: Bool {
|
||||||
if case .camera = self.item?.content {
|
if case .camera = self.item?.content {
|
||||||
return true
|
return true
|
||||||
@ -459,8 +498,17 @@ final class CameraCollageView: UIView, UIGestureRecognizerDelegate {
|
|||||||
override init(frame: CGRect) {
|
override init(frame: CGRect) {
|
||||||
super.init(frame: frame)
|
super.init(frame: frame)
|
||||||
|
|
||||||
self.clippingView.clipsToBounds = true
|
self.scrollView.delegate = self
|
||||||
|
self.scrollView.contentInsetAdjustmentBehavior = .never
|
||||||
|
self.scrollView.contentInset = .zero
|
||||||
|
self.scrollView.showsHorizontalScrollIndicator = false
|
||||||
|
self.scrollView.showsVerticalScrollIndicator = false
|
||||||
|
self.scrollView.decelerationRate = .fast
|
||||||
|
//self.scrollView.panGestureRecognizer.minimumNumberOfTouches = 2
|
||||||
|
|
||||||
|
self.clippingView.clipsToBounds = true
|
||||||
|
self.clippingView.isUserInteractionEnabled = false
|
||||||
|
|
||||||
self.addSubview(self.extractedContainerView)
|
self.addSubview(self.extractedContainerView)
|
||||||
|
|
||||||
self.isGestureEnabled = false
|
self.isGestureEnabled = false
|
||||||
@ -468,8 +516,11 @@ final class CameraCollageView: UIView, UIGestureRecognizerDelegate {
|
|||||||
|
|
||||||
self.clipsToBounds = true
|
self.clipsToBounds = true
|
||||||
self.extractedContainerView.contentView.clipsToBounds = true
|
self.extractedContainerView.contentView.clipsToBounds = true
|
||||||
|
self.extractedContainerView.contentView.addSubview(self.scrollView)
|
||||||
self.extractedContainerView.contentView.addSubview(self.clippingView)
|
self.extractedContainerView.contentView.addSubview(self.clippingView)
|
||||||
|
|
||||||
|
self.scrollView.addSubview(self.contentView)
|
||||||
|
|
||||||
self.extractedContainerView.willUpdateIsExtractedToContextPreview = { [weak self] value, _ in
|
self.extractedContainerView.willUpdateIsExtractedToContextPreview = { [weak self] value, _ in
|
||||||
guard let self else {
|
guard let self else {
|
||||||
return
|
return
|
||||||
@ -477,10 +528,13 @@ final class CameraCollageView: UIView, UIGestureRecognizerDelegate {
|
|||||||
let transition = ContainedViewLayoutTransition.animated(duration: 0.2, curve: .easeInOut)
|
let transition = ContainedViewLayoutTransition.animated(duration: 0.2, curve: .easeInOut)
|
||||||
if value {
|
if value {
|
||||||
self.clippingView.layer.cornerRadius = 12.0
|
self.clippingView.layer.cornerRadius = 12.0
|
||||||
|
self.scrollView.layer.cornerRadius = 12.0
|
||||||
transition.updateSublayerTransformScale(layer: self.extractedContainerView.contentView.layer, scale: CGPoint(x: 0.9, y: 0.9))
|
transition.updateSublayerTransformScale(layer: self.extractedContainerView.contentView.layer, scale: CGPoint(x: 0.9, y: 0.9))
|
||||||
} else {
|
} else {
|
||||||
self.clippingView.layer.cornerRadius = 0.0
|
self.clippingView.layer.cornerRadius = 0.0
|
||||||
self.clippingView.layer.animate(from: NSNumber(value: Float(12.0)), to: NSNumber(value: Float(0.0)), keyPath: "cornerRadius", timingFunction: CAMediaTimingFunctionName.easeInEaseOut.rawValue, duration: 0.2)
|
self.clippingView.layer.animate(from: NSNumber(value: Float(12.0)), to: NSNumber(value: Float(0.0)), keyPath: "cornerRadius", timingFunction: CAMediaTimingFunctionName.easeInEaseOut.rawValue, duration: 0.2)
|
||||||
|
self.scrollView.layer.cornerRadius = 0.0
|
||||||
|
self.scrollView.layer.animate(from: NSNumber(value: Float(12.0)), to: NSNumber(value: Float(0.0)), keyPath: "cornerRadius", timingFunction: CAMediaTimingFunctionName.easeInEaseOut.rawValue, duration: 0.2)
|
||||||
transition.updateSublayerTransformScale(layer: self.extractedContainerView.contentView.layer, scale: CGPoint(x: 1.0, y: 1.0))
|
transition.updateSublayerTransformScale(layer: self.extractedContainerView.contentView.layer, scale: CGPoint(x: 1.0, y: 1.0))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -521,6 +575,13 @@ final class CameraCollageView: UIView, UIGestureRecognizerDelegate {
|
|||||||
|
|
||||||
let center = CGPoint(x: size.width / 2.0, y: size.height / 2.0)
|
let center = CGPoint(x: size.width / 2.0, y: size.height / 2.0)
|
||||||
|
|
||||||
|
let bounds = CGRect(origin: .zero, size: size)
|
||||||
|
var sizeUpdated = false
|
||||||
|
if self.scrollView.frame.size.width > 0.0 && self.scrollView.frame.size != size {
|
||||||
|
sizeUpdated = true
|
||||||
|
}
|
||||||
|
transition.setFrame(view: self.scrollView, frame: CGRect(origin: .zero, size: size))
|
||||||
|
|
||||||
switch item.content {
|
switch item.content {
|
||||||
case let .pending(placeholder):
|
case let .pending(placeholder):
|
||||||
if let placeholder {
|
if let placeholder {
|
||||||
@ -659,7 +720,8 @@ final class CameraCollageView: UIView, UIGestureRecognizerDelegate {
|
|||||||
previewLayer.removeFromSuperlayer()
|
previewLayer.removeFromSuperlayer()
|
||||||
self.previewLayer = nil
|
self.previewLayer = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var added = false
|
||||||
var imageTransition = transition
|
var imageTransition = transition
|
||||||
var imageView: UIImageView
|
var imageView: UIImageView
|
||||||
if let current = self.imageView {
|
if let current = self.imageView {
|
||||||
@ -669,10 +731,19 @@ final class CameraCollageView: UIView, UIGestureRecognizerDelegate {
|
|||||||
imageView = UIImageView()
|
imageView = UIImageView()
|
||||||
imageView.contentMode = .scaleAspectFill
|
imageView.contentMode = .scaleAspectFill
|
||||||
self.imageView = imageView
|
self.imageView = imageView
|
||||||
self.clippingView.addSubview(imageView)
|
self.contentView.addSubview(imageView)
|
||||||
|
added = true
|
||||||
}
|
}
|
||||||
imageView.image = image
|
imageView.image = image
|
||||||
imageTransition.setFrame(view: imageView, frame: CGRect(origin: .zero, size: size))
|
|
||||||
|
let dimensions = image.size.aspectFilled(size)
|
||||||
|
imageTransition.setFrame(view: imageView, frame: CGRect(origin: .zero, size: dimensions))
|
||||||
|
|
||||||
|
if added || sizeUpdated {
|
||||||
|
self.contentView.bounds = CGRect(origin: .zero, size: dimensions)
|
||||||
|
self.scrollView.contentSize = dimensions
|
||||||
|
self.scrollView.resetZooming()
|
||||||
|
}
|
||||||
case let .video(asset, _, _, _):
|
case let .video(asset, _, _, _):
|
||||||
if let cameraContainerView = self.cameraContainerView {
|
if let cameraContainerView = self.cameraContainerView {
|
||||||
cameraContainerView.removeFromSuperview()
|
cameraContainerView.removeFromSuperview()
|
||||||
@ -696,6 +767,7 @@ final class CameraCollageView: UIView, UIGestureRecognizerDelegate {
|
|||||||
self.previewLayer = nil
|
self.previewLayer = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var added = false
|
||||||
var imageTransition = transition
|
var imageTransition = transition
|
||||||
if self.videoLayer == nil {
|
if self.videoLayer == nil {
|
||||||
imageTransition = .immediate
|
imageTransition = .immediate
|
||||||
@ -723,17 +795,27 @@ final class CameraCollageView: UIView, UIGestureRecognizerDelegate {
|
|||||||
self.videoLayer = videoLayer
|
self.videoLayer = videoLayer
|
||||||
self.videoPlayer = player
|
self.videoPlayer = player
|
||||||
|
|
||||||
self.clippingView.layer.addSublayer(videoLayer)
|
self.contentView.layer.addSublayer(videoLayer)
|
||||||
|
|
||||||
player.playImmediately(atRate: 1.0)
|
player.playImmediately(atRate: 1.0)
|
||||||
|
|
||||||
|
added = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let dimensions = (asset.videoDimensions ?? CGSize(width: 1.0, height: 1.0)).aspectFilled(size)
|
||||||
if let videoLayer = self.videoLayer {
|
if let videoLayer = self.videoLayer {
|
||||||
imageTransition.setFrame(layer: videoLayer, frame: CGRect(origin: .zero, size: size))
|
imageTransition.setFrame(layer: videoLayer, frame: CGRect(origin: .zero, size: dimensions))
|
||||||
|
}
|
||||||
|
|
||||||
|
if added || sizeUpdated {
|
||||||
|
self.contentView.bounds = CGRect(origin: .zero, size: dimensions)
|
||||||
|
self.scrollView.contentSize = dimensions
|
||||||
|
self.scrollView.resetZooming()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let bounds = CGRect(origin: .zero, size: size)
|
self.adjustPreviewZoom(updating: true)
|
||||||
|
|
||||||
transition.setFrame(view: self.extractedContainerView, frame: bounds)
|
transition.setFrame(view: self.extractedContainerView, frame: bounds)
|
||||||
transition.setFrame(view: self.extractedContainerView.contentView, frame: bounds)
|
transition.setFrame(view: self.extractedContainerView.contentView, frame: bounds)
|
||||||
transition.setBounds(view: self.clippingView, bounds: bounds)
|
transition.setBounds(view: self.clippingView, bounds: bounds)
|
||||||
@ -774,6 +856,49 @@ final class CameraCollageView: UIView, UIGestureRecognizerDelegate {
|
|||||||
completion()
|
completion()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private func adjustPreviewZoom(updating: Bool = false) {
|
||||||
|
let minScale: CGFloat = 1.0
|
||||||
|
let maxScale: CGFloat = 3.5
|
||||||
|
|
||||||
|
if self.scrollView.minimumZoomScale != minScale {
|
||||||
|
self.scrollView.minimumZoomScale = minScale
|
||||||
|
}
|
||||||
|
if self.scrollView.maximumZoomScale != maxScale {
|
||||||
|
self.scrollView.maximumZoomScale = maxScale
|
||||||
|
}
|
||||||
|
|
||||||
|
let boundsSize = self.scrollView.frame.size
|
||||||
|
var contentFrame = self.contentView.frame
|
||||||
|
if boundsSize.width > contentFrame.size.width {
|
||||||
|
contentFrame.origin.x = (boundsSize.width - contentFrame.size.width) / 2.0
|
||||||
|
} else {
|
||||||
|
contentFrame.origin.x = 0.0
|
||||||
|
}
|
||||||
|
|
||||||
|
if boundsSize.height > contentFrame.size.height {
|
||||||
|
contentFrame.origin.y = (boundsSize.height - contentFrame.size.height) / 2.0
|
||||||
|
} else {
|
||||||
|
contentFrame.origin.y = 0.0
|
||||||
|
}
|
||||||
|
self.contentView.frame = contentFrame
|
||||||
|
}
|
||||||
|
|
||||||
|
func scrollViewDidZoom(_ scrollView: UIScrollView) {
|
||||||
|
self.adjustPreviewZoom()
|
||||||
|
}
|
||||||
|
|
||||||
|
func scrollViewDidEndZooming(_ scrollView: UIScrollView, with view: UIView?, atScale scale: CGFloat) {
|
||||||
|
self.adjustPreviewZoom()
|
||||||
|
|
||||||
|
if scrollView.zoomScale < 1.0 {
|
||||||
|
scrollView.setZoomScale(1.0, animated: true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func viewForZooming(in scrollView: UIScrollView) -> UIView? {
|
||||||
|
return self.contentView
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private let context: AccountContext
|
private let context: AccountContext
|
||||||
@ -805,6 +930,10 @@ final class CameraCollageView: UIView, UIGestureRecognizerDelegate {
|
|||||||
|
|
||||||
var isEnabled: Bool = true
|
var isEnabled: Bool = true
|
||||||
|
|
||||||
|
var result: Signal<CameraScreenImpl.Result, NoError> {
|
||||||
|
return self.collage.result(itemViews: self.itemViews)
|
||||||
|
}
|
||||||
|
|
||||||
init(context: AccountContext, collage: CameraCollage, camera: Camera?, cameraContainerView: UIView?) {
|
init(context: AccountContext, collage: CameraCollage, camera: Camera?, cameraContainerView: UIView?) {
|
||||||
self.context = context
|
self.context = context
|
||||||
self.collage = collage
|
self.collage = collage
|
||||||
@ -934,6 +1063,15 @@ final class CameraCollageView: UIView, UIGestureRecognizerDelegate {
|
|||||||
if otherGestureRecognizer is UITapGestureRecognizer {
|
if otherGestureRecognizer is UITapGestureRecognizer {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
if otherGestureRecognizer is UIPanGestureRecognizer {
|
||||||
|
if gestureRecognizer === self.reorderRecognizer, ![.began, .changed].contains(gestureRecognizer.state) {
|
||||||
|
gestureRecognizer.isEnabled = false
|
||||||
|
gestureRecognizer.isEnabled = true
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1074,7 +1212,9 @@ final class CameraCollageView: UIView, UIGestureRecognizerDelegate {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if self.itemViews.count > 2 {
|
if self.itemViews.count > 2 {
|
||||||
itemList.append(.separator)
|
if itemList.count > 0 {
|
||||||
|
itemList.append(.separator)
|
||||||
|
}
|
||||||
|
|
||||||
itemList.append(.action(ContextMenuActionItem(text: presentationData.strings.Camera_CollageDelete, textColor: .destructive, icon: { theme in
|
itemList.append(.action(ContextMenuActionItem(text: presentationData.strings.Camera_CollageDelete, textColor: .destructive, icon: { theme in
|
||||||
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Delete"), color: theme.contextMenu.destructiveColor)
|
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Delete"), color: theme.contextMenu.destructiveColor)
|
||||||
@ -1418,3 +1558,46 @@ private final class CollageContextExtractedContentSource: ContextExtractedConten
|
|||||||
return ContextControllerPutBackViewInfo(contentAreaInScreenSpace: UIScreen.main.bounds)
|
return ContextControllerPutBackViewInfo(contentAreaInScreenSpace: UIScreen.main.bounds)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private extension AVAsset {
|
||||||
|
var videoDimensions: CGSize? {
|
||||||
|
if let videoTrack = self.tracks(withMediaType: .video).first {
|
||||||
|
let size = videoTrack.naturalSize
|
||||||
|
let transform = videoTrack.preferredTransform
|
||||||
|
let isPortrait = transform.a == 0 && abs(transform.b) == 1 && abs(transform.c) == 1 && transform.d == 0
|
||||||
|
return isPortrait ? CGSize(width: size.height, height: size.width) : size
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private extension UIScrollView {
|
||||||
|
func resetZooming() {
|
||||||
|
guard let contentView = self.delegate?.viewForZooming?(in: self) else { return }
|
||||||
|
|
||||||
|
let scrollViewSize = self.bounds.size
|
||||||
|
let contentSize = contentView.frame.size
|
||||||
|
|
||||||
|
let offsetX = (scrollViewSize.width - contentSize.width) * 0.5
|
||||||
|
let offsetY = (scrollViewSize.height - contentSize.height) * 0.5
|
||||||
|
|
||||||
|
contentView.center = CGPoint(
|
||||||
|
x: scrollViewSize.width / 2.0 + self.contentOffset.x,
|
||||||
|
y: scrollViewSize.height / 2.0 + self.contentOffset.y
|
||||||
|
)
|
||||||
|
|
||||||
|
self.contentOffset = CGPoint(x: -offsetX, y: -offsetY)
|
||||||
|
}
|
||||||
|
|
||||||
|
var offsetFromCenter: CGPoint {
|
||||||
|
let contentCenterX = (self.contentSize.width - self.bounds.width) / 2.0
|
||||||
|
let contentCenterY = (self.contentSize.height - self.bounds.height) / 2.0
|
||||||
|
let contentCenter = CGPoint(x: contentCenterX, y: contentCenterY)
|
||||||
|
|
||||||
|
let currentOffset = self.contentOffset
|
||||||
|
let deltaX = currentOffset.x - contentCenter.x
|
||||||
|
let deltaY = currentOffset.y - contentCenter.y
|
||||||
|
|
||||||
|
return CGPoint(x: -(deltaX / self.bounds.width), y: (deltaY / self.bounds.height))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -154,6 +154,7 @@ private final class CameraScreenComponent: CombinedComponent {
|
|||||||
let hasAppeared: Bool
|
let hasAppeared: Bool
|
||||||
let isVisible: Bool
|
let isVisible: Bool
|
||||||
let panelWidth: CGFloat
|
let panelWidth: CGFloat
|
||||||
|
let resolvedCodePeer: EnginePeer?
|
||||||
let animateFlipAction: ActionSlot<Void>
|
let animateFlipAction: ActionSlot<Void>
|
||||||
let animateShutter: () -> Void
|
let animateShutter: () -> Void
|
||||||
let toggleCameraPositionAction: ActionSlot<Void>
|
let toggleCameraPositionAction: ActionSlot<Void>
|
||||||
@ -162,6 +163,7 @@ private final class CameraScreenComponent: CombinedComponent {
|
|||||||
let present: (ViewController) -> Void
|
let present: (ViewController) -> Void
|
||||||
let push: (ViewController) -> Void
|
let push: (ViewController) -> Void
|
||||||
let completion: ActionSlot<Signal<CameraScreenImpl.Result, NoError>>
|
let completion: ActionSlot<Signal<CameraScreenImpl.Result, NoError>>
|
||||||
|
let openResolvedPeer: (EnginePeer) -> Void
|
||||||
|
|
||||||
init(
|
init(
|
||||||
context: AccountContext,
|
context: AccountContext,
|
||||||
@ -171,6 +173,7 @@ private final class CameraScreenComponent: CombinedComponent {
|
|||||||
hasAppeared: Bool,
|
hasAppeared: Bool,
|
||||||
isVisible: Bool,
|
isVisible: Bool,
|
||||||
panelWidth: CGFloat,
|
panelWidth: CGFloat,
|
||||||
|
resolvedCodePeer: EnginePeer?,
|
||||||
animateFlipAction: ActionSlot<Void>,
|
animateFlipAction: ActionSlot<Void>,
|
||||||
animateShutter: @escaping () -> Void,
|
animateShutter: @escaping () -> Void,
|
||||||
toggleCameraPositionAction: ActionSlot<Void>,
|
toggleCameraPositionAction: ActionSlot<Void>,
|
||||||
@ -178,7 +181,8 @@ private final class CameraScreenComponent: CombinedComponent {
|
|||||||
getController: @escaping () -> CameraScreenImpl?,
|
getController: @escaping () -> CameraScreenImpl?,
|
||||||
present: @escaping (ViewController) -> Void,
|
present: @escaping (ViewController) -> Void,
|
||||||
push: @escaping (ViewController) -> Void,
|
push: @escaping (ViewController) -> Void,
|
||||||
completion: ActionSlot<Signal<CameraScreenImpl.Result, NoError>>
|
completion: ActionSlot<Signal<CameraScreenImpl.Result, NoError>>,
|
||||||
|
openResolvedPeer: @escaping (EnginePeer) -> Void
|
||||||
) {
|
) {
|
||||||
self.context = context
|
self.context = context
|
||||||
self.cameraState = cameraState
|
self.cameraState = cameraState
|
||||||
@ -187,6 +191,7 @@ private final class CameraScreenComponent: CombinedComponent {
|
|||||||
self.hasAppeared = hasAppeared
|
self.hasAppeared = hasAppeared
|
||||||
self.isVisible = isVisible
|
self.isVisible = isVisible
|
||||||
self.panelWidth = panelWidth
|
self.panelWidth = panelWidth
|
||||||
|
self.resolvedCodePeer = resolvedCodePeer
|
||||||
self.animateFlipAction = animateFlipAction
|
self.animateFlipAction = animateFlipAction
|
||||||
self.animateShutter = animateShutter
|
self.animateShutter = animateShutter
|
||||||
self.toggleCameraPositionAction = toggleCameraPositionAction
|
self.toggleCameraPositionAction = toggleCameraPositionAction
|
||||||
@ -195,6 +200,7 @@ private final class CameraScreenComponent: CombinedComponent {
|
|||||||
self.present = present
|
self.present = present
|
||||||
self.push = push
|
self.push = push
|
||||||
self.completion = completion
|
self.completion = completion
|
||||||
|
self.openResolvedPeer = openResolvedPeer
|
||||||
}
|
}
|
||||||
|
|
||||||
static func ==(lhs: CameraScreenComponent, rhs: CameraScreenComponent) -> Bool {
|
static func ==(lhs: CameraScreenComponent, rhs: CameraScreenComponent) -> Bool {
|
||||||
@ -219,6 +225,9 @@ private final class CameraScreenComponent: CombinedComponent {
|
|||||||
if lhs.panelWidth != rhs.panelWidth {
|
if lhs.panelWidth != rhs.panelWidth {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
if lhs.resolvedCodePeer != rhs.resolvedCodePeer {
|
||||||
|
return false
|
||||||
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -630,6 +639,10 @@ private final class CameraScreenComponent: CombinedComponent {
|
|||||||
self.updated(transition: .easeInOut(duration: 0.2))
|
self.updated(transition: .easeInOut(duration: 0.2))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var isRecording: Bool {
|
||||||
|
return self.cameraState?.recording != CameraState.Recording.none
|
||||||
|
}
|
||||||
|
|
||||||
var isTakingPhoto = false
|
var isTakingPhoto = false
|
||||||
func takePhoto() {
|
func takePhoto() {
|
||||||
guard let controller = self.getController(), let camera = controller.camera, let cameraState = self.cameraState else {
|
guard let controller = self.getController(), let camera = controller.camera, let cameraState = self.cameraState else {
|
||||||
@ -890,11 +903,14 @@ private final class CameraScreenComponent: CombinedComponent {
|
|||||||
state.cameraState = component.cameraState
|
state.cameraState = component.cameraState
|
||||||
state.volumeButtonsListenerActive = component.hasAppeared && component.isVisible
|
state.volumeButtonsListenerActive = component.hasAppeared && component.isVisible
|
||||||
|
|
||||||
let isSticker: Bool
|
var isSticker = false
|
||||||
if let controller = controller() as? CameraScreenImpl, case .sticker = controller.mode {
|
var isAvatar = false
|
||||||
isSticker = true
|
if let controller = controller() as? CameraScreenImpl {
|
||||||
} else {
|
if case .sticker = controller.mode {
|
||||||
isSticker = false
|
isSticker = true
|
||||||
|
} else if case .avatar = controller.mode {
|
||||||
|
isAvatar = true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let isTablet: Bool
|
let isTablet: Bool
|
||||||
@ -1028,8 +1044,10 @@ private final class CameraScreenComponent: CombinedComponent {
|
|||||||
|
|
||||||
let captureControls = captureControls.update(
|
let captureControls = captureControls.update(
|
||||||
component: CaptureControlsComponent(
|
component: CaptureControlsComponent(
|
||||||
|
context: component.context,
|
||||||
isTablet: isTablet,
|
isTablet: isTablet,
|
||||||
isSticker: isSticker,
|
isSticker: isSticker,
|
||||||
|
hasGallery: !isSticker && !isAvatar,
|
||||||
hasAppeared: component.hasAppeared && hasAllRequiredAccess,
|
hasAppeared: component.hasAppeared && hasAllRequiredAccess,
|
||||||
hasAccess: hasAllRequiredAccess,
|
hasAccess: hasAllRequiredAccess,
|
||||||
hideControls: component.cameraState.collageProgress > 1.0 - .ulpOfOne,
|
hideControls: component.cameraState.collageProgress > 1.0 - .ulpOfOne,
|
||||||
@ -1038,6 +1056,7 @@ private final class CameraScreenComponent: CombinedComponent {
|
|||||||
tintColor: controlsTintColor,
|
tintColor: controlsTintColor,
|
||||||
shutterState: shutterState,
|
shutterState: shutterState,
|
||||||
lastGalleryAsset: state.lastGalleryAsset,
|
lastGalleryAsset: state.lastGalleryAsset,
|
||||||
|
resolvedCodePeer: state.isTakingPhoto || state.isRecording ? nil : component.resolvedCodePeer,
|
||||||
tag: captureControlsTag,
|
tag: captureControlsTag,
|
||||||
galleryButtonTag: galleryButtonTag,
|
galleryButtonTag: galleryButtonTag,
|
||||||
shutterTapped: { [weak state] in
|
shutterTapped: { [weak state] in
|
||||||
@ -1096,7 +1115,8 @@ private final class CameraScreenComponent: CombinedComponent {
|
|||||||
state.updateZoom(fraction: fraction)
|
state.updateZoom(fraction: fraction)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
flipAnimationAction: animateFlipAction
|
flipAnimationAction: animateFlipAction,
|
||||||
|
openResolvedPeer: component.openResolvedPeer
|
||||||
),
|
),
|
||||||
availableSize: captureControlsAvailableSize,
|
availableSize: captureControlsAvailableSize,
|
||||||
transition: context.transition
|
transition: context.transition
|
||||||
@ -1259,7 +1279,7 @@ private final class CameraScreenComponent: CombinedComponent {
|
|||||||
rightMostButtonWidth = flashButton.size.width
|
rightMostButtonWidth = flashButton.size.width
|
||||||
}
|
}
|
||||||
|
|
||||||
if !isSticker && !isTablet {
|
if !isSticker && !isAvatar && !isTablet {
|
||||||
var nextButtonX = availableSize.width - topControlInset - rightMostButtonWidth / 2.0 - 58.0
|
var nextButtonX = availableSize.width - topControlInset - rightMostButtonWidth / 2.0 - 58.0
|
||||||
if Camera.isDualCameraSupported(forRoundVideo: false) && !component.cameraState.isCollageEnabled {
|
if Camera.isDualCameraSupported(forRoundVideo: false) && !component.cameraState.isCollageEnabled {
|
||||||
let dualButton = dualButton.update(
|
let dualButton = dualButton.update(
|
||||||
@ -1581,6 +1601,7 @@ public class CameraScreenImpl: ViewController, CameraScreen {
|
|||||||
public enum Mode {
|
public enum Mode {
|
||||||
case story
|
case story
|
||||||
case sticker
|
case sticker
|
||||||
|
case avatar
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum PIPPosition: Int32 {
|
public enum PIPPosition: Int32 {
|
||||||
@ -1618,6 +1639,8 @@ public class CameraScreenImpl: ViewController, CameraScreen {
|
|||||||
}
|
}
|
||||||
public let content: Content
|
public let content: Content
|
||||||
public let frame: CGRect
|
public let frame: CGRect
|
||||||
|
public let contentScale: CGFloat
|
||||||
|
public let contentOffset: CGPoint
|
||||||
}
|
}
|
||||||
public let items: [Item]
|
public let items: [Item]
|
||||||
}
|
}
|
||||||
@ -1687,6 +1710,7 @@ public class CameraScreenImpl: ViewController, CameraScreen {
|
|||||||
fileprivate let backgroundView: UIView
|
fileprivate let backgroundView: UIView
|
||||||
fileprivate let containerView: UIView
|
fileprivate let containerView: UIView
|
||||||
fileprivate let componentHost: ComponentView<ViewControllerComponentContainer.Environment>
|
fileprivate let componentHost: ComponentView<ViewControllerComponentContainer.Environment>
|
||||||
|
fileprivate let codeFrameView: CameraCodeFrameView
|
||||||
private let previewContainerView: UIView
|
private let previewContainerView: UIView
|
||||||
|
|
||||||
private let collageContainerView: UIView
|
private let collageContainerView: UIView
|
||||||
@ -1821,7 +1845,7 @@ public class CameraScreenImpl: ViewController, CameraScreen {
|
|||||||
isDualCameraEnabled = isDualCameraEnabledValue.boolValue
|
isDualCameraEnabled = isDualCameraEnabledValue.boolValue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if case .sticker = controller.mode {
|
if [.sticker, .avatar].contains(controller.mode) {
|
||||||
isDualCameraEnabled = false
|
isDualCameraEnabled = false
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1836,6 +1860,8 @@ public class CameraScreenImpl: ViewController, CameraScreen {
|
|||||||
cameraFrontPosition = true
|
cameraFrontPosition = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self.codeFrameView = CameraCodeFrameView(frame: .zero)
|
||||||
|
|
||||||
self.collageContainerView = UIView()
|
self.collageContainerView = UIView()
|
||||||
self.collageContainerView.clipsToBounds = true
|
self.collageContainerView.clipsToBounds = true
|
||||||
|
|
||||||
@ -1901,6 +1927,7 @@ public class CameraScreenImpl: ViewController, CameraScreen {
|
|||||||
self.previewContainerView.addSubview(self.previewBlurView)
|
self.previewContainerView.addSubview(self.previewBlurView)
|
||||||
self.previewContainerView.addSubview(self.previewFrameLeftDimView)
|
self.previewContainerView.addSubview(self.previewFrameLeftDimView)
|
||||||
self.previewContainerView.addSubview(self.previewFrameRightDimView)
|
self.previewContainerView.addSubview(self.previewFrameRightDimView)
|
||||||
|
self.previewContainerView.addSubview(self.codeFrameView)
|
||||||
self.containerView.addSubview(self.transitionDimView)
|
self.containerView.addSubview(self.transitionDimView)
|
||||||
self.view.addSubview(self.transitionCornersView)
|
self.view.addSubview(self.transitionCornersView)
|
||||||
|
|
||||||
@ -1912,21 +1939,16 @@ public class CameraScreenImpl: ViewController, CameraScreen {
|
|||||||
if let self {
|
if let self {
|
||||||
let pipPosition = self.pipPosition
|
let pipPosition = self.pipPosition
|
||||||
if self.cameraState.isCollageEnabled {
|
if self.cameraState.isCollageEnabled {
|
||||||
if let collage = self.collage {
|
if let collage = self.collage, let collageView = self.collageView {
|
||||||
if collage.isComplete {
|
if collage.isComplete {
|
||||||
self.animateOutToEditor()
|
self.animateOutToEditor()
|
||||||
self.controller?.completion(
|
self.controller?.completion(
|
||||||
collage.result
|
collageView.result
|
||||||
|> beforeNext { [weak self] value in
|
|> beforeNext { [weak self] value in
|
||||||
guard let self else {
|
guard let self else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
Queue.mainQueue().async {
|
Queue.mainQueue().async {
|
||||||
if case .image = value {
|
|
||||||
Queue.mainQueue().after(0.3) {
|
|
||||||
self.previewBlurPromise.set(true)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
self.mainPreviewView.isEnabled = false
|
self.mainPreviewView.isEnabled = false
|
||||||
self.additionalPreviewView.isEnabled = false
|
self.additionalPreviewView.isEnabled = false
|
||||||
self.camera?.stopCapture()
|
self.camera?.stopCapture()
|
||||||
@ -2099,7 +2121,7 @@ public class CameraScreenImpl: ViewController, CameraScreen {
|
|||||||
isDualEnabled: self.cameraState.isDualCameraEnabled,
|
isDualEnabled: self.cameraState.isDualCameraEnabled,
|
||||||
audio: true,
|
audio: true,
|
||||||
photo: true,
|
photo: true,
|
||||||
metadata: false
|
metadata: true
|
||||||
),
|
),
|
||||||
previewView: self.mainPreviewView,
|
previewView: self.mainPreviewView,
|
||||||
secondaryPreviewView: self.additionalPreviewView
|
secondaryPreviewView: self.additionalPreviewView
|
||||||
@ -2216,6 +2238,29 @@ public class CameraScreenImpl: ViewController, CameraScreen {
|
|||||||
|
|
||||||
camera.focus(at: CGPoint(x: 0.5, y: 0.5), autoFocus: true)
|
camera.focus(at: CGPoint(x: 0.5, y: 0.5), autoFocus: true)
|
||||||
if isNew {
|
if isNew {
|
||||||
|
let throttledSignal = camera.detectedCodes
|
||||||
|
|> mapToThrottled { next -> Signal<[CameraCode], NoError> in
|
||||||
|
return .single(next) |> then(.complete() |> delay(0.1, queue: Queue.concurrentDefaultQueue()))
|
||||||
|
}
|
||||||
|
self.controller?.codeDisposable = (throttledSignal
|
||||||
|
|> deliverOnMainQueue).start(next: { [weak self] codes in
|
||||||
|
guard let self else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
let filteredCodes = codes.filter {
|
||||||
|
let message = $0.message.replacingOccurrences(of: "https://", with: "")
|
||||||
|
if message.hasPrefix("t.me/c/") || message.hasPrefix("t.me/+") || message.hasPrefix("t.me/contact/") || message.hasPrefix("t.me/") {
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if let code = filteredCodes.first, !self.cameraState.isCollageEnabled && self.cameraState.recording == CameraState.Recording.none {
|
||||||
|
self.controller?.updateFocusedCode(code)
|
||||||
|
} else {
|
||||||
|
self.controller?.updateFocusedCode(nil)
|
||||||
|
}
|
||||||
|
})
|
||||||
camera.startCapture()
|
camera.startCapture()
|
||||||
}
|
}
|
||||||
self.captureStartTimestamp = CACurrentMediaTime()
|
self.captureStartTimestamp = CACurrentMediaTime()
|
||||||
@ -2287,7 +2332,7 @@ public class CameraScreenImpl: ViewController, CameraScreen {
|
|||||||
gestureRecognizer.isEnabled = false
|
gestureRecognizer.isEnabled = false
|
||||||
gestureRecognizer.isEnabled = true
|
gestureRecognizer.isEnabled = true
|
||||||
}
|
}
|
||||||
case .sticker:
|
case .sticker, .avatar:
|
||||||
if (abs(translation.y) > 10.0 || self.isDismissing) && self.hasAppeared {
|
if (abs(translation.y) > 10.0 || self.isDismissing) && self.hasAppeared {
|
||||||
self.containerView.layer.sublayerTransform = CATransform3DMakeTranslation(0.0, translation.y, 0.0)
|
self.containerView.layer.sublayerTransform = CATransform3DMakeTranslation(0.0, translation.y, 0.0)
|
||||||
if !self.isDismissing {
|
if !self.isDismissing {
|
||||||
@ -2308,7 +2353,7 @@ public class CameraScreenImpl: ViewController, CameraScreen {
|
|||||||
controller.completeWithTransitionProgress(transitionFraction, velocity: abs(velocity.x), dismissing: true)
|
controller.completeWithTransitionProgress(transitionFraction, velocity: abs(velocity.x), dismissing: true)
|
||||||
|
|
||||||
self.isDismissing = false
|
self.isDismissing = false
|
||||||
case .sticker:
|
case .sticker, .avatar:
|
||||||
let velocity = gestureRecognizer.velocity(in: self.view)
|
let velocity = gestureRecognizer.velocity(in: self.view)
|
||||||
let transitionFraction = translation.y / self.frame.height
|
let transitionFraction = translation.y / self.frame.height
|
||||||
if abs(transitionFraction) > 0.3 || abs(velocity.y) > 1000.0 {
|
if abs(transitionFraction) > 0.3 || abs(velocity.y) > 1000.0 {
|
||||||
@ -2495,7 +2540,7 @@ public class CameraScreenImpl: ViewController, CameraScreen {
|
|||||||
}
|
}
|
||||||
self.mainPreviewAnimationWrapperView.layer.animateBounds(from: sourceBounds, to: self.mainPreviewView.bounds, duration: 0.3, timingFunction: kCAMediaTimingFunctionSpring)
|
self.mainPreviewAnimationWrapperView.layer.animateBounds(from: sourceBounds, to: self.mainPreviewView.bounds, duration: 0.3, timingFunction: kCAMediaTimingFunctionSpring)
|
||||||
|
|
||||||
let sourceScale = sourceInnerFrame.height / self.previewContainerView.frame.height
|
let sourceScale = max(sourceInnerFrame.width / self.previewContainerView.frame.width, sourceInnerFrame.height / self.previewContainerView.frame.height)
|
||||||
self.mainPreviewView.transform = CGAffineTransform.identity
|
self.mainPreviewView.transform = CGAffineTransform.identity
|
||||||
self.mainPreviewAnimationWrapperView.layer.animateScale(from: sourceScale, to: 1.0, duration: 0.3, timingFunction: kCAMediaTimingFunctionSpring, completion: { _ in
|
self.mainPreviewAnimationWrapperView.layer.animateScale(from: sourceScale, to: 1.0, duration: 0.3, timingFunction: kCAMediaTimingFunctionSpring, completion: { _ in
|
||||||
self.mainPreviewContainerView.addSubview(self.mainPreviewView)
|
self.mainPreviewContainerView.addSubview(self.mainPreviewView)
|
||||||
@ -2562,10 +2607,14 @@ public class CameraScreenImpl: ViewController, CameraScreen {
|
|||||||
if let holder = controller.holder {
|
if let holder = controller.holder {
|
||||||
targetBounds = CGRect(origin: .zero, size: holder.parentView.frame.size.aspectFitted(targetBounds.size))
|
targetBounds = CGRect(origin: .zero, size: holder.parentView.frame.size.aspectFitted(targetBounds.size))
|
||||||
}
|
}
|
||||||
self.mainPreviewView.center = self.mainPreviewView.center.offsetBy(dx: (targetBounds.width - self.mainPreviewView.bounds.width) / 2.0, dy: 0.0)
|
|
||||||
|
let previousPosition = self.mainPreviewView.center
|
||||||
|
self.mainPreviewView.center = self.mainPreviewView.center.offsetBy(dx: (targetBounds.width - self.mainPreviewView.bounds.width) / 2.0, dy: (targetBounds.height - self.mainPreviewView.bounds.height) / 2.0)
|
||||||
|
self.mainPreviewView.layer.animatePosition(from: previousPosition, to: self.mainPreviewView.center, duration: 0.3, timingFunction: kCAMediaTimingFunctionSpring)
|
||||||
|
|
||||||
self.mainPreviewAnimationWrapperView.layer.animateBounds(from: self.mainPreviewView.bounds, to: targetBounds, duration: 0.3, timingFunction: kCAMediaTimingFunctionSpring, removeOnCompletion: false)
|
self.mainPreviewAnimationWrapperView.layer.animateBounds(from: self.mainPreviewView.bounds, to: targetBounds, duration: 0.3, timingFunction: kCAMediaTimingFunctionSpring, removeOnCompletion: false)
|
||||||
|
|
||||||
let targetScale = destinationInnerFrame.height / self.previewContainerView.frame.height
|
let targetScale = max(destinationInnerFrame.width / self.previewContainerView.frame.width, destinationInnerFrame.height / self.previewContainerView.frame.height)
|
||||||
self.mainPreviewAnimationWrapperView.layer.animateScale(from: 1.0, to: targetScale, duration: 0.3, timingFunction: kCAMediaTimingFunctionSpring, removeOnCompletion: false)
|
self.mainPreviewAnimationWrapperView.layer.animateScale(from: 1.0, to: targetScale, duration: 0.3, timingFunction: kCAMediaTimingFunctionSpring, removeOnCompletion: false)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2616,6 +2665,8 @@ public class CameraScreenImpl: ViewController, CameraScreen {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Queue.mainQueue().after(1.5, {
|
Queue.mainQueue().after(1.5, {
|
||||||
|
self.controller?.updateFocusedCode(nil)
|
||||||
|
|
||||||
if let collageView = self.collageView {
|
if let collageView = self.collageView {
|
||||||
collageView.stopPlayback()
|
collageView.stopPlayback()
|
||||||
}
|
}
|
||||||
@ -2833,7 +2884,11 @@ public class CameraScreenImpl: ViewController, CameraScreen {
|
|||||||
if self.additionalPreviewContainerView.bounds.contains(self.view.convert(point, to: self.additionalPreviewContainerView)) {
|
if self.additionalPreviewContainerView.bounds.contains(self.view.convert(point, to: self.additionalPreviewContainerView)) {
|
||||||
return self.additionalPreviewContainerView
|
return self.additionalPreviewContainerView
|
||||||
} else {
|
} else {
|
||||||
return self.collageView ?? self.mainPreviewView
|
if let collageView = self.collageView {
|
||||||
|
return collageView.hitTest(self.view.convert(point, to: collageView), with: event)
|
||||||
|
} else {
|
||||||
|
return self.mainPreviewView
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result
|
return result
|
||||||
@ -2926,7 +2981,8 @@ public class CameraScreenImpl: ViewController, CameraScreen {
|
|||||||
}
|
}
|
||||||
self.didAppear()
|
self.didAppear()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
let componentSize = self.componentHost.update(
|
let componentSize = self.componentHost.update(
|
||||||
transition: transition,
|
transition: transition,
|
||||||
component: AnyComponent(
|
component: AnyComponent(
|
||||||
@ -2938,6 +2994,7 @@ public class CameraScreenImpl: ViewController, CameraScreen {
|
|||||||
hasAppeared: self.hasAppeared,
|
hasAppeared: self.hasAppeared,
|
||||||
isVisible: self.cameraIsActive && !self.hasGallery && self.postingAvailable,
|
isVisible: self.cameraIsActive && !self.hasGallery && self.postingAvailable,
|
||||||
panelWidth: panelWidth,
|
panelWidth: panelWidth,
|
||||||
|
resolvedCodePeer: controller.resolvedCodePeer,
|
||||||
animateFlipAction: self.animateFlipAction,
|
animateFlipAction: self.animateFlipAction,
|
||||||
animateShutter: { [weak self] in
|
animateShutter: { [weak self] in
|
||||||
guard let self else {
|
guard let self else {
|
||||||
@ -2963,7 +3020,21 @@ public class CameraScreenImpl: ViewController, CameraScreen {
|
|||||||
push: { [weak self] c in
|
push: { [weak self] c in
|
||||||
self?.controller?.push(c)
|
self?.controller?.push(c)
|
||||||
},
|
},
|
||||||
completion: self.completion
|
completion: self.completion,
|
||||||
|
openResolvedPeer: { [weak self] peer in
|
||||||
|
guard let self, let controller = self.controller else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
let context = self.context
|
||||||
|
let navigationController = controller.navigationController as? NavigationController
|
||||||
|
controller.requestDismiss(animated: true, interactive: false)
|
||||||
|
Queue.mainQueue().after(0.4) {
|
||||||
|
guard let navigationController else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(peer)))
|
||||||
|
}
|
||||||
|
}
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
environment: {
|
environment: {
|
||||||
@ -3002,6 +3073,9 @@ public class CameraScreenImpl: ViewController, CameraScreen {
|
|||||||
transition.setFrame(view: self.previewContainerView, frame: previewContainerFrame)
|
transition.setFrame(view: self.previewContainerView, frame: previewContainerFrame)
|
||||||
transition.setFrame(view: self.collageContainerView, frame: CGRect(origin: .zero, size: previewContainerFrame.size))
|
transition.setFrame(view: self.collageContainerView, frame: CGRect(origin: .zero, size: previewContainerFrame.size))
|
||||||
|
|
||||||
|
transition.setFrame(view: self.codeFrameView, frame: CGRect(origin: .zero, size: previewContainerFrame.size))
|
||||||
|
self.codeFrameView.update(size: previewContainerFrame.size, code: controller.focusedCode)
|
||||||
|
|
||||||
if self.cameraState.isCollageEnabled {
|
if self.cameraState.isCollageEnabled {
|
||||||
let collage: CameraCollage
|
let collage: CameraCollage
|
||||||
if let current = self.collage {
|
if let current = self.collage {
|
||||||
@ -3045,7 +3119,7 @@ public class CameraScreenImpl: ViewController, CameraScreen {
|
|||||||
self.controller?.updateCameraState({ $0.updatedIsCollageEnabled(false).updatedCollageProgress(0.0) }, transition: .spring(duration: 0.3))
|
self.controller?.updateCameraState({ $0.updatedIsCollageEnabled(false).updatedCollageProgress(0.0) }, transition: .spring(duration: 0.3))
|
||||||
} else {
|
} else {
|
||||||
let currentCount = self.cameraState.collageGrid.count
|
let currentCount = self.cameraState.collageGrid.count
|
||||||
for grid in collageGrids.reversed() {
|
for grid in collageGrids {
|
||||||
if grid.count == currentCount - 1 {
|
if grid.count == currentCount - 1 {
|
||||||
self.controller?.updateCameraState({ $0.updatedCollageGrid(grid) }, transition: .spring(duration: 0.3))
|
self.controller?.updateCameraState({ $0.updatedCollageGrid(grid) }, transition: .spring(duration: 0.3))
|
||||||
break
|
break
|
||||||
@ -3164,7 +3238,7 @@ public class CameraScreenImpl: ViewController, CameraScreen {
|
|||||||
let additionalPreviewInnerFrame = CGRect(origin: CGPoint(x: floorToScreenPixels((circleSide - additionalPreviewInnerSize.width) / 2.0), y: floorToScreenPixels((circleSide - additionalPreviewInnerSize.height) / 2.0)), size: additionalPreviewInnerSize)
|
let additionalPreviewInnerFrame = CGRect(origin: CGPoint(x: floorToScreenPixels((circleSide - additionalPreviewInnerSize.width) / 2.0), y: floorToScreenPixels((circleSide - additionalPreviewInnerSize.height) / 2.0)), size: additionalPreviewInnerSize)
|
||||||
|
|
||||||
if mainPreviewView.superview != self.mainPreviewContainerView {
|
if mainPreviewView.superview != self.mainPreviewContainerView {
|
||||||
if case .sticker = controller.mode, !self.animatedIn {
|
if [.sticker, .avatar].contains(controller.mode), !self.animatedIn {
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
self.mainPreviewContainerView.insertSubview(mainPreviewView, at: 0)
|
self.mainPreviewContainerView.insertSubview(mainPreviewView, at: 0)
|
||||||
@ -3174,7 +3248,7 @@ public class CameraScreenImpl: ViewController, CameraScreen {
|
|||||||
self.additionalPreviewContainerView.insertSubview(additionalPreviewView, at: 0)
|
self.additionalPreviewContainerView.insertSubview(additionalPreviewView, at: 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
if case .sticker = controller.mode {
|
if [.sticker, .avatar].contains(controller.mode) {
|
||||||
if self.animatedIn {
|
if self.animatedIn {
|
||||||
mainPreviewView.frame = mainPreviewInnerFrame
|
mainPreviewView.frame = mainPreviewInnerFrame
|
||||||
}
|
}
|
||||||
@ -3207,7 +3281,7 @@ public class CameraScreenImpl: ViewController, CameraScreen {
|
|||||||
transition.setPosition(view: self.transitionCornersView, position: CGPoint(x: layout.size.width + screenCornerRadius / 2.0, y: layout.size.height / 2.0))
|
transition.setPosition(view: self.transitionCornersView, position: CGPoint(x: layout.size.width + screenCornerRadius / 2.0, y: layout.size.height / 2.0))
|
||||||
transition.setBounds(view: self.transitionCornersView, bounds: CGRect(origin: .zero, size: CGSize(width: screenCornerRadius, height: layout.size.height)))
|
transition.setBounds(view: self.transitionCornersView, bounds: CGRect(origin: .zero, size: CGSize(width: screenCornerRadius, height: layout.size.height)))
|
||||||
|
|
||||||
if (controller.mode == .sticker || isTablet) && isFirstTime {
|
if ([.sticker, .avatar].contains(controller.mode) || isTablet) && isFirstTime {
|
||||||
self.animateIn()
|
self.animateIn()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3256,6 +3330,17 @@ public class CameraScreenImpl: ViewController, CameraScreen {
|
|||||||
private let postingAvailabilityPromise = Promise<StoriesUploadAvailability>()
|
private let postingAvailabilityPromise = Promise<StoriesUploadAvailability>()
|
||||||
private var postingAvailabilityDisposable: Disposable?
|
private var postingAvailabilityDisposable: Disposable?
|
||||||
|
|
||||||
|
private var codeDisposable: Disposable?
|
||||||
|
private var resolveCodeDisposable: Disposable?
|
||||||
|
private var focusedCodePromise = ValuePromise<CameraCode?>()
|
||||||
|
var focusedCode: CameraCode? {
|
||||||
|
didSet {
|
||||||
|
self.focusedCodePromise.set(self.focusedCode)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private var resolvePeerDisposable = MetaDisposable()
|
||||||
|
private var resolvedCodePeer: EnginePeer?
|
||||||
|
|
||||||
private let hapticFeedback = HapticFeedback()
|
private let hapticFeedback = HapticFeedback()
|
||||||
|
|
||||||
private var validLayout: ContainerViewLayout?
|
private var validLayout: ContainerViewLayout?
|
||||||
@ -3312,6 +3397,9 @@ public class CameraScreenImpl: ViewController, CameraScreen {
|
|||||||
deinit {
|
deinit {
|
||||||
self.audioSessionDisposable?.dispose()
|
self.audioSessionDisposable?.dispose()
|
||||||
self.postingAvailabilityDisposable?.dispose()
|
self.postingAvailabilityDisposable?.dispose()
|
||||||
|
self.codeDisposable?.dispose()
|
||||||
|
self.resolveCodeDisposable?.dispose()
|
||||||
|
self.resolvePeerDisposable.dispose()
|
||||||
if #available(iOS 13.0, *) {
|
if #available(iOS 13.0, *) {
|
||||||
try? AVAudioSession.sharedInstance().setAllowHapticsAndSystemSoundsDuringRecording(false)
|
try? AVAudioSession.sharedInstance().setAllowHapticsAndSystemSoundsDuringRecording(false)
|
||||||
}
|
}
|
||||||
@ -3378,6 +3466,54 @@ public class CameraScreenImpl: ViewController, CameraScreen {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self.resolveCodeDisposable = (self.focusedCodePromise.get()
|
||||||
|
|> map { code in
|
||||||
|
return code?.message
|
||||||
|
}
|
||||||
|
|> distinctUntilChanged
|
||||||
|
|> mapToSignal { code -> Signal<String?, NoError> in
|
||||||
|
if let _ = code {
|
||||||
|
return .single(code)
|
||||||
|
} else {
|
||||||
|
return .single(code)
|
||||||
|
|> delay(1.0, queue: Queue.mainQueue())
|
||||||
|
}
|
||||||
|
}).start(next: { [weak self] code in
|
||||||
|
guard let self else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if let code {
|
||||||
|
self.resolvePeerDisposable.set(
|
||||||
|
(self.context.sharedContext.resolveUrl(context: self.context, peerId: nil, url: code, skipUrlAuth: false)
|
||||||
|
|> deliverOnMainQueue).start(next: { [weak self] resolvedUrl in
|
||||||
|
guard let self else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if case let .peer(peer, _) = resolvedUrl, let peer {
|
||||||
|
self.resolvedCodePeer = EnginePeer(peer)
|
||||||
|
self.requestLayout(transition: .animated(duration: 0.4, curve: .spring))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
self.resolvedCodePeer = nil
|
||||||
|
self.requestLayout(transition: .animated(duration: 0.4, curve: .spring))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
private func updateFocusedCode(_ code: CameraCode?) {
|
||||||
|
if self.focusedCode != code {
|
||||||
|
self.focusedCode = code
|
||||||
|
if code == nil {
|
||||||
|
Queue.mainQueue().after(1.0, {
|
||||||
|
self.requestLayout(transition: .animated(duration: 0.4, curve: .spring))
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
self.requestLayout(transition: .animated(duration: 0.4, curve: .spring))
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private func requestAudioSession() {
|
private func requestAudioSession() {
|
||||||
@ -3439,24 +3575,106 @@ public class CameraScreenImpl: ViewController, CameraScreen {
|
|||||||
if let current = self.galleryController {
|
if let current = self.galleryController {
|
||||||
controller = current
|
controller = current
|
||||||
} else {
|
} else {
|
||||||
controller = self.context.sharedContext.makeStoryMediaPickerScreen(context: self.context, isDark: true, forCollage: self.cameraState.isCollageEnabled, getSourceRect: { [weak self] in
|
var selectionLimit: Int?
|
||||||
if let self {
|
if self.cameraState.isCollageEnabled, let collage = self.node.collage {
|
||||||
if let galleryButton = self.node.componentHost.findTaggedView(tag: galleryButtonTag) {
|
selectionLimit = collage.grid.count - collage.results.count
|
||||||
return galleryButton.convert(galleryButton.bounds, to: self.view).offsetBy(dx: 0.0, dy: -15.0)
|
} else {
|
||||||
|
selectionLimit = 6
|
||||||
|
}
|
||||||
|
controller = self.context.sharedContext.makeStoryMediaPickerScreen(
|
||||||
|
context: self.context,
|
||||||
|
isDark: true,
|
||||||
|
forCollage: self.cameraState.isCollageEnabled,
|
||||||
|
selectionLimit: selectionLimit,
|
||||||
|
getSourceRect: { [weak self] in
|
||||||
|
if let self {
|
||||||
|
if let galleryButton = self.node.componentHost.findTaggedView(tag: galleryButtonTag) {
|
||||||
|
return galleryButton.convert(galleryButton.bounds, to: self.view).offsetBy(dx: 0.0, dy: -15.0)
|
||||||
|
} else {
|
||||||
|
return .zero
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
return .zero
|
return .zero
|
||||||
}
|
}
|
||||||
} else {
|
}, completion: { [weak self] result, transitionView, transitionRect, transitionImage, transitionOut, dismissed in
|
||||||
return .zero
|
if let self {
|
||||||
}
|
if self.cameraState.isCollageEnabled {
|
||||||
}, completion: { [weak self] result, transitionView, transitionRect, transitionImage, transitionOut, dismissed in
|
if let asset = result as? PHAsset {
|
||||||
if let self {
|
if asset.mediaType == .video && asset.duration > 1.0 {
|
||||||
if self.cameraState.isCollageEnabled {
|
self.node.collage?.addResult(.single(.asset(asset)), snapshotView: nil)
|
||||||
if let asset = result as? PHAsset {
|
} else {
|
||||||
|
self.node.collage?.addResult(
|
||||||
|
assetImage(asset: asset, targetSize: CGSize(width: 1080, height: 1080), exact: false, deliveryMode: .highQualityFormat)
|
||||||
|
|> runOn(Queue.concurrentDefaultQueue())
|
||||||
|
|> mapToSignal { image -> Signal<CameraScreenImpl.Result, NoError> in
|
||||||
|
if let image {
|
||||||
|
return .single(.image(Result.Image(image: image, additionalImage: nil, additionalImagePosition: .topLeft)))
|
||||||
|
} else {
|
||||||
|
return .complete()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
snapshotView: nil
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dismissControllerImpl?()
|
||||||
|
} else {
|
||||||
|
stopCameraCapture()
|
||||||
|
|
||||||
|
let resultTransition = ResultTransition(
|
||||||
|
sourceView: transitionView,
|
||||||
|
sourceRect: transitionRect,
|
||||||
|
sourceImage: transitionImage,
|
||||||
|
transitionOut: transitionOut
|
||||||
|
)
|
||||||
|
if let asset = result as? PHAsset {
|
||||||
|
if asset.mediaType == .video && asset.duration < 1.0 {
|
||||||
|
let presentationData = self.context.sharedContext.currentPresentationData.with { $0 }
|
||||||
|
let alertController = textAlertController(
|
||||||
|
context: self.context,
|
||||||
|
forceTheme: defaultDarkColorPresentationTheme,
|
||||||
|
title: nil,
|
||||||
|
text: presentationData.strings.Story_Editor_VideoTooShort,
|
||||||
|
actions: [
|
||||||
|
TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {})
|
||||||
|
],
|
||||||
|
actionLayout: .vertical
|
||||||
|
)
|
||||||
|
self.present(alertController, in: .window(.root))
|
||||||
|
} else {
|
||||||
|
self.completion(.single(.asset(asset)), resultTransition, dismissed)
|
||||||
|
}
|
||||||
|
} else if let draft = result as? MediaEditorDraft {
|
||||||
|
self.completion(.single(.draft(draft)), resultTransition, dismissed)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, multipleCompletion: { [weak self] results in
|
||||||
|
guard let self else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if !self.cameraState.isCollageEnabled {
|
||||||
|
var selectedGrid: Camera.CollageGrid = collageGrids.first!
|
||||||
|
for grid in collageGrids {
|
||||||
|
if grid.count == results.count {
|
||||||
|
selectedGrid = grid
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self.updateCameraState({
|
||||||
|
$0.updatedIsCollageEnabled(true).updatedCollageProgress(0.0).updatedIsDualCameraEnabled(false).updatedCollageGrid(selectedGrid)
|
||||||
|
}, transition: .spring(duration: 0.3))
|
||||||
|
}
|
||||||
|
|
||||||
|
if let assets = results as? [PHAsset] {
|
||||||
|
var results: [Signal<CameraScreenImpl.Result, NoError>] = []
|
||||||
|
for asset in assets {
|
||||||
if asset.mediaType == .video && asset.duration > 1.0 {
|
if asset.mediaType == .video && asset.duration > 1.0 {
|
||||||
self.node.collage?.addResult(.single(.asset(asset)), snapshotView: nil)
|
results.append(.single(.asset(asset)))
|
||||||
} else {
|
} else {
|
||||||
self.node.collage?.addResult(
|
results.append(
|
||||||
assetImage(asset: asset, targetSize: CGSize(width: 1080, height: 1080), exact: false, deliveryMode: .highQualityFormat)
|
assetImage(asset: asset, targetSize: CGSize(width: 1080, height: 1080), exact: false, deliveryMode: .highQualityFormat)
|
||||||
|> runOn(Queue.concurrentDefaultQueue())
|
|> runOn(Queue.concurrentDefaultQueue())
|
||||||
|> mapToSignal { image -> Signal<CameraScreenImpl.Result, NoError> in
|
|> mapToSignal { image -> Signal<CameraScreenImpl.Result, NoError> in
|
||||||
@ -3465,55 +3683,25 @@ public class CameraScreenImpl: ViewController, CameraScreen {
|
|||||||
} else {
|
} else {
|
||||||
return .complete()
|
return .complete()
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
snapshotView: nil
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
self.node.collage?.addResults(signals: results)
|
||||||
|
|
||||||
|
|
||||||
dismissControllerImpl?()
|
|
||||||
} else {
|
|
||||||
stopCameraCapture()
|
|
||||||
|
|
||||||
let resultTransition = ResultTransition(
|
|
||||||
sourceView: transitionView,
|
|
||||||
sourceRect: transitionRect,
|
|
||||||
sourceImage: transitionImage,
|
|
||||||
transitionOut: transitionOut
|
|
||||||
)
|
|
||||||
if let asset = result as? PHAsset {
|
|
||||||
if asset.mediaType == .video && asset.duration < 1.0 {
|
|
||||||
let presentationData = self.context.sharedContext.currentPresentationData.with { $0 }
|
|
||||||
let alertController = textAlertController(
|
|
||||||
context: self.context,
|
|
||||||
forceTheme: defaultDarkColorPresentationTheme,
|
|
||||||
title: nil,
|
|
||||||
text: presentationData.strings.Story_Editor_VideoTooShort,
|
|
||||||
actions: [
|
|
||||||
TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {})
|
|
||||||
],
|
|
||||||
actionLayout: .vertical
|
|
||||||
)
|
|
||||||
self.present(alertController, in: .window(.root))
|
|
||||||
} else {
|
|
||||||
self.completion(.single(.asset(asset)), resultTransition, dismissed)
|
|
||||||
}
|
|
||||||
} else if let draft = result as? MediaEditorDraft {
|
|
||||||
self.completion(.single(.draft(draft)), resultTransition, dismissed)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
self.galleryController = nil
|
||||||
|
|
||||||
|
dismissControllerImpl?()
|
||||||
|
}, dismissed: { [weak self] in
|
||||||
|
resumeCameraCapture()
|
||||||
|
if let self {
|
||||||
|
self.node.hasGallery = false
|
||||||
|
self.node.requestUpdateLayout(transition: .immediate)
|
||||||
|
}
|
||||||
|
}, groupsPresented: {
|
||||||
|
stopCameraCapture()
|
||||||
}
|
}
|
||||||
}, dismissed: { [weak self] in
|
)
|
||||||
resumeCameraCapture()
|
|
||||||
if let self {
|
|
||||||
self.node.hasGallery = false
|
|
||||||
self.node.requestUpdateLayout(transition: .immediate)
|
|
||||||
}
|
|
||||||
}, groupsPresented: {
|
|
||||||
stopCameraCapture()
|
|
||||||
})
|
|
||||||
self.galleryController = controller
|
self.galleryController = controller
|
||||||
|
|
||||||
dismissControllerImpl = { [weak controller] in
|
dismissControllerImpl = { [weak controller] in
|
||||||
@ -3557,7 +3745,7 @@ public class CameraScreenImpl: ViewController, CameraScreen {
|
|||||||
self.isDismissed = true
|
self.isDismissed = true
|
||||||
if animated {
|
if animated {
|
||||||
self.ignoreStatusBar = true
|
self.ignoreStatusBar = true
|
||||||
if let layout = self.validLayout, layout.metrics.isTablet || self.mode == .sticker {
|
if let layout = self.validLayout, layout.metrics.isTablet || [.sticker, .avatar].contains(self.mode) {
|
||||||
self.node.animateOut(completion: {
|
self.node.animateOut(completion: {
|
||||||
self.dismiss(animated: false)
|
self.dismiss(animated: false)
|
||||||
self.transitionedOut()
|
self.transitionedOut()
|
||||||
|
@ -3,10 +3,12 @@ import UIKit
|
|||||||
import Display
|
import Display
|
||||||
import ComponentFlow
|
import ComponentFlow
|
||||||
import SwiftSignalKit
|
import SwiftSignalKit
|
||||||
|
import TelegramCore
|
||||||
import Photos
|
import Photos
|
||||||
import LocalMediaResources
|
import LocalMediaResources
|
||||||
import CameraButtonComponent
|
import CameraButtonComponent
|
||||||
import UIKitRuntimeUtils
|
import UIKitRuntimeUtils
|
||||||
|
import AccountContext
|
||||||
|
|
||||||
enum ShutterButtonState: Equatable {
|
enum ShutterButtonState: Equatable {
|
||||||
case disabled
|
case disabled
|
||||||
@ -560,8 +562,10 @@ final class CaptureControlsComponent: Component {
|
|||||||
case flip
|
case flip
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let context: AccountContext
|
||||||
let isTablet: Bool
|
let isTablet: Bool
|
||||||
let isSticker: Bool
|
let isSticker: Bool
|
||||||
|
let hasGallery: Bool
|
||||||
let hasAppeared: Bool
|
let hasAppeared: Bool
|
||||||
let hasAccess: Bool
|
let hasAccess: Bool
|
||||||
let hideControls: Bool
|
let hideControls: Bool
|
||||||
@ -570,6 +574,7 @@ final class CaptureControlsComponent: Component {
|
|||||||
let tintColor: UIColor
|
let tintColor: UIColor
|
||||||
let shutterState: ShutterButtonState
|
let shutterState: ShutterButtonState
|
||||||
let lastGalleryAsset: PHAsset?
|
let lastGalleryAsset: PHAsset?
|
||||||
|
let resolvedCodePeer: EnginePeer?
|
||||||
let tag: AnyObject?
|
let tag: AnyObject?
|
||||||
let galleryButtonTag: AnyObject?
|
let galleryButtonTag: AnyObject?
|
||||||
let shutterTapped: () -> Void
|
let shutterTapped: () -> Void
|
||||||
@ -581,10 +586,13 @@ final class CaptureControlsComponent: Component {
|
|||||||
let swipeHintUpdated: (SwipeHint) -> Void
|
let swipeHintUpdated: (SwipeHint) -> Void
|
||||||
let zoomUpdated: (CGFloat) -> Void
|
let zoomUpdated: (CGFloat) -> Void
|
||||||
let flipAnimationAction: ActionSlot<Void>
|
let flipAnimationAction: ActionSlot<Void>
|
||||||
|
let openResolvedPeer: (EnginePeer) -> Void
|
||||||
|
|
||||||
init(
|
init(
|
||||||
|
context: AccountContext,
|
||||||
isTablet: Bool,
|
isTablet: Bool,
|
||||||
isSticker: Bool,
|
isSticker: Bool,
|
||||||
|
hasGallery: Bool,
|
||||||
hasAppeared: Bool,
|
hasAppeared: Bool,
|
||||||
hasAccess: Bool,
|
hasAccess: Bool,
|
||||||
hideControls: Bool,
|
hideControls: Bool,
|
||||||
@ -593,6 +601,7 @@ final class CaptureControlsComponent: Component {
|
|||||||
tintColor: UIColor,
|
tintColor: UIColor,
|
||||||
shutterState: ShutterButtonState,
|
shutterState: ShutterButtonState,
|
||||||
lastGalleryAsset: PHAsset?,
|
lastGalleryAsset: PHAsset?,
|
||||||
|
resolvedCodePeer: EnginePeer?,
|
||||||
tag: AnyObject?,
|
tag: AnyObject?,
|
||||||
galleryButtonTag: AnyObject?,
|
galleryButtonTag: AnyObject?,
|
||||||
shutterTapped: @escaping () -> Void,
|
shutterTapped: @escaping () -> Void,
|
||||||
@ -603,10 +612,13 @@ final class CaptureControlsComponent: Component {
|
|||||||
galleryTapped: @escaping () -> Void,
|
galleryTapped: @escaping () -> Void,
|
||||||
swipeHintUpdated: @escaping (SwipeHint) -> Void,
|
swipeHintUpdated: @escaping (SwipeHint) -> Void,
|
||||||
zoomUpdated: @escaping (CGFloat) -> Void,
|
zoomUpdated: @escaping (CGFloat) -> Void,
|
||||||
flipAnimationAction: ActionSlot<Void>
|
flipAnimationAction: ActionSlot<Void>,
|
||||||
|
openResolvedPeer: @escaping (EnginePeer) -> Void
|
||||||
) {
|
) {
|
||||||
|
self.context = context
|
||||||
self.isTablet = isTablet
|
self.isTablet = isTablet
|
||||||
self.isSticker = isSticker
|
self.isSticker = isSticker
|
||||||
|
self.hasGallery = hasGallery
|
||||||
self.hasAppeared = hasAppeared
|
self.hasAppeared = hasAppeared
|
||||||
self.hasAccess = hasAccess
|
self.hasAccess = hasAccess
|
||||||
self.hideControls = hideControls
|
self.hideControls = hideControls
|
||||||
@ -615,6 +627,7 @@ final class CaptureControlsComponent: Component {
|
|||||||
self.tintColor = tintColor
|
self.tintColor = tintColor
|
||||||
self.shutterState = shutterState
|
self.shutterState = shutterState
|
||||||
self.lastGalleryAsset = lastGalleryAsset
|
self.lastGalleryAsset = lastGalleryAsset
|
||||||
|
self.resolvedCodePeer = resolvedCodePeer
|
||||||
self.tag = tag
|
self.tag = tag
|
||||||
self.galleryButtonTag = galleryButtonTag
|
self.galleryButtonTag = galleryButtonTag
|
||||||
self.shutterTapped = shutterTapped
|
self.shutterTapped = shutterTapped
|
||||||
@ -626,15 +639,22 @@ final class CaptureControlsComponent: Component {
|
|||||||
self.swipeHintUpdated = swipeHintUpdated
|
self.swipeHintUpdated = swipeHintUpdated
|
||||||
self.zoomUpdated = zoomUpdated
|
self.zoomUpdated = zoomUpdated
|
||||||
self.flipAnimationAction = flipAnimationAction
|
self.flipAnimationAction = flipAnimationAction
|
||||||
|
self.openResolvedPeer = openResolvedPeer
|
||||||
}
|
}
|
||||||
|
|
||||||
static func ==(lhs: CaptureControlsComponent, rhs: CaptureControlsComponent) -> Bool {
|
static func ==(lhs: CaptureControlsComponent, rhs: CaptureControlsComponent) -> Bool {
|
||||||
|
if lhs.context !== rhs.context {
|
||||||
|
return false
|
||||||
|
}
|
||||||
if lhs.isTablet != rhs.isTablet {
|
if lhs.isTablet != rhs.isTablet {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
if lhs.isSticker != rhs.isSticker {
|
if lhs.isSticker != rhs.isSticker {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
if lhs.hasGallery != rhs.hasGallery {
|
||||||
|
return false
|
||||||
|
}
|
||||||
if lhs.hasAppeared != rhs.hasAppeared {
|
if lhs.hasAppeared != rhs.hasAppeared {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@ -659,6 +679,9 @@ final class CaptureControlsComponent: Component {
|
|||||||
if lhs.lastGalleryAsset?.localIdentifier != rhs.lastGalleryAsset?.localIdentifier {
|
if lhs.lastGalleryAsset?.localIdentifier != rhs.lastGalleryAsset?.localIdentifier {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
if lhs.resolvedCodePeer != rhs.resolvedCodePeer {
|
||||||
|
return false
|
||||||
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -710,6 +733,8 @@ final class CaptureControlsComponent: Component {
|
|||||||
private var state: State?
|
private var state: State?
|
||||||
private var availableSize: CGSize?
|
private var availableSize: CGSize?
|
||||||
|
|
||||||
|
private var codeResultView: ComponentView<Empty>?
|
||||||
|
|
||||||
private let zoomView = ComponentView<Empty>()
|
private let zoomView = ComponentView<Empty>()
|
||||||
private let lockView = ComponentView<Empty>()
|
private let lockView = ComponentView<Empty>()
|
||||||
private let galleryButtonView = ComponentView<Empty>()
|
private let galleryButtonView = ComponentView<Empty>()
|
||||||
@ -1050,7 +1075,7 @@ final class CaptureControlsComponent: Component {
|
|||||||
|
|
||||||
let galleryButtonFrame: CGRect
|
let galleryButtonFrame: CGRect
|
||||||
let gallerySize: CGSize
|
let gallerySize: CGSize
|
||||||
if !component.isSticker {
|
if component.hasGallery {
|
||||||
let galleryCornerRadius: CGFloat
|
let galleryCornerRadius: CGFloat
|
||||||
if component.isTablet {
|
if component.isTablet {
|
||||||
gallerySize = CGSize(width: 72.0, height: 72.0)
|
gallerySize = CGSize(width: 72.0, height: 72.0)
|
||||||
@ -1276,6 +1301,46 @@ final class CaptureControlsComponent: Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let resolvedCodePeer = component.resolvedCodePeer {
|
||||||
|
let codeResultView: ComponentView<Empty>
|
||||||
|
if let current = self.codeResultView {
|
||||||
|
codeResultView = current
|
||||||
|
} else {
|
||||||
|
codeResultView = ComponentView<Empty>()
|
||||||
|
self.codeResultView = codeResultView
|
||||||
|
}
|
||||||
|
|
||||||
|
let codeResultSize = codeResultView.update(
|
||||||
|
transition: .immediate,
|
||||||
|
component: AnyComponent(
|
||||||
|
CameraCodeResultComponent(
|
||||||
|
context: component.context,
|
||||||
|
peer: resolvedCodePeer,
|
||||||
|
pressed: component.openResolvedPeer
|
||||||
|
)
|
||||||
|
),
|
||||||
|
environment: {},
|
||||||
|
containerSize: availableSize
|
||||||
|
)
|
||||||
|
|
||||||
|
if let view = codeResultView.view {
|
||||||
|
if view.superview == nil {
|
||||||
|
self.insertSubview(view, at: 0)
|
||||||
|
if let view = view as? CameraCodeResultComponent.View {
|
||||||
|
view.animateIn()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
view.frame = CGRect(origin: CGPoint(x: (availableSize.width - codeResultSize.width) / 2.0, y: (size.height - shutterButtonSize.height) / 2.0 - codeResultSize.height), size: codeResultSize)
|
||||||
|
}
|
||||||
|
} else if let codeResultView = self.codeResultView {
|
||||||
|
self.codeResultView = nil
|
||||||
|
codeResultView.view?.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.25, removeOnCompletion: false, completion: { _ in
|
||||||
|
codeResultView.view?.removeFromSuperview()
|
||||||
|
})
|
||||||
|
codeResultView.view?.layer.animateScale(from: 1.0, to: 0.2, duration: 0.25, removeOnCompletion: false)
|
||||||
|
codeResultView.view?.layer.animatePosition(from: .zero, to: CGPoint(x: 0.0, y: 64.0), duration: 0.4, timingFunction: kCAMediaTimingFunctionSpring, removeOnCompletion: false, additive: true)
|
||||||
|
}
|
||||||
|
|
||||||
let _ = self.lockView.update(
|
let _ = self.lockView.update(
|
||||||
transition: .immediate,
|
transition: .immediate,
|
||||||
component: AnyComponent(
|
component: AnyComponent(
|
||||||
@ -1353,6 +1418,13 @@ final class CaptureControlsComponent: Component {
|
|||||||
|
|
||||||
return size
|
return size
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
|
||||||
|
if let codeResultView = self.codeResultView?.view, codeResultView.frame.contains(point) {
|
||||||
|
return codeResultView.hitTest(self.convert(point, to: codeResultView), with: event)
|
||||||
|
}
|
||||||
|
return super.hitTest(point, with: event)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func makeView() -> View {
|
func makeView() -> View {
|
||||||
|
@ -228,10 +228,7 @@ private func contentNodeMessagesAndClassesForItem(_ item: ChatMessageItem) -> ([
|
|||||||
result.append((message, ChatMessageJoinedChannelBubbleContentNode.self, itemAttributes, BubbleItemAttributes(isAttachment: false, neighborType: .text, neighborSpacing: .default)))
|
result.append((message, ChatMessageJoinedChannelBubbleContentNode.self, itemAttributes, BubbleItemAttributes(isAttachment: false, neighborType: .text, neighborSpacing: .default)))
|
||||||
needReactions = false
|
needReactions = false
|
||||||
} else {
|
} else {
|
||||||
switch action.action {
|
if !canAddMessageReactions(message: message) {
|
||||||
case .photoUpdated:
|
|
||||||
break
|
|
||||||
default:
|
|
||||||
needReactions = false
|
needReactions = false
|
||||||
}
|
}
|
||||||
result.append((message, ChatMessageActionBubbleContentNode.self, itemAttributes, BubbleItemAttributes(isAttachment: false, neighborType: .text, neighborSpacing: .default)))
|
result.append((message, ChatMessageActionBubbleContentNode.self, itemAttributes, BubbleItemAttributes(isAttachment: false, neighborType: .text, neighborSpacing: .default)))
|
||||||
@ -2717,7 +2714,7 @@ public class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewI
|
|||||||
|
|
||||||
var maximumNodeWidth = maximumNodeWidth
|
var maximumNodeWidth = maximumNodeWidth
|
||||||
if hasInstantVideo {
|
if hasInstantVideo {
|
||||||
maximumNodeWidth = min(309, baseWidth - 84)
|
maximumNodeWidth = min(309.0, baseWidth - 84.0)
|
||||||
}
|
}
|
||||||
let (minWidth, buttonsLayout) = reactionButtonsLayout(ChatMessageReactionButtonsNode.Arguments(
|
let (minWidth, buttonsLayout) = reactionButtonsLayout(ChatMessageReactionButtonsNode.Arguments(
|
||||||
context: item.context,
|
context: item.context,
|
||||||
@ -3055,7 +3052,7 @@ public class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewI
|
|||||||
if let reactionButtonsFinalize = reactionButtonsFinalize {
|
if let reactionButtonsFinalize = reactionButtonsFinalize {
|
||||||
var maxContentWidth = maxContentWidth
|
var maxContentWidth = maxContentWidth
|
||||||
if hasInstantVideo {
|
if hasInstantVideo {
|
||||||
maxContentWidth = min(310, baseWidth - 84.0)
|
maxContentWidth = min(310.0, baseWidth - 84.0)
|
||||||
}
|
}
|
||||||
reactionButtonsSizeAndApply = reactionButtonsFinalize(maxContentWidth)
|
reactionButtonsSizeAndApply = reactionButtonsFinalize(maxContentWidth)
|
||||||
}
|
}
|
||||||
@ -3185,7 +3182,8 @@ public class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewI
|
|||||||
shareButtonOffset: shareButtonOffset,
|
shareButtonOffset: shareButtonOffset,
|
||||||
avatarOffset: avatarOffset,
|
avatarOffset: avatarOffset,
|
||||||
hidesHeaders: hidesHeaders,
|
hidesHeaders: hidesHeaders,
|
||||||
disablesComments: disablesComments
|
disablesComments: disablesComments,
|
||||||
|
alignment: alignment
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -3244,7 +3242,8 @@ public class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewI
|
|||||||
shareButtonOffset: CGPoint?,
|
shareButtonOffset: CGPoint?,
|
||||||
avatarOffset: CGFloat?,
|
avatarOffset: CGFloat?,
|
||||||
hidesHeaders: Bool,
|
hidesHeaders: Bool,
|
||||||
disablesComments: Bool
|
disablesComments: Bool,
|
||||||
|
alignment: ChatMessageBubbleContentAlignment
|
||||||
) -> Void {
|
) -> Void {
|
||||||
guard let strongSelf = selfReference.value else {
|
guard let strongSelf = selfReference.value else {
|
||||||
return
|
return
|
||||||
@ -4367,7 +4366,14 @@ public class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewI
|
|||||||
|
|
||||||
if let reactionButtonsSizeAndApply = reactionButtonsSizeAndApply {
|
if let reactionButtonsSizeAndApply = reactionButtonsSizeAndApply {
|
||||||
let reactionButtonsNode = reactionButtonsSizeAndApply.1(animation)
|
let reactionButtonsNode = reactionButtonsSizeAndApply.1(animation)
|
||||||
var reactionButtonsFrame = CGRect(origin: CGPoint(x: backgroundFrame.minX + (incoming ? (layoutConstants.bubble.contentInsets.left + 2.0) : (layoutConstants.bubble.contentInsets.right - 2.0)), y: backgroundFrame.maxY + reactionButtonsOffset + 4.0), size: reactionButtonsSizeAndApply.0)
|
|
||||||
|
var reactionButtonsOriginX: CGFloat
|
||||||
|
if case .center = alignment {
|
||||||
|
reactionButtonsOriginX = backgroundFrame.minX + 3.0
|
||||||
|
} else {
|
||||||
|
reactionButtonsOriginX = backgroundFrame.minX + (incoming ? (layoutConstants.bubble.contentInsets.left + 2.0) : (layoutConstants.bubble.contentInsets.right - 2.0))
|
||||||
|
}
|
||||||
|
var reactionButtonsFrame = CGRect(origin: CGPoint(x: reactionButtonsOriginX, y: backgroundFrame.maxY + reactionButtonsOffset + 4.0), size: reactionButtonsSizeAndApply.0)
|
||||||
if !disablesComments && !incoming {
|
if !disablesComments && !incoming {
|
||||||
reactionButtonsFrame.origin.x = backgroundFrame.maxX - reactionButtonsSizeAndApply.0.width - layoutConstants.bubble.contentInsets.left
|
reactionButtonsFrame.origin.x = backgroundFrame.maxX - reactionButtonsSizeAndApply.0.width - layoutConstants.bubble.contentInsets.left
|
||||||
}
|
}
|
||||||
|
@ -219,8 +219,8 @@ public final class ChatMessageCommentFooterContentNode: ChatMessageBubbleContent
|
|||||||
|
|
||||||
let textInsets = UIEdgeInsets()//(top: 2.0, left: 2.0, bottom: 5.0, right: 2.0)
|
let textInsets = UIEdgeInsets()//(top: 2.0, left: 2.0, bottom: 5.0, right: 2.0)
|
||||||
|
|
||||||
let (countLayout, countApply) = makeCountLayout(textConstrainedSize, rawSegments)
|
let (countLayout, countApply) = makeCountLayout(textConstrainedSize, .zero, rawSegments)
|
||||||
let (alternativeCountLayout, alternativeCountApply) = makeAlternativeCountLayout(textConstrainedSize, rawAlternativeSegments)
|
let (alternativeCountLayout, alternativeCountApply) = makeAlternativeCountLayout(textConstrainedSize, .zero, rawAlternativeSegments)
|
||||||
|
|
||||||
var textFrame = CGRect(origin: CGPoint(x: -textInsets.left + textLeftInset - 2.0, y: -textInsets.top + 5.0 + topOffset), size: countLayout.size)
|
var textFrame = CGRect(origin: CGPoint(x: -textInsets.left + textLeftInset - 2.0, y: -textInsets.top + 5.0 + topOffset), size: countLayout.size)
|
||||||
var textFrameWithoutInsets = CGRect(origin: CGPoint(x: textFrame.origin.x + textInsets.left, y: textFrame.origin.y + textInsets.top), size: CGSize(width: textFrame.width - textInsets.left - textInsets.right, height: textFrame.height - textInsets.top - textInsets.bottom))
|
var textFrameWithoutInsets = CGRect(origin: CGPoint(x: textFrame.origin.x + textInsets.left, y: textFrame.origin.y + textInsets.top), size: CGSize(width: textFrame.width - textInsets.left - textInsets.right, height: textFrame.height - textInsets.top - textInsets.bottom))
|
||||||
|
@ -442,7 +442,11 @@ public class ChatMessageGiftBubbleContentNode: ChatMessageBubbleContentNode {
|
|||||||
text = item.presentationData.strings.Notification_StarGift_Bot_Subtitle
|
text = item.presentationData.strings.Notification_StarGift_Bot_Subtitle
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
text = item.presentationData.strings.Notification_StarGift_Subtitle_Other(peerName, item.presentationData.strings.Notification_StarGift_Subtitle_Other_Stars(Int32(convertStars ?? 0))).string
|
let formattedString = item.presentationData.strings.Notification_StarGift_Subtitle_Other(peerName, item.presentationData.strings.Notification_StarGift_Subtitle_Other_Stars(Int32(convertStars ?? 0)))
|
||||||
|
text = formattedString.string
|
||||||
|
if let starsRange = formattedString.ranges.last {
|
||||||
|
entities.append(MessageTextEntity(range: starsRange.range.lowerBound ..< starsRange.range.upperBound, type: .Bold))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -284,8 +284,17 @@ public func canAddMessageReactions(message: Message) -> Bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
for media in message.media {
|
for media in message.media {
|
||||||
if let _ = media as? TelegramMediaAction {
|
if let action = media as? TelegramMediaAction {
|
||||||
return message.flags.contains(.ReactionsArePossible)
|
if message.flags.contains(.ReactionsArePossible) {
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
switch action.action {
|
||||||
|
case .unknown, .groupCreated, .channelMigratedFromGroup, .groupMigratedToChannel, .historyCleared, .customText, .botDomainAccessGranted, .botAppAccessGranted, .botSentSecureValues, .phoneNumberRequest, .webViewData, .topicCreated, .attachMenuBotAllowed, .requestedPeer:
|
||||||
|
return false
|
||||||
|
default:
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
} else if let story = media as? TelegramMediaStory {
|
} else if let story = media as? TelegramMediaStory {
|
||||||
if story.isMention {
|
if story.isMention {
|
||||||
return false
|
return false
|
||||||
|
@ -29,6 +29,7 @@ swift_library(
|
|||||||
"//submodules/TelegramUI/Components/EmojiStatusComponent",
|
"//submodules/TelegramUI/Components/EmojiStatusComponent",
|
||||||
"//submodules/TelegramUI/Components/SliderComponent",
|
"//submodules/TelegramUI/Components/SliderComponent",
|
||||||
"//submodules/TelegramUI/Components/Utils/RoundedRectWithTailPath",
|
"//submodules/TelegramUI/Components/Utils/RoundedRectWithTailPath",
|
||||||
|
"//submodules/TelegramUI/Components/CheckComponent",
|
||||||
"//submodules/AvatarNode",
|
"//submodules/AvatarNode",
|
||||||
"//submodules/Components/BundleIconComponent",
|
"//submodules/Components/BundleIconComponent",
|
||||||
"//submodules/CheckNode",
|
"//submodules/CheckNode",
|
||||||
|
@ -20,6 +20,7 @@ import AvatarNode
|
|||||||
import BundleIconComponent
|
import BundleIconComponent
|
||||||
import CheckNode
|
import CheckNode
|
||||||
import TextFormat
|
import TextFormat
|
||||||
|
import CheckComponent
|
||||||
|
|
||||||
private final class BalanceComponent: CombinedComponent {
|
private final class BalanceComponent: CombinedComponent {
|
||||||
let context: AccountContext
|
let context: AccountContext
|
||||||
@ -2569,97 +2570,3 @@ private final class SliderStarsView: UIView {
|
|||||||
self.emitterLayer.emitterSize = size
|
self.emitterLayer.emitterSize = size
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private final class CheckComponent: Component {
|
|
||||||
struct Theme: Equatable {
|
|
||||||
public let backgroundColor: UIColor
|
|
||||||
public let strokeColor: UIColor
|
|
||||||
public let borderColor: UIColor
|
|
||||||
public let overlayBorder: Bool
|
|
||||||
public let hasInset: Bool
|
|
||||||
public let hasShadow: Bool
|
|
||||||
public let filledBorder: Bool
|
|
||||||
public let borderWidth: CGFloat?
|
|
||||||
|
|
||||||
public init(backgroundColor: UIColor, strokeColor: UIColor, borderColor: UIColor, overlayBorder: Bool, hasInset: Bool, hasShadow: Bool, filledBorder: Bool = false, borderWidth: CGFloat? = nil) {
|
|
||||||
self.backgroundColor = backgroundColor
|
|
||||||
self.strokeColor = strokeColor
|
|
||||||
self.borderColor = borderColor
|
|
||||||
self.overlayBorder = overlayBorder
|
|
||||||
self.hasInset = hasInset
|
|
||||||
self.hasShadow = hasShadow
|
|
||||||
self.filledBorder = filledBorder
|
|
||||||
self.borderWidth = borderWidth
|
|
||||||
}
|
|
||||||
|
|
||||||
var checkNodeTheme: CheckNodeTheme {
|
|
||||||
return CheckNodeTheme(
|
|
||||||
backgroundColor: self.backgroundColor,
|
|
||||||
strokeColor: self.strokeColor,
|
|
||||||
borderColor: self.borderColor,
|
|
||||||
overlayBorder: self.overlayBorder,
|
|
||||||
hasInset: self.hasInset,
|
|
||||||
hasShadow: self.hasShadow,
|
|
||||||
filledBorder: self.filledBorder,
|
|
||||||
borderWidth: self.borderWidth
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let theme: Theme
|
|
||||||
let selected: Bool
|
|
||||||
|
|
||||||
init(
|
|
||||||
theme: Theme,
|
|
||||||
selected: Bool
|
|
||||||
) {
|
|
||||||
self.theme = theme
|
|
||||||
self.selected = selected
|
|
||||||
}
|
|
||||||
|
|
||||||
static func ==(lhs: CheckComponent, rhs: CheckComponent) -> Bool {
|
|
||||||
if lhs.theme != rhs.theme {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
if lhs.selected != rhs.selected {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
final class View: UIView {
|
|
||||||
private var currentValue: CGFloat?
|
|
||||||
private var animator: DisplayLinkAnimator?
|
|
||||||
|
|
||||||
private var checkLayer: CheckLayer {
|
|
||||||
return self.layer as! CheckLayer
|
|
||||||
}
|
|
||||||
|
|
||||||
override class var layerClass: AnyClass {
|
|
||||||
return CheckLayer.self
|
|
||||||
}
|
|
||||||
|
|
||||||
init() {
|
|
||||||
super.init(frame: CGRect())
|
|
||||||
}
|
|
||||||
|
|
||||||
required init?(coder aDecoder: NSCoder) {
|
|
||||||
preconditionFailure()
|
|
||||||
}
|
|
||||||
|
|
||||||
func update(component: CheckComponent, availableSize: CGSize, transition: ComponentTransition) -> CGSize {
|
|
||||||
self.checkLayer.setSelected(component.selected, animated: true)
|
|
||||||
self.checkLayer.theme = component.theme.checkNodeTheme
|
|
||||||
|
|
||||||
return CGSize(width: 22.0, height: 22.0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func makeView() -> View {
|
|
||||||
return View()
|
|
||||||
}
|
|
||||||
|
|
||||||
func update(view: View, availableSize: CGSize, state: EmptyComponentState, environment: Environment<Empty>, transition: ComponentTransition) -> CGSize {
|
|
||||||
return view.update(component: self, availableSize: availableSize, transition: transition)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -29,7 +29,7 @@ swift_library(
|
|||||||
"//submodules/PremiumUI:PremiumUI",
|
"//submodules/PremiumUI:PremiumUI",
|
||||||
"//submodules/UndoUI:UndoUI",
|
"//submodules/UndoUI:UndoUI",
|
||||||
"//submodules/ContextUI:ContextUI",
|
"//submodules/ContextUI:ContextUI",
|
||||||
"//submodules/GalleryUI:GalleryUI",
|
"//submodules/StickerResources",
|
||||||
"//submodules/TelegramPresentationData:TelegramPresentationData",
|
"//submodules/TelegramPresentationData:TelegramPresentationData",
|
||||||
"//submodules/TelegramNotices:TelegramNotices",
|
"//submodules/TelegramNotices:TelegramNotices",
|
||||||
"//submodules/StickerPeekUI:StickerPeekUI",
|
"//submodules/StickerPeekUI:StickerPeekUI",
|
||||||
@ -37,7 +37,6 @@ swift_library(
|
|||||||
"//submodules/TelegramUI/Components/MultiplexedVideoNode:MultiplexedVideoNode",
|
"//submodules/TelegramUI/Components/MultiplexedVideoNode:MultiplexedVideoNode",
|
||||||
"//submodules/TelegramUI/Components/ChatControllerInteraction:ChatControllerInteraction",
|
"//submodules/TelegramUI/Components/ChatControllerInteraction:ChatControllerInteraction",
|
||||||
"//submodules/FeaturedStickersScreen:FeaturedStickersScreen",
|
"//submodules/FeaturedStickersScreen:FeaturedStickersScreen",
|
||||||
"//submodules/StickerPackPreviewUI",
|
|
||||||
"//submodules/TelegramUI/Components/EntityKeyboardGifContent:EntityKeyboardGifContent",
|
"//submodules/TelegramUI/Components/EntityKeyboardGifContent:EntityKeyboardGifContent",
|
||||||
"//submodules/TelegramUI/Components/LegacyMessageInputPanelInputView:LegacyMessageInputPanelInputView",
|
"//submodules/TelegramUI/Components/LegacyMessageInputPanelInputView:LegacyMessageInputPanelInputView",
|
||||||
"//submodules/AttachmentTextInputPanelNode",
|
"//submodules/AttachmentTextInputPanelNode",
|
||||||
|
@ -19,7 +19,6 @@ import PremiumUI
|
|||||||
import AudioToolbox
|
import AudioToolbox
|
||||||
import UndoUI
|
import UndoUI
|
||||||
import ContextUI
|
import ContextUI
|
||||||
import GalleryUI
|
|
||||||
import TelegramPresentationData
|
import TelegramPresentationData
|
||||||
import TelegramNotices
|
import TelegramNotices
|
||||||
import StickerPeekUI
|
import StickerPeekUI
|
||||||
@ -29,7 +28,6 @@ import MultiplexedVideoNode
|
|||||||
import ChatControllerInteraction
|
import ChatControllerInteraction
|
||||||
import FeaturedStickersScreen
|
import FeaturedStickersScreen
|
||||||
import Pasteboard
|
import Pasteboard
|
||||||
import StickerPackPreviewUI
|
|
||||||
import EntityKeyboardGifContent
|
import EntityKeyboardGifContent
|
||||||
import LegacyMessageInputPanelInputView
|
import LegacyMessageInputPanelInputView
|
||||||
import AttachmentTextInputPanelNode
|
import AttachmentTextInputPanelNode
|
||||||
@ -647,25 +645,6 @@ public final class ChatEntityKeyboardInputNode: ChatInputNode {
|
|||||||
parentInputInteraction: emojiInputInteraction
|
parentInputInteraction: emojiInputInteraction
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
/*let controller = StickerPackScreen(
|
|
||||||
context: context,
|
|
||||||
updatedPresentationData: controllerInteraction.updatedPresentationData,
|
|
||||||
mode: .default,
|
|
||||||
mainStickerPack: .id(id: featuredStickerPack.info.id.id, accessHash: featuredStickerPack.info.accessHash),
|
|
||||||
stickerPacks: [.id(id: featuredStickerPack.info.id.id, accessHash: featuredStickerPack.info.accessHash)],
|
|
||||||
loadedStickerPacks: [.result(info: featuredStickerPack.info, items: featuredStickerPack.topItems, installed: false)],
|
|
||||||
parentNavigationController: controllerInteraction.navigationController(),
|
|
||||||
sendSticker: nil,
|
|
||||||
sendEmoji: { [weak interfaceInteraction] text, emojiAttribute in
|
|
||||||
guard let interfaceInteraction else {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
interfaceInteraction.insertText(NSAttributedString(string: text, attributes: [ChatTextInputAttributes.customEmoji: emojiAttribute]))
|
|
||||||
}
|
|
||||||
)
|
|
||||||
controllerInteraction.presentController(controller, nil)*/
|
|
||||||
|
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1395,6 +1374,7 @@ public final class ChatEntityKeyboardInputNode: ChatInputNode {
|
|||||||
mainStickerPack: packReference,
|
mainStickerPack: packReference,
|
||||||
stickerPacks: [packReference],
|
stickerPacks: [packReference],
|
||||||
loadedStickerPacks: [],
|
loadedStickerPacks: [],
|
||||||
|
actionTitle: nil,
|
||||||
isEditing: true,
|
isEditing: true,
|
||||||
expandIfNeeded: true,
|
expandIfNeeded: true,
|
||||||
parentNavigationController: interaction.getNavigationController(),
|
parentNavigationController: interaction.getNavigationController(),
|
||||||
@ -2131,9 +2111,7 @@ public final class ChatEntityKeyboardInputNode: ChatInputNode {
|
|||||||
|
|
||||||
let message = Message(stableId: 0, stableVersion: 0, id: MessageId(peerId: PeerId(0), namespace: Namespaces.Message.Local, id: 0), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: 0, flags: [], tags: [], globalTags: [], localTags: [], customTags: [], forwardInfo: nil, author: nil, text: "", attributes: [], media: [file.media], peers: SimpleDictionary(), associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil, associatedStories: [:])
|
let message = Message(stableId: 0, stableVersion: 0, id: MessageId(peerId: PeerId(0), namespace: Namespaces.Message.Local, id: 0), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: 0, flags: [], tags: [], globalTags: [], localTags: [], customTags: [], forwardInfo: nil, author: nil, text: "", attributes: [], media: [file.media], peers: SimpleDictionary(), associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil, associatedStories: [:])
|
||||||
|
|
||||||
let gallery = GalleryController(context: strongSelf.context, source: .standaloneMessage(message, nil), streamSingleVideo: true, replaceRootController: { _, _ in
|
let gallery = strongSelf.context.sharedContext.makeGalleryController(context: strongSelf.context, source: .standaloneMessage(message, nil), streamSingleVideo: true, isPreview: true)
|
||||||
}, baseNavigationController: nil)
|
|
||||||
gallery.setHintWillBePresentedInPreviewingContext(true)
|
|
||||||
|
|
||||||
var items: [ContextMenuItem] = []
|
var items: [ContextMenuItem] = []
|
||||||
items.append(.action(ContextMenuActionItem(text: presentationData.strings.MediaPicker_Send, icon: { theme in
|
items.append(.action(ContextMenuActionItem(text: presentationData.strings.MediaPicker_Send, icon: { theme in
|
||||||
@ -2282,7 +2260,7 @@ private final class ContextControllerContentSourceImpl: ContextControllerContent
|
|||||||
}
|
}
|
||||||
|
|
||||||
func animatedIn() {
|
func animatedIn() {
|
||||||
if let controller = self.controller as? GalleryController {
|
if let controller = self.controller as? GalleryControllerProtocol {
|
||||||
controller.viewDidAppear(false)
|
controller.viewDidAppear(false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2883,7 +2861,7 @@ public final class EmojiContentPeekBehaviorImpl: EmojiContentPeekBehavior {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
let controller = strongSelf.context.sharedContext.makeStickerPackScreen(context: context, updatedPresentationData: nil, mainStickerPack: packReference, stickerPacks: [packReference], loadedStickerPacks: [], isEditing: false, expandIfNeeded: false, parentNavigationController: interaction.navigationController(), sendSticker: { file, sourceView, sourceRect in
|
let controller = strongSelf.context.sharedContext.makeStickerPackScreen(context: context, updatedPresentationData: nil, mainStickerPack: packReference, stickerPacks: [packReference], loadedStickerPacks: [], actionTitle: nil, isEditing: false, expandIfNeeded: false, parentNavigationController: interaction.navigationController(), sendSticker: { file, sourceView, sourceRect in
|
||||||
sendSticker(file, false, false, nil, false, sourceView, sourceRect, nil)
|
sendSticker(file, false, false, nil, false, sourceView, sourceRect, nil)
|
||||||
return true
|
return true
|
||||||
}, actionPerformed: nil)
|
}, actionPerformed: nil)
|
||||||
|
@ -10,7 +10,6 @@ import PresentationDataUtils
|
|||||||
import LegacyComponents
|
import LegacyComponents
|
||||||
import MergeLists
|
import MergeLists
|
||||||
import AccountContext
|
import AccountContext
|
||||||
import StickerPackPreviewUI
|
|
||||||
import StickerPeekUI
|
import StickerPeekUI
|
||||||
import Emoji
|
import Emoji
|
||||||
import AppBundle
|
import AppBundle
|
||||||
@ -19,6 +18,7 @@ import UndoUI
|
|||||||
import ChatControllerInteraction
|
import ChatControllerInteraction
|
||||||
import FeaturedStickersScreen
|
import FeaturedStickersScreen
|
||||||
import ChatPresentationInterfaceState
|
import ChatPresentationInterfaceState
|
||||||
|
import StickerResources
|
||||||
|
|
||||||
private enum StickerSearchEntryId: Equatable, Hashable {
|
private enum StickerSearchEntryId: Equatable, Hashable {
|
||||||
case sticker(String?, Int64)
|
case sticker(String?, Int64)
|
||||||
@ -224,13 +224,25 @@ final class StickerPaneSearchContentNode: ASDisplayNode, PaneSearchContentNode {
|
|||||||
|
|
||||||
let presentationData = strongSelf.context.sharedContext.currentPresentationData.with { $0 }.withUpdated(theme: theme)
|
let presentationData = strongSelf.context.sharedContext.currentPresentationData.with { $0 }.withUpdated(theme: theme)
|
||||||
|
|
||||||
let controller = StickerPackScreen(context: strongSelf.context, updatedPresentationData: (presentationData, .single(presentationData)), mainStickerPack: packReference, stickerPacks: [packReference], actionTitle: stickerActionTitle, parentNavigationController: strongSelf.interaction.getNavigationController(), sendSticker: { [weak self] fileReference, sourceNode, sourceRect in
|
let controller = strongSelf.context.sharedContext.makeStickerPackScreen(
|
||||||
if let strongSelf = self {
|
context: strongSelf.context,
|
||||||
return strongSelf.interaction.sendSticker(fileReference, false, false, nil, false, sourceNode, sourceRect, nil, [])
|
updatedPresentationData: (presentationData, .single(presentationData)),
|
||||||
} else {
|
mainStickerPack: packReference,
|
||||||
return false
|
stickerPacks: [packReference],
|
||||||
}
|
loadedStickerPacks: [],
|
||||||
})
|
actionTitle: stickerActionTitle,
|
||||||
|
isEditing: false,
|
||||||
|
expandIfNeeded: false,
|
||||||
|
parentNavigationController: strongSelf.interaction.getNavigationController(),
|
||||||
|
sendSticker: { [weak self] fileReference, sourceView, sourceRect in
|
||||||
|
if let strongSelf = self {
|
||||||
|
return strongSelf.interaction.sendSticker(fileReference, false, false, nil, false, sourceView, sourceRect, nil, [])
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
actionPerformed: nil
|
||||||
|
)
|
||||||
strongSelf.interaction.presentController(controller, nil)
|
strongSelf.interaction.presentController(controller, nil)
|
||||||
}
|
}
|
||||||
}, install: { [weak self] info, items, install in
|
}, install: { [weak self] info, items, install in
|
||||||
|
@ -277,9 +277,11 @@ public final class ChatTitleView: UIView, NavigationBarTitleView {
|
|||||||
}
|
}
|
||||||
titleCredibilityIcon = .emojiStatus(emojiStatus)
|
titleCredibilityIcon = .emojiStatus(emojiStatus)
|
||||||
} else if peer.isVerified {
|
} else if peer.isVerified {
|
||||||
titleCredibilityIcon = .verified
|
titleVerifiedIcon = .verified
|
||||||
} else if peer.isPremium && !premiumConfiguration.isPremiumDisabled {
|
} else if peer.isPremium && !premiumConfiguration.isPremiumDisabled {
|
||||||
titleCredibilityIcon = .premium
|
titleCredibilityIcon = .premium
|
||||||
|
} else if let verification = peer.verification {
|
||||||
|
titleVerifiedIcon = .emojiStatus(PeerEmojiStatus(fileId: verification.iconFileId, expirationDate: nil))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -399,7 +401,7 @@ public final class ChatTitleView: UIView, NavigationBarTitleView {
|
|||||||
}
|
}
|
||||||
updated = true
|
updated = true
|
||||||
}
|
}
|
||||||
|
|
||||||
if titleCredibilityIcon != self.titleCredibilityIcon {
|
if titleCredibilityIcon != self.titleCredibilityIcon {
|
||||||
self.titleCredibilityIcon = titleCredibilityIcon
|
self.titleCredibilityIcon = titleCredibilityIcon
|
||||||
updated = true
|
updated = true
|
||||||
@ -906,9 +908,15 @@ public final class ChatTitleView: UIView, NavigationBarTitleView {
|
|||||||
let titleSideInset: CGFloat = 6.0
|
let titleSideInset: CGFloat = 6.0
|
||||||
var titleFrame: CGRect
|
var titleFrame: CGRect
|
||||||
if size.height > 40.0 {
|
if size.height > 40.0 {
|
||||||
var titleSize = self.titleTextNode.updateLayout(size: CGSize(width: clearBounds.width - leftIconWidth - credibilityIconWidth - verifiedIconWidth - rightIconWidth - titleSideInset * 2.0, height: size.height), animated: titleTransition.isAnimated)
|
var titleInsets: UIEdgeInsets = .zero
|
||||||
|
if verifiedIconWidth > 0.0 {
|
||||||
|
titleInsets.left = verifiedIconWidth + 2.0
|
||||||
|
}
|
||||||
|
|
||||||
|
var titleSize = self.titleTextNode.updateLayout(size: CGSize(width: clearBounds.width - leftIconWidth - credibilityIconWidth - verifiedIconWidth - rightIconWidth - titleSideInset * 2.0, height: size.height), insets: titleInsets, animated: titleTransition.isAnimated)
|
||||||
titleSize.width += credibilityIconWidth
|
titleSize.width += credibilityIconWidth
|
||||||
titleSize.width += verifiedIconWidth
|
titleSize.width += verifiedIconWidth
|
||||||
|
|
||||||
let activitySize = self.activityNode.updateLayout(CGSize(width: clearBounds.size.width - titleSideInset * 2.0, height: clearBounds.size.height), alignment: .center)
|
let activitySize = self.activityNode.updateLayout(CGSize(width: clearBounds.size.width - titleSideInset * 2.0, height: clearBounds.size.height), alignment: .center)
|
||||||
let titleInfoSpacing: CGFloat = 0.0
|
let titleInfoSpacing: CGFloat = 0.0
|
||||||
|
|
||||||
@ -943,11 +951,7 @@ public final class ChatTitleView: UIView, NavigationBarTitleView {
|
|||||||
|
|
||||||
var nextIconX: CGFloat = titleFrame.width
|
var nextIconX: CGFloat = titleFrame.width
|
||||||
|
|
||||||
self.titleVerifiedIconView.frame = CGRect(origin: CGPoint(x: titleFrame.width - titleVerifiedSize.width, y: floor((titleFrame.height - titleVerifiedSize.height) / 2.0)), size: titleVerifiedSize)
|
self.titleVerifiedIconView.frame = CGRect(origin: CGPoint(x: 0.0, y: floor((titleFrame.height - titleVerifiedSize.height) / 2.0)), size: titleVerifiedSize)
|
||||||
nextIconX -= titleVerifiedSize.width
|
|
||||||
if !titleVerifiedSize.width.isZero {
|
|
||||||
nextIconX -= 2.0
|
|
||||||
}
|
|
||||||
|
|
||||||
self.titleCredibilityIconView.frame = CGRect(origin: CGPoint(x: nextIconX - titleCredibilitySize.width, y: floor((titleFrame.height - titleCredibilitySize.height) / 2.0)), size: titleCredibilitySize)
|
self.titleCredibilityIconView.frame = CGRect(origin: CGPoint(x: nextIconX - titleCredibilitySize.width, y: floor((titleFrame.height - titleCredibilitySize.height) / 2.0)), size: titleCredibilitySize)
|
||||||
nextIconX -= titleCredibilitySize.width
|
nextIconX -= titleCredibilitySize.width
|
||||||
@ -975,11 +979,7 @@ public final class ChatTitleView: UIView, NavigationBarTitleView {
|
|||||||
|
|
||||||
var nextIconX: CGFloat = titleFrame.maxX
|
var nextIconX: CGFloat = titleFrame.maxX
|
||||||
|
|
||||||
self.titleVerifiedIconView.frame = CGRect(origin: CGPoint(x: nextIconX - titleVerifiedSize.width, y: floor((titleFrame.height - titleVerifiedSize.height) / 2.0)), size: titleVerifiedSize)
|
self.titleVerifiedIconView.frame = CGRect(origin: CGPoint(x: 0.0, y: floor((titleFrame.height - titleVerifiedSize.height) / 2.0)), size: titleVerifiedSize)
|
||||||
nextIconX -= titleVerifiedSize.width
|
|
||||||
if !titleVerifiedSize.width.isZero {
|
|
||||||
nextIconX -= 2.0
|
|
||||||
}
|
|
||||||
|
|
||||||
self.titleCredibilityIconView.frame = CGRect(origin: CGPoint(x: nextIconX - titleCredibilitySize.width, y: floor((titleFrame.height - titleCredibilitySize.height) / 2.0)), size: titleCredibilitySize)
|
self.titleCredibilityIconView.frame = CGRect(origin: CGPoint(x: nextIconX - titleCredibilitySize.width, y: floor((titleFrame.height - titleCredibilitySize.height) / 2.0)), size: titleCredibilitySize)
|
||||||
nextIconX -= titleCredibilitySize.width
|
nextIconX -= titleCredibilitySize.width
|
||||||
|
21
submodules/TelegramUI/Components/CheckComponent/BUILD
Normal file
21
submodules/TelegramUI/Components/CheckComponent/BUILD
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
load("@build_bazel_rules_swift//swift:swift.bzl", "swift_library")
|
||||||
|
|
||||||
|
swift_library(
|
||||||
|
name = "CheckComponent",
|
||||||
|
module_name = "CheckComponent",
|
||||||
|
srcs = glob([
|
||||||
|
"Sources/**/*.swift",
|
||||||
|
]),
|
||||||
|
copts = [
|
||||||
|
"-warnings-as-errors",
|
||||||
|
],
|
||||||
|
deps = [
|
||||||
|
"//submodules/AsyncDisplayKit:AsyncDisplayKit",
|
||||||
|
"//submodules/Display:Display",
|
||||||
|
"//submodules/ComponentFlow:ComponentFlow",
|
||||||
|
"//submodules/CheckNode:CheckNode",
|
||||||
|
],
|
||||||
|
visibility = [
|
||||||
|
"//visibility:public",
|
||||||
|
],
|
||||||
|
)
|
@ -0,0 +1,105 @@
|
|||||||
|
import Foundation
|
||||||
|
import UIKit
|
||||||
|
import Display
|
||||||
|
import ComponentFlow
|
||||||
|
import CheckNode
|
||||||
|
|
||||||
|
public final class CheckComponent: Component {
|
||||||
|
public struct Theme: Equatable {
|
||||||
|
public let backgroundColor: UIColor
|
||||||
|
public let strokeColor: UIColor
|
||||||
|
public let borderColor: UIColor
|
||||||
|
public let overlayBorder: Bool
|
||||||
|
public let hasInset: Bool
|
||||||
|
public let hasShadow: Bool
|
||||||
|
public let filledBorder: Bool
|
||||||
|
public let borderWidth: CGFloat?
|
||||||
|
|
||||||
|
public init(backgroundColor: UIColor, strokeColor: UIColor, borderColor: UIColor, overlayBorder: Bool, hasInset: Bool, hasShadow: Bool, filledBorder: Bool = false, borderWidth: CGFloat? = nil) {
|
||||||
|
self.backgroundColor = backgroundColor
|
||||||
|
self.strokeColor = strokeColor
|
||||||
|
self.borderColor = borderColor
|
||||||
|
self.overlayBorder = overlayBorder
|
||||||
|
self.hasInset = hasInset
|
||||||
|
self.hasShadow = hasShadow
|
||||||
|
self.filledBorder = filledBorder
|
||||||
|
self.borderWidth = borderWidth
|
||||||
|
}
|
||||||
|
|
||||||
|
var checkNodeTheme: CheckNodeTheme {
|
||||||
|
return CheckNodeTheme(
|
||||||
|
backgroundColor: self.backgroundColor,
|
||||||
|
strokeColor: self.strokeColor,
|
||||||
|
borderColor: self.borderColor,
|
||||||
|
overlayBorder: self.overlayBorder,
|
||||||
|
hasInset: self.hasInset,
|
||||||
|
hasShadow: self.hasShadow,
|
||||||
|
filledBorder: self.filledBorder,
|
||||||
|
borderWidth: self.borderWidth
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let theme: Theme
|
||||||
|
let size: CGSize
|
||||||
|
let selected: Bool
|
||||||
|
|
||||||
|
public init(
|
||||||
|
theme: Theme,
|
||||||
|
size: CGSize = CGSize(width: 22.0, height: 22.0),
|
||||||
|
selected: Bool
|
||||||
|
) {
|
||||||
|
self.theme = theme
|
||||||
|
self.size = size
|
||||||
|
self.selected = selected
|
||||||
|
}
|
||||||
|
|
||||||
|
public static func ==(lhs: CheckComponent, rhs: CheckComponent) -> Bool {
|
||||||
|
if lhs.theme != rhs.theme {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if lhs.size != rhs.size {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if lhs.selected != rhs.selected {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class View: UIView {
|
||||||
|
private var currentValue: CGFloat?
|
||||||
|
private var animator: DisplayLinkAnimator?
|
||||||
|
|
||||||
|
private var checkLayer: CheckLayer {
|
||||||
|
return self.layer as! CheckLayer
|
||||||
|
}
|
||||||
|
|
||||||
|
public override class var layerClass: AnyClass {
|
||||||
|
return CheckLayer.self
|
||||||
|
}
|
||||||
|
|
||||||
|
init() {
|
||||||
|
super.init(frame: CGRect())
|
||||||
|
}
|
||||||
|
|
||||||
|
required init?(coder aDecoder: NSCoder) {
|
||||||
|
preconditionFailure()
|
||||||
|
}
|
||||||
|
|
||||||
|
public func update(component: CheckComponent, availableSize: CGSize, transition: ComponentTransition) -> CGSize {
|
||||||
|
self.checkLayer.setSelected(component.selected, animated: true)
|
||||||
|
self.checkLayer.theme = component.theme.checkNodeTheme
|
||||||
|
|
||||||
|
return component.size
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public func makeView() -> View {
|
||||||
|
return View()
|
||||||
|
}
|
||||||
|
|
||||||
|
public func update(view: View, availableSize: CGSize, state: EmptyComponentState, environment: Environment<Empty>, transition: ComponentTransition) -> CGSize {
|
||||||
|
return view.update(component: self, availableSize: availableSize, transition: transition)
|
||||||
|
}
|
||||||
|
}
|
@ -299,7 +299,7 @@ public final class EmojiStatusComponent: Component {
|
|||||||
imageNamePrefix = "Peer Info/VerifiedIcon"
|
imageNamePrefix = "Peer Info/VerifiedIcon"
|
||||||
}
|
}
|
||||||
|
|
||||||
if let backgroundImage = UIImage(bundleImageName: "\(imageNamePrefix)Background"), let foregroundImage = UIImage(bundleImageName: "\(imageNamePrefix)Foreground") {
|
if let backgroundImage = UIImage(bundleImageName: "\(imageNamePrefix)Background"), let foregroundImage = UIImage(bundleImageName: "Share/QrPlaneIcon") {
|
||||||
iconImage = generateImage(backgroundImage.size, contextGenerator: { size, context in
|
iconImage = generateImage(backgroundImage.size, contextGenerator: { size, context in
|
||||||
if let backgroundCgImage = backgroundImage.cgImage, let foregroundCgImage = foregroundImage.cgImage {
|
if let backgroundCgImage = backgroundImage.cgImage, let foregroundCgImage = foregroundImage.cgImage {
|
||||||
context.clear(CGRect(origin: CGPoint(), size: size))
|
context.clear(CGRect(origin: CGPoint(), size: size))
|
||||||
|
@ -473,6 +473,9 @@ public final class InlineStickerItemLayer: MultiAnimationRenderTarget {
|
|||||||
self.updateTon()
|
self.updateTon()
|
||||||
case let .animation(name):
|
case let .animation(name):
|
||||||
self.updateLocalAnimation(name: name, attemptSynchronousLoad: attemptSynchronousLoad)
|
self.updateLocalAnimation(name: name, attemptSynchronousLoad: attemptSynchronousLoad)
|
||||||
|
case .verification:
|
||||||
|
self.updateVerification()
|
||||||
|
self.updateTintColor()
|
||||||
}
|
}
|
||||||
} else if let file = file {
|
} else if let file = file {
|
||||||
self.updateFile(file: file, attemptSynchronousLoad: attemptSynchronousLoad)
|
self.updateFile(file: file, attemptSynchronousLoad: attemptSynchronousLoad)
|
||||||
@ -558,8 +561,13 @@ public final class InlineStickerItemLayer: MultiAnimationRenderTarget {
|
|||||||
if file.isCustomTemplateEmoji {
|
if file.isCustomTemplateEmoji {
|
||||||
customColor = self.dynamicColor
|
customColor = self.dynamicColor
|
||||||
}
|
}
|
||||||
} else if let emoji = self.arguments?.emoji, let custom = emoji.custom, case .stars = custom {
|
} else if let emoji = self.arguments?.emoji, let custom = emoji.custom {
|
||||||
customColor = self.dynamicColor
|
switch custom {
|
||||||
|
case .stars(true), .verification:
|
||||||
|
customColor = self.dynamicColor
|
||||||
|
default:
|
||||||
|
break
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if customColor != nil {
|
if customColor != nil {
|
||||||
@ -662,6 +670,10 @@ public final class InlineStickerItemLayer: MultiAnimationRenderTarget {
|
|||||||
self.contents = tonImage?.cgImage
|
self.contents = tonImage?.cgImage
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private func updateVerification() {
|
||||||
|
self.contents = verificationImage?.cgImage
|
||||||
|
}
|
||||||
|
|
||||||
private func updateLocalAnimation(name: String, attemptSynchronousLoad: Bool) {
|
private func updateLocalAnimation(name: String, attemptSynchronousLoad: Bool) {
|
||||||
guard let arguments = self.arguments else {
|
guard let arguments = self.arguments else {
|
||||||
return
|
return
|
||||||
@ -992,7 +1004,6 @@ private let tintedStarImage: UIImage? = {
|
|||||||
})?.withRenderingMode(.alwaysTemplate)
|
})?.withRenderingMode(.alwaysTemplate)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
|
||||||
private let starImage: UIImage? = {
|
private let starImage: UIImage? = {
|
||||||
generateImage(CGSize(width: 32.0, height: 32.0), contextGenerator: { size, context in
|
generateImage(CGSize(width: 32.0, height: 32.0), contextGenerator: { size, context in
|
||||||
context.clear(CGRect(origin: .zero, size: size))
|
context.clear(CGRect(origin: .zero, size: size))
|
||||||
@ -1012,3 +1023,28 @@ private let tonImage: UIImage? = {
|
|||||||
}
|
}
|
||||||
})?.withRenderingMode(.alwaysTemplate)
|
})?.withRenderingMode(.alwaysTemplate)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
private let verificationImage: UIImage? = {
|
||||||
|
if let backgroundImage = UIImage(bundleImageName: "Peer Info/VerifiedIconBackground"), let foregroundImage = UIImage(bundleImageName: "Share/QrPlaneIcon") {
|
||||||
|
return generateImage(backgroundImage.size, contextGenerator: { size, context in
|
||||||
|
let fittedRect = CGRect(origin: .zero, size: size).insetBy(dx: 2.0 + UIScreenPixel, dy: 2.0 + UIScreenPixel)
|
||||||
|
if let backgroundCgImage = backgroundImage.cgImage, let foregroundCgImage = foregroundImage.cgImage {
|
||||||
|
context.clear(CGRect(origin: CGPoint(), size: size))
|
||||||
|
|
||||||
|
context.saveGState()
|
||||||
|
context.clip(to: fittedRect, mask: backgroundCgImage)
|
||||||
|
|
||||||
|
context.setFillColor(UIColor.white.cgColor)
|
||||||
|
context.fill(CGRect(origin: CGPoint(), size: size))
|
||||||
|
context.restoreGState()
|
||||||
|
|
||||||
|
context.clip(to: fittedRect, mask: foregroundCgImage)
|
||||||
|
context.setBlendMode(.clear)
|
||||||
|
context.setFillColor(UIColor.clear.cgColor)
|
||||||
|
context.fill(CGRect(origin: CGPoint(), size: size))
|
||||||
|
}
|
||||||
|
}, opaque: false)?.withRenderingMode(.alwaysTemplate)
|
||||||
|
} else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
@ -119,6 +119,7 @@ public final class MediaEditor {
|
|||||||
public enum Mode {
|
public enum Mode {
|
||||||
case `default`
|
case `default`
|
||||||
case sticker
|
case sticker
|
||||||
|
case avatar
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum Subject {
|
public enum Subject {
|
||||||
@ -130,6 +131,8 @@ public final class MediaEditor {
|
|||||||
}
|
}
|
||||||
public let content: Content
|
public let content: Content
|
||||||
public let frame: CGRect
|
public let frame: CGRect
|
||||||
|
public let contentScale: CGFloat
|
||||||
|
public let contentOffset: CGPoint
|
||||||
|
|
||||||
var isVideo: Bool {
|
var isVideo: Bool {
|
||||||
return self.duration > 0.0
|
return self.duration > 0.0
|
||||||
@ -146,9 +149,16 @@ public final class MediaEditor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public init(content: Content, frame: CGRect) {
|
public init(
|
||||||
|
content: Content,
|
||||||
|
frame: CGRect,
|
||||||
|
contentScale: CGFloat,
|
||||||
|
contentOffset: CGPoint
|
||||||
|
) {
|
||||||
self.content = content
|
self.content = content
|
||||||
self.frame = frame
|
self.frame = frame
|
||||||
|
self.contentScale = contentScale
|
||||||
|
self.contentOffset = contentOffset
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -599,7 +609,7 @@ public final class MediaEditor {
|
|||||||
self.renderer.videoFinishPass.additionalTextureRotation = .rotate0DegreesMirrored
|
self.renderer.videoFinishPass.additionalTextureRotation = .rotate0DegreesMirrored
|
||||||
}
|
}
|
||||||
let hasTransparency = imageHasTransparency(image)
|
let hasTransparency = imageHasTransparency(image)
|
||||||
self.renderer.consume(main: .texture(texture, time, hasTransparency, nil), additionals: additionalTexture.flatMap { [.texture($0, time, false, nil)] } ?? [], render: true, displayEnabled: false)
|
self.renderer.consume(main: .texture(texture, time, hasTransparency, nil, 1.0, .zero), additionals: additionalTexture.flatMap { [.texture($0, time, false, nil, 1.0, .zero)] } ?? [], render: true, displayEnabled: false)
|
||||||
}
|
}
|
||||||
|
|
||||||
private func setupSource(andPlay: Bool) {
|
private func setupSource(andPlay: Bool) {
|
||||||
@ -619,6 +629,8 @@ public final class MediaEditor {
|
|||||||
let stickerEntity: MediaEditorComposerStickerEntity?
|
let stickerEntity: MediaEditorComposerStickerEntity?
|
||||||
let playerIsReference: Bool
|
let playerIsReference: Bool
|
||||||
let rect: CGRect?
|
let rect: CGRect?
|
||||||
|
let scale: CGFloat
|
||||||
|
let offset: CGPoint
|
||||||
let gradientColors: GradientColors
|
let gradientColors: GradientColors
|
||||||
|
|
||||||
init(
|
init(
|
||||||
@ -628,6 +640,8 @@ public final class MediaEditor {
|
|||||||
stickerEntity: MediaEditorComposerStickerEntity? = nil,
|
stickerEntity: MediaEditorComposerStickerEntity? = nil,
|
||||||
playerIsReference: Bool = false,
|
playerIsReference: Bool = false,
|
||||||
rect: CGRect? = nil,
|
rect: CGRect? = nil,
|
||||||
|
scale: CGFloat = 1.0,
|
||||||
|
offset: CGPoint = .zero,
|
||||||
gradientColors: GradientColors
|
gradientColors: GradientColors
|
||||||
) {
|
) {
|
||||||
self.image = image
|
self.image = image
|
||||||
@ -636,11 +650,13 @@ public final class MediaEditor {
|
|||||||
self.stickerEntity = stickerEntity
|
self.stickerEntity = stickerEntity
|
||||||
self.playerIsReference = playerIsReference
|
self.playerIsReference = playerIsReference
|
||||||
self.rect = rect
|
self.rect = rect
|
||||||
|
self.scale = scale
|
||||||
|
self.offset = offset
|
||||||
self.gradientColors = gradientColors
|
self.gradientColors = gradientColors
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func textureSourceResult(for asset: AVAsset, gradientColors: GradientColors? = nil, rect: CGRect? = nil) -> Signal<TextureSourceResult, NoError> {
|
func textureSourceResult(for asset: AVAsset, gradientColors: GradientColors? = nil, rect: CGRect? = nil, scale: CGFloat = 1.0, offset: CGPoint = .zero) -> Signal<TextureSourceResult, NoError> {
|
||||||
return Signal { [weak self] subscriber in
|
return Signal { [weak self] subscriber in
|
||||||
guard let self else {
|
guard let self else {
|
||||||
subscriber.putCompletion()
|
subscriber.putCompletion()
|
||||||
@ -648,7 +664,13 @@ public final class MediaEditor {
|
|||||||
}
|
}
|
||||||
let player = self.makePlayer(asset: asset)
|
let player = self.makePlayer(asset: asset)
|
||||||
if let gradientColors {
|
if let gradientColors {
|
||||||
subscriber.putNext(TextureSourceResult(player: player, rect: rect, gradientColors: gradientColors))
|
subscriber.putNext(TextureSourceResult(
|
||||||
|
player: player,
|
||||||
|
rect: rect,
|
||||||
|
scale: scale,
|
||||||
|
offset: offset,
|
||||||
|
gradientColors: gradientColors
|
||||||
|
))
|
||||||
subscriber.putCompletion()
|
subscriber.putCompletion()
|
||||||
return EmptyDisposable
|
return EmptyDisposable
|
||||||
} else {
|
} else {
|
||||||
@ -657,7 +679,13 @@ public final class MediaEditor {
|
|||||||
imageGenerator.maximumSize = CGSize(width: 72, height: 128)
|
imageGenerator.maximumSize = CGSize(width: 72, height: 128)
|
||||||
imageGenerator.generateCGImagesAsynchronously(forTimes: [NSValue(time: CMTime(seconds: 0, preferredTimescale: CMTimeScale(30.0)))]) { _, image, _, _, _ in
|
imageGenerator.generateCGImagesAsynchronously(forTimes: [NSValue(time: CMTime(seconds: 0, preferredTimescale: CMTimeScale(30.0)))]) { _, image, _, _, _ in
|
||||||
let gradientColors: GradientColors = image.flatMap({ mediaEditorGetGradientColors(from: UIImage(cgImage: $0)) }) ?? GradientColors(top: .black, bottom: .black)
|
let gradientColors: GradientColors = image.flatMap({ mediaEditorGetGradientColors(from: UIImage(cgImage: $0)) }) ?? GradientColors(top: .black, bottom: .black)
|
||||||
subscriber.putNext(TextureSourceResult(player: player, rect: rect, gradientColors: gradientColors))
|
subscriber.putNext(TextureSourceResult(
|
||||||
|
player: player,
|
||||||
|
rect: rect,
|
||||||
|
scale: scale,
|
||||||
|
offset: offset,
|
||||||
|
gradientColors: gradientColors
|
||||||
|
))
|
||||||
subscriber.putCompletion()
|
subscriber.putCompletion()
|
||||||
}
|
}
|
||||||
return ActionDisposable {
|
return ActionDisposable {
|
||||||
@ -667,7 +695,7 @@ public final class MediaEditor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func textureSourceResult(for asset: PHAsset, rect: CGRect? = nil) -> Signal<TextureSourceResult, NoError> {
|
func textureSourceResult(for asset: PHAsset, rect: CGRect? = nil, scale: CGFloat = 1.0, offset: CGPoint = .zero) -> Signal<TextureSourceResult, NoError> {
|
||||||
return Signal { [weak self] subscriber in
|
return Signal { [weak self] subscriber in
|
||||||
let isVideo = asset.mediaType == .video
|
let isVideo = asset.mediaType == .video
|
||||||
|
|
||||||
@ -700,6 +728,8 @@ public final class MediaEditor {
|
|||||||
TextureSourceResult(
|
TextureSourceResult(
|
||||||
player: player,
|
player: player,
|
||||||
rect: rect,
|
rect: rect,
|
||||||
|
scale: scale,
|
||||||
|
offset: offset,
|
||||||
gradientColors: mediaEditorGetGradientColors(from: image)
|
gradientColors: mediaEditorGetGradientColors(from: image)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@ -712,6 +742,8 @@ public final class MediaEditor {
|
|||||||
TextureSourceResult(
|
TextureSourceResult(
|
||||||
image: image,
|
image: image,
|
||||||
rect: rect,
|
rect: rect,
|
||||||
|
scale: scale,
|
||||||
|
offset: offset,
|
||||||
gradientColors: mediaEditorGetGradientColors(from: image)
|
gradientColors: mediaEditorGetGradientColors(from: image)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@ -764,9 +796,9 @@ public final class MediaEditor {
|
|||||||
switch longestItem.content {
|
switch longestItem.content {
|
||||||
case let .video(path, _):
|
case let .video(path, _):
|
||||||
let asset = AVURLAsset(url: URL(fileURLWithPath: path))
|
let asset = AVURLAsset(url: URL(fileURLWithPath: path))
|
||||||
textureSource = textureSourceResult(for: asset, rect: longestItem.frame)
|
textureSource = textureSourceResult(for: asset, rect: longestItem.frame, scale: longestItem.contentScale, offset: longestItem.contentOffset)
|
||||||
case let .asset(asset):
|
case let .asset(asset):
|
||||||
textureSource = textureSourceResult(for: asset, rect: longestItem.frame)
|
textureSource = textureSourceResult(for: asset, rect: longestItem.frame, scale: longestItem.contentScale, offset: longestItem.contentOffset)
|
||||||
default:
|
default:
|
||||||
textureSource = .complete()
|
textureSource = .complete()
|
||||||
}
|
}
|
||||||
@ -838,9 +870,9 @@ public final class MediaEditor {
|
|||||||
|
|
||||||
if let image = textureSourceResult.image {
|
if let image = textureSourceResult.image {
|
||||||
if self.values.nightTheme, let nightImage = textureSourceResult.nightImage {
|
if self.values.nightTheme, let nightImage = textureSourceResult.nightImage {
|
||||||
textureSource.setMainInput(.image(nightImage, nil))
|
textureSource.setMainInput(.image(nightImage, nil, 1.0, .zero))
|
||||||
} else {
|
} else {
|
||||||
textureSource.setMainInput(.image(image, nil))
|
textureSource.setMainInput(.image(image, nil, 1.0, .zero))
|
||||||
}
|
}
|
||||||
|
|
||||||
if case .sticker = self.mode {
|
if case .sticker = self.mode {
|
||||||
@ -880,10 +912,10 @@ public final class MediaEditor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if let player = self.player, let playerItem = player.currentItem, !textureSourceResult.playerIsReference {
|
if let player = self.player, let playerItem = player.currentItem, !textureSourceResult.playerIsReference {
|
||||||
textureSource.setMainInput(.video(playerItem, textureSourceResult.rect))
|
textureSource.setMainInput(.video(playerItem, textureSourceResult.rect, textureSourceResult.scale, textureSourceResult.offset))
|
||||||
}
|
}
|
||||||
if self.values.collage.isEmpty, let additionalPlayer = self.additionalPlayers.first, let playerItem = additionalPlayer.currentItem {
|
if self.values.collage.isEmpty, let additionalPlayer = self.additionalPlayers.first, let playerItem = additionalPlayer.currentItem {
|
||||||
textureSource.setAdditionalInputs([.video(playerItem, nil)])
|
textureSource.setAdditionalInputs([.video(playerItem, nil, 1.0, .zero)])
|
||||||
}
|
}
|
||||||
if let entity = textureSourceResult.stickerEntity {
|
if let entity = textureSourceResult.stickerEntity {
|
||||||
textureSource.setMainInput(.entity(entity))
|
textureSource.setMainInput(.entity(entity))
|
||||||
@ -898,7 +930,7 @@ public final class MediaEditor {
|
|||||||
switch self.mode {
|
switch self.mode {
|
||||||
case .default:
|
case .default:
|
||||||
self.setGradientColors(textureSourceResult.gradientColors)
|
self.setGradientColors(textureSourceResult.gradientColors)
|
||||||
case .sticker:
|
case .sticker, .avatar:
|
||||||
self.setGradientColors(GradientColors(top: .clear, bottom: .clear))
|
self.setGradientColors(GradientColors(top: .clear, bottom: .clear))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1202,9 +1234,9 @@ public final class MediaEditor {
|
|||||||
|
|
||||||
if let textureSource = self.renderer.textureSource as? UniversalTextureSource {
|
if let textureSource = self.renderer.textureSource as? UniversalTextureSource {
|
||||||
if nightTheme {
|
if nightTheme {
|
||||||
textureSource.setMainInput(.image(nightImage, nil))
|
textureSource.setMainInput(.image(nightImage, nil, 1.0, .zero))
|
||||||
} else {
|
} else {
|
||||||
textureSource.setMainInput(.image(dayImage, nil))
|
textureSource.setMainInput(.image(dayImage, nil, 1.0, .zero))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1221,6 +1253,10 @@ public final class MediaEditor {
|
|||||||
|
|
||||||
public var onPlaybackAction: (PlaybackAction) -> Void = { _ in }
|
public var onPlaybackAction: (PlaybackAction) -> Void = { _ in }
|
||||||
|
|
||||||
|
public var currentPosition: CMTime {
|
||||||
|
return self.player?.currentTime() ?? .zero
|
||||||
|
}
|
||||||
|
|
||||||
private var initialSeekPosition: Double?
|
private var initialSeekPosition: Double?
|
||||||
private var targetTimePosition: (CMTime, Bool)?
|
private var targetTimePosition: (CMTime, Bool)?
|
||||||
private var updatingTimePosition = false
|
private var updatingTimePosition = false
|
||||||
@ -1716,6 +1752,8 @@ public final class MediaEditor {
|
|||||||
let item = MediaEditorValues.VideoCollageItem(
|
let item = MediaEditorValues.VideoCollageItem(
|
||||||
content: content,
|
content: content,
|
||||||
frame: item.frame,
|
frame: item.frame,
|
||||||
|
contentScale: item.contentScale,
|
||||||
|
contentOffset: item.contentOffset,
|
||||||
videoTrimRange: 0 ..< item.duration,
|
videoTrimRange: 0 ..< item.duration,
|
||||||
videoOffset: nil,
|
videoOffset: nil,
|
||||||
videoVolume: passedFirstVideo ? 0.0 : nil
|
videoVolume: passedFirstVideo ? 0.0 : nil
|
||||||
@ -1736,7 +1774,9 @@ public final class MediaEditor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if mainVideoIsMuted {
|
if mainVideoIsMuted {
|
||||||
self.setVideoVolume(0.0)
|
Queue.mainQueue().after(0.3) {
|
||||||
|
self.setVideoVolume(0.0)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.setupAdditionalVideoPlayback()
|
self.setupAdditionalVideoPlayback()
|
||||||
@ -1795,13 +1835,13 @@ public final class MediaEditor {
|
|||||||
break
|
break
|
||||||
case let .imageFile(path):
|
case let .imageFile(path):
|
||||||
if let image = UIImage(contentsOfFile: path) {
|
if let image = UIImage(contentsOfFile: path) {
|
||||||
signals.append(.single((.image(image, item.frame), nil, nil)))
|
signals.append(.single((.image(image, item.frame, item.contentScale, item.contentOffset), nil, nil)))
|
||||||
}
|
}
|
||||||
case let .videoFile(path):
|
case let .videoFile(path):
|
||||||
let asset = AVURLAsset(url: URL(fileURLWithPath: path))
|
let asset = AVURLAsset(url: URL(fileURLWithPath: path))
|
||||||
let player = self.makePlayer(asset: asset)
|
let player = self.makePlayer(asset: asset)
|
||||||
if let playerItem = player.currentItem {
|
if let playerItem = player.currentItem {
|
||||||
signals.append(.single((.video(playerItem, item.frame), player, item.videoVolume)))
|
signals.append(.single((.video(playerItem, item.frame, item.contentScale, item.contentOffset), player, item.videoVolume)))
|
||||||
}
|
}
|
||||||
case let .asset(localIdentifier, _):
|
case let .asset(localIdentifier, _):
|
||||||
let fetchResult = PHAsset.fetchAssets(withLocalIdentifiers: [localIdentifier], options: nil)
|
let fetchResult = PHAsset.fetchAssets(withLocalIdentifiers: [localIdentifier], options: nil)
|
||||||
@ -1819,7 +1859,7 @@ public final class MediaEditor {
|
|||||||
}
|
}
|
||||||
let player = self.makePlayer(asset: avAsset)
|
let player = self.makePlayer(asset: avAsset)
|
||||||
if let playerItem = player.currentItem {
|
if let playerItem = player.currentItem {
|
||||||
subscriber.putNext((.video(playerItem, item.frame), player, item.videoVolume))
|
subscriber.putNext((.video(playerItem, item.frame, item.contentScale, item.contentOffset), player, item.videoVolume))
|
||||||
}
|
}
|
||||||
subscriber.putCompletion()
|
subscriber.putCompletion()
|
||||||
})
|
})
|
||||||
@ -1890,7 +1930,7 @@ public final class MediaEditor {
|
|||||||
self.additionalPlayersPromise.set(.single([player]))
|
self.additionalPlayersPromise.set(.single([player]))
|
||||||
self.additionalPlayerAudioMixes = [audioMix]
|
self.additionalPlayerAudioMixes = [audioMix]
|
||||||
|
|
||||||
(self.renderer.textureSource as? UniversalTextureSource)?.setAdditionalInputs([.video(playerItem, nil)])
|
(self.renderer.textureSource as? UniversalTextureSource)?.setAdditionalInputs([.video(playerItem, nil, 1.0, .zero)])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -50,17 +50,25 @@ private func roundedCornersMaskImage(size: CGSize) -> CIImage {
|
|||||||
return CIImage(cgImage: image!)
|
return CIImage(cgImage: image!)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private func rectangleMaskImage(size: CGSize) -> CIImage {
|
||||||
|
let image = generateImage(size, opaque: true, scale: 1.0) { size, context in
|
||||||
|
context.setFillColor(UIColor.white.cgColor)
|
||||||
|
context.fill(CGRect(origin: .zero, size: size))
|
||||||
|
}?.cgImage
|
||||||
|
return CIImage(cgImage: image!)
|
||||||
|
}
|
||||||
|
|
||||||
final class MediaEditorComposer {
|
final class MediaEditorComposer {
|
||||||
enum Input {
|
enum Input {
|
||||||
case texture(MTLTexture, CMTime, Bool, CGRect?)
|
case texture(MTLTexture, CMTime, Bool, CGRect?, CGFloat, CGPoint)
|
||||||
case videoBuffer(VideoPixelBuffer, CGRect?)
|
case videoBuffer(VideoPixelBuffer, CGRect?, CGFloat, CGPoint)
|
||||||
case ciImage(CIImage, CMTime)
|
case ciImage(CIImage, CMTime)
|
||||||
|
|
||||||
var timestamp: CMTime {
|
var timestamp: CMTime {
|
||||||
switch self {
|
switch self {
|
||||||
case let .texture(_, timestamp, _, _):
|
case let .texture(_, timestamp, _, _, _, _):
|
||||||
return timestamp
|
return timestamp
|
||||||
case let .videoBuffer(videoBuffer, _):
|
case let .videoBuffer(videoBuffer, _, _, _):
|
||||||
return videoBuffer.timestamp
|
return videoBuffer.timestamp
|
||||||
case let .ciImage(_, timestamp):
|
case let .ciImage(_, timestamp):
|
||||||
return timestamp
|
return timestamp
|
||||||
@ -69,10 +77,10 @@ final class MediaEditorComposer {
|
|||||||
|
|
||||||
var rendererInput: MediaEditorRenderer.Input {
|
var rendererInput: MediaEditorRenderer.Input {
|
||||||
switch self {
|
switch self {
|
||||||
case let .texture(texture, timestamp, hasTransparency, rect):
|
case let .texture(texture, timestamp, hasTransparency, rect, scale, offset):
|
||||||
return .texture(texture, timestamp, hasTransparency, rect)
|
return .texture(texture, timestamp, hasTransparency, rect, scale, offset)
|
||||||
case let .videoBuffer(videoBuffer, rect):
|
case let .videoBuffer(videoBuffer, rect, scale, offset):
|
||||||
return .videoBuffer(videoBuffer, rect)
|
return .videoBuffer(videoBuffer, rect, scale, offset)
|
||||||
case let .ciImage(image, timestamp):
|
case let .ciImage(image, timestamp):
|
||||||
return .ciImage(image, timestamp)
|
return .ciImage(image, timestamp)
|
||||||
}
|
}
|
||||||
@ -216,6 +224,8 @@ public func makeEditorImageComposition(context: CIContext, postbox: Postbox, inp
|
|||||||
var maskImage: CIImage?
|
var maskImage: CIImage?
|
||||||
if values.isSticker {
|
if values.isSticker {
|
||||||
maskImage = roundedCornersMaskImage(size: CGSize(width: floor(1080.0 * 0.97), height: floor(1080.0 * 0.97)))
|
maskImage = roundedCornersMaskImage(size: CGSize(width: floor(1080.0 * 0.97), height: floor(1080.0 * 0.97)))
|
||||||
|
} else if let _ = outputDimensions {
|
||||||
|
maskImage = rectangleMaskImage(size: CGSize(width: 1080.0, height: 1080.0))
|
||||||
}
|
}
|
||||||
|
|
||||||
if let drawing = values.drawing, let image = CIImage(image: drawing, options: [.colorSpace: colorSpace]) {
|
if let drawing = values.drawing, let image = CIImage(image: drawing, options: [.colorSpace: colorSpace]) {
|
||||||
@ -285,7 +295,7 @@ private func makeEditorImageFrameComposition(context: CIContext, inputImage: CII
|
|||||||
}
|
}
|
||||||
|
|
||||||
resultImage = resultImage.transformed(by: CGAffineTransform(translationX: dimensions.width / 2.0, y: dimensions.height / 2.0))
|
resultImage = resultImage.transformed(by: CGAffineTransform(translationX: dimensions.width / 2.0, y: dimensions.height / 2.0))
|
||||||
if values.isSticker {
|
if values.isSticker || values.isAvatar {
|
||||||
let minSize = min(dimensions.width, dimensions.height)
|
let minSize = min(dimensions.width, dimensions.height)
|
||||||
let scaledSize = CGSize(width: floor(minSize * 0.97), height: floor(minSize * 0.97))
|
let scaledSize = CGSize(width: floor(minSize * 0.97), height: floor(minSize * 0.97))
|
||||||
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))
|
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))
|
||||||
|
@ -59,15 +59,15 @@ protocol RenderTarget: AnyObject {
|
|||||||
|
|
||||||
final class MediaEditorRenderer {
|
final class MediaEditorRenderer {
|
||||||
enum Input {
|
enum Input {
|
||||||
case texture(MTLTexture, CMTime, Bool, CGRect?)
|
case texture(MTLTexture, CMTime, Bool, CGRect?, CGFloat, CGPoint)
|
||||||
case videoBuffer(VideoPixelBuffer, CGRect?)
|
case videoBuffer(VideoPixelBuffer, CGRect?, CGFloat, CGPoint)
|
||||||
case ciImage(CIImage, CMTime)
|
case ciImage(CIImage, CMTime)
|
||||||
|
|
||||||
var timestamp: CMTime {
|
var timestamp: CMTime {
|
||||||
switch self {
|
switch self {
|
||||||
case let .texture(_, timestamp, _, _):
|
case let .texture(_, timestamp, _, _, _, _):
|
||||||
return timestamp
|
return timestamp
|
||||||
case let .videoBuffer(videoBuffer, _):
|
case let .videoBuffer(videoBuffer, _, _, _):
|
||||||
return videoBuffer.timestamp
|
return videoBuffer.timestamp
|
||||||
case let .ciImage(_, timestamp):
|
case let .ciImage(_, timestamp):
|
||||||
return timestamp
|
return timestamp
|
||||||
@ -193,17 +193,17 @@ final class MediaEditorRenderer {
|
|||||||
|
|
||||||
func textureFromInput(_ input: MediaEditorRenderer.Input, videoInputPass: VideoInputPass) -> VideoFinishPass.Input? {
|
func textureFromInput(_ input: MediaEditorRenderer.Input, videoInputPass: VideoInputPass) -> VideoFinishPass.Input? {
|
||||||
switch input {
|
switch input {
|
||||||
case let .texture(texture, _, hasTransparency, rect):
|
case let .texture(texture, _, hasTransparency, rect, scale, offset):
|
||||||
return VideoFinishPass.Input(texture: texture, hasTransparency: hasTransparency, rect: rect)
|
return VideoFinishPass.Input(texture: texture, hasTransparency: hasTransparency, rect: rect, scale: scale, offset: offset)
|
||||||
case let .videoBuffer(videoBuffer, rect):
|
case let .videoBuffer(videoBuffer, rect, scale, offset):
|
||||||
if let texture = videoInputPass.processPixelBuffer(videoBuffer, textureCache: textureCache, device: device, commandBuffer: commandBuffer) {
|
if let texture = videoInputPass.processPixelBuffer(videoBuffer, textureCache: textureCache, device: device, commandBuffer: commandBuffer) {
|
||||||
return VideoFinishPass.Input(texture: texture, hasTransparency: false, rect: rect)
|
return VideoFinishPass.Input(texture: texture, hasTransparency: false, rect: rect, scale: scale, offset: offset)
|
||||||
} else {
|
} else {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
case let .ciImage(image, _):
|
case let .ciImage(image, _):
|
||||||
if let texture = self.ciInputPass.processCIImage(image, device: device, commandBuffer: commandBuffer) {
|
if let texture = self.ciInputPass.processCIImage(image, device: device, commandBuffer: commandBuffer) {
|
||||||
return VideoFinishPass.Input(texture: texture, hasTransparency: true, rect: nil)
|
return VideoFinishPass.Input(texture: texture, hasTransparency: true, rect: nil, scale: 1.0, offset: .zero)
|
||||||
} else {
|
} else {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -418,6 +418,8 @@ public final class MediaEditorValues: Codable, Equatable {
|
|||||||
case contentValue
|
case contentValue
|
||||||
case isVideo
|
case isVideo
|
||||||
case frame
|
case frame
|
||||||
|
case contentScale
|
||||||
|
case contentOffset
|
||||||
case videoTrimRange
|
case videoTrimRange
|
||||||
case videoOffset
|
case videoOffset
|
||||||
case videoVolume
|
case videoVolume
|
||||||
@ -441,6 +443,8 @@ public final class MediaEditorValues: Codable, Equatable {
|
|||||||
|
|
||||||
public let content: Content
|
public let content: Content
|
||||||
public let frame: CGRect
|
public let frame: CGRect
|
||||||
|
public let contentScale: CGFloat
|
||||||
|
public let contentOffset: CGPoint
|
||||||
|
|
||||||
public let videoTrimRange: Range<Double>?
|
public let videoTrimRange: Range<Double>?
|
||||||
public let videoOffset: Double?
|
public let videoOffset: Double?
|
||||||
@ -449,12 +453,16 @@ public final class MediaEditorValues: Codable, Equatable {
|
|||||||
public init(
|
public init(
|
||||||
content: Content,
|
content: Content,
|
||||||
frame: CGRect,
|
frame: CGRect,
|
||||||
|
contentScale: CGFloat,
|
||||||
|
contentOffset: CGPoint,
|
||||||
videoTrimRange: Range<Double>?,
|
videoTrimRange: Range<Double>?,
|
||||||
videoOffset: Double?,
|
videoOffset: Double?,
|
||||||
videoVolume: CGFloat?
|
videoVolume: CGFloat?
|
||||||
) {
|
) {
|
||||||
self.content = content
|
self.content = content
|
||||||
self.frame = frame
|
self.frame = frame
|
||||||
|
self.contentScale = contentScale
|
||||||
|
self.contentOffset = contentOffset
|
||||||
self.videoTrimRange = videoTrimRange
|
self.videoTrimRange = videoTrimRange
|
||||||
self.videoOffset = videoOffset
|
self.videoOffset = videoOffset
|
||||||
self.videoVolume = videoVolume
|
self.videoVolume = videoVolume
|
||||||
@ -475,6 +483,10 @@ public final class MediaEditorValues: Codable, Equatable {
|
|||||||
throw DecodingError.generic
|
throw DecodingError.generic
|
||||||
}
|
}
|
||||||
self.frame = try container.decode(CGRect.self, forKey: .frame)
|
self.frame = try container.decode(CGRect.self, forKey: .frame)
|
||||||
|
|
||||||
|
self.contentScale = try container.decodeIfPresent(CGFloat.self, forKey: .contentScale) ?? 1.0
|
||||||
|
self.contentOffset = try container.decodeIfPresent(CGPoint.self, forKey: .contentOffset) ?? .zero
|
||||||
|
|
||||||
self.videoTrimRange = try container.decodeIfPresent(Range<Double>.self, forKey: .videoTrimRange)
|
self.videoTrimRange = try container.decodeIfPresent(Range<Double>.self, forKey: .videoTrimRange)
|
||||||
self.videoOffset = try container.decodeIfPresent(Double.self, forKey: .videoOffset)
|
self.videoOffset = try container.decodeIfPresent(Double.self, forKey: .videoOffset)
|
||||||
self.videoVolume = try container.decodeIfPresent(CGFloat.self, forKey: .videoVolume)
|
self.videoVolume = try container.decodeIfPresent(CGFloat.self, forKey: .videoVolume)
|
||||||
@ -497,6 +509,8 @@ public final class MediaEditorValues: Codable, Equatable {
|
|||||||
try container.encode(isVideo, forKey: .isVideo)
|
try container.encode(isVideo, forKey: .isVideo)
|
||||||
}
|
}
|
||||||
try container.encode(self.frame, forKey: .frame)
|
try container.encode(self.frame, forKey: .frame)
|
||||||
|
try container.encode(self.contentScale, forKey: .contentScale)
|
||||||
|
try container.encode(self.contentOffset, forKey: .contentOffset)
|
||||||
try container.encodeIfPresent(self.videoTrimRange, forKey: .videoTrimRange)
|
try container.encodeIfPresent(self.videoTrimRange, forKey: .videoTrimRange)
|
||||||
try container.encodeIfPresent(self.videoOffset, forKey: .videoOffset)
|
try container.encodeIfPresent(self.videoOffset, forKey: .videoOffset)
|
||||||
try container.encodeIfPresent(self.videoVolume, forKey: .videoVolume)
|
try container.encodeIfPresent(self.videoVolume, forKey: .videoVolume)
|
||||||
@ -506,6 +520,8 @@ public final class MediaEditorValues: Codable, Equatable {
|
|||||||
return VideoCollageItem(
|
return VideoCollageItem(
|
||||||
content: self.content,
|
content: self.content,
|
||||||
frame: self.frame,
|
frame: self.frame,
|
||||||
|
contentScale: self.contentScale,
|
||||||
|
contentOffset: self.contentOffset,
|
||||||
videoTrimRange: videoTrimRange,
|
videoTrimRange: videoTrimRange,
|
||||||
videoOffset: self.videoOffset,
|
videoOffset: self.videoOffset,
|
||||||
videoVolume: self.videoVolume
|
videoVolume: self.videoVolume
|
||||||
@ -516,6 +532,8 @@ public final class MediaEditorValues: Codable, Equatable {
|
|||||||
return VideoCollageItem(
|
return VideoCollageItem(
|
||||||
content: self.content,
|
content: self.content,
|
||||||
frame: self.frame,
|
frame: self.frame,
|
||||||
|
contentScale: self.contentScale,
|
||||||
|
contentOffset: self.contentOffset,
|
||||||
videoTrimRange: self.videoTrimRange,
|
videoTrimRange: self.videoTrimRange,
|
||||||
videoOffset: videoOffset,
|
videoOffset: videoOffset,
|
||||||
videoVolume: self.videoVolume
|
videoVolume: self.videoVolume
|
||||||
@ -526,6 +544,8 @@ public final class MediaEditorValues: Codable, Equatable {
|
|||||||
return VideoCollageItem(
|
return VideoCollageItem(
|
||||||
content: self.content,
|
content: self.content,
|
||||||
frame: self.frame,
|
frame: self.frame,
|
||||||
|
contentScale: self.contentScale,
|
||||||
|
contentOffset: self.contentOffset,
|
||||||
videoTrimRange: self.videoTrimRange,
|
videoTrimRange: self.videoTrimRange,
|
||||||
videoOffset: self.videoOffset,
|
videoOffset: self.videoOffset,
|
||||||
videoVolume: videoVolume
|
videoVolume: videoVolume
|
||||||
@ -590,6 +610,10 @@ public final class MediaEditorValues: Codable, Equatable {
|
|||||||
return self.qualityPreset == .sticker
|
return self.qualityPreset == .sticker
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var isAvatar: Bool {
|
||||||
|
return [.profile].contains(self.qualityPreset)
|
||||||
|
}
|
||||||
|
|
||||||
public var cropValues: (offset: CGPoint, rotation: CGFloat, scale: CGFloat) {
|
public var cropValues: (offset: CGPoint, rotation: CGFloat, scale: CGFloat) {
|
||||||
return (self.cropOffset, self.cropRotation, self.cropScale)
|
return (self.cropOffset, self.cropRotation, self.cropScale)
|
||||||
}
|
}
|
||||||
|
@ -184,9 +184,12 @@ public final class MediaEditorVideoExport {
|
|||||||
private var reader: AVAssetReader?
|
private var reader: AVAssetReader?
|
||||||
private var videoOutput: AVAssetReaderOutput?
|
private var videoOutput: AVAssetReaderOutput?
|
||||||
private var textureRotation: TextureRotation = .rotate0Degrees
|
private var textureRotation: TextureRotation = .rotate0Degrees
|
||||||
private var videoRect: CGRect?
|
|
||||||
private var frameRate: Float?
|
private var frameRate: Float?
|
||||||
|
|
||||||
|
private var mainVideoRect: CGRect?
|
||||||
|
private var mainVideoScale: CGFloat = 1.0
|
||||||
|
private var mainVideoOffset: CGPoint = .zero
|
||||||
|
|
||||||
class VideoOutput {
|
class VideoOutput {
|
||||||
enum Output {
|
enum Output {
|
||||||
case videoOutput(AVAssetReaderOutput)
|
case videoOutput(AVAssetReaderOutput)
|
||||||
@ -194,6 +197,8 @@ public final class MediaEditorVideoExport {
|
|||||||
}
|
}
|
||||||
let output: Output
|
let output: Output
|
||||||
let rect: CGRect?
|
let rect: CGRect?
|
||||||
|
let scale: CGFloat
|
||||||
|
let offset: CGPoint
|
||||||
let textureRotation: TextureRotation
|
let textureRotation: TextureRotation
|
||||||
let duration: Double
|
let duration: Double
|
||||||
let frameRate: Float
|
let frameRate: Float
|
||||||
@ -202,6 +207,8 @@ public final class MediaEditorVideoExport {
|
|||||||
init(
|
init(
|
||||||
output: Output,
|
output: Output,
|
||||||
rect: CGRect?,
|
rect: CGRect?,
|
||||||
|
scale: CGFloat,
|
||||||
|
offset: CGPoint,
|
||||||
textureRotation: TextureRotation,
|
textureRotation: TextureRotation,
|
||||||
duration: Double,
|
duration: Double,
|
||||||
frameRate: Float,
|
frameRate: Float,
|
||||||
@ -209,6 +216,8 @@ public final class MediaEditorVideoExport {
|
|||||||
) {
|
) {
|
||||||
self.output = output
|
self.output = output
|
||||||
self.rect = rect
|
self.rect = rect
|
||||||
|
self.scale = scale
|
||||||
|
self.offset = offset
|
||||||
self.textureRotation = textureRotation
|
self.textureRotation = textureRotation
|
||||||
self.duration = duration
|
self.duration = duration
|
||||||
self.frameRate = frameRate
|
self.frameRate = frameRate
|
||||||
@ -275,8 +284,8 @@ public final class MediaEditorVideoExport {
|
|||||||
}
|
}
|
||||||
|
|
||||||
enum Input {
|
enum Input {
|
||||||
case image(image: UIImage, rect: CGRect?)
|
case image(image: UIImage, rect: CGRect?, scale: CGFloat, offset: CGPoint)
|
||||||
case video(asset: AVAsset, rect: CGRect?, rotation: TextureRotation, duration: Double, trimRange: Range<Double>?, offset: Double?, volume: CGFloat?)
|
case video(asset: AVAsset, rect: CGRect?, scale: CGFloat, offset: CGPoint, rotation: TextureRotation, duration: Double, trimRange: Range<Double>?, trimOffset: Double?, volume: CGFloat?)
|
||||||
case sticker(TelegramMediaFile)
|
case sticker(TelegramMediaFile)
|
||||||
|
|
||||||
var isVideo: Bool {
|
var isVideo: Bool {
|
||||||
@ -293,19 +302,23 @@ public final class MediaEditorVideoExport {
|
|||||||
var signals: [Signal<Input, NoError>] = []
|
var signals: [Signal<Input, NoError>] = []
|
||||||
|
|
||||||
var mainRect: CGRect?
|
var mainRect: CGRect?
|
||||||
|
var mainScale: CGFloat = 1.0
|
||||||
|
var mainOffset: CGPoint = .zero
|
||||||
var additionalAsset: AVAsset?
|
var additionalAsset: AVAsset?
|
||||||
if !self.configuration.values.collage.isEmpty {
|
if !self.configuration.values.collage.isEmpty {
|
||||||
for item in self.configuration.values.collage {
|
for item in self.configuration.values.collage {
|
||||||
switch item.content {
|
switch item.content {
|
||||||
case .main:
|
case .main:
|
||||||
mainRect = item.frame
|
mainRect = item.frame
|
||||||
|
mainScale = item.contentScale
|
||||||
|
mainOffset = item.contentOffset
|
||||||
case let .imageFile(path):
|
case let .imageFile(path):
|
||||||
if let image = UIImage(contentsOfFile: path) {
|
if let image = UIImage(contentsOfFile: path) {
|
||||||
signals.append(.single(.image(image: image, rect: item.frame)))
|
signals.append(.single(.image(image: image, rect: item.frame, scale: item.contentScale, offset: item.contentOffset)))
|
||||||
}
|
}
|
||||||
case let .videoFile(path):
|
case let .videoFile(path):
|
||||||
let asset = AVURLAsset(url: URL(fileURLWithPath: path))
|
let asset = AVURLAsset(url: URL(fileURLWithPath: path))
|
||||||
signals.append(.single(.video(asset: asset, rect: item.frame, rotation: textureRotatonForAVAsset(asset, mirror: false), duration: asset.duration.seconds, trimRange: item.videoTrimRange, offset: item.videoOffset, volume: item.videoVolume)))
|
signals.append(.single(.video(asset: asset, rect: item.frame, scale: item.contentScale, offset: item.contentOffset, rotation: textureRotatonForAVAsset(asset, mirror: false), duration: asset.duration.seconds, trimRange: item.videoTrimRange, trimOffset: item.videoOffset, volume: item.videoVolume)))
|
||||||
case let .asset(localIdentifier, _):
|
case let .asset(localIdentifier, _):
|
||||||
let fetchResult = PHAsset.fetchAssets(withLocalIdentifiers: [localIdentifier], options: nil)
|
let fetchResult = PHAsset.fetchAssets(withLocalIdentifiers: [localIdentifier], options: nil)
|
||||||
if fetchResult.count != 0 {
|
if fetchResult.count != 0 {
|
||||||
@ -321,7 +334,7 @@ public final class MediaEditorVideoExport {
|
|||||||
subscriber.putCompletion()
|
subscriber.putCompletion()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
subscriber.putNext(.video(asset: avAsset, rect: item.frame, rotation: textureRotatonForAVAsset(avAsset, mirror: false), duration: avAsset.duration.seconds, trimRange: item.videoTrimRange, offset: item.videoOffset, volume: item.videoVolume))
|
subscriber.putNext(.video(asset: avAsset, rect: item.frame, scale: item.contentScale, offset: item.contentOffset, rotation: textureRotatonForAVAsset(avAsset, mirror: false), duration: avAsset.duration.seconds, trimRange: item.videoTrimRange, trimOffset: item.videoOffset, volume: item.videoVolume))
|
||||||
subscriber.putCompletion()
|
subscriber.putCompletion()
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -335,7 +348,7 @@ public final class MediaEditorVideoExport {
|
|||||||
} else if let additionalPath = self.configuration.values.additionalVideoPath {
|
} else if let additionalPath = self.configuration.values.additionalVideoPath {
|
||||||
let asset = AVURLAsset(url: URL(fileURLWithPath: additionalPath))
|
let asset = AVURLAsset(url: URL(fileURLWithPath: additionalPath))
|
||||||
additionalAsset = asset
|
additionalAsset = asset
|
||||||
signals = [.single(.video(asset: asset, rect: nil, rotation: textureRotatonForAVAsset(asset, mirror: true), duration: asset.duration.seconds, trimRange: nil, offset: nil, volume: nil))]
|
signals = [.single(.video(asset: asset, rect: nil, scale: 1.0, offset: .zero, rotation: textureRotatonForAVAsset(asset, mirror: true), duration: asset.duration.seconds, trimRange: nil, trimOffset: nil, volume: nil))]
|
||||||
}
|
}
|
||||||
|
|
||||||
var audioAsset: AVAsset?
|
var audioAsset: AVAsset?
|
||||||
@ -349,10 +362,10 @@ public final class MediaEditorVideoExport {
|
|||||||
switch self.subject {
|
switch self.subject {
|
||||||
case let .video(asset, isStoryValue):
|
case let .video(asset, isStoryValue):
|
||||||
mainAsset = asset
|
mainAsset = asset
|
||||||
mainInput = .video(asset: asset, rect: mainRect, rotation: textureRotatonForAVAsset(asset), duration: asset.duration.seconds, trimRange: nil, offset: nil, volume: nil)
|
mainInput = .video(asset: asset, rect: mainRect, scale: mainScale, offset: mainOffset, rotation: textureRotatonForAVAsset(asset), duration: asset.duration.seconds, trimRange: nil, trimOffset: nil, volume: nil)
|
||||||
isStory = isStoryValue
|
isStory = isStoryValue
|
||||||
case let .image(image):
|
case let .image(image):
|
||||||
mainInput = .image(image: image, rect: nil)
|
mainInput = .image(image: image, rect: nil, scale: 1.0, offset: .zero)
|
||||||
case let .sticker(file):
|
case let .sticker(file):
|
||||||
mainInput = .sticker(file)
|
mainInput = .sticker(file)
|
||||||
}
|
}
|
||||||
@ -436,8 +449,8 @@ public final class MediaEditorVideoExport {
|
|||||||
}
|
}
|
||||||
|
|
||||||
enum AdditionalTrack {
|
enum AdditionalTrack {
|
||||||
case image(image: UIImage, rect: CGRect?)
|
case image(image: UIImage, rect: CGRect?, scale: CGFloat, offset: CGPoint)
|
||||||
case video(track: AVMutableCompositionTrack, rect: CGRect?, rotation: TextureRotation, duration: Double, frameRate: Float, startTime: CMTime?)
|
case video(track: AVMutableCompositionTrack, rect: CGRect?, scale: CGFloat, offset: CGPoint, rotation: TextureRotation, duration: Double, frameRate: Float, startTime: CMTime?)
|
||||||
}
|
}
|
||||||
|
|
||||||
func frameRate(for track: AVCompositionTrack) -> Float {
|
func frameRate(for track: AVCompositionTrack) -> Float {
|
||||||
@ -471,8 +484,10 @@ public final class MediaEditorVideoExport {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var readerRange = wholeRange
|
var readerRange = wholeRange
|
||||||
if case let .video(asset, rect, rotation, _, _, _, _) = main {
|
if case let .video(asset, rect, scale, offset, rotation, _, _, _, _) = main {
|
||||||
self.videoRect = rect
|
self.mainVideoRect = rect
|
||||||
|
self.mainVideoScale = scale
|
||||||
|
self.mainVideoOffset = offset
|
||||||
self.textureRotation = rotation
|
self.textureRotation = rotation
|
||||||
if let videoAssetTrack = asset.tracks(withMediaType: .video).first {
|
if let videoAssetTrack = asset.tracks(withMediaType: .video).first {
|
||||||
if let compositionTrack = composition?.addMutableTrack(withMediaType: .video, preferredTrackID: kCMPersistentTrackID_Invalid) {
|
if let compositionTrack = composition?.addMutableTrack(withMediaType: .video, preferredTrackID: kCMPersistentTrackID_Invalid) {
|
||||||
@ -502,15 +517,15 @@ public final class MediaEditorVideoExport {
|
|||||||
if !self.configuration.values.collage.isEmpty {
|
if !self.configuration.values.collage.isEmpty {
|
||||||
for input in additional {
|
for input in additional {
|
||||||
switch input {
|
switch input {
|
||||||
case let .image(image, rect):
|
case let .image(image, rect, scale, offset):
|
||||||
additionalTracks.append(.image(image: image, rect: rect))
|
additionalTracks.append(.image(image: image, rect: rect, scale: scale, offset: offset))
|
||||||
case let .video(asset, rect, rotation, duration, trimRange, offset, volume):
|
case let .video(asset, rect, scale, offset, rotation, duration, trimRange, trimOffset, volume):
|
||||||
let startTime = videoStartTime(trimRange: trimRange, offset: offset)
|
let startTime = videoStartTime(trimRange: trimRange, offset: trimOffset)
|
||||||
let timeRange = clampedRange(trackDuration: asset.duration, trackTrimRange: videoTimeRange(trimRange: trimRange), trackStart: startTime, maxDuration: readerRange.end)
|
let timeRange = clampedRange(trackDuration: asset.duration, trackTrimRange: videoTimeRange(trimRange: trimRange), trackStart: startTime, maxDuration: readerRange.end)
|
||||||
|
|
||||||
if let videoAssetTrack = asset.tracks(withMediaType: .video).first {
|
if let videoAssetTrack = asset.tracks(withMediaType: .video).first {
|
||||||
if let compositionTrack = composition?.addMutableTrack(withMediaType: .video, preferredTrackID: kCMPersistentTrackID_Invalid) {
|
if let compositionTrack = composition?.addMutableTrack(withMediaType: .video, preferredTrackID: kCMPersistentTrackID_Invalid) {
|
||||||
additionalTracks.append(.video(track: compositionTrack, rect: rect, rotation: rotation, duration: duration, frameRate: frameRate(for: compositionTrack), startTime: startTime))
|
additionalTracks.append(.video(track: compositionTrack, rect: rect, scale: scale, offset: offset, rotation: rotation, duration: duration, frameRate: frameRate(for: compositionTrack), startTime: startTime))
|
||||||
|
|
||||||
compositionTrack.preferredTransform = videoAssetTrack.preferredTransform
|
compositionTrack.preferredTransform = videoAssetTrack.preferredTransform
|
||||||
|
|
||||||
@ -533,7 +548,7 @@ public final class MediaEditorVideoExport {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if let additional = additional.first, case let .video(asset, _, rotation, duration, _, _, _) = additional {
|
} else if let additional = additional.first, case let .video(asset, _, _, _, rotation, duration, _, _, _) = additional {
|
||||||
let startTime: CMTime
|
let startTime: CMTime
|
||||||
let timeRange: CMTimeRange
|
let timeRange: CMTimeRange
|
||||||
if mainVideoTrack == nil {
|
if mainVideoTrack == nil {
|
||||||
@ -546,7 +561,7 @@ public final class MediaEditorVideoExport {
|
|||||||
|
|
||||||
if let videoAssetTrack = asset.tracks(withMediaType: .video).first {
|
if let videoAssetTrack = asset.tracks(withMediaType: .video).first {
|
||||||
if let compositionTrack = composition?.addMutableTrack(withMediaType: .video, preferredTrackID: kCMPersistentTrackID_Invalid) {
|
if let compositionTrack = composition?.addMutableTrack(withMediaType: .video, preferredTrackID: kCMPersistentTrackID_Invalid) {
|
||||||
additionalTracks.append(.video(track: compositionTrack, rect: nil, rotation: rotation, duration: duration, frameRate: frameRate(for: compositionTrack), startTime: self.configuration.additionalVideoStartTime))
|
additionalTracks.append(.video(track: compositionTrack, rect: nil, scale: 1.0, offset: .zero, rotation: rotation, duration: duration, frameRate: frameRate(for: compositionTrack), startTime: self.configuration.additionalVideoStartTime))
|
||||||
|
|
||||||
compositionTrack.preferredTransform = videoAssetTrack.preferredTransform
|
compositionTrack.preferredTransform = videoAssetTrack.preferredTransform
|
||||||
|
|
||||||
@ -644,16 +659,18 @@ public final class MediaEditorVideoExport {
|
|||||||
var additionalIndex = 0
|
var additionalIndex = 0
|
||||||
for track in additionalTracks {
|
for track in additionalTracks {
|
||||||
switch track {
|
switch track {
|
||||||
case let .image(image, rect):
|
case let .image(image, rect, scale, offset):
|
||||||
self.additionalVideoOutput[additionalIndex] = VideoOutput(
|
self.additionalVideoOutput[additionalIndex] = VideoOutput(
|
||||||
output: .image(image),
|
output: .image(image),
|
||||||
rect: rect,
|
rect: rect,
|
||||||
|
scale: scale,
|
||||||
|
offset: offset,
|
||||||
textureRotation: .rotate0Degrees,
|
textureRotation: .rotate0Degrees,
|
||||||
duration: 0.0,
|
duration: 0.0,
|
||||||
frameRate: 0.0,
|
frameRate: 0.0,
|
||||||
startTime: .zero
|
startTime: .zero
|
||||||
)
|
)
|
||||||
case let .video(track, rect, rotation, duration, frameRate, startTime):
|
case let .video(track, rect, scale, offset, rotation, duration, frameRate, startTime):
|
||||||
let videoOutput = AVAssetReaderTrackOutput(track: track, outputSettings: outputSettings)
|
let videoOutput = AVAssetReaderTrackOutput(track: track, outputSettings: outputSettings)
|
||||||
videoOutput.alwaysCopiesSampleData = true
|
videoOutput.alwaysCopiesSampleData = true
|
||||||
if reader.canAdd(videoOutput) {
|
if reader.canAdd(videoOutput) {
|
||||||
@ -666,6 +683,8 @@ public final class MediaEditorVideoExport {
|
|||||||
self.additionalVideoOutput[additionalIndex] = VideoOutput(
|
self.additionalVideoOutput[additionalIndex] = VideoOutput(
|
||||||
output: .videoOutput(videoOutput),
|
output: .videoOutput(videoOutput),
|
||||||
rect: rect,
|
rect: rect,
|
||||||
|
scale: scale,
|
||||||
|
offset: offset,
|
||||||
textureRotation: rotation,
|
textureRotation: rotation,
|
||||||
duration: duration,
|
duration: duration,
|
||||||
frameRate: frameRate,
|
frameRate: frameRate,
|
||||||
@ -740,11 +759,16 @@ public final class MediaEditorVideoExport {
|
|||||||
if let pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer) {
|
if let pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer) {
|
||||||
let timestamp = CMSampleBufferGetPresentationTimeStamp(sampleBuffer)
|
let timestamp = CMSampleBufferGetPresentationTimeStamp(sampleBuffer)
|
||||||
mainTimestamp = timestamp
|
mainTimestamp = timestamp
|
||||||
mainInput = .videoBuffer(VideoPixelBuffer(
|
mainInput = .videoBuffer(
|
||||||
pixelBuffer: pixelBuffer,
|
VideoPixelBuffer(
|
||||||
rotation: self.textureRotation,
|
pixelBuffer: pixelBuffer,
|
||||||
timestamp: timestamp
|
rotation: self.textureRotation,
|
||||||
), self.videoRect)
|
timestamp: timestamp
|
||||||
|
),
|
||||||
|
self.mainVideoRect,
|
||||||
|
self.mainVideoScale,
|
||||||
|
self.mainVideoOffset
|
||||||
|
)
|
||||||
|
|
||||||
if let duration = self.durationValue {
|
if let duration = self.durationValue {
|
||||||
let startTime = self.reader?.timeRange.start.seconds ?? 0.0
|
let startTime = self.reader?.timeRange.start.seconds ?? 0.0
|
||||||
@ -767,11 +791,18 @@ public final class MediaEditorVideoExport {
|
|||||||
if case let .videoOutput(videoOutput) = additionalVideoOutput.output {
|
if case let .videoOutput(videoOutput) = additionalVideoOutput.output {
|
||||||
if let _ = videoOutput.copyNextSampleBuffer(), let sampleBuffer = videoOutput.copyNextSampleBuffer() {
|
if let _ = videoOutput.copyNextSampleBuffer(), let sampleBuffer = videoOutput.copyNextSampleBuffer() {
|
||||||
if let pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer) {
|
if let pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer) {
|
||||||
additionalInput.append(.videoBuffer(VideoPixelBuffer(
|
additionalInput.append(
|
||||||
pixelBuffer: pixelBuffer,
|
.videoBuffer(
|
||||||
rotation: additionalVideoOutput.textureRotation,
|
VideoPixelBuffer(
|
||||||
timestamp: .zero
|
pixelBuffer: pixelBuffer,
|
||||||
), additionalVideoOutput.rect))
|
rotation: additionalVideoOutput.textureRotation,
|
||||||
|
timestamp: .zero
|
||||||
|
),
|
||||||
|
additionalVideoOutput.rect,
|
||||||
|
additionalVideoOutput.scale,
|
||||||
|
additionalVideoOutput.offset
|
||||||
|
)
|
||||||
|
)
|
||||||
} else {
|
} else {
|
||||||
additionalInput.append(nil)
|
additionalInput.append(nil)
|
||||||
}
|
}
|
||||||
@ -792,17 +823,33 @@ public final class MediaEditorVideoExport {
|
|||||||
switch additionalVideoOutput.output {
|
switch additionalVideoOutput.output {
|
||||||
case let .image(image):
|
case let .image(image):
|
||||||
if let texture = self.composer?.textureForImage(index: i, image: image) {
|
if let texture = self.composer?.textureForImage(index: i, image: image) {
|
||||||
additionalInput.append(.texture(texture, .zero, false, additionalVideoOutput.rect))
|
additionalInput.append(
|
||||||
|
.texture(
|
||||||
|
texture,
|
||||||
|
.zero,
|
||||||
|
false,
|
||||||
|
additionalVideoOutput.rect,
|
||||||
|
additionalVideoOutput.scale,
|
||||||
|
additionalVideoOutput.offset
|
||||||
|
)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
case let .videoOutput(videoOutput):
|
case let .videoOutput(videoOutput):
|
||||||
if let sampleBuffer = videoOutput.copyNextSampleBuffer() {
|
if let sampleBuffer = videoOutput.copyNextSampleBuffer() {
|
||||||
if let pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer) {
|
if let pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer) {
|
||||||
let timestamp = CMSampleBufferGetPresentationTimeStamp(sampleBuffer)
|
let timestamp = CMSampleBufferGetPresentationTimeStamp(sampleBuffer)
|
||||||
additionalInput.append(.videoBuffer(VideoPixelBuffer(
|
additionalInput.append(
|
||||||
pixelBuffer: pixelBuffer,
|
.videoBuffer(
|
||||||
rotation: additionalVideoOutput.textureRotation,
|
VideoPixelBuffer(
|
||||||
timestamp: timestamp
|
pixelBuffer: pixelBuffer,
|
||||||
), additionalVideoOutput.rect))
|
rotation: additionalVideoOutput.textureRotation,
|
||||||
|
timestamp: timestamp
|
||||||
|
),
|
||||||
|
additionalVideoOutput.rect,
|
||||||
|
additionalVideoOutput.scale,
|
||||||
|
additionalVideoOutput.offset
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
if !updatedProgress, let duration = self.durationValue {
|
if !updatedProgress, let duration = self.durationValue {
|
||||||
let startTime = self.reader?.timeRange.start.seconds ?? 0.0
|
let startTime = self.reader?.timeRange.start.seconds ?? 0.0
|
||||||
@ -830,7 +877,7 @@ public final class MediaEditorVideoExport {
|
|||||||
|
|
||||||
|
|
||||||
if case let .image(image) = self.subject, let texture = self.composer?.textureForImage(index: -1, image: image) {
|
if case let .image(image) = self.subject, let texture = self.composer?.textureForImage(index: -1, image: image) {
|
||||||
mainInput = .texture(texture, self.imageArguments?.position ?? .zero, imageHasTransparency(image), nil)
|
mainInput = .texture(texture, self.imageArguments?.position ?? .zero, imageHasTransparency(image), nil, 1.0, .zero)
|
||||||
|
|
||||||
if !updatedProgress, let imageArguments = self.imageArguments, let duration = self.durationValue {
|
if !updatedProgress, let imageArguments = self.imageArguments, let duration = self.durationValue {
|
||||||
let progress = imageArguments.position.seconds / duration.seconds
|
let progress = imageArguments.position.seconds / duration.seconds
|
||||||
|
@ -7,8 +7,8 @@ import SwiftSignalKit
|
|||||||
|
|
||||||
final class UniversalTextureSource: TextureSource {
|
final class UniversalTextureSource: TextureSource {
|
||||||
enum Input {
|
enum Input {
|
||||||
case image(UIImage, CGRect?)
|
case image(UIImage, CGRect?, CGFloat, CGPoint)
|
||||||
case video(AVPlayerItem, CGRect?)
|
case video(AVPlayerItem, CGRect?, CGFloat, CGPoint)
|
||||||
case entity(MediaEditorComposerEntity)
|
case entity(MediaEditorComposerEntity)
|
||||||
|
|
||||||
fileprivate func createContext(renderTarget: RenderTarget, queue: DispatchQueue, additional: Bool) -> InputContext {
|
fileprivate func createContext(renderTarget: RenderTarget, queue: DispatchQueue, additional: Bool) -> InputContext {
|
||||||
@ -48,7 +48,7 @@ final class UniversalTextureSource: TextureSource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var mainImage: UIImage? {
|
var mainImage: UIImage? {
|
||||||
if let mainInput = self.mainInputContext?.input, case let .image(image, _) = mainInput {
|
if let mainInput = self.mainInputContext?.input, case let .image(image, _, _, _) = mainInput {
|
||||||
return image
|
return image
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@ -208,13 +208,17 @@ private class ImageInputContext: InputContext {
|
|||||||
private var texture: MTLTexture?
|
private var texture: MTLTexture?
|
||||||
private var hasTransparency = false
|
private var hasTransparency = false
|
||||||
fileprivate var rect: CGRect?
|
fileprivate var rect: CGRect?
|
||||||
|
fileprivate var scale: CGFloat
|
||||||
|
fileprivate var offset: CGPoint
|
||||||
|
|
||||||
init(input: Input, renderTarget: RenderTarget, queue: DispatchQueue) {
|
init(input: Input, renderTarget: RenderTarget, queue: DispatchQueue) {
|
||||||
guard case let .image(image, rect) = input else {
|
guard case let .image(image, rect, scale, offset) = input else {
|
||||||
fatalError()
|
fatalError()
|
||||||
}
|
}
|
||||||
self.input = input
|
self.input = input
|
||||||
self.rect = rect
|
self.rect = rect
|
||||||
|
self.scale = scale
|
||||||
|
self.offset = offset
|
||||||
if let device = renderTarget.mtlDevice {
|
if let device = renderTarget.mtlDevice {
|
||||||
self.texture = loadTexture(image: image, device: device)
|
self.texture = loadTexture(image: image, device: device)
|
||||||
}
|
}
|
||||||
@ -222,7 +226,7 @@ private class ImageInputContext: InputContext {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func output(time: Double) -> Output? {
|
func output(time: Double) -> Output? {
|
||||||
return self.texture.flatMap { .texture($0, .zero, self.hasTransparency, self.rect) }
|
return self.texture.flatMap { .texture($0, .zero, self.hasTransparency, self.rect, self.scale, self.offset) }
|
||||||
}
|
}
|
||||||
|
|
||||||
func invalidate() {
|
func invalidate() {
|
||||||
@ -239,20 +243,24 @@ private class VideoInputContext: NSObject, InputContext, AVPlayerItemOutputPullD
|
|||||||
private var videoOutput: AVPlayerItemVideoOutput?
|
private var videoOutput: AVPlayerItemVideoOutput?
|
||||||
private var textureRotation: TextureRotation = .rotate0Degrees
|
private var textureRotation: TextureRotation = .rotate0Degrees
|
||||||
fileprivate var rect: CGRect?
|
fileprivate var rect: CGRect?
|
||||||
|
fileprivate var scale: CGFloat
|
||||||
|
fileprivate var offset: CGPoint
|
||||||
|
|
||||||
var playerItem: AVPlayerItem {
|
var playerItem: AVPlayerItem {
|
||||||
guard case let .video(playerItem, _) = self.input else {
|
guard case let .video(playerItem, _, _, _) = self.input else {
|
||||||
fatalError()
|
fatalError()
|
||||||
}
|
}
|
||||||
return playerItem
|
return playerItem
|
||||||
}
|
}
|
||||||
|
|
||||||
init(input: Input, renderTarget: RenderTarget, queue: DispatchQueue, additional: Bool) {
|
init(input: Input, renderTarget: RenderTarget, queue: DispatchQueue, additional: Bool) {
|
||||||
guard case let .video(_, rect) = input else {
|
guard case let .video(_, rect, scale, offset) = input else {
|
||||||
fatalError()
|
fatalError()
|
||||||
}
|
}
|
||||||
self.input = input
|
self.input = input
|
||||||
self.rect = rect
|
self.rect = rect
|
||||||
|
self.scale = scale
|
||||||
|
self.offset = offset
|
||||||
|
|
||||||
super.init()
|
super.init()
|
||||||
|
|
||||||
@ -291,7 +299,7 @@ private class VideoInputContext: NSObject, InputContext, AVPlayerItemOutputPullD
|
|||||||
if let pixelBuffer = videoOutput.copyPixelBuffer(forItemTime: requestTime, itemTimeForDisplay: &presentationTime) {
|
if let pixelBuffer = videoOutput.copyPixelBuffer(forItemTime: requestTime, itemTimeForDisplay: &presentationTime) {
|
||||||
videoPixelBuffer = VideoPixelBuffer(pixelBuffer: pixelBuffer, rotation: self.textureRotation, timestamp: presentationTime)
|
videoPixelBuffer = VideoPixelBuffer(pixelBuffer: pixelBuffer, rotation: self.textureRotation, timestamp: presentationTime)
|
||||||
}
|
}
|
||||||
return videoPixelBuffer.flatMap { .videoBuffer($0, self.rect) }
|
return videoPixelBuffer.flatMap { .videoBuffer($0, self.rect, self.scale, self.offset) }
|
||||||
}
|
}
|
||||||
|
|
||||||
func invalidate() {
|
func invalidate() {
|
||||||
|
@ -10,12 +10,13 @@ private func verticesData(
|
|||||||
position: CGPoint,
|
position: CGPoint,
|
||||||
size: CGSize,
|
size: CGSize,
|
||||||
rotation: CGFloat,
|
rotation: CGFloat,
|
||||||
|
mirror: Bool = false,
|
||||||
z: Float = 0.0
|
z: Float = 0.0
|
||||||
) -> [VertexData] {
|
) -> [VertexData] {
|
||||||
let topLeft: simd_float2
|
var topLeft: simd_float2
|
||||||
let topRight: simd_float2
|
var topRight: simd_float2
|
||||||
let bottomLeft: simd_float2
|
var bottomLeft: simd_float2
|
||||||
let bottomRight: simd_float2
|
var bottomRight: simd_float2
|
||||||
|
|
||||||
switch textureRotation {
|
switch textureRotation {
|
||||||
case .rotate0Degrees:
|
case .rotate0Degrees:
|
||||||
@ -50,6 +51,13 @@ private func verticesData(
|
|||||||
bottomRight = simd_float2(1.0, 1.0)
|
bottomRight = simd_float2(1.0, 1.0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if mirror {
|
||||||
|
topLeft = simd_float2(1.0 - topLeft.x, topLeft.y)
|
||||||
|
topRight = simd_float2(1.0 - topRight.x, topRight.y)
|
||||||
|
bottomLeft = simd_float2(1.0 - bottomLeft.x, bottomLeft.y)
|
||||||
|
bottomRight = simd_float2(1.0 - bottomRight.x, bottomRight.y)
|
||||||
|
}
|
||||||
|
|
||||||
let containerSize = CGSize(width: containerSize.width, height: containerSize.height)
|
let containerSize = CGSize(width: containerSize.width, height: containerSize.height)
|
||||||
|
|
||||||
let angle = Float(.pi - rotation)
|
let angle = Float(.pi - rotation)
|
||||||
@ -111,6 +119,8 @@ private func verticesData(
|
|||||||
textureRotation: TextureRotation,
|
textureRotation: TextureRotation,
|
||||||
containerSize: CGSize,
|
containerSize: CGSize,
|
||||||
textureRect: CGRect,
|
textureRect: CGRect,
|
||||||
|
scale: simd_float1,
|
||||||
|
offset: simd_float2,
|
||||||
z: Float = 0.0
|
z: Float = 0.0
|
||||||
) -> [VertexData] {
|
) -> [VertexData] {
|
||||||
let textureRect = CGRect(origin: CGPoint(x: textureRect.origin.x, y: containerSize.height - textureRect.maxY ), size: textureRect.size)
|
let textureRect = CGRect(origin: CGPoint(x: textureRect.origin.x, y: containerSize.height - textureRect.maxY ), size: textureRect.size)
|
||||||
@ -118,17 +128,24 @@ private func verticesData(
|
|||||||
let containerAspect = textureRect.width / textureRect.height
|
let containerAspect = textureRect.width / textureRect.height
|
||||||
let imageAspect = size.width / size.height
|
let imageAspect = size.width / size.height
|
||||||
|
|
||||||
let texCoordScale: simd_float2
|
var texCoordScale: simd_float2
|
||||||
if imageAspect > containerAspect {
|
if imageAspect > containerAspect {
|
||||||
texCoordScale = simd_float2(Float(containerAspect / imageAspect), 1.0)
|
texCoordScale = simd_float2(Float(containerAspect / imageAspect), 1.0)
|
||||||
} else {
|
} else {
|
||||||
texCoordScale = simd_float2(1.0, Float(imageAspect / containerAspect))
|
texCoordScale = simd_float2(1.0, Float(imageAspect / containerAspect))
|
||||||
}
|
}
|
||||||
|
|
||||||
let scaledTopLeft = simd_float2(0.5 - texCoordScale.x * 0.5, 0.5 + texCoordScale.y * 0.5)
|
let adjustedOffset = simd_float2(
|
||||||
let scaledTopRight = simd_float2(0.5 + texCoordScale.x * 0.5, 0.5 + texCoordScale.y * 0.5)
|
offset.x / texCoordScale.x,
|
||||||
let scaledBottomLeft = simd_float2(0.5 - texCoordScale.x * 0.5, 0.5 - texCoordScale.y * 0.5)
|
offset.y / texCoordScale.y
|
||||||
let scaledBottomRight = simd_float2(0.5 + texCoordScale.x * 0.5, 0.5 - texCoordScale.y * 0.5)
|
)
|
||||||
|
|
||||||
|
texCoordScale *= 1.0 / scale
|
||||||
|
|
||||||
|
let scaledTopLeft = simd_float2(0.5 - texCoordScale.x * 0.5, 0.5 + texCoordScale.y * 0.5) - adjustedOffset
|
||||||
|
let scaledTopRight = simd_float2(0.5 + texCoordScale.x * 0.5, 0.5 + texCoordScale.y * 0.5) - adjustedOffset
|
||||||
|
let scaledBottomLeft = simd_float2(0.5 - texCoordScale.x * 0.5, 0.5 - texCoordScale.y * 0.5) - adjustedOffset
|
||||||
|
let scaledBottomRight = simd_float2(0.5 + texCoordScale.x * 0.5, 0.5 - texCoordScale.y * 0.5) - adjustedOffset
|
||||||
|
|
||||||
let topLeft: simd_float2
|
let topLeft: simd_float2
|
||||||
let topRight: simd_float2
|
let topRight: simd_float2
|
||||||
@ -322,6 +339,8 @@ final class VideoFinishPass: RenderPass {
|
|||||||
texture: MTLTexture,
|
texture: MTLTexture,
|
||||||
textureRotation: TextureRotation,
|
textureRotation: TextureRotation,
|
||||||
rect: CGRect,
|
rect: CGRect,
|
||||||
|
scale: CGFloat,
|
||||||
|
offset: CGPoint,
|
||||||
zPosition: Float,
|
zPosition: Float,
|
||||||
device: MTLDevice
|
device: MTLDevice
|
||||||
) {
|
) {
|
||||||
@ -333,6 +352,8 @@ final class VideoFinishPass: RenderPass {
|
|||||||
textureRotation: textureRotation,
|
textureRotation: textureRotation,
|
||||||
containerSize: containerSize,
|
containerSize: containerSize,
|
||||||
textureRect: rect,
|
textureRect: rect,
|
||||||
|
scale: simd_float1(scale),
|
||||||
|
offset: simd_float2(Float(offset.x / scale), Float(-offset.y / scale)),
|
||||||
z: zPosition
|
z: zPosition
|
||||||
)
|
)
|
||||||
let buffer = device.makeBuffer(
|
let buffer = device.makeBuffer(
|
||||||
@ -387,6 +408,7 @@ final class VideoFinishPass: RenderPass {
|
|||||||
position: center,
|
position: center,
|
||||||
size: size,
|
size: size,
|
||||||
rotation: position.rotation,
|
rotation: position.rotation,
|
||||||
|
mirror: position.mirroring,
|
||||||
z: zPosition
|
z: zPosition
|
||||||
)
|
)
|
||||||
let buffer = device.makeBuffer(
|
let buffer = device.makeBuffer(
|
||||||
@ -415,10 +437,10 @@ final class VideoFinishPass: RenderPass {
|
|||||||
|
|
||||||
self.isStory = values.isStory || values.isSticker
|
self.isStory = values.isStory || values.isSticker
|
||||||
self.isSticker = values.gradientColors?.first?.alpha == 0.0
|
self.isSticker = values.gradientColors?.first?.alpha == 0.0
|
||||||
self.mainPosition = VideoFinishPass.VideoPosition(position: position, size: self.mainPosition.size, scale: values.cropScale, rotation: values.cropRotation, baseScale: self.mainPosition.baseScale)
|
self.mainPosition = VideoFinishPass.VideoPosition(position: position, size: self.mainPosition.size, scale: values.cropScale, rotation: values.cropRotation, mirroring: values.cropMirroring, baseScale: self.mainPosition.baseScale)
|
||||||
|
|
||||||
if let position = values.additionalVideoPosition, let scale = values.additionalVideoScale, let rotation = values.additionalVideoRotation {
|
if let position = values.additionalVideoPosition, let scale = values.additionalVideoScale, let rotation = values.additionalVideoRotation {
|
||||||
self.additionalPosition = VideoFinishPass.VideoPosition(position: position, size: CGSize(width: 1080.0 / 4.0, height: 1440.0 / 4.0), scale: scale, rotation: rotation, baseScale: self.additionalPosition.baseScale)
|
self.additionalPosition = VideoFinishPass.VideoPosition(position: position, size: CGSize(width: 1080.0 / 4.0, height: 1440.0 / 4.0), scale: scale, rotation: rotation, mirroring: false, baseScale: self.additionalPosition.baseScale)
|
||||||
}
|
}
|
||||||
if !values.additionalVideoPositionChanges.isEmpty {
|
if !values.additionalVideoPositionChanges.isEmpty {
|
||||||
self.videoPositionChanges = values.additionalVideoPositionChanges
|
self.videoPositionChanges = values.additionalVideoPositionChanges
|
||||||
@ -451,6 +473,7 @@ final class VideoFinishPass: RenderPass {
|
|||||||
size: CGSize(width: 1080.0, height: 1920.0),
|
size: CGSize(width: 1080.0, height: 1920.0),
|
||||||
scale: 1.0,
|
scale: 1.0,
|
||||||
rotation: 0.0,
|
rotation: 0.0,
|
||||||
|
mirroring: false,
|
||||||
baseScale: 1.0
|
baseScale: 1.0
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -459,6 +482,7 @@ final class VideoFinishPass: RenderPass {
|
|||||||
size: CGSize(width: 1440.0, height: 1920.0),
|
size: CGSize(width: 1440.0, height: 1920.0),
|
||||||
scale: 0.5,
|
scale: 0.5,
|
||||||
rotation: 0.0,
|
rotation: 0.0,
|
||||||
|
mirroring: false,
|
||||||
baseScale: 1.0
|
baseScale: 1.0
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -482,10 +506,11 @@ final class VideoFinishPass: RenderPass {
|
|||||||
let size: CGSize
|
let size: CGSize
|
||||||
let scale: CGFloat
|
let scale: CGFloat
|
||||||
let rotation: CGFloat
|
let rotation: CGFloat
|
||||||
|
let mirroring: Bool
|
||||||
let baseScale: CGFloat
|
let baseScale: CGFloat
|
||||||
|
|
||||||
func with(size: CGSize, baseScale: CGFloat) -> VideoPosition {
|
func with(size: CGSize, baseScale: CGFloat) -> VideoPosition {
|
||||||
return VideoPosition(position: self.position, size: size, scale: self.scale, rotation: self.rotation, baseScale: baseScale)
|
return VideoPosition(position: self.position, size: size, scale: self.scale, rotation: self.rotation, mirroring: self.mirroring, baseScale: baseScale)
|
||||||
}
|
}
|
||||||
|
|
||||||
func mixed(with other: VideoPosition, fraction: CGFloat) -> VideoPosition {
|
func mixed(with other: VideoPosition, fraction: CGFloat) -> VideoPosition {
|
||||||
@ -505,6 +530,7 @@ final class VideoFinishPass: RenderPass {
|
|||||||
size: size,
|
size: size,
|
||||||
scale: scale,
|
scale: scale,
|
||||||
rotation: rotation,
|
rotation: rotation,
|
||||||
|
mirroring: self.mirroring,
|
||||||
baseScale: self.baseScale
|
baseScale: self.baseScale
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -558,13 +584,13 @@ final class VideoFinishPass: RenderPass {
|
|||||||
backgroundTexture = additionalInput
|
backgroundTexture = additionalInput
|
||||||
backgroundTextureRotation = self.additionalTextureRotation
|
backgroundTextureRotation = self.additionalTextureRotation
|
||||||
|
|
||||||
mainPosition = VideoPosition(position: mainPosition.position, size: CGSize(width: 1440.0, height: 1920.0), scale: mainPosition.scale, rotation: mainPosition.rotation, baseScale: mainPosition.baseScale)
|
mainPosition = VideoPosition(position: mainPosition.position, size: CGSize(width: 1440.0, height: 1920.0), scale: mainPosition.scale, rotation: mainPosition.rotation, mirroring: mainPosition.mirroring, baseScale: mainPosition.baseScale)
|
||||||
additionalPosition = VideoPosition(position: additionalPosition.position, size: CGSize(width: 1080.0 / 4.0, height: 1920.0 / 4.0), scale: additionalPosition.scale, rotation: additionalPosition.rotation, baseScale: additionalPosition.baseScale)
|
additionalPosition = VideoPosition(position: additionalPosition.position, size: CGSize(width: 1080.0 / 4.0, height: 1920.0 / 4.0), scale: additionalPosition.scale, rotation: additionalPosition.rotation, mirroring: additionalPosition.mirroring, baseScale: additionalPosition.baseScale)
|
||||||
|
|
||||||
foregroundTexture = mainInput
|
foregroundTexture = mainInput
|
||||||
foregroundTextureRotation = self.mainTextureRotation
|
foregroundTextureRotation = self.mainTextureRotation
|
||||||
} else {
|
} else {
|
||||||
disappearingPosition = VideoPosition(position: mainPosition.position, size: CGSize(width: 1440.0, height: 1920.0), scale: mainPosition.scale, rotation: mainPosition.rotation, baseScale: mainPosition.baseScale)
|
disappearingPosition = VideoPosition(position: mainPosition.position, size: CGSize(width: 1440.0, height: 1920.0), scale: mainPosition.scale, rotation: mainPosition.rotation, mirroring: mainPosition.mirroring, baseScale: mainPosition.baseScale)
|
||||||
}
|
}
|
||||||
if previousChange.timestamp > 0.0 && timestamp < previousChange.timestamp + transitionDuration {
|
if previousChange.timestamp > 0.0 && timestamp < previousChange.timestamp + transitionDuration {
|
||||||
transitionFraction = (timestamp - previousChange.timestamp) / transitionDuration
|
transitionFraction = (timestamp - previousChange.timestamp) / transitionDuration
|
||||||
@ -582,8 +608,8 @@ final class VideoFinishPass: RenderPass {
|
|||||||
if transitionFraction < 1.0 {
|
if transitionFraction < 1.0 {
|
||||||
let springFraction = lookupSpringValue(transitionFraction)
|
let springFraction = lookupSpringValue(transitionFraction)
|
||||||
|
|
||||||
let appearingPosition = VideoPosition(position: additionalPosition.position, size: additionalPosition.size, scale: 0.01, rotation: self.additionalPosition.rotation, baseScale: self.additionalPosition.baseScale)
|
let appearingPosition = VideoPosition(position: additionalPosition.position, size: additionalPosition.size, scale: 0.01, rotation: self.additionalPosition.rotation, mirroring: self.additionalPosition.mirroring, baseScale: self.additionalPosition.baseScale)
|
||||||
let backgroundInitialPosition = VideoPosition(position: additionalPosition.position, size: CGSize(width: mainPosition.size.width / 4.0, height: mainPosition.size.height / 4.0), scale: additionalPosition.scale, rotation: additionalPosition.rotation, baseScale: additionalPosition.baseScale)
|
let backgroundInitialPosition = VideoPosition(position: additionalPosition.position, size: CGSize(width: mainPosition.size.width / 4.0, height: mainPosition.size.height / 4.0), scale: additionalPosition.scale, rotation: additionalPosition.rotation, mirroring: additionalPosition.mirroring, baseScale: additionalPosition.baseScale)
|
||||||
|
|
||||||
foregroundPosition = appearingPosition.mixed(with: additionalPosition, fraction: springFraction)
|
foregroundPosition = appearingPosition.mixed(with: additionalPosition, fraction: springFraction)
|
||||||
|
|
||||||
@ -612,7 +638,7 @@ final class VideoFinishPass: RenderPass {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (trimRangeLowerBound != nil || trimRangeUpperBound != nil), let _ = self.videoDuration {
|
if (trimRangeLowerBound != nil || trimRangeUpperBound != nil), let _ = self.videoDuration {
|
||||||
let disappearingPosition = VideoPosition(position: foregroundPosition.position, size: foregroundPosition.size, scale: 0.01, rotation: foregroundPosition.rotation, baseScale: foregroundPosition.baseScale)
|
let disappearingPosition = VideoPosition(position: foregroundPosition.position, size: foregroundPosition.size, scale: 0.01, rotation: foregroundPosition.rotation, mirroring: foregroundPosition.mirroring, baseScale: foregroundPosition.baseScale)
|
||||||
|
|
||||||
let mainLowerBound = self.videoRange?.lowerBound ?? 0.0
|
let mainLowerBound = self.videoRange?.lowerBound ?? 0.0
|
||||||
|
|
||||||
@ -635,7 +661,7 @@ final class VideoFinishPass: RenderPass {
|
|||||||
|
|
||||||
if isVisible {
|
if isVisible {
|
||||||
if let additionalVideoRemovalStartTimestamp {
|
if let additionalVideoRemovalStartTimestamp {
|
||||||
let disappearingPosition = VideoPosition(position: foregroundPosition.position, size: foregroundPosition.size, scale: 0.01, rotation: foregroundPosition.rotation, baseScale: foregroundPosition.baseScale)
|
let disappearingPosition = VideoPosition(position: foregroundPosition.position, size: foregroundPosition.size, scale: 0.01, rotation: foregroundPosition.rotation, mirroring: foregroundPosition.mirroring, baseScale: foregroundPosition.baseScale)
|
||||||
|
|
||||||
let visibilityFraction = max(0.0, min(1.0, 1.0 - (CACurrentMediaTime() - additionalVideoRemovalStartTimestamp) / videoRemovalDuration))
|
let visibilityFraction = max(0.0, min(1.0, 1.0 - (CACurrentMediaTime() - additionalVideoRemovalStartTimestamp) / videoRemovalDuration))
|
||||||
if visibilityFraction.isZero {
|
if visibilityFraction.isZero {
|
||||||
@ -655,6 +681,8 @@ final class VideoFinishPass: RenderPass {
|
|||||||
let texture: MTLTexture
|
let texture: MTLTexture
|
||||||
let hasTransparency: Bool
|
let hasTransparency: Bool
|
||||||
let rect: CGRect?
|
let rect: CGRect?
|
||||||
|
let scale: CGFloat
|
||||||
|
let offset: CGPoint
|
||||||
}
|
}
|
||||||
|
|
||||||
func process(
|
func process(
|
||||||
@ -739,6 +767,8 @@ final class VideoFinishPass: RenderPass {
|
|||||||
texture: input.texture,
|
texture: input.texture,
|
||||||
textureRotation: self.mainTextureRotation,
|
textureRotation: self.mainTextureRotation,
|
||||||
rect: rect,
|
rect: rect,
|
||||||
|
scale: input.scale,
|
||||||
|
offset: input.offset,
|
||||||
zPosition: 0.0,
|
zPosition: 0.0,
|
||||||
device: device
|
device: device
|
||||||
)
|
)
|
||||||
@ -751,6 +781,8 @@ final class VideoFinishPass: RenderPass {
|
|||||||
texture: input.texture,
|
texture: input.texture,
|
||||||
textureRotation: self.mainTextureRotation,
|
textureRotation: self.mainTextureRotation,
|
||||||
rect: rect,
|
rect: rect,
|
||||||
|
scale: input.scale,
|
||||||
|
offset: input.offset,
|
||||||
zPosition: 0.0,
|
zPosition: 0.0,
|
||||||
device: device
|
device: device
|
||||||
)
|
)
|
||||||
|
@ -21,6 +21,10 @@ extension MediaEditorScreenImpl {
|
|||||||
let codableEntities = DrawingEntitiesView.encodeEntities(entities, entitiesView: self.node.entitiesView)
|
let codableEntities = DrawingEntitiesView.encodeEntities(entities, entitiesView: self.node.entitiesView)
|
||||||
mediaEditor.setDrawingAndEntities(data: nil, image: mediaEditor.values.drawing, entities: codableEntities)
|
mediaEditor.setDrawingAndEntities(data: nil, image: mediaEditor.values.drawing, entities: codableEntities)
|
||||||
|
|
||||||
|
if case .avatarEditor = self.mode {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
let filteredEntities = self.node.entitiesView.entities.filter { entity in
|
let filteredEntities = self.node.entitiesView.entities.filter { entity in
|
||||||
if entity is DrawingMediaEntity {
|
if entity is DrawingMediaEntity {
|
||||||
return false
|
return false
|
||||||
@ -49,7 +53,7 @@ extension MediaEditorScreenImpl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func saveDraft(id: Int64?, edit: Bool = false) {
|
func saveDraft(id: Int64?, edit: Bool = false) {
|
||||||
guard let subject = self.node.subject, let actualSubject = self.node.actualSubject, let mediaEditor = self.node.mediaEditor else {
|
guard case .storyEditor = self.mode, let subject = self.node.subject, let actualSubject = self.node.actualSubject, let mediaEditor = self.node.mediaEditor else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
try? FileManager.default.createDirectory(atPath: draftPath(engine: self.context.engine), withIntermediateDirectories: true)
|
try? FileManager.default.createDirectory(atPath: draftPath(engine: self.context.engine), withIntermediateDirectories: true)
|
||||||
|
@ -171,6 +171,8 @@ final class MediaEditorScreenComponent: Component {
|
|||||||
case text
|
case text
|
||||||
case sticker
|
case sticker
|
||||||
case tools
|
case tools
|
||||||
|
case rotate
|
||||||
|
case flip
|
||||||
case done
|
case done
|
||||||
case cutout
|
case cutout
|
||||||
case undo
|
case undo
|
||||||
@ -193,6 +195,10 @@ final class MediaEditorScreenComponent: Component {
|
|||||||
image = generateTintedImage(image: UIImage(bundleImageName: "Media Editor/AddSticker"), color: .white)!
|
image = generateTintedImage(image: UIImage(bundleImageName: "Media Editor/AddSticker"), color: .white)!
|
||||||
case .tools:
|
case .tools:
|
||||||
image = generateTintedImage(image: UIImage(bundleImageName: "Media Editor/Tools"), color: .white)!
|
image = generateTintedImage(image: UIImage(bundleImageName: "Media Editor/Tools"), color: .white)!
|
||||||
|
case .rotate:
|
||||||
|
image = generateTintedImage(image: UIImage(bundleImageName: "Media Editor/Rotate"), color: .white)!
|
||||||
|
case .flip:
|
||||||
|
image = generateTintedImage(image: UIImage(bundleImageName: "Media Editor/Mirror"), color: .white)!
|
||||||
case .cutout:
|
case .cutout:
|
||||||
image = UIImage(bundleImageName: "Media Editor/Cutout")!.withRenderingMode(.alwaysTemplate)
|
image = UIImage(bundleImageName: "Media Editor/Cutout")!.withRenderingMode(.alwaysTemplate)
|
||||||
case .undo:
|
case .undo:
|
||||||
@ -289,11 +295,14 @@ final class MediaEditorScreenComponent: Component {
|
|||||||
|
|
||||||
public final class View: UIView {
|
public final class View: UIView {
|
||||||
private let cancelButton = ComponentView<Empty>()
|
private let cancelButton = ComponentView<Empty>()
|
||||||
|
private let doneButton = ComponentView<Empty>()
|
||||||
private let drawButton = ComponentView<Empty>()
|
private let drawButton = ComponentView<Empty>()
|
||||||
private let textButton = ComponentView<Empty>()
|
private let textButton = ComponentView<Empty>()
|
||||||
private let stickerButton = ComponentView<Empty>()
|
private let stickerButton = ComponentView<Empty>()
|
||||||
private let toolsButton = ComponentView<Empty>()
|
private let toolsButton = ComponentView<Empty>()
|
||||||
private let doneButton = ComponentView<Empty>()
|
|
||||||
|
private let rotateButton = ComponentView<Empty>()
|
||||||
|
private let flipButton = ComponentView<Empty>()
|
||||||
|
|
||||||
private let cutoutButton = ComponentView<Empty>()
|
private let cutoutButton = ComponentView<Empty>()
|
||||||
private let undoButton = ComponentView<Empty>()
|
private let undoButton = ComponentView<Empty>()
|
||||||
@ -308,6 +317,7 @@ final class MediaEditorScreenComponent: Component {
|
|||||||
private let inputPanelBackground = ComponentView<Empty>()
|
private let inputPanelBackground = ComponentView<Empty>()
|
||||||
|
|
||||||
private var scrubber: ComponentView<Empty>?
|
private var scrubber: ComponentView<Empty>?
|
||||||
|
private var scrubberLabel: ComponentView<Empty>?
|
||||||
|
|
||||||
private let playbackButton = ComponentView<Empty>()
|
private let playbackButton = ComponentView<Empty>()
|
||||||
private let muteButton = ComponentView<Empty>()
|
private let muteButton = ComponentView<Empty>()
|
||||||
@ -332,6 +342,9 @@ final class MediaEditorScreenComponent: Component {
|
|||||||
private var inputMediaNodeStateContext = ChatEntityKeyboardInputNode.StateContext()
|
private var inputMediaNodeStateContext = ChatEntityKeyboardInputNode.StateContext()
|
||||||
private var inputMediaInteraction: ChatEntityKeyboardInputNode.Interaction?
|
private var inputMediaInteraction: ChatEntityKeyboardInputNode.Interaction?
|
||||||
private var inputMediaNode: ChatEntityKeyboardInputNode?
|
private var inputMediaNode: ChatEntityKeyboardInputNode?
|
||||||
|
|
||||||
|
private var cover: (position: Double, image: UIImage)?
|
||||||
|
private var coverApplyTimer: SwiftSignalKit.Timer?
|
||||||
|
|
||||||
private var videoRecorder: EntityVideoRecorder?
|
private var videoRecorder: EntityVideoRecorder?
|
||||||
|
|
||||||
@ -367,6 +380,7 @@ final class MediaEditorScreenComponent: Component {
|
|||||||
|
|
||||||
deinit {
|
deinit {
|
||||||
self.inputMediaNodeDataDisposable?.dispose()
|
self.inputMediaNodeDataDisposable?.dispose()
|
||||||
|
self.coverApplyTimer?.invalidate()
|
||||||
}
|
}
|
||||||
|
|
||||||
private func setupIfNeeded() {
|
private func setupIfNeeded() {
|
||||||
@ -724,6 +738,22 @@ final class MediaEditorScreenComponent: Component {
|
|||||||
return inputText
|
return inputText
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private func updateCoverPosition() {
|
||||||
|
guard let controller = self.environment?.controller() as? MediaEditorScreenImpl, let mediaEditor = controller.node.mediaEditor else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if let image = mediaEditor.resultImage {
|
||||||
|
self.cover = (mediaEditor.currentPosition.seconds, image)
|
||||||
|
}
|
||||||
|
controller.node.requestLayout(forceUpdate: true, transition: .immediate)
|
||||||
|
|
||||||
|
self.coverApplyTimer = SwiftSignalKit.Timer(timeout: 1.0, repeat: false, completion: { [weak mediaEditor] in
|
||||||
|
mediaEditor?.play()
|
||||||
|
}, queue: Queue.mainQueue())
|
||||||
|
self.coverApplyTimer?.start()
|
||||||
|
}
|
||||||
|
|
||||||
func update(component: MediaEditorScreenComponent, availableSize: CGSize, state: State, environment: Environment<ViewControllerComponentContainer.Environment>, transition: ComponentTransition) -> CGSize {
|
func update(component: MediaEditorScreenComponent, availableSize: CGSize, state: State, environment: Environment<ViewControllerComponentContainer.Environment>, transition: ComponentTransition) -> CGSize {
|
||||||
guard !self.isDismissed else {
|
guard !self.isDismissed else {
|
||||||
return availableSize
|
return availableSize
|
||||||
@ -757,6 +787,8 @@ final class MediaEditorScreenComponent: Component {
|
|||||||
|
|
||||||
self.setupIfNeeded()
|
self.setupIfNeeded()
|
||||||
|
|
||||||
|
let mediaEditor = controller.node.mediaEditor
|
||||||
|
|
||||||
let isTablet = environment.metrics.isTablet
|
let isTablet = environment.metrics.isTablet
|
||||||
|
|
||||||
let openDrawing = component.openDrawing
|
let openDrawing = component.openDrawing
|
||||||
@ -833,7 +865,7 @@ final class MediaEditorScreenComponent: Component {
|
|||||||
case .storyEditor:
|
case .storyEditor:
|
||||||
doneButtonTitle = isEditingStory ? environment.strings.Story_Editor_Done.uppercased() : environment.strings.Story_Editor_Next.uppercased()
|
doneButtonTitle = isEditingStory ? environment.strings.Story_Editor_Done.uppercased() : environment.strings.Story_Editor_Next.uppercased()
|
||||||
doneButtonIcon = UIImage(bundleImageName: "Media Editor/Next")!
|
doneButtonIcon = UIImage(bundleImageName: "Media Editor/Next")!
|
||||||
case .stickerEditor:
|
case .stickerEditor, .avatarEditor:
|
||||||
doneButtonTitle = nil
|
doneButtonTitle = nil
|
||||||
doneButtonIcon = generateTintedImage(image: UIImage(bundleImageName: "Media Editor/Apply"), color: .white)!
|
doneButtonIcon = generateTintedImage(image: UIImage(bundleImageName: "Media Editor/Apply"), color: .white)!
|
||||||
case .botPreview:
|
case .botPreview:
|
||||||
@ -964,14 +996,104 @@ final class MediaEditorScreenComponent: Component {
|
|||||||
size: stickerButtonSize
|
size: stickerButtonSize
|
||||||
)
|
)
|
||||||
|
|
||||||
if let subject = controller.node.subject, case .empty = subject {
|
let rotateButtonSize = self.rotateButton.update(
|
||||||
|
transition: transition,
|
||||||
|
component: AnyComponent(ContextReferenceButtonComponent(
|
||||||
|
content: AnyComponent(Image(
|
||||||
|
image: state.image(.rotate),
|
||||||
|
size: CGSize(width: 30.0, height: 30.0)
|
||||||
|
)),
|
||||||
|
tag: textButtonTag,
|
||||||
|
minSize: CGSize(width: 30.0, height: 30.0),
|
||||||
|
action: { [weak controller, weak mediaEditor] _, _ in
|
||||||
|
guard let controller, let mediaEditor else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
guard !controller.node.recording.isActive else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
mediaEditor.setCrop(
|
||||||
|
offset: mediaEditor.values.cropOffset,
|
||||||
|
scale: mediaEditor.values.cropScale,
|
||||||
|
rotation: mediaEditor.values.cropRotation - .pi / 2.0,
|
||||||
|
mirroring: mediaEditor.values.cropMirroring
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)),
|
||||||
|
environment: {},
|
||||||
|
containerSize: CGSize(width: 40.0, height: 40.0)
|
||||||
|
)
|
||||||
|
let rotateButtonFrame = CGRect(
|
||||||
|
origin: CGPoint(x: drawButtonFrame.origin.x, y: availableSize.height - environment.safeInsets.bottom + buttonBottomInset + controlsBottomInset + 2.0),
|
||||||
|
size: rotateButtonSize
|
||||||
|
)
|
||||||
|
|
||||||
|
let flipButtonSize = self.flipButton.update(
|
||||||
|
transition: transition,
|
||||||
|
component: AnyComponent(ContextReferenceButtonComponent(
|
||||||
|
content: AnyComponent(Image(
|
||||||
|
image: state.image(.flip),
|
||||||
|
size: CGSize(width: 30.0, height: 30.0)
|
||||||
|
)),
|
||||||
|
tag: textButtonTag,
|
||||||
|
minSize: CGSize(width: 30.0, height: 30.0),
|
||||||
|
action: { [weak controller, weak mediaEditor] _, _ in
|
||||||
|
guard let controller, let mediaEditor else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
guard !controller.node.recording.isActive else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
mediaEditor.setCrop(
|
||||||
|
offset: mediaEditor.values.cropOffset,
|
||||||
|
scale: mediaEditor.values.cropScale,
|
||||||
|
rotation: mediaEditor.values.cropRotation,
|
||||||
|
mirroring: !mediaEditor.values.cropMirroring
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)),
|
||||||
|
environment: {},
|
||||||
|
containerSize: CGSize(width: 40.0, height: 40.0)
|
||||||
|
)
|
||||||
|
let flipButtonFrame = CGRect(
|
||||||
|
origin: CGPoint(x: textButtonFrame.origin.x, y: availableSize.height - environment.safeInsets.bottom + buttonBottomInset + controlsBottomInset + 2.0),
|
||||||
|
size: flipButtonSize
|
||||||
|
)
|
||||||
|
|
||||||
|
var isAvatarEditor = false
|
||||||
|
if case .avatarEditor = controller.mode {
|
||||||
|
isAvatarEditor = true
|
||||||
|
|
||||||
|
drawButtonFrame.origin.x = stickerButtonFrame.origin.x
|
||||||
|
|
||||||
|
if let rotateButtonView = self.rotateButton.view {
|
||||||
|
if rotateButtonView.superview == nil {
|
||||||
|
self.addSubview(rotateButtonView)
|
||||||
|
}
|
||||||
|
transition.setPosition(view: rotateButtonView, position: rotateButtonFrame.center)
|
||||||
|
transition.setBounds(view: rotateButtonView, bounds: CGRect(origin: .zero, size: rotateButtonFrame.size))
|
||||||
|
if !self.animatingButtons {
|
||||||
|
transition.setAlpha(view: rotateButtonView, alpha: buttonsAreHidden ? 0.0 : bottomButtonsAlpha)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if let flipButtonView = self.flipButton.view {
|
||||||
|
if flipButtonView.superview == nil {
|
||||||
|
self.addSubview(flipButtonView)
|
||||||
|
}
|
||||||
|
transition.setPosition(view: flipButtonView, position: flipButtonFrame.center)
|
||||||
|
transition.setBounds(view: flipButtonView, bounds: CGRect(origin: .zero, size: flipButtonFrame.size))
|
||||||
|
if !self.animatingButtons {
|
||||||
|
transition.setAlpha(view: flipButtonView, alpha: buttonsAreHidden ? 0.0 : bottomButtonsAlpha)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if let subject = controller.node.subject, case .empty = subject {
|
||||||
let distance = floor((stickerButtonFrame.minX - textButtonFrame.minX) * 1.2)
|
let distance = floor((stickerButtonFrame.minX - textButtonFrame.minX) * 1.2)
|
||||||
textButtonFrame.origin.x = availableSize.width / 2.0 - textButtonFrame.width / 2.0
|
textButtonFrame.origin.x = availableSize.width / 2.0 - textButtonFrame.width / 2.0
|
||||||
drawButtonFrame.origin.x = textButtonFrame.origin.x - distance
|
drawButtonFrame.origin.x = textButtonFrame.origin.x - distance
|
||||||
stickerButtonFrame.origin.x = textButtonFrame.origin.x + distance
|
stickerButtonFrame.origin.x = textButtonFrame.origin.x + distance
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if let drawButtonView = self.drawButton.view {
|
if let drawButtonView = self.drawButton.view {
|
||||||
if drawButtonView.superview == nil {
|
if drawButtonView.superview == nil {
|
||||||
self.addSubview(drawButtonView)
|
self.addSubview(drawButtonView)
|
||||||
@ -983,7 +1105,7 @@ final class MediaEditorScreenComponent: Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let textButtonView = self.textButton.view {
|
if !isAvatarEditor, let textButtonView = self.textButton.view {
|
||||||
if textButtonView.superview == nil {
|
if textButtonView.superview == nil {
|
||||||
self.addSubview(textButtonView)
|
self.addSubview(textButtonView)
|
||||||
}
|
}
|
||||||
@ -994,7 +1116,7 @@ final class MediaEditorScreenComponent: Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let stickerButtonView = self.stickerButton.view {
|
if !isAvatarEditor, let stickerButtonView = self.stickerButton.view {
|
||||||
if stickerButtonView.superview == nil {
|
if stickerButtonView.superview == nil {
|
||||||
self.addSubview(stickerButtonView)
|
self.addSubview(stickerButtonView)
|
||||||
}
|
}
|
||||||
@ -1180,7 +1302,6 @@ final class MediaEditorScreenComponent: Component {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
let mediaEditor = controller.node.mediaEditor
|
|
||||||
var isOutlineActive = false
|
var isOutlineActive = false
|
||||||
if let value = mediaEditor?.values.toolValues[.stickerOutline] as? Float, value > 0.0 {
|
if let value = mediaEditor?.values.toolValues[.stickerOutline] as? Float, value > 0.0 {
|
||||||
isOutlineActive = true
|
isOutlineActive = true
|
||||||
@ -1869,7 +1990,11 @@ final class MediaEditorScreenComponent: Component {
|
|||||||
maxDuration = 15.0
|
maxDuration = 15.0
|
||||||
} else {
|
} else {
|
||||||
minDuration = 1.0
|
minDuration = 1.0
|
||||||
maxDuration = storyMaxVideoDuration
|
if case .avatarEditor = controller.mode {
|
||||||
|
maxDuration = 10.0
|
||||||
|
} else {
|
||||||
|
maxDuration = storyMaxVideoDuration
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let previousTrackCount = self.currentVisibleTracks?.count
|
let previousTrackCount = self.currentVisibleTracks?.count
|
||||||
@ -1895,6 +2020,36 @@ final class MediaEditorScreenComponent: Component {
|
|||||||
isCollage = videoCount > 1
|
isCollage = videoCount > 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var scrubberBottomOffset: CGFloat = 0.0
|
||||||
|
if case .avatarEditor = controller.mode {
|
||||||
|
let scrubberLabel: ComponentView<Empty>
|
||||||
|
if let current = self.scrubberLabel {
|
||||||
|
scrubberLabel = current
|
||||||
|
} else {
|
||||||
|
scrubberLabel = ComponentView<Empty>()
|
||||||
|
self.scrubberLabel = scrubberLabel
|
||||||
|
}
|
||||||
|
|
||||||
|
let scrubberLabelSize = scrubberLabel.update(
|
||||||
|
transition: scrubberTransition,
|
||||||
|
component: AnyComponent(MultilineTextComponent(
|
||||||
|
text: .plain(NSAttributedString(string: environment.strings.PhotoEditor_SelectCoverFrame, font: Font.regular(14.0), textColor: UIColor(rgb: 0xffffff, alpha: 0.7)))
|
||||||
|
)),
|
||||||
|
environment: {},
|
||||||
|
containerSize: availableSize
|
||||||
|
)
|
||||||
|
if let view = scrubberLabel.view {
|
||||||
|
if view.superview == nil {
|
||||||
|
self.addSubview(view)
|
||||||
|
}
|
||||||
|
|
||||||
|
let scrubberLabelFrame = CGRect(origin: CGPoint(x: floorToScreenPixels((availableSize.width - scrubberLabelSize.width) / 2.0), y: availableSize.height - environment.safeInsets.bottom - scrubberLabelSize.height + controlsBottomInset - inputPanelSize.height + 2.0), size: scrubberLabelSize)
|
||||||
|
view.frame = scrubberLabelFrame
|
||||||
|
|
||||||
|
scrubberBottomOffset += scrubberLabelSize.height + 12.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let scrubber: ComponentView<Empty>
|
let scrubber: ComponentView<Empty>
|
||||||
if let current = self.scrubber {
|
if let current = self.scrubber {
|
||||||
scrubber = current
|
scrubber = current
|
||||||
@ -1918,8 +2073,21 @@ final class MediaEditorScreenComponent: Component {
|
|||||||
isCollage: isCollage,
|
isCollage: isCollage,
|
||||||
isCollageSelected: component.isCollageTimelineOpen,
|
isCollageSelected: component.isCollageTimelineOpen,
|
||||||
collageSamples: playerState.collageSamples,
|
collageSamples: playerState.collageSamples,
|
||||||
positionUpdated: { [weak mediaEditor] position, apply in
|
cover: self.cover,
|
||||||
if let mediaEditor {
|
getCoverSourceView: { [weak controller] in
|
||||||
|
return controller?.node.stickerBackgroundView
|
||||||
|
},
|
||||||
|
positionUpdated: { [weak self, weak controller, weak mediaEditor] position, apply in
|
||||||
|
if let self, let mediaEditor {
|
||||||
|
var apply = apply
|
||||||
|
if !apply, self.coverApplyTimer != nil {
|
||||||
|
self.coverApplyTimer?.invalidate()
|
||||||
|
self.coverApplyTimer = nil
|
||||||
|
}
|
||||||
|
if apply, let controller, case .avatarEditor = controller.mode {
|
||||||
|
apply = false
|
||||||
|
self.updateCoverPosition()
|
||||||
|
}
|
||||||
mediaEditor.seek(position, andPlay: apply)
|
mediaEditor.seek(position, andPlay: apply)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -2038,7 +2206,7 @@ final class MediaEditorScreenComponent: Component {
|
|||||||
component.externalState.timelineHeight = 0.0
|
component.externalState.timelineHeight = 0.0
|
||||||
}
|
}
|
||||||
|
|
||||||
let scrubberFrame = CGRect(origin: CGPoint(x: floorToScreenPixels((availableSize.width - scrubberSize.width) / 2.0), y: availableSize.height - environment.safeInsets.bottom - scrubberSize.height + controlsBottomInset - inputPanelSize.height + 3.0), size: scrubberSize)
|
let scrubberFrame = CGRect(origin: CGPoint(x: floorToScreenPixels((availableSize.width - scrubberSize.width) / 2.0), y: availableSize.height - environment.safeInsets.bottom - scrubberSize.height + controlsBottomInset - inputPanelSize.height + 3.0 - scrubberBottomOffset), size: scrubberSize)
|
||||||
if let scrubberView = scrubber.view {
|
if let scrubberView = scrubber.view {
|
||||||
var animateIn = false
|
var animateIn = false
|
||||||
if scrubberView.superview == nil {
|
if scrubberView.superview == nil {
|
||||||
@ -2055,11 +2223,20 @@ final class MediaEditorScreenComponent: Component {
|
|||||||
scrubberTransition.setFrame(view: scrubberView, frame: scrubberFrame)
|
scrubberTransition.setFrame(view: scrubberView, frame: scrubberFrame)
|
||||||
}
|
}
|
||||||
if !self.animatingButtons && !(!hasMainVideoTrack && animateIn) {
|
if !self.animatingButtons && !(!hasMainVideoTrack && animateIn) {
|
||||||
transition.setAlpha(view: scrubberView, alpha: component.isDisplayingTool != nil || component.isDismissing || component.isInteractingWithEntities || isEditingCaption || isRecordingAdditionalVideo || isEditingTextEntity ? 0.0 : 1.0)
|
let scrubberAlpha = component.isDisplayingTool != nil || component.isDismissing || component.isInteractingWithEntities || isEditingCaption || isRecordingAdditionalVideo || isEditingTextEntity ? 0.0 : 1.0
|
||||||
|
transition.setAlpha(view: scrubberView, alpha: scrubberAlpha)
|
||||||
|
if let scrubberLabelView = self.scrubberLabel?.view {
|
||||||
|
transition.setAlpha(view: scrubberLabelView, alpha: scrubberAlpha)
|
||||||
|
}
|
||||||
} else if animateIn {
|
} else if animateIn {
|
||||||
scrubberView.layer.animatePosition(from: CGPoint(x: 0.0, y: 44.0), to: .zero, duration: 0.3, timingFunction: kCAMediaTimingFunctionSpring, additive: true)
|
scrubberView.layer.animatePosition(from: CGPoint(x: 0.0, y: 44.0), to: .zero, duration: 0.3, timingFunction: kCAMediaTimingFunctionSpring, additive: true)
|
||||||
scrubberView.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2)
|
scrubberView.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2)
|
||||||
scrubberView.layer.animateScale(from: 0.6, to: 1.0, duration: 0.2)
|
scrubberView.layer.animateScale(from: 0.6, to: 1.0, duration: 0.2)
|
||||||
|
|
||||||
|
if let scrubberLabelView = self.scrubberLabel?.view {
|
||||||
|
scrubberLabelView.layer.animatePosition(from: CGPoint(x: 0.0, y: 44.0), to: .zero, duration: 0.3, timingFunction: kCAMediaTimingFunctionSpring, additive: true)
|
||||||
|
scrubberLabelView.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -2501,6 +2678,7 @@ public final class MediaEditorScreenImpl: ViewController, MediaEditorScreen, UID
|
|||||||
case storyEditor
|
case storyEditor
|
||||||
case stickerEditor(mode: StickerEditorMode)
|
case stickerEditor(mode: StickerEditorMode)
|
||||||
case botPreview
|
case botPreview
|
||||||
|
case avatarEditor
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum TransitionIn {
|
public enum TransitionIn {
|
||||||
@ -2589,7 +2767,7 @@ public final class MediaEditorScreenImpl: ViewController, MediaEditorScreen, UID
|
|||||||
private let gradientView: UIImageView
|
private let gradientView: UIImageView
|
||||||
private var gradientColorsDisposable: Disposable?
|
private var gradientColorsDisposable: Disposable?
|
||||||
|
|
||||||
private var stickerBackgroundView: UIImageView?
|
fileprivate var stickerBackgroundView: UIImageView?
|
||||||
private var stickerOverlayLayer: SimpleShapeLayer?
|
private var stickerOverlayLayer: SimpleShapeLayer?
|
||||||
private var stickerFrameLayer: SimpleShapeLayer?
|
private var stickerFrameLayer: SimpleShapeLayer?
|
||||||
|
|
||||||
@ -2642,7 +2820,7 @@ public final class MediaEditorScreenImpl: ViewController, MediaEditorScreen, UID
|
|||||||
|
|
||||||
private var previousDrawingData: Data?
|
private var previousDrawingData: Data?
|
||||||
private var previousDrawingEntities: [DrawingEntity]?
|
private var previousDrawingEntities: [DrawingEntity]?
|
||||||
|
|
||||||
private var weatherPromise: Promise<StickerPickerScreen.Weather>?
|
private var weatherPromise: Promise<StickerPickerScreen.Weather>?
|
||||||
|
|
||||||
private var playbackPositionDisposable: Disposable?
|
private var playbackPositionDisposable: Disposable?
|
||||||
@ -2694,12 +2872,15 @@ public final class MediaEditorScreenImpl: ViewController, MediaEditorScreen, UID
|
|||||||
self.gradientView = UIImageView()
|
self.gradientView = UIImageView()
|
||||||
|
|
||||||
var isStickerEditor = false
|
var isStickerEditor = false
|
||||||
|
var isAvatarEditor = false
|
||||||
if case .stickerEditor = controller.mode {
|
if case .stickerEditor = controller.mode {
|
||||||
isStickerEditor = true
|
isStickerEditor = true
|
||||||
|
} else if case .avatarEditor = controller.mode {
|
||||||
|
isAvatarEditor = true
|
||||||
}
|
}
|
||||||
|
|
||||||
self.entitiesContainerView = UIView(frame: CGRect(origin: .zero, size: storyDimensions))
|
self.entitiesContainerView = UIView(frame: CGRect(origin: .zero, size: storyDimensions))
|
||||||
self.entitiesView = DrawingEntitiesView(context: controller.context, size: storyDimensions, hasBin: !isStickerEditor, isStickerEditor: isStickerEditor)
|
self.entitiesView = DrawingEntitiesView(context: controller.context, size: storyDimensions, hasBin: !isStickerEditor && !isAvatarEditor, isStickerEditor: isStickerEditor)
|
||||||
self.entitiesView.getEntityCenterPosition = {
|
self.entitiesView.getEntityCenterPosition = {
|
||||||
return CGPoint(x: storyDimensions.width / 2.0, y: storyDimensions.height / 2.0)
|
return CGPoint(x: storyDimensions.width / 2.0, y: storyDimensions.height / 2.0)
|
||||||
}
|
}
|
||||||
@ -2739,7 +2920,8 @@ public final class MediaEditorScreenImpl: ViewController, MediaEditorScreen, UID
|
|||||||
|
|
||||||
self.containerView.addSubview(self.previewContainerView)
|
self.containerView.addSubview(self.previewContainerView)
|
||||||
|
|
||||||
if case .stickerEditor = controller.mode {
|
switch controller.mode {
|
||||||
|
case .stickerEditor:
|
||||||
let rowsCount = 40
|
let rowsCount = 40
|
||||||
let stickerBackgroundView = UIImageView()
|
let stickerBackgroundView = UIImageView()
|
||||||
stickerBackgroundView.clipsToBounds = true
|
stickerBackgroundView.clipsToBounds = true
|
||||||
@ -2762,7 +2944,11 @@ public final class MediaEditorScreenImpl: ViewController, MediaEditorScreen, UID
|
|||||||
stickerBackgroundView.layer.rasterizationScale = UIScreenScale
|
stickerBackgroundView.layer.rasterizationScale = UIScreenScale
|
||||||
self.stickerBackgroundView = stickerBackgroundView
|
self.stickerBackgroundView = stickerBackgroundView
|
||||||
self.previewContainerView.addSubview(stickerBackgroundView)
|
self.previewContainerView.addSubview(stickerBackgroundView)
|
||||||
} else {
|
case .avatarEditor:
|
||||||
|
let stickerBackgroundView = UIImageView()
|
||||||
|
self.stickerBackgroundView = stickerBackgroundView
|
||||||
|
self.previewContainerView.addSubview(stickerBackgroundView)
|
||||||
|
default:
|
||||||
self.previewContainerView.addSubview(self.gradientView)
|
self.previewContainerView.addSubview(self.gradientView)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2774,7 +2960,8 @@ public final class MediaEditorScreenImpl: ViewController, MediaEditorScreen, UID
|
|||||||
self.entitiesContainerView.addSubview(self.entitiesView)
|
self.entitiesContainerView.addSubview(self.entitiesView)
|
||||||
self.entitiesView.addSubview(self.drawingView)
|
self.entitiesView.addSubview(self.drawingView)
|
||||||
|
|
||||||
if case .stickerEditor = controller.mode {
|
switch controller.mode {
|
||||||
|
case .stickerEditor, .avatarEditor:
|
||||||
let stickerOverlayLayer = SimpleShapeLayer()
|
let stickerOverlayLayer = SimpleShapeLayer()
|
||||||
stickerOverlayLayer.fillColor = UIColor(rgb: 0x000000, alpha: 0.7).cgColor
|
stickerOverlayLayer.fillColor = UIColor(rgb: 0x000000, alpha: 0.7).cgColor
|
||||||
stickerOverlayLayer.fillRule = .evenOdd
|
stickerOverlayLayer.fillRule = .evenOdd
|
||||||
@ -2789,6 +2976,8 @@ public final class MediaEditorScreenImpl: ViewController, MediaEditorScreen, UID
|
|||||||
|
|
||||||
self.stickerFrameLayer = stickerFrameLayer
|
self.stickerFrameLayer = stickerFrameLayer
|
||||||
self.previewContainerView.layer.addSublayer(stickerFrameLayer)
|
self.previewContainerView.layer.addSublayer(stickerFrameLayer)
|
||||||
|
default:
|
||||||
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
self.previewContainerView.addSubview(self.selectionContainerView)
|
self.previewContainerView.addSubview(self.selectionContainerView)
|
||||||
@ -2974,7 +3163,7 @@ public final class MediaEditorScreenImpl: ViewController, MediaEditorScreen, UID
|
|||||||
} else {
|
} else {
|
||||||
mediaEntity.scale = storyDimensions.width / fittedSize.width
|
mediaEntity.scale = storyDimensions.width / fittedSize.width
|
||||||
}
|
}
|
||||||
case .stickerEditor:
|
case .stickerEditor, .avatarEditor:
|
||||||
if fittedSize.height > fittedSize.width {
|
if fittedSize.height > fittedSize.width {
|
||||||
mediaEntity.scale = storyDimensions.width / fittedSize.width
|
mediaEntity.scale = storyDimensions.width / fittedSize.width
|
||||||
} else {
|
} else {
|
||||||
@ -3011,9 +3200,11 @@ public final class MediaEditorScreenImpl: ViewController, MediaEditorScreen, UID
|
|||||||
initialValues = nil
|
initialValues = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
var isStickerEditor = false
|
var mediaEditorMode: MediaEditor.Mode = .default
|
||||||
if case .stickerEditor = controller.mode {
|
if case .stickerEditor = controller.mode {
|
||||||
isStickerEditor = true
|
mediaEditorMode = .sticker
|
||||||
|
} else if case .avatarEditor = controller.mode {
|
||||||
|
mediaEditorMode = .avatar
|
||||||
}
|
}
|
||||||
|
|
||||||
if let mediaEntityView = self.entitiesView.add(mediaEntity, announce: false) as? DrawingMediaEntityView {
|
if let mediaEntityView = self.entitiesView.add(mediaEntity, announce: false) as? DrawingMediaEntityView {
|
||||||
@ -3038,7 +3229,7 @@ public final class MediaEditorScreenImpl: ViewController, MediaEditorScreen, UID
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let mediaEditor = MediaEditor(context: self.context, mode: isStickerEditor ? .sticker : .default, subject: effectiveSubject.editorSubject, values: initialValues, hasHistogram: true)
|
let mediaEditor = MediaEditor(context: self.context, mode: mediaEditorMode, subject: effectiveSubject.editorSubject, values: initialValues, hasHistogram: true)
|
||||||
if let initialVideoPosition = controller.initialVideoPosition {
|
if let initialVideoPosition = controller.initialVideoPosition {
|
||||||
if controller.isEditingStoryCover {
|
if controller.isEditingStoryCover {
|
||||||
mediaEditor.setCoverImageTimestamp(initialVideoPosition)
|
mediaEditor.setCoverImageTimestamp(initialVideoPosition)
|
||||||
@ -3583,6 +3774,9 @@ public final class MediaEditorScreenImpl: ViewController, MediaEditorScreen, UID
|
|||||||
if case .stickerEditor = controller.mode {
|
if case .stickerEditor = controller.mode {
|
||||||
hasSwipeToDismiss = false
|
hasSwipeToDismiss = false
|
||||||
hasSwipeToEnhance = false
|
hasSwipeToEnhance = false
|
||||||
|
} else if case .avatarEditor = controller.mode {
|
||||||
|
hasSwipeToDismiss = false
|
||||||
|
hasSwipeToEnhance = false
|
||||||
} else if self.isCollageTimelineOpen {
|
} else if self.isCollageTimelineOpen {
|
||||||
hasSwipeToEnhance = false
|
hasSwipeToEnhance = false
|
||||||
}
|
}
|
||||||
@ -3772,7 +3966,7 @@ public final class MediaEditorScreenImpl: ViewController, MediaEditorScreen, UID
|
|||||||
} else {
|
} else {
|
||||||
initialScale = self.previewContainerView.bounds.width / image.size.width
|
initialScale = self.previewContainerView.bounds.width / image.size.width
|
||||||
}
|
}
|
||||||
case .stickerEditor:
|
case .stickerEditor, .avatarEditor:
|
||||||
if image.size.height > image.size.width {
|
if image.size.height > image.size.width {
|
||||||
initialScale = self.previewContainerView.bounds.width / image.size.width
|
initialScale = self.previewContainerView.bounds.width / image.size.width
|
||||||
} else {
|
} else {
|
||||||
@ -4845,6 +5039,8 @@ public final class MediaEditorScreenImpl: ViewController, MediaEditorScreen, UID
|
|||||||
controller.requestStickerCompletion(animated: true)
|
controller.requestStickerCompletion(animated: true)
|
||||||
case .botPreview:
|
case .botPreview:
|
||||||
controller.requestStoryCompletion(animated: true)
|
controller.requestStoryCompletion(animated: true)
|
||||||
|
case .avatarEditor:
|
||||||
|
controller.requestStoryCompletion(animated: true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5110,7 +5306,7 @@ public final class MediaEditorScreenImpl: ViewController, MediaEditorScreen, UID
|
|||||||
var hasInteractiveStickers = true
|
var hasInteractiveStickers = true
|
||||||
if let controller = self.controller {
|
if let controller = self.controller {
|
||||||
switch controller.mode {
|
switch controller.mode {
|
||||||
case .stickerEditor, .botPreview:
|
case .stickerEditor, .botPreview, .avatarEditor:
|
||||||
hasInteractiveStickers = false
|
hasInteractiveStickers = false
|
||||||
default:
|
default:
|
||||||
break
|
break
|
||||||
@ -5597,7 +5793,16 @@ public final class MediaEditorScreenImpl: ViewController, MediaEditorScreen, UID
|
|||||||
let stickerFrameRect = CGRect(origin: CGPoint(x: floorToScreenPixels((previewSize.width - stickerFrameWidth) / 2.0), y: floorToScreenPixels((previewSize.height - stickerFrameWidth) / 2.0)), size: CGSize(width: stickerFrameWidth, height: stickerFrameWidth))
|
let stickerFrameRect = CGRect(origin: CGPoint(x: floorToScreenPixels((previewSize.width - stickerFrameWidth) / 2.0), y: floorToScreenPixels((previewSize.height - stickerFrameWidth) / 2.0)), size: CGSize(width: stickerFrameWidth, height: stickerFrameWidth))
|
||||||
|
|
||||||
let overlayOuterRect = UIBezierPath(rect: CGRect(origin: .zero, size: previewSize))
|
let overlayOuterRect = UIBezierPath(rect: CGRect(origin: .zero, size: previewSize))
|
||||||
let overlayInnerRect = UIBezierPath(cgPath: CGPath(roundedRect: stickerFrameRect, cornerWidth: stickerFrameWidth / 8.0, cornerHeight: stickerFrameWidth / 8.0, transform: nil))
|
let overlayInnerRect: UIBezierPath
|
||||||
|
|
||||||
|
switch controller.mode {
|
||||||
|
case .avatarEditor:
|
||||||
|
overlayInnerRect = UIBezierPath(cgPath: CGPath(ellipseIn: stickerFrameRect, transform: nil))
|
||||||
|
stickerFrameLayer.isHidden = true
|
||||||
|
default:
|
||||||
|
overlayInnerRect = UIBezierPath(cgPath: CGPath(roundedRect: stickerFrameRect, cornerWidth: stickerFrameWidth / 8.0, cornerHeight: stickerFrameWidth / 8.0, transform: nil))
|
||||||
|
}
|
||||||
|
|
||||||
let overlayLineWidth: CGFloat = 2.0 - UIScreenPixel
|
let overlayLineWidth: CGFloat = 2.0 - UIScreenPixel
|
||||||
overlayOuterRect.append(overlayInnerRect)
|
overlayOuterRect.append(overlayInnerRect)
|
||||||
overlayOuterRect.usesEvenOddFillRule = true
|
overlayOuterRect.usesEvenOddFillRule = true
|
||||||
@ -5687,14 +5892,28 @@ public final class MediaEditorScreenImpl: ViewController, MediaEditorScreen, UID
|
|||||||
}
|
}
|
||||||
public let content: Content
|
public let content: Content
|
||||||
public let frame: CGRect
|
public let frame: CGRect
|
||||||
|
public let contentScale: CGFloat
|
||||||
|
public let contentOffset: CGPoint
|
||||||
|
|
||||||
var editorItem: MediaEditor.Subject.VideoCollageItem {
|
var editorItem: MediaEditor.Subject.VideoCollageItem {
|
||||||
return MediaEditor.Subject.VideoCollageItem(content: self.content.editorContent, frame: self.frame)
|
return MediaEditor.Subject.VideoCollageItem(
|
||||||
|
content: self.content.editorContent,
|
||||||
|
frame: self.frame,
|
||||||
|
contentScale: self.contentScale,
|
||||||
|
contentOffset: self.contentOffset
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
public init(content: Content, frame: CGRect) {
|
public init(
|
||||||
|
content: Content,
|
||||||
|
frame: CGRect,
|
||||||
|
contentScale: CGFloat,
|
||||||
|
contentOffset: CGPoint
|
||||||
|
) {
|
||||||
self.content = content
|
self.content = content
|
||||||
self.frame = frame
|
self.frame = frame
|
||||||
|
self.contentScale = contentScale
|
||||||
|
self.contentOffset = contentOffset
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -6559,7 +6778,7 @@ public final class MediaEditorScreenImpl: ViewController, MediaEditorScreen, UID
|
|||||||
save = presentationData.strings.Story_Editor_DraftKeepMedia
|
save = presentationData.strings.Story_Editor_DraftKeepMedia
|
||||||
}
|
}
|
||||||
text = presentationData.strings.Story_Editor_DraftDiscaedText
|
text = presentationData.strings.Story_Editor_DraftDiscaedText
|
||||||
case .stickerEditor, .botPreview:
|
case .stickerEditor, .botPreview, .avatarEditor:
|
||||||
title = presentationData.strings.Story_Editor_DraftDiscardMedia
|
title = presentationData.strings.Story_Editor_DraftDiscardMedia
|
||||||
text = presentationData.strings.Story_Editor_DiscardText
|
text = presentationData.strings.Story_Editor_DiscardText
|
||||||
}
|
}
|
||||||
@ -7063,7 +7282,13 @@ public final class MediaEditorScreenImpl: ViewController, MediaEditorScreen, UID
|
|||||||
if let image = mediaEditor.resultImage {
|
if let image = mediaEditor.resultImage {
|
||||||
self.saveDraft(id: randomId)
|
self.saveDraft(id: randomId)
|
||||||
|
|
||||||
makeEditorImageComposition(context: self.node.ciContext, postbox: self.context.account.postbox, inputImage: image, dimensions: storyDimensions, values: mediaEditor.values, time: .zero, textScale: 2.0, completion: { [weak self] resultImage in
|
var values = mediaEditor.values
|
||||||
|
var outputDimensions: CGSize?
|
||||||
|
if case .avatarEditor = self.mode {
|
||||||
|
outputDimensions = CGSize(width: 640.0, height: 640.0)
|
||||||
|
values = values.withUpdatedQualityPreset(.profile)
|
||||||
|
}
|
||||||
|
makeEditorImageComposition(context: self.node.ciContext, postbox: self.context.account.postbox, inputImage: image, dimensions: storyDimensions, outputDimensions: outputDimensions, values: values, time: .zero, textScale: 2.0, completion: { [weak self] resultImage in
|
||||||
if let self, let resultImage {
|
if let self, let resultImage {
|
||||||
Logger.shared.log("MediaEditor", "Completed with image \(resultImage)")
|
Logger.shared.log("MediaEditor", "Completed with image \(resultImage)")
|
||||||
self.completion(MediaEditorScreenImpl.Result(media: .image(image: resultImage, dimensions: PixelDimensions(resultImage.size)), mediaAreas: mediaAreas, caption: caption, coverTimestamp: nil, options: self.state.privacy, stickers: stickers, randomId: randomId), { [weak self] finished in
|
self.completion(MediaEditorScreenImpl.Result(media: .image(image: resultImage, dimensions: PixelDimensions(resultImage.size)), mediaAreas: mediaAreas, caption: caption, coverTimestamp: nil, options: self.state.privacy, stickers: stickers, randomId: randomId), { [weak self] finished in
|
||||||
@ -7649,7 +7874,7 @@ public final class MediaEditorScreenImpl: ViewController, MediaEditorScreen, UID
|
|||||||
case .addToStickerPack, .createStickerPack:
|
case .addToStickerPack, .createStickerPack:
|
||||||
if let (packReference, packTitle) = packReferenceAndTitle, let navigationController = self.navigationController as? NavigationController {
|
if let (packReference, packTitle) = packReferenceAndTitle, let navigationController = self.navigationController as? NavigationController {
|
||||||
Queue.mainQueue().after(0.2) {
|
Queue.mainQueue().after(0.2) {
|
||||||
let controller = self.context.sharedContext.makeStickerPackScreen(context: self.context, updatedPresentationData: nil, mainStickerPack: packReference, stickerPacks: [packReference], loadedStickerPacks: [], isEditing: false, expandIfNeeded: true, parentNavigationController: navigationController, sendSticker: self.sendSticker, actionPerformed: nil)
|
let controller = self.context.sharedContext.makeStickerPackScreen(context: self.context, updatedPresentationData: nil, mainStickerPack: packReference, stickerPacks: [packReference], loadedStickerPacks: [], actionTitle: nil, isEditing: false, expandIfNeeded: true, parentNavigationController: navigationController, sendSticker: self.sendSticker, actionPerformed: nil)
|
||||||
(navigationController.viewControllers.last as? ViewController)?.present(controller, in: .window(.root))
|
(navigationController.viewControllers.last as? ViewController)?.present(controller, in: .window(.root))
|
||||||
|
|
||||||
Queue.mainQueue().after(0.1) {
|
Queue.mainQueue().after(0.1) {
|
||||||
@ -7865,7 +8090,10 @@ public final class MediaEditorScreenImpl: ViewController, MediaEditorScreen, UID
|
|||||||
let videoExport = MediaEditorVideoExport(postbox: self.context.account.postbox, subject: exportSubject, configuration: configuration, outputPath: outputPath, textScale: 2.0)
|
let videoExport = MediaEditorVideoExport(postbox: self.context.account.postbox, subject: exportSubject, configuration: configuration, outputPath: outputPath, textScale: 2.0)
|
||||||
self.videoExport = videoExport
|
self.videoExport = videoExport
|
||||||
|
|
||||||
self.exportDisposable.set((videoExport.status
|
let status: Signal<MediaEditorVideoExport.ExportStatus, NoError> = .single(.progress(0.0))
|
||||||
|
|> then(videoExport.status)
|
||||||
|
|
||||||
|
self.exportDisposable.set((status
|
||||||
|> deliverOnMainQueue).start(next: { [weak self] status in
|
|> deliverOnMainQueue).start(next: { [weak self] status in
|
||||||
if let self {
|
if let self {
|
||||||
switch status {
|
switch status {
|
||||||
|
@ -91,6 +91,9 @@ public final class MediaScrubberComponent: Component {
|
|||||||
let isCollageSelected: Bool
|
let isCollageSelected: Bool
|
||||||
let collageSamples: (samples: Data, peak: Int32)?
|
let collageSamples: (samples: Data, peak: Int32)?
|
||||||
|
|
||||||
|
let cover: (position: Double, image: UIImage)?
|
||||||
|
let getCoverSourceView: () -> UIView?
|
||||||
|
|
||||||
let portalView: PortalView?
|
let portalView: PortalView?
|
||||||
|
|
||||||
let positionUpdated: (Double, Bool) -> Void
|
let positionUpdated: (Double, Bool) -> Void
|
||||||
@ -114,6 +117,8 @@ public final class MediaScrubberComponent: Component {
|
|||||||
isCollage: Bool,
|
isCollage: Bool,
|
||||||
isCollageSelected: Bool = false,
|
isCollageSelected: Bool = false,
|
||||||
collageSamples: (samples: Data, peak: Int32)? = nil,
|
collageSamples: (samples: Data, peak: Int32)? = nil,
|
||||||
|
cover: (position: Double, image: UIImage)? = nil,
|
||||||
|
getCoverSourceView: @escaping () -> UIView? = { return nil },
|
||||||
portalView: PortalView? = nil,
|
portalView: PortalView? = nil,
|
||||||
positionUpdated: @escaping (Double, Bool) -> Void,
|
positionUpdated: @escaping (Double, Bool) -> Void,
|
||||||
coverPositionUpdated: @escaping (Double, Bool, @escaping () -> Void) -> Void = { _, _, _ in },
|
coverPositionUpdated: @escaping (Double, Bool, @escaping () -> Void) -> Void = { _, _, _ in },
|
||||||
@ -135,6 +140,8 @@ public final class MediaScrubberComponent: Component {
|
|||||||
self.isCollage = isCollage
|
self.isCollage = isCollage
|
||||||
self.isCollageSelected = isCollageSelected
|
self.isCollageSelected = isCollageSelected
|
||||||
self.collageSamples = collageSamples
|
self.collageSamples = collageSamples
|
||||||
|
self.cover = cover
|
||||||
|
self.getCoverSourceView = getCoverSourceView
|
||||||
self.portalView = portalView
|
self.portalView = portalView
|
||||||
self.positionUpdated = positionUpdated
|
self.positionUpdated = positionUpdated
|
||||||
self.coverPositionUpdated = coverPositionUpdated
|
self.coverPositionUpdated = coverPositionUpdated
|
||||||
@ -179,6 +186,9 @@ public final class MediaScrubberComponent: Component {
|
|||||||
if lhs.collageSamples?.samples != rhs.collageSamples?.samples || lhs.collageSamples?.peak != rhs.collageSamples?.peak {
|
if lhs.collageSamples?.samples != rhs.collageSamples?.samples || lhs.collageSamples?.peak != rhs.collageSamples?.peak {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
if lhs.cover?.position != rhs.cover?.position {
|
||||||
|
return false
|
||||||
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -192,6 +202,10 @@ public final class MediaScrubberComponent: Component {
|
|||||||
private let cursorView: HandleView
|
private let cursorView: HandleView
|
||||||
private let cursorImageView: UIImageView
|
private let cursorImageView: UIImageView
|
||||||
|
|
||||||
|
private let coverDotWrapper: UIView
|
||||||
|
private let coverDotView: UIImageView
|
||||||
|
private let coverImageView: UIImageView
|
||||||
|
|
||||||
private var cursorDisplayLink: SharedDisplayLinkDriver.Link?
|
private var cursorDisplayLink: SharedDisplayLinkDriver.Link?
|
||||||
private var cursorPositionAnimation: (start: Double, from: Double, to: Double, ended: Bool)?
|
private var cursorPositionAnimation: (start: Double, from: Double, to: Double, ended: Bool)?
|
||||||
|
|
||||||
@ -213,6 +227,16 @@ public final class MediaScrubberComponent: Component {
|
|||||||
self.cursorView = HandleView()
|
self.cursorView = HandleView()
|
||||||
self.cursorImageView = UIImageView()
|
self.cursorImageView = UIImageView()
|
||||||
|
|
||||||
|
self.coverDotWrapper = UIView()
|
||||||
|
self.coverDotWrapper.isUserInteractionEnabled = false
|
||||||
|
self.coverDotWrapper.isHidden = true
|
||||||
|
|
||||||
|
self.coverDotView = UIImageView(image: generateFilledCircleImage(diameter: 7.0, color: UIColor(rgb: 0x007aff)))
|
||||||
|
|
||||||
|
self.coverImageView = UIImageView()
|
||||||
|
self.coverImageView.clipsToBounds = true
|
||||||
|
self.coverImageView.contentMode = .scaleAspectFill
|
||||||
|
|
||||||
super.init(frame: frame)
|
super.init(frame: frame)
|
||||||
|
|
||||||
self.clipsToBounds = false
|
self.clipsToBounds = false
|
||||||
@ -246,6 +270,10 @@ public final class MediaScrubberComponent: Component {
|
|||||||
self.addSubview(self.cursorView)
|
self.addSubview(self.cursorView)
|
||||||
self.cursorView.addSubview(self.cursorImageView)
|
self.cursorView.addSubview(self.cursorImageView)
|
||||||
|
|
||||||
|
self.addSubview(self.coverDotWrapper)
|
||||||
|
self.coverDotWrapper.addSubview(self.coverDotView)
|
||||||
|
self.coverDotWrapper.addSubview(self.coverImageView)
|
||||||
|
|
||||||
self.cursorView.addGestureRecognizer(UIPanGestureRecognizer(target: self, action: #selector(self.handleCursorPan(_:))))
|
self.cursorView.addGestureRecognizer(UIPanGestureRecognizer(target: self, action: #selector(self.handleCursorPan(_:))))
|
||||||
|
|
||||||
self.cursorDisplayLink = SharedDisplayLinkDriver.shared.add { [weak self] _ in
|
self.cursorDisplayLink = SharedDisplayLinkDriver.shared.add { [weak self] _ in
|
||||||
@ -632,12 +660,13 @@ public final class MediaScrubberComponent: Component {
|
|||||||
self.collageTrackView = trackView
|
self.collageTrackView = trackView
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let strings = component.context.sharedContext.currentPresentationData.with { $0 }.strings
|
||||||
let trackSize = trackView.update(
|
let trackSize = trackView.update(
|
||||||
context: component.context,
|
context: component.context,
|
||||||
style: component.style,
|
style: component.style,
|
||||||
track: MediaScrubberComponent.Track(
|
track: MediaScrubberComponent.Track(
|
||||||
id: 1024,
|
id: 1024,
|
||||||
content: .audio(artist: nil, title: "Timeline", samples: component.collageSamples?.samples, peak: component.collageSamples?.peak ?? 0, isTimeline: true),
|
content: .audio(artist: nil, title: strings.MediaEditor_Timeline, samples: component.collageSamples?.samples, peak: component.collageSamples?.peak ?? 0, isTimeline: true),
|
||||||
duration: component.maxDuration,
|
duration: component.maxDuration,
|
||||||
trimRange: nil,
|
trimRange: nil,
|
||||||
offset: nil,
|
offset: nil,
|
||||||
@ -808,7 +837,7 @@ public final class MediaScrubberComponent: Component {
|
|||||||
if let offset = self.mainAudioTrackOffset {
|
if let offset = self.mainAudioTrackOffset {
|
||||||
cursorPosition -= offset
|
cursorPosition -= offset
|
||||||
}
|
}
|
||||||
let cursorFrame = cursorFrame(size: scrubberSize, height: self.effectiveCursorHeight, position: cursorPosition, duration: trimDuration)
|
let cursorFrame = cursorFrame(size: scrubberSize, height: self.effectiveCursorHeight, position: cursorPosition, duration: self.trimDuration)
|
||||||
transition.setFrame(view: self.cursorView, frame: cursorFrame)
|
transition.setFrame(view: self.cursorView, frame: cursorFrame)
|
||||||
transition.setFrame(view: self.cursorContentView, frame: cursorFrame.insetBy(dx: 6.0, dy: 2.0).offsetBy(dx: -1.0 - UIScreenPixel, dy: 0.0))
|
transition.setFrame(view: self.cursorContentView, frame: cursorFrame.insetBy(dx: 6.0, dy: 2.0).offsetBy(dx: -1.0 - UIScreenPixel, dy: 0.0))
|
||||||
}
|
}
|
||||||
@ -826,6 +855,42 @@ public final class MediaScrubberComponent: Component {
|
|||||||
|
|
||||||
transition.setFrame(view: self.cursorImageView, frame: CGRect(origin: .zero, size: self.cursorView.frame.size))
|
transition.setFrame(view: self.cursorImageView, frame: CGRect(origin: .zero, size: self.cursorView.frame.size))
|
||||||
|
|
||||||
|
|
||||||
|
if let (coverPosition, coverImage) = component.cover {
|
||||||
|
let imageSize = CGSize(width: 36.0, height: 36.0)
|
||||||
|
var animateFrame = false
|
||||||
|
if previousComponent?.cover?.position != coverPosition {
|
||||||
|
self.coverDotWrapper.isHidden = false
|
||||||
|
if let _ = previousComponent?.cover {
|
||||||
|
if let snapshotView = self.coverDotWrapper.layer.snapshotContentTreeAsView() {
|
||||||
|
snapshotView.frame = self.coverDotWrapper.frame
|
||||||
|
self.addSubview(snapshotView)
|
||||||
|
snapshotView.layer.animateScale(from: 1.0, to: 0.01, duration: 0.2, removeOnCompletion: false)
|
||||||
|
snapshotView.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.2, removeOnCompletion: false, completion: { _ in
|
||||||
|
snapshotView.removeFromSuperview()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self.coverDotView.layer.animateScale(from: 0.01, to: 1.0, duration: 0.2)
|
||||||
|
self.coverImageView.image = coverImage
|
||||||
|
self.coverImageView.layer.cornerRadius = imageSize.width / 2.0
|
||||||
|
|
||||||
|
animateFrame = true
|
||||||
|
}
|
||||||
|
|
||||||
|
let dotSize = self.coverDotView.bounds.size
|
||||||
|
let dotFrame = cursorFrame(size: scrubberSize, height: dotSize.height, position: coverPosition, duration: self.trimDuration)
|
||||||
|
self.coverDotWrapper.frame = CGRect(origin: CGPoint(x: floor(dotFrame.center.x - dotSize.width / 2.0), y: -18.0), size: dotSize)
|
||||||
|
self.coverDotView.frame = CGRect(origin: .zero, size: dotSize)
|
||||||
|
self.coverImageView.frame = CGRect(origin: CGPoint(x: floorToScreenPixels((dotSize.width - imageSize.width) / 2.0), y: -42.0), size: imageSize)
|
||||||
|
|
||||||
|
if animateFrame, let sourceView = component.getCoverSourceView() {
|
||||||
|
let sourceFrame = sourceView.convert(sourceView.bounds, to: self.coverDotWrapper)
|
||||||
|
self.coverImageView.layer.animate(from: sourceFrame.width as NSNumber, to: self.coverImageView.layer.cornerRadius as NSNumber, keyPath: "cornerRadius", timingFunction: kCAMediaTimingFunctionSpring, duration: 0.4)
|
||||||
|
self.coverImageView.layer.animateFrame(from: sourceFrame, to: self.coverImageView.frame, duration: 0.4, timingFunction: kCAMediaTimingFunctionSpring)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if component.isCollage {
|
if component.isCollage {
|
||||||
transition.setAlpha(view: self.trackContainerView, alpha: component.isCollageSelected ? 1.0 : 0.0)
|
transition.setAlpha(view: self.trackContainerView, alpha: component.isCollageSelected ? 1.0 : 0.0)
|
||||||
}
|
}
|
||||||
@ -1114,7 +1179,10 @@ private class TrackView: UIView, UIScrollViewDelegate, UIGestureRecognizerDelega
|
|||||||
var deselectedClipWidth: CGFloat = 0.0
|
var deselectedClipWidth: CGFloat = 0.0
|
||||||
var deselectedClipOrigin: CGFloat = 0.0
|
var deselectedClipOrigin: CGFloat = 0.0
|
||||||
|
|
||||||
if !track.isMain, duration > 0.0 {
|
if track.isTimeline {
|
||||||
|
deselectedClipWidth = clipWidth
|
||||||
|
deselectedClipOrigin = clipOrigin
|
||||||
|
} else if !track.isMain, duration > 0.0 {
|
||||||
let trackDuration: Double
|
let trackDuration: Double
|
||||||
if let trimRange = track.trimRange {
|
if let trimRange = track.trimRange {
|
||||||
trackDuration = trimRange.upperBound - trimRange.lowerBound
|
trackDuration = trimRange.upperBound - trimRange.lowerBound
|
||||||
@ -1184,12 +1252,7 @@ private class TrackView: UIView, UIScrollViewDelegate, UIGestureRecognizerDelega
|
|||||||
|
|
||||||
let containerFrame = CGRect(origin: .zero, size: CGSize(width: containerTotalWidth, height: scrubberSize.height))
|
let containerFrame = CGRect(origin: .zero, size: CGSize(width: containerTotalWidth, height: scrubberSize.height))
|
||||||
transition.setFrame(view: self.containerView, frame: containerFrame)
|
transition.setFrame(view: self.containerView, frame: containerFrame)
|
||||||
|
|
||||||
transition.setFrame(view: self.backgroundView, frame: CGRect(origin: .zero, size: containerFrame.size))
|
|
||||||
self.backgroundView.update(size: containerFrame.size, transition: transition.containedViewLayoutTransition)
|
|
||||||
transition.setFrame(view: self.vibrancyView, frame: CGRect(origin: .zero, size: containerFrame.size))
|
|
||||||
transition.setFrame(view: self.vibrancyContainer, frame: CGRect(origin: .zero, size: containerFrame.size))
|
|
||||||
|
|
||||||
let contentContainerFrame = CGRect(origin: .zero, size: CGSize(width: clipWidth, height: containerFrame.height))
|
let contentContainerFrame = CGRect(origin: .zero, size: CGSize(width: clipWidth, height: containerFrame.height))
|
||||||
let contentContainerOrigin = deselectedClipOrigin + self.scrollView.contentOffset.x
|
let contentContainerOrigin = deselectedClipOrigin + self.scrollView.contentOffset.x
|
||||||
transition.setFrame(view: self.audioContentContainerView, frame: contentContainerFrame.offsetBy(dx: contentContainerOrigin, dy: 0.0))
|
transition.setFrame(view: self.audioContentContainerView, frame: contentContainerFrame.offsetBy(dx: contentContainerOrigin, dy: 0.0))
|
||||||
@ -1402,6 +1465,11 @@ private class TrackView: UIView, UIScrollViewDelegate, UIGestureRecognizerDelega
|
|||||||
transition.setFrame(layer: self.waveformCloneLayer, frame: audioWaveformFrame)
|
transition.setFrame(layer: self.waveformCloneLayer, frame: audioWaveformFrame)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
transition.setFrame(view: self.backgroundView, frame: CGRect(origin: .zero, size: containerFrame.size))
|
||||||
|
self.backgroundView.update(size: containerFrame.size, transition: transition.containedViewLayoutTransition)
|
||||||
|
transition.setFrame(view: self.vibrancyView, frame: CGRect(origin: .zero, size: containerFrame.size))
|
||||||
|
transition.setFrame(view: self.vibrancyContainer, frame: CGRect(origin: .zero, size: containerFrame.size))
|
||||||
|
|
||||||
return scrubberSize
|
return scrubberSize
|
||||||
}
|
}
|
||||||
|
@ -59,8 +59,44 @@ private func patternScaleValueAt(fraction: CGFloat, t: CGFloat, reverse: Bool) -
|
|||||||
}
|
}
|
||||||
|
|
||||||
public final class PeerInfoCoverComponent: Component {
|
public final class PeerInfoCoverComponent: Component {
|
||||||
|
public enum Subject: Equatable {
|
||||||
|
case peer(EnginePeer)
|
||||||
|
case custom(UIColor?, UIColor?, Int64?)
|
||||||
|
|
||||||
|
func colors(context: AccountContext, isDark: Bool) -> (UIColor, UIColor)? {
|
||||||
|
switch self {
|
||||||
|
case let .peer(peer):
|
||||||
|
if let colors = peer._asPeer().profileColor.flatMap({ context.peerNameColors.getProfile($0, dark: isDark) }) {
|
||||||
|
let backgroundColor = colors.main
|
||||||
|
let secondaryBackgroundColor = colors.secondary ?? colors.main
|
||||||
|
return (backgroundColor, secondaryBackgroundColor)
|
||||||
|
} else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
case let .custom(color, secondColor, _):
|
||||||
|
if let color {
|
||||||
|
if let secondColor {
|
||||||
|
return (color, secondColor)
|
||||||
|
} else {
|
||||||
|
return (color, color)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var fileId: Int64? {
|
||||||
|
switch self {
|
||||||
|
case let .peer(peer):
|
||||||
|
return peer.profileBackgroundEmojiId
|
||||||
|
case let .custom(_, _, fileId):
|
||||||
|
return fileId
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
public let context: AccountContext
|
public let context: AccountContext
|
||||||
public let peer: EnginePeer?
|
public let subject: Subject?
|
||||||
public let files: [Int64: TelegramMediaFile]
|
public let files: [Int64: TelegramMediaFile]
|
||||||
public let isDark: Bool
|
public let isDark: Bool
|
||||||
public let avatarCenter: CGPoint
|
public let avatarCenter: CGPoint
|
||||||
@ -71,7 +107,7 @@ public final class PeerInfoCoverComponent: Component {
|
|||||||
|
|
||||||
public init(
|
public init(
|
||||||
context: AccountContext,
|
context: AccountContext,
|
||||||
peer: EnginePeer?,
|
subject: Subject?,
|
||||||
files: [Int64: TelegramMediaFile],
|
files: [Int64: TelegramMediaFile],
|
||||||
isDark: Bool,
|
isDark: Bool,
|
||||||
avatarCenter: CGPoint,
|
avatarCenter: CGPoint,
|
||||||
@ -81,7 +117,7 @@ public final class PeerInfoCoverComponent: Component {
|
|||||||
patternTransitionFraction: CGFloat
|
patternTransitionFraction: CGFloat
|
||||||
) {
|
) {
|
||||||
self.context = context
|
self.context = context
|
||||||
self.peer = peer
|
self.subject = subject
|
||||||
self.files = files
|
self.files = files
|
||||||
self.isDark = isDark
|
self.isDark = isDark
|
||||||
self.avatarCenter = avatarCenter
|
self.avatarCenter = avatarCenter
|
||||||
@ -95,7 +131,7 @@ public final class PeerInfoCoverComponent: Component {
|
|||||||
if lhs.context !== rhs.context {
|
if lhs.context !== rhs.context {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
if lhs.peer != rhs.peer {
|
if lhs.subject != rhs.subject {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
if lhs.files != rhs.files {
|
if lhs.files != rhs.files {
|
||||||
@ -185,6 +221,32 @@ public final class PeerInfoCoverComponent: Component {
|
|||||||
self.patternImageDisposable?.dispose()
|
self.patternImageDisposable?.dispose()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public func animateTransition() {
|
||||||
|
if let snapshotLayer = self.backgroundView.layer.snapshotContentTree() {
|
||||||
|
self.layer.insertSublayer(snapshotLayer, above: self.backgroundGradientLayer)
|
||||||
|
if let gradientSnapshotLayer = self.backgroundGradientLayer.snapshotContentTree() {
|
||||||
|
self.layer.insertSublayer(gradientSnapshotLayer, above: snapshotLayer)
|
||||||
|
snapshotLayer.animateAlpha(from: 1.0, to: 0.0, duration: 0.25, removeOnCompletion: false, completion: { _ in
|
||||||
|
snapshotLayer.removeFromSuperlayer()
|
||||||
|
})
|
||||||
|
gradientSnapshotLayer.animateAlpha(from: 1.0, to: 0.0, duration: 0.25, removeOnCompletion: false, completion: { _ in
|
||||||
|
gradientSnapshotLayer.removeFromSuperlayer()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for layer in self.avatarPatternContentLayers {
|
||||||
|
if let snapshot = layer.snapshotContentTree() {
|
||||||
|
layer.superlayer?.addSublayer(snapshot)
|
||||||
|
snapshot.animateAlpha(from: 1.0, to: 0.0, duration: 0.25, removeOnCompletion: false, completion: { _ in
|
||||||
|
snapshot.removeFromSuperlayer()
|
||||||
|
})
|
||||||
|
layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.25)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let values: [NSNumber] = [1.0, 1.08, 1.0]
|
||||||
|
self.avatarBackgroundPatternContentsLayer.animateKeyframes(values: values, duration: 0.25, keyPath: "transform.scale")
|
||||||
|
}
|
||||||
|
|
||||||
private func loadPatternFromFile() {
|
private func loadPatternFromFile() {
|
||||||
guard let component = self.component else {
|
guard let component = self.component else {
|
||||||
return
|
return
|
||||||
@ -236,8 +298,8 @@ public final class PeerInfoCoverComponent: Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func update(component: PeerInfoCoverComponent, availableSize: CGSize, state: EmptyComponentState, environment: Environment<Empty>, transition: ComponentTransition) -> CGSize {
|
func update(component: PeerInfoCoverComponent, availableSize: CGSize, state: EmptyComponentState, environment: Environment<Empty>, transition: ComponentTransition) -> CGSize {
|
||||||
if self.component?.peer?.profileBackgroundEmojiId != component.peer?.profileBackgroundEmojiId {
|
if self.component?.subject?.fileId != component.subject?.fileId {
|
||||||
if let profileBackgroundEmojiId = component.peer?.profileBackgroundEmojiId, profileBackgroundEmojiId != 0 {
|
if let fileId = component.subject?.fileId, fileId != 0 {
|
||||||
if self.patternContentsTarget == nil {
|
if self.patternContentsTarget == nil {
|
||||||
self.patternContentsTarget = PatternContentsTarget(imageUpdated: { [weak self] hadContents in
|
self.patternContentsTarget = PatternContentsTarget(imageUpdated: { [weak self] hadContents in
|
||||||
guard let self else {
|
guard let self else {
|
||||||
@ -252,7 +314,6 @@ public final class PeerInfoCoverComponent: Component {
|
|||||||
self.patternFileDisposable = nil
|
self.patternFileDisposable = nil
|
||||||
self.patternImageDisposable?.dispose()
|
self.patternImageDisposable?.dispose()
|
||||||
|
|
||||||
let fileId = profileBackgroundEmojiId
|
|
||||||
if let file = component.files[fileId] {
|
if let file = component.files[fileId] {
|
||||||
self.patternFile = file
|
self.patternFile = file
|
||||||
self.loadPatternFromFile()
|
self.loadPatternFromFile()
|
||||||
@ -283,10 +344,9 @@ public final class PeerInfoCoverComponent: Component {
|
|||||||
let backgroundColor: UIColor
|
let backgroundColor: UIColor
|
||||||
let secondaryBackgroundColor: UIColor
|
let secondaryBackgroundColor: UIColor
|
||||||
|
|
||||||
if let peer = component.peer, let colors = peer._asPeer().profileColor.flatMap({ component.context.peerNameColors.getProfile($0, dark: component.isDark) }) {
|
if let subject = component.subject, let colors = subject.colors(context: component.context, isDark: component.isDark) {
|
||||||
|
backgroundColor = colors.0
|
||||||
backgroundColor = colors.main
|
secondaryBackgroundColor = colors.1
|
||||||
secondaryBackgroundColor = colors.secondary ?? colors.main
|
|
||||||
} else {
|
} else {
|
||||||
backgroundColor = .clear
|
backgroundColor = .clear
|
||||||
secondaryBackgroundColor = .clear
|
secondaryBackgroundColor = .clear
|
||||||
@ -324,7 +384,7 @@ public final class PeerInfoCoverComponent: Component {
|
|||||||
let avatarPatternFrame = CGSize(width: 380.0, height: floor(component.defaultHeight * 1.0)).centered(around: component.avatarCenter)
|
let avatarPatternFrame = CGSize(width: 380.0, height: floor(component.defaultHeight * 1.0)).centered(around: component.avatarCenter)
|
||||||
transition.setFrame(layer: self.avatarBackgroundPatternContentsLayer, frame: avatarPatternFrame)
|
transition.setFrame(layer: self.avatarBackgroundPatternContentsLayer, frame: avatarPatternFrame)
|
||||||
|
|
||||||
if component.peer?.profileColor != nil {
|
if component.subject?.colors(context: component.context, isDark: component.isDark) != nil {
|
||||||
self.avatarBackgroundPatternContentsLayer.compositingFilter = "overlayBlendMode"
|
self.avatarBackgroundPatternContentsLayer.compositingFilter = "overlayBlendMode"
|
||||||
self.avatarBackgroundPatternContentsLayer.colors = [
|
self.avatarBackgroundPatternContentsLayer.colors = [
|
||||||
UIColor(white: 0.0, alpha: 0.6).cgColor,
|
UIColor(white: 0.0, alpha: 0.6).cgColor,
|
||||||
@ -341,17 +401,17 @@ public final class PeerInfoCoverComponent: Component {
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
self.avatarBackgroundGradientLayer.isHidden = component.peer?.profileColor == nil
|
self.avatarBackgroundGradientLayer.isHidden = component.subject?.colors(context: component.context, isDark: component.isDark) == nil
|
||||||
transition.setFrame(layer: self.avatarBackgroundGradientLayer, frame: CGSize(width: 300.0, height: 300.0).centered(around: component.avatarCenter))
|
transition.setFrame(layer: self.avatarBackgroundGradientLayer, frame: CGSize(width: 300.0, height: 300.0).centered(around: component.avatarCenter))
|
||||||
transition.setAlpha(layer: self.avatarBackgroundGradientLayer, alpha: 1.0 - component.avatarTransitionFraction)
|
transition.setAlpha(layer: self.avatarBackgroundGradientLayer, alpha: 1.0 - component.avatarTransitionFraction)
|
||||||
|
|
||||||
let backgroundPatternContainerFrame = CGRect(origin: CGPoint(x: 0.0, y: availableSize.height), size: CGSize(width: availableSize.width, height: 0.0))
|
let backgroundPatternContainerFrame = CGRect(origin: CGPoint(x: 0.0, y: availableSize.height), size: CGSize(width: availableSize.width, height: 0.0))
|
||||||
transition.containedViewLayoutTransition.updateFrameAdditive(view: self.backgroundPatternContainer, frame: backgroundPatternContainerFrame)
|
transition.containedViewLayoutTransition.updateFrameAdditive(view: self.backgroundPatternContainer, frame: backgroundPatternContainerFrame)
|
||||||
if component.peer?.id == component.context.account.peerId {
|
// if component.peer?.id == component.context.account.peerId {
|
||||||
transition.setAlpha(view: self.backgroundPatternContainer, alpha: 0.0)
|
// transition.setAlpha(view: self.backgroundPatternContainer, alpha: 0.0)
|
||||||
} else {
|
// } else {
|
||||||
transition.setAlpha(view: self.backgroundPatternContainer, alpha: component.patternTransitionFraction)
|
transition.setAlpha(view: self.backgroundPatternContainer, alpha: component.patternTransitionFraction)
|
||||||
}
|
// }
|
||||||
|
|
||||||
var avatarBackgroundPatternLayerCount = 0
|
var avatarBackgroundPatternLayerCount = 0
|
||||||
let lokiRng = LokiRng(seed0: 123, seed1: 0, seed2: 0)
|
let lokiRng = LokiRng(seed0: 123, seed1: 0, seed2: 0)
|
||||||
|
@ -150,6 +150,10 @@ swift_library(
|
|||||||
"//submodules/TelegramUI/Components/TextNodeWithEntities",
|
"//submodules/TelegramUI/Components/TextNodeWithEntities",
|
||||||
"//submodules/UrlHandling",
|
"//submodules/UrlHandling",
|
||||||
"//submodules/TelegramUI/Components/EmojiTextAttachmentView",
|
"//submodules/TelegramUI/Components/EmojiTextAttachmentView",
|
||||||
|
"//submodules/TelegramUI/Components/MediaEditor",
|
||||||
|
"//submodules/TelegramUI/Components/MediaEditorScreen",
|
||||||
|
"//submodules/TelegramUI/Components/CameraScreen",
|
||||||
|
"//submodules/TelegramUI/Components/PeerInfo/VerifyAlertController",
|
||||||
],
|
],
|
||||||
visibility = [
|
visibility = [
|
||||||
"//visibility:public",
|
"//visibility:public",
|
||||||
|
@ -4,6 +4,8 @@ import TelegramPresentationData
|
|||||||
import TextFormat
|
import TextFormat
|
||||||
import Markdown
|
import Markdown
|
||||||
import AccountContext
|
import AccountContext
|
||||||
|
import TextNodeWithEntities
|
||||||
|
import TextFormat
|
||||||
|
|
||||||
final class PeerInfoScreenCommentItem: PeerInfoScreenItem {
|
final class PeerInfoScreenCommentItem: PeerInfoScreenItem {
|
||||||
enum LinkAction {
|
enum LinkAction {
|
||||||
@ -12,11 +14,15 @@ final class PeerInfoScreenCommentItem: PeerInfoScreenItem {
|
|||||||
|
|
||||||
let id: AnyHashable
|
let id: AnyHashable
|
||||||
let text: String
|
let text: String
|
||||||
|
let attributedPrefix: NSAttributedString?
|
||||||
|
let useAccentLinkColor: Bool
|
||||||
let linkAction: ((LinkAction) -> Void)?
|
let linkAction: ((LinkAction) -> Void)?
|
||||||
|
|
||||||
init(id: AnyHashable, text: String, linkAction: ((LinkAction) -> Void)? = nil) {
|
init(id: AnyHashable, text: String, attributedPrefix: NSAttributedString? = nil, useAccentLinkColor: Bool = true, linkAction: ((LinkAction) -> Void)? = nil) {
|
||||||
self.id = id
|
self.id = id
|
||||||
self.text = text
|
self.text = text
|
||||||
|
self.attributedPrefix = attributedPrefix
|
||||||
|
self.useAccentLinkColor = useAccentLinkColor
|
||||||
self.linkAction = linkAction
|
self.linkAction = linkAction
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -26,7 +32,7 @@ final class PeerInfoScreenCommentItem: PeerInfoScreenItem {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private final class PeerInfoScreenCommentItemNode: PeerInfoScreenItemNode {
|
private final class PeerInfoScreenCommentItemNode: PeerInfoScreenItemNode {
|
||||||
private let textNode: ImmediateTextNode
|
private let textNode: ImmediateTextNodeWithEntities
|
||||||
private var linkHighlightingNode: LinkHighlightingNode?
|
private var linkHighlightingNode: LinkHighlightingNode?
|
||||||
private let activateArea: AccessibilityAreaNode
|
private let activateArea: AccessibilityAreaNode
|
||||||
|
|
||||||
@ -36,7 +42,7 @@ private final class PeerInfoScreenCommentItemNode: PeerInfoScreenItemNode {
|
|||||||
private var chevronImage: UIImage?
|
private var chevronImage: UIImage?
|
||||||
|
|
||||||
override init() {
|
override init() {
|
||||||
self.textNode = ImmediateTextNode()
|
self.textNode = ImmediateTextNodeWithEntities()
|
||||||
self.textNode.displaysAsynchronously = false
|
self.textNode.displaysAsynchronously = false
|
||||||
self.textNode.isUserInteractionEnabled = false
|
self.textNode.isUserInteractionEnabled = false
|
||||||
|
|
||||||
@ -77,15 +83,30 @@ private final class PeerInfoScreenCommentItemNode: PeerInfoScreenItemNode {
|
|||||||
let verticalInset: CGFloat = 7.0
|
let verticalInset: CGFloat = 7.0
|
||||||
|
|
||||||
self.textNode.maximumNumberOfLines = 0
|
self.textNode.maximumNumberOfLines = 0
|
||||||
|
self.textNode.arguments = TextNodeWithEntities.Arguments(
|
||||||
|
context: context,
|
||||||
|
cache: context.animationCache,
|
||||||
|
renderer: context.animationRenderer,
|
||||||
|
placeholderColor: presentationData.theme.list.mediaPlaceholderColor,
|
||||||
|
attemptSynchronous: false
|
||||||
|
)
|
||||||
|
|
||||||
let textFont = Font.regular(presentationData.listsFontSize.itemListBaseHeaderFontSize)
|
let textFont = Font.regular(presentationData.listsFontSize.itemListBaseHeaderFontSize)
|
||||||
let textColor = presentationData.theme.list.freeTextColor
|
let textColor = presentationData.theme.list.freeTextColor
|
||||||
|
|
||||||
var text = item.text
|
var text = item.text
|
||||||
text = text.replacingOccurrences(of: " >]", with: "\u{00A0}>]")
|
text = text.replacingOccurrences(of: " >]", with: "\u{00A0}>]")
|
||||||
let attributedText = parseMarkdownIntoAttributedString(text, attributes: MarkdownAttributes(body: MarkdownAttributeSet(font: textFont, textColor: textColor), bold: MarkdownAttributeSet(font: textFont, textColor: textColor), link: MarkdownAttributeSet(font: textFont, textColor: presentationData.theme.list.itemAccentColor), linkAttribute: { contents in
|
|
||||||
|
let attributedText = parseMarkdownIntoAttributedString(text, attributes: MarkdownAttributes(body: MarkdownAttributeSet(font: textFont, textColor: textColor), bold: MarkdownAttributeSet(font: textFont, textColor: textColor), link: MarkdownAttributeSet(font: textFont, textColor: item.useAccentLinkColor ? presentationData.theme.list.itemAccentColor : textColor, additionalAttributes: item.useAccentLinkColor ? [:] : [NSAttributedString.Key.underlineStyle.rawValue: NSUnderlineStyle.single.rawValue as NSNumber]), linkAttribute: { contents in
|
||||||
return (TelegramTextAttributes.URL, contents)
|
return (TelegramTextAttributes.URL, contents)
|
||||||
})).mutableCopy() as! NSMutableAttributedString
|
})).mutableCopy() as! NSMutableAttributedString
|
||||||
|
|
||||||
|
if let attributedPrefix = item.attributedPrefix {
|
||||||
|
attributedText.insert(attributedPrefix, at: 0)
|
||||||
|
attributedText.addAttribute(NSAttributedString.Key.font, value: textFont, range: NSRange(location: 0, length: attributedPrefix.length))
|
||||||
|
attributedText.addAttribute(NSAttributedString.Key.foregroundColor, value: textColor, range: NSRange(location: 0, length: attributedPrefix.length))
|
||||||
|
}
|
||||||
|
|
||||||
if let _ = item.text.range(of: ">]"), let range = attributedText.string.range(of: ">") {
|
if let _ = item.text.range(of: ">]"), let range = attributedText.string.range(of: ">") {
|
||||||
if themeUpdated || self.chevronImage == nil {
|
if themeUpdated || self.chevronImage == nil {
|
||||||
self.chevronImage = generateTintedImage(image: UIImage(bundleImageName: "Contact List/SubtitleArrow"), color: presentationData.theme.list.itemAccentColor)
|
self.chevronImage = generateTintedImage(image: UIImage(bundleImageName: "Contact List/SubtitleArrow"), color: presentationData.theme.list.itemAccentColor)
|
||||||
@ -96,6 +117,8 @@ private final class PeerInfoScreenCommentItemNode: PeerInfoScreenItemNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
self.textNode.attributedText = attributedText
|
self.textNode.attributedText = attributedText
|
||||||
|
self.textNode.visibility = true
|
||||||
|
self.textNode.lineSpacing = 0.12
|
||||||
self.activateArea.accessibilityLabel = attributedText.string
|
self.activateArea.accessibilityLabel = attributedText.string
|
||||||
|
|
||||||
let textSize = self.textNode.updateLayout(CGSize(width: width - sideInset * 2.0, height: .greatestFiniteMagnitude))
|
let textSize = self.textNode.updateLayout(CGSize(width: width - sideInset * 2.0, height: .greatestFiniteMagnitude))
|
||||||
@ -135,7 +158,7 @@ private final class PeerInfoScreenCommentItemNode: PeerInfoScreenItemNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private func updateTouchesAtPoint(_ point: CGPoint?) {
|
private func updateTouchesAtPoint(_ point: CGPoint?) {
|
||||||
if let _ = self.item, let presentationData = self.presentationData {
|
if let item = self.item, let presentationData = self.presentationData {
|
||||||
var rects: [CGRect]?
|
var rects: [CGRect]?
|
||||||
if let point = point {
|
if let point = point {
|
||||||
let textNodeFrame = self.textNode.frame
|
let textNodeFrame = self.textNode.frame
|
||||||
@ -161,7 +184,7 @@ private final class PeerInfoScreenCommentItemNode: PeerInfoScreenItemNode {
|
|||||||
if let current = self.linkHighlightingNode {
|
if let current = self.linkHighlightingNode {
|
||||||
linkHighlightingNode = current
|
linkHighlightingNode = current
|
||||||
} else {
|
} else {
|
||||||
linkHighlightingNode = LinkHighlightingNode(color: presentationData.theme.list.itemAccentColor.withAlphaComponent(0.2))
|
linkHighlightingNode = LinkHighlightingNode(color: item.useAccentLinkColor ? presentationData.theme.list.itemAccentColor.withAlphaComponent(0.2) : presentationData.theme.list.freeTextColor.withAlphaComponent(0.2))
|
||||||
self.linkHighlightingNode = linkHighlightingNode
|
self.linkHighlightingNode = linkHighlightingNode
|
||||||
self.insertSubnode(linkHighlightingNode, belowSubnode: self.textNode)
|
self.insertSubnode(linkHighlightingNode, belowSubnode: self.textNode)
|
||||||
}
|
}
|
||||||
|
@ -531,17 +531,17 @@ final class PeerInfoHeaderNode: ASDisplayNode {
|
|||||||
} else if peer.isScam {
|
} else if peer.isScam {
|
||||||
credibilityIcon = .scam
|
credibilityIcon = .scam
|
||||||
} else if let emojiStatus = peer.emojiStatus, !premiumConfiguration.isPremiumDisabled {
|
} else if let emojiStatus = peer.emojiStatus, !premiumConfiguration.isPremiumDisabled {
|
||||||
if peer is TelegramChannel, peer.isVerified {
|
|
||||||
verifiedIcon = .verified
|
|
||||||
}
|
|
||||||
credibilityIcon = .emojiStatus(emojiStatus)
|
credibilityIcon = .emojiStatus(emojiStatus)
|
||||||
} else if peer.isVerified {
|
|
||||||
credibilityIcon = .verified
|
|
||||||
} else if peer.isPremium && !premiumConfiguration.isPremiumDisabled && (peer.id != self.context.account.peerId || self.isSettings || self.isMyProfile) {
|
} else if peer.isPremium && !premiumConfiguration.isPremiumDisabled && (peer.id != self.context.account.peerId || self.isSettings || self.isMyProfile) {
|
||||||
credibilityIcon = .premium
|
credibilityIcon = .premium
|
||||||
} else {
|
} else {
|
||||||
credibilityIcon = .none
|
credibilityIcon = .none
|
||||||
}
|
}
|
||||||
|
if peer.isVerified {
|
||||||
|
verifiedIcon = .verified
|
||||||
|
} else if let verification = peer.verification {
|
||||||
|
verifiedIcon = .emojiStatus(PeerEmojiStatus(fileId: verification.iconFileId, expirationDate: nil))
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
credibilityIcon = .none
|
credibilityIcon = .none
|
||||||
}
|
}
|
||||||
@ -780,8 +780,8 @@ final class PeerInfoHeaderNode: ASDisplayNode {
|
|||||||
emojiRegularStatusContent = .premium(color: navigationContentsAccentColor)
|
emojiRegularStatusContent = .premium(color: navigationContentsAccentColor)
|
||||||
emojiExpandedStatusContent = .premium(color: navigationContentsAccentColor)
|
emojiExpandedStatusContent = .premium(color: navigationContentsAccentColor)
|
||||||
case .verified:
|
case .verified:
|
||||||
emojiRegularStatusContent = .verified(fillColor: presentationData.theme.list.itemCheckColors.fillColor, foregroundColor: presentationData.theme.list.itemCheckColors.foregroundColor, sizeType: .large)
|
emojiRegularStatusContent = .none
|
||||||
emojiExpandedStatusContent = .verified(fillColor: navigationContentsAccentColor, foregroundColor: .clear, sizeType: .large)
|
emojiExpandedStatusContent = .none
|
||||||
case .fake:
|
case .fake:
|
||||||
emojiRegularStatusContent = .text(color: presentationData.theme.chat.message.incoming.scamColor, string: presentationData.strings.Message_FakeAccount.uppercased())
|
emojiRegularStatusContent = .text(color: presentationData.theme.chat.message.incoming.scamColor, string: presentationData.strings.Message_FakeAccount.uppercased())
|
||||||
emojiExpandedStatusContent = emojiRegularStatusContent
|
emojiExpandedStatusContent = emojiRegularStatusContent
|
||||||
@ -793,7 +793,7 @@ final class PeerInfoHeaderNode: ASDisplayNode {
|
|||||||
emojiRegularStatusContent = .animation(content: .customEmoji(fileId: emojiStatus.fileId), size: CGSize(width: 80.0, height: 80.0), placeholderColor: presentationData.theme.list.mediaPlaceholderColor, themeColor: navigationContentsAccentColor, loopMode: .forever)
|
emojiRegularStatusContent = .animation(content: .customEmoji(fileId: emojiStatus.fileId), size: CGSize(width: 80.0, height: 80.0), placeholderColor: presentationData.theme.list.mediaPlaceholderColor, themeColor: navigationContentsAccentColor, loopMode: .forever)
|
||||||
emojiExpandedStatusContent = .animation(content: .customEmoji(fileId: emojiStatus.fileId), size: CGSize(width: 80.0, height: 80.0), placeholderColor: navigationContentsAccentColor, themeColor: navigationContentsAccentColor, loopMode: .forever)
|
emojiExpandedStatusContent = .animation(content: .customEmoji(fileId: emojiStatus.fileId), size: CGSize(width: 80.0, height: 80.0), placeholderColor: navigationContentsAccentColor, themeColor: navigationContentsAccentColor, loopMode: .forever)
|
||||||
}
|
}
|
||||||
|
|
||||||
let iconSize = self.titleCredibilityIconView.update(
|
let iconSize = self.titleCredibilityIconView.update(
|
||||||
transition: ComponentTransition(navigationTransition),
|
transition: ComponentTransition(navigationTransition),
|
||||||
component: AnyComponent(EmojiStatusComponent(
|
component: AnyComponent(EmojiStatusComponent(
|
||||||
@ -848,7 +848,7 @@ final class PeerInfoHeaderNode: ASDisplayNode {
|
|||||||
}
|
}
|
||||||
)),
|
)),
|
||||||
environment: {},
|
environment: {},
|
||||||
containerSize: CGSize(width: 34.0, height: 34.0)
|
containerSize: CGSize(width: 26.0, height: 26.0)
|
||||||
)
|
)
|
||||||
let expandedIconSize = self.titleExpandedCredibilityIconView.update(
|
let expandedIconSize = self.titleExpandedCredibilityIconView.update(
|
||||||
transition: ComponentTransition(navigationTransition),
|
transition: ComponentTransition(navigationTransition),
|
||||||
@ -867,7 +867,7 @@ final class PeerInfoHeaderNode: ASDisplayNode {
|
|||||||
}
|
}
|
||||||
)),
|
)),
|
||||||
environment: {},
|
environment: {},
|
||||||
containerSize: CGSize(width: 34.0, height: 34.0)
|
containerSize: CGSize(width: 26.0, height: 26.0)
|
||||||
)
|
)
|
||||||
|
|
||||||
self.credibilityIconSize = iconSize
|
self.credibilityIconSize = iconSize
|
||||||
@ -877,29 +877,18 @@ final class PeerInfoHeaderNode: ASDisplayNode {
|
|||||||
do {
|
do {
|
||||||
self.currentVerifiedIcon = verifiedIcon
|
self.currentVerifiedIcon = verifiedIcon
|
||||||
|
|
||||||
var currentEmojiStatus: PeerEmojiStatus?
|
|
||||||
let emojiRegularStatusContent: EmojiStatusComponent.Content
|
let emojiRegularStatusContent: EmojiStatusComponent.Content
|
||||||
let emojiExpandedStatusContent: EmojiStatusComponent.Content
|
let emojiExpandedStatusContent: EmojiStatusComponent.Content
|
||||||
switch verifiedIcon {
|
switch verifiedIcon {
|
||||||
case .none:
|
|
||||||
emojiRegularStatusContent = .none
|
|
||||||
emojiExpandedStatusContent = .none
|
|
||||||
case .premium:
|
|
||||||
emojiRegularStatusContent = .premium(color: navigationContentsAccentColor)
|
|
||||||
emojiExpandedStatusContent = .premium(color: navigationContentsAccentColor)
|
|
||||||
case .verified:
|
case .verified:
|
||||||
emojiRegularStatusContent = .verified(fillColor: presentationData.theme.list.itemCheckColors.fillColor, foregroundColor: presentationData.theme.list.itemCheckColors.foregroundColor, sizeType: .large)
|
emojiRegularStatusContent = .verified(fillColor: presentationData.theme.list.itemCheckColors.fillColor, foregroundColor: presentationData.theme.list.itemCheckColors.foregroundColor, sizeType: .large)
|
||||||
emojiExpandedStatusContent = .verified(fillColor: navigationContentsAccentColor, foregroundColor: .clear, sizeType: .large)
|
emojiExpandedStatusContent = .verified(fillColor: navigationContentsAccentColor, foregroundColor: .clear, sizeType: .large)
|
||||||
case .fake:
|
|
||||||
emojiRegularStatusContent = .text(color: presentationData.theme.chat.message.incoming.scamColor, string: presentationData.strings.Message_FakeAccount.uppercased())
|
|
||||||
emojiExpandedStatusContent = emojiRegularStatusContent
|
|
||||||
case .scam:
|
|
||||||
emojiRegularStatusContent = .text(color: presentationData.theme.chat.message.incoming.scamColor, string: presentationData.strings.Message_ScamAccount.uppercased())
|
|
||||||
emojiExpandedStatusContent = emojiRegularStatusContent
|
|
||||||
case let .emojiStatus(emojiStatus):
|
case let .emojiStatus(emojiStatus):
|
||||||
currentEmojiStatus = emojiStatus
|
|
||||||
emojiRegularStatusContent = .animation(content: .customEmoji(fileId: emojiStatus.fileId), size: CGSize(width: 80.0, height: 80.0), placeholderColor: presentationData.theme.list.mediaPlaceholderColor, themeColor: navigationContentsAccentColor, loopMode: .forever)
|
emojiRegularStatusContent = .animation(content: .customEmoji(fileId: emojiStatus.fileId), size: CGSize(width: 80.0, height: 80.0), placeholderColor: presentationData.theme.list.mediaPlaceholderColor, themeColor: navigationContentsAccentColor, loopMode: .forever)
|
||||||
emojiExpandedStatusContent = .animation(content: .customEmoji(fileId: emojiStatus.fileId), size: CGSize(width: 80.0, height: 80.0), placeholderColor: navigationContentsAccentColor, themeColor: navigationContentsAccentColor, loopMode: .forever)
|
emojiExpandedStatusContent = .animation(content: .customEmoji(fileId: emojiStatus.fileId), size: CGSize(width: 80.0, height: 80.0), placeholderColor: navigationContentsAccentColor, themeColor: navigationContentsAccentColor, loopMode: .forever)
|
||||||
|
default:
|
||||||
|
emojiRegularStatusContent = .none
|
||||||
|
emojiExpandedStatusContent = .none
|
||||||
}
|
}
|
||||||
|
|
||||||
let iconSize = self.titleVerifiedIconView.update(
|
let iconSize = self.titleVerifiedIconView.update(
|
||||||
@ -915,7 +904,7 @@ final class PeerInfoHeaderNode: ASDisplayNode {
|
|||||||
emojiFileUpdated: nil
|
emojiFileUpdated: nil
|
||||||
)),
|
)),
|
||||||
environment: {},
|
environment: {},
|
||||||
containerSize: CGSize(width: 34.0, height: 34.0)
|
containerSize: CGSize(width: 26.0, height: 26.0)
|
||||||
)
|
)
|
||||||
let expandedIconSize = self.titleExpandedVerifiedIconView.update(
|
let expandedIconSize = self.titleExpandedVerifiedIconView.update(
|
||||||
transition: ComponentTransition(navigationTransition),
|
transition: ComponentTransition(navigationTransition),
|
||||||
@ -926,15 +915,10 @@ final class PeerInfoHeaderNode: ASDisplayNode {
|
|||||||
content: emojiExpandedStatusContent,
|
content: emojiExpandedStatusContent,
|
||||||
isVisibleForAnimations: true,
|
isVisibleForAnimations: true,
|
||||||
useSharedAnimation: true,
|
useSharedAnimation: true,
|
||||||
action: { [weak self] in
|
action: {}
|
||||||
guard let strongSelf = self else {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
strongSelf.displayPremiumIntro?(strongSelf.titleExpandedVerifiedIconView, currentEmojiStatus, strongSelf.emojiStatusFileAndPackTitle.get(), true)
|
|
||||||
}
|
|
||||||
)),
|
)),
|
||||||
environment: {},
|
environment: {},
|
||||||
containerSize: CGSize(width: 34.0, height: 34.0)
|
containerSize: CGSize(width: 26.0, height: 26.0)
|
||||||
)
|
)
|
||||||
|
|
||||||
self.verifiedIconSize = iconSize
|
self.verifiedIconSize = iconSize
|
||||||
@ -1318,35 +1302,44 @@ final class PeerInfoHeaderNode: ASDisplayNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var titleHorizontalOffset: CGFloat = 0.0
|
var titleHorizontalOffset: CGFloat = 0.0
|
||||||
|
var titleExpandedHorizontalOffset: CGFloat = 0.0
|
||||||
var nextIconX: CGFloat = titleSize.width
|
var nextIconX: CGFloat = titleSize.width
|
||||||
var nextExpandedIconX: CGFloat = titleExpandedSize.width
|
var nextExpandedIconX: CGFloat = titleExpandedSize.width
|
||||||
|
|
||||||
if let credibilityIconSize = self.credibilityIconSize, let titleExpandedCredibilityIconSize = self.titleExpandedCredibilityIconSize {
|
if let credibilityIconSize = self.credibilityIconSize, let titleExpandedCredibilityIconSize = self.titleExpandedCredibilityIconSize {
|
||||||
titleHorizontalOffset += -(credibilityIconSize.width + 4.0) / 2.0
|
let offset = (credibilityIconSize.width + 4.0) / 2.0
|
||||||
|
|
||||||
|
let leftOffset: CGFloat = nextIconX + 4.0
|
||||||
|
let leftExpandedOffset: CGFloat = nextExpandedIconX + 4.0
|
||||||
|
titleHorizontalOffset -= offset
|
||||||
|
|
||||||
var collapsedTransitionOffset: CGFloat = 0.0
|
var collapsedTransitionOffset: CGFloat = 0.0
|
||||||
if let navigationTransition = self.navigationTransition {
|
if let navigationTransition = self.navigationTransition {
|
||||||
collapsedTransitionOffset = -10.0 * navigationTransition.fraction
|
collapsedTransitionOffset = -10.0 * navigationTransition.fraction
|
||||||
}
|
}
|
||||||
|
|
||||||
transition.updateFrame(view: self.titleCredibilityIconView, frame: CGRect(origin: CGPoint(x: nextIconX + 4.0 + collapsedTransitionOffset, y: floor((titleSize.height - credibilityIconSize.height) / 2.0)), size: credibilityIconSize))
|
transition.updateFrame(view: self.titleCredibilityIconView, frame: CGRect(origin: CGPoint(x: leftOffset + collapsedTransitionOffset, y: floor((titleSize.height - credibilityIconSize.height) / 2.0)), size: credibilityIconSize))
|
||||||
|
transition.updateFrame(view: self.titleExpandedCredibilityIconView, frame: CGRect(origin: CGPoint(x: leftExpandedOffset, y: floor((titleExpandedSize.height - titleExpandedCredibilityIconSize.height) / 2.0) + 1.0), size: titleExpandedCredibilityIconSize))
|
||||||
|
|
||||||
nextIconX += 4.0 + credibilityIconSize.width
|
nextIconX += 4.0 + credibilityIconSize.width
|
||||||
transition.updateFrame(view: self.titleExpandedCredibilityIconView, frame: CGRect(origin: CGPoint(x: nextExpandedIconX + 4.0, y: floor((titleExpandedSize.height - titleExpandedCredibilityIconSize.height) / 2.0) + 1.0), size: titleExpandedCredibilityIconSize))
|
|
||||||
nextExpandedIconX += 4.0 + titleExpandedCredibilityIconSize.width
|
nextExpandedIconX += 4.0 + titleExpandedCredibilityIconSize.width
|
||||||
}
|
}
|
||||||
|
|
||||||
if let verifiedIconSize = self.verifiedIconSize, let titleExpandedVerifiedIconSize = self.titleExpandedVerifiedIconSize {
|
if let verifiedIconSize = self.verifiedIconSize, let titleExpandedVerifiedIconSize = self.titleExpandedVerifiedIconSize {
|
||||||
titleHorizontalOffset += -(verifiedIconSize.width + 4.0) / 2.0
|
let offset = (verifiedIconSize.width + 4.0) / 2.0
|
||||||
|
titleHorizontalOffset += offset
|
||||||
|
titleExpandedHorizontalOffset += offset
|
||||||
|
|
||||||
|
let leftOffset: CGFloat = -verifiedIconSize.width - 4.0
|
||||||
|
let leftExpandedOffset: CGFloat = -titleExpandedVerifiedIconSize.width - 4.0
|
||||||
|
|
||||||
var collapsedTransitionOffset: CGFloat = 0.0
|
var collapsedTransitionOffset: CGFloat = 0.0
|
||||||
if let navigationTransition = self.navigationTransition {
|
if let navigationTransition = self.navigationTransition {
|
||||||
collapsedTransitionOffset = -10.0 * navigationTransition.fraction
|
collapsedTransitionOffset = -10.0 * navigationTransition.fraction
|
||||||
}
|
}
|
||||||
|
|
||||||
transition.updateFrame(view: self.titleVerifiedIconView, frame: CGRect(origin: CGPoint(x: nextIconX + 4.0 + collapsedTransitionOffset, y: floor((titleSize.height - verifiedIconSize.height) / 2.0)), size: verifiedIconSize))
|
transition.updateFrame(view: self.titleVerifiedIconView, frame: CGRect(origin: CGPoint(x: leftOffset + collapsedTransitionOffset, y: floor((titleSize.height - verifiedIconSize.height) / 2.0)), size: verifiedIconSize))
|
||||||
nextIconX += 4.0 + verifiedIconSize.width
|
transition.updateFrame(view: self.titleExpandedVerifiedIconView, frame: CGRect(origin: CGPoint(x: leftExpandedOffset, y: floor((titleExpandedSize.height - titleExpandedVerifiedIconSize.height) / 2.0) + 1.0), size: titleExpandedVerifiedIconSize))
|
||||||
transition.updateFrame(view: self.titleExpandedVerifiedIconView, frame: CGRect(origin: CGPoint(x: nextExpandedIconX + 4.0, y: floor((titleExpandedSize.height - titleExpandedVerifiedIconSize.height) / 2.0) + 1.0), size: titleExpandedVerifiedIconSize))
|
|
||||||
nextExpandedIconX += 4.0 + titleExpandedVerifiedIconSize.width
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var titleFrame: CGRect
|
var titleFrame: CGRect
|
||||||
@ -1766,7 +1759,7 @@ final class PeerInfoHeaderNode: ASDisplayNode {
|
|||||||
|
|
||||||
var titleFrame = titleFrame
|
var titleFrame = titleFrame
|
||||||
if !self.isAvatarExpanded {
|
if !self.isAvatarExpanded {
|
||||||
titleFrame = titleFrame.offsetBy(dx: self.isAvatarExpanded ? 0.0 : titleHorizontalOffset * titleScale, dy: 0.0)
|
titleFrame = titleFrame.offsetBy(dx: self.isAvatarExpanded ? titleExpandedHorizontalOffset : titleHorizontalOffset * titleScale, dy: 0.0)
|
||||||
}
|
}
|
||||||
|
|
||||||
let titleCenter = CGPoint(x: transitionFraction * transitionSourceTitleFrame.midX + (1.0 - transitionFraction) * titleFrame.midX, y: transitionFraction * transitionSourceTitleFrame.midY + (1.0 - transitionFraction) * titleFrame.midY)
|
let titleCenter = CGPoint(x: transitionFraction * transitionSourceTitleFrame.midX + (1.0 - transitionFraction) * titleFrame.midX, y: transitionFraction * transitionSourceTitleFrame.midY + (1.0 - transitionFraction) * titleFrame.midY)
|
||||||
@ -1807,7 +1800,7 @@ final class PeerInfoHeaderNode: ASDisplayNode {
|
|||||||
subtitleBadgeFraction = (1.0 - titleCollapseFraction)
|
subtitleBadgeFraction = (1.0 - titleCollapseFraction)
|
||||||
}
|
}
|
||||||
|
|
||||||
let rawTitleFrame = titleFrame.offsetBy(dx: self.isAvatarExpanded ? 0.0 : titleHorizontalOffset * titleScale, dy: 0.0)
|
let rawTitleFrame = titleFrame.offsetBy(dx: self.isAvatarExpanded ? titleExpandedHorizontalOffset : titleHorizontalOffset * titleScale, dy: 0.0)
|
||||||
self.titleNodeRawContainer.frame = rawTitleFrame
|
self.titleNodeRawContainer.frame = rawTitleFrame
|
||||||
transition.updateFrame(node: self.titleNode, frame: CGRect(origin: CGPoint(), size: CGSize()))
|
transition.updateFrame(node: self.titleNode, frame: CGRect(origin: CGPoint(), size: CGSize()))
|
||||||
let rawSubtitleFrame = subtitleFrame
|
let rawSubtitleFrame = subtitleFrame
|
||||||
@ -2119,7 +2112,7 @@ final class PeerInfoHeaderNode: ASDisplayNode {
|
|||||||
transition: ComponentTransition(transition),
|
transition: ComponentTransition(transition),
|
||||||
component: AnyComponent(PeerInfoCoverComponent(
|
component: AnyComponent(PeerInfoCoverComponent(
|
||||||
context: self.context,
|
context: self.context,
|
||||||
peer: peer.flatMap(EnginePeer.init),
|
subject: peer.flatMap { .peer(EnginePeer($0)) },
|
||||||
files: [:],
|
files: [:],
|
||||||
isDark: presentationData.theme.overallDarkAppearance,
|
isDark: presentationData.theme.overallDarkAppearance,
|
||||||
avatarCenter: apparentAvatarFrame.center,
|
avatarCenter: apparentAvatarFrame.center,
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,607 @@
|
|||||||
|
import Foundation
|
||||||
|
import UIKit
|
||||||
|
import Display
|
||||||
|
import SwiftSignalKit
|
||||||
|
import TelegramCore
|
||||||
|
import AccountContext
|
||||||
|
import MediaEditor
|
||||||
|
import MediaEditorScreen
|
||||||
|
import CameraScreen
|
||||||
|
import Photos
|
||||||
|
import PeerInfoAvatarListNode
|
||||||
|
import MapResourceToAvatarSizes
|
||||||
|
import AvatarEditorScreen
|
||||||
|
import OverlayStatusController
|
||||||
|
import UndoUI
|
||||||
|
import PeerAvatarGalleryUI
|
||||||
|
import PresentationDataUtils
|
||||||
|
|
||||||
|
extension PeerInfoScreenImpl {
|
||||||
|
func openAvatarForEditing(mode: PeerInfoAvatarEditingMode = .generic, fromGallery: Bool = false, completion: @escaping (UIImage?) -> Void = { _ in }) {
|
||||||
|
guard let data = self.controllerNode.data, let peer = data.peer, mode != .generic || canEditPeerInfo(context: self.context, peer: peer, chatLocation: self.chatLocation, threadData: data.threadData) else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
self.view.endEditing(true)
|
||||||
|
|
||||||
|
let peerId = self.peerId
|
||||||
|
var isForum = false
|
||||||
|
if let peer = peer as? TelegramChannel, peer.flags.contains(.isForum) {
|
||||||
|
isForum = true
|
||||||
|
}
|
||||||
|
|
||||||
|
var currentIsVideo = false
|
||||||
|
var emojiMarkup: TelegramMediaImage.EmojiMarkup?
|
||||||
|
let item = self.controllerNode.headerNode.avatarListNode.listContainerNode.currentItemNode?.item
|
||||||
|
if let item = item, case let .image(_, _, videoRepresentations, _, _, emojiMarkupValue) = item {
|
||||||
|
currentIsVideo = !videoRepresentations.isEmpty
|
||||||
|
emojiMarkup = emojiMarkupValue
|
||||||
|
}
|
||||||
|
|
||||||
|
let _ = isForum
|
||||||
|
let _ = currentIsVideo
|
||||||
|
|
||||||
|
let _ = (self.context.engine.data.get(
|
||||||
|
TelegramEngine.EngineData.Item.Peer.Peer(id: peerId)
|
||||||
|
)
|
||||||
|
|> deliverOnMainQueue).startStandalone(next: { [weak self] peer in
|
||||||
|
guard let self, let peer else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
let keyboardInputData = Promise<AvatarKeyboardInputData>()
|
||||||
|
keyboardInputData.set(AvatarEditorScreen.inputData(context: self.context, isGroup: peer.id.namespace != Namespaces.Peer.CloudUser))
|
||||||
|
|
||||||
|
var hasPhotos = false
|
||||||
|
if !peer.profileImageRepresentations.isEmpty {
|
||||||
|
hasPhotos = true
|
||||||
|
}
|
||||||
|
|
||||||
|
var hasDeleteButton = false
|
||||||
|
if case .generic = mode {
|
||||||
|
hasDeleteButton = hasPhotos && !fromGallery
|
||||||
|
} else if case .custom = mode {
|
||||||
|
hasDeleteButton = peer.profileImageRepresentations.first?.isPersonal == true
|
||||||
|
} else if case .fallback = mode {
|
||||||
|
if let cachedData = data.cachedData as? CachedUserData, case let .known(photo) = cachedData.fallbackPhoto {
|
||||||
|
hasDeleteButton = photo != nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let _ = hasDeleteButton
|
||||||
|
|
||||||
|
let parentController = (self.context.sharedContext.mainWindow?.viewController as? NavigationController)?.topViewController as? ViewController
|
||||||
|
|
||||||
|
var dismissImpl: (() -> Void)?
|
||||||
|
let mainController = self.context.sharedContext.makeAvatarMediaPickerScreen(context: self.context, getSourceRect: { return nil }, canDelete: hasDeleteButton, performDelete: { [weak self] in
|
||||||
|
self?.openAvatarRemoval(mode: mode, peer: peer, item: item)
|
||||||
|
}, completion: { result, transitionView, transitionRect, transitionImage, fromCamera, transitionOut, cancelled in
|
||||||
|
let subject: Signal<MediaEditorScreenImpl.Subject?, NoError>
|
||||||
|
if let asset = result as? PHAsset {
|
||||||
|
subject = .single(.asset(asset))
|
||||||
|
} else if let image = result as? UIImage {
|
||||||
|
subject = .single(.image(image: image, dimensions: PixelDimensions(image.size), additionalImage: nil, additionalImagePosition: .bottomRight))
|
||||||
|
} else if let result = result as? Signal<CameraScreenImpl.Result, NoError> {
|
||||||
|
subject = result
|
||||||
|
|> map { value -> MediaEditorScreenImpl.Subject? in
|
||||||
|
switch value {
|
||||||
|
case .pendingImage:
|
||||||
|
return nil
|
||||||
|
case let .image(image):
|
||||||
|
return .image(image: image.image, dimensions: PixelDimensions(image.image.size), additionalImage: nil, additionalImagePosition: .topLeft)
|
||||||
|
case let .video(video):
|
||||||
|
return .video(videoPath: video.videoPath, thumbnail: video.coverImage, mirror: video.mirror, additionalVideoPath: nil, additionalThumbnail: nil, dimensions: video.dimensions, duration: video.duration, videoPositionChanges: [], additionalVideoPosition: .topLeft)
|
||||||
|
default:
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
let peerType: AvatarEditorScreen.PeerType
|
||||||
|
if mode == .suggest {
|
||||||
|
peerType = .suggest
|
||||||
|
} else if case .legacyGroup = peer {
|
||||||
|
peerType = .group
|
||||||
|
} else if case let .channel(channel) = peer {
|
||||||
|
if case .group = channel.info {
|
||||||
|
peerType = channel.flags.contains(.isForum) ? .forum : .group
|
||||||
|
} else {
|
||||||
|
peerType = .channel
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
peerType = .user
|
||||||
|
}
|
||||||
|
let controller = AvatarEditorScreen(context: self.context, inputData: keyboardInputData.get(), peerType: peerType, markup: emojiMarkup)
|
||||||
|
//controller.imageCompletion = imageCompletion
|
||||||
|
//controller.videoCompletion = videoCompletion
|
||||||
|
parentController?.push(controller)
|
||||||
|
//isFromEditor = true
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
let editorController = MediaEditorScreenImpl(
|
||||||
|
context: self.context,
|
||||||
|
mode: .avatarEditor,
|
||||||
|
subject: subject,
|
||||||
|
transitionIn: fromCamera ? .camera : transitionView.flatMap({ .gallery(
|
||||||
|
MediaEditorScreenImpl.TransitionIn.GalleryTransitionIn(
|
||||||
|
sourceView: $0,
|
||||||
|
sourceRect: transitionRect,
|
||||||
|
sourceImage: transitionImage
|
||||||
|
)
|
||||||
|
) }),
|
||||||
|
transitionOut: { finished, isNew in
|
||||||
|
if !finished, let transitionView {
|
||||||
|
return MediaEditorScreenImpl.TransitionOut(
|
||||||
|
destinationView: transitionView,
|
||||||
|
destinationRect: transitionView.bounds,
|
||||||
|
destinationCornerRadius: 0.0
|
||||||
|
)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}, completion: { [weak self] result, commit in
|
||||||
|
dismissImpl?()
|
||||||
|
|
||||||
|
switch result.media {
|
||||||
|
case let .image(image, _):
|
||||||
|
self?.updateProfilePhoto(image, mode: mode)
|
||||||
|
commit({})
|
||||||
|
case let .video(video, coverImage, values, _, _):
|
||||||
|
if let coverImage {
|
||||||
|
self?.updateProfileVideo(coverImage, asset: video, adjustments: values, mode: mode)
|
||||||
|
}
|
||||||
|
commit({})
|
||||||
|
default:
|
||||||
|
break
|
||||||
|
}
|
||||||
|
} as (MediaEditorScreenImpl.Result, @escaping (@escaping () -> Void) -> Void) -> Void
|
||||||
|
)
|
||||||
|
editorController.cancelled = { _ in
|
||||||
|
cancelled()
|
||||||
|
}
|
||||||
|
self.push(editorController)
|
||||||
|
}, dismissed: {
|
||||||
|
|
||||||
|
})
|
||||||
|
dismissImpl = { [weak mainController] in
|
||||||
|
if let mainController, let navigationController = mainController.navigationController {
|
||||||
|
var viewControllers = navigationController.viewControllers
|
||||||
|
viewControllers = viewControllers.filter { c in
|
||||||
|
return !(c is CameraScreen) && c !== mainController
|
||||||
|
}
|
||||||
|
navigationController.setViewControllers(viewControllers, animated: false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mainController.navigationPresentation = .flatModal
|
||||||
|
mainController.supportedOrientations = ViewControllerSupportedOrientations(regularSize: .all, compactSize: .portrait)
|
||||||
|
self.push(mainController)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func openAvatarRemoval(mode: PeerInfoAvatarEditingMode, peer: EnginePeer? = nil, item: PeerInfoAvatarListItem? = nil, completion: @escaping () -> Void = {}) {
|
||||||
|
let proceed = { [weak self] in
|
||||||
|
guard let strongSelf = self else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
completion()
|
||||||
|
|
||||||
|
if let item = item {
|
||||||
|
strongSelf.controllerNode.deleteProfilePhoto(item)
|
||||||
|
}
|
||||||
|
if mode != .fallback {
|
||||||
|
if let peer = peer, let _ = peer.smallProfileImage {
|
||||||
|
strongSelf.controllerNode.state = strongSelf.controllerNode.state.withUpdatingAvatar(nil)
|
||||||
|
if let (layout, navigationHeight) = strongSelf.controllerNode.validLayout {
|
||||||
|
strongSelf.controllerNode.containerLayoutUpdated(layout: layout, navigationHeight: navigationHeight, transition: .immediate, additive: false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let postbox = strongSelf.context.account.postbox
|
||||||
|
let signal: Signal<UpdatePeerPhotoStatus, UploadPeerPhotoError>
|
||||||
|
if case .custom = mode {
|
||||||
|
signal = strongSelf.context.engine.contacts.updateContactPhoto(peerId: strongSelf.peerId, resource: nil, videoResource: nil, videoStartTimestamp: nil, markup: nil, mode: .custom, mapResourceToAvatarSizes: { resource, representations in
|
||||||
|
return mapResourceToAvatarSizes(postbox: postbox, resource: resource, representations: representations)
|
||||||
|
})
|
||||||
|
} else if case .fallback = mode {
|
||||||
|
signal = strongSelf.context.engine.accountData.removeFallbackPhoto(reference: nil)
|
||||||
|
|> castError(UploadPeerPhotoError.self)
|
||||||
|
|> map { _ in
|
||||||
|
return .complete([])
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
signal = strongSelf.context.engine.peers.updatePeerPhoto(peerId: strongSelf.peerId, photo: nil, mapResourceToAvatarSizes: { resource, representations in
|
||||||
|
return mapResourceToAvatarSizes(postbox: postbox, resource: resource, representations: representations)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
strongSelf.controllerNode.updateAvatarDisposable.set((signal
|
||||||
|
|> deliverOnMainQueue).startStrict(next: { result in
|
||||||
|
guard let strongSelf = self else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
switch result {
|
||||||
|
case .complete:
|
||||||
|
strongSelf.controllerNode.state = strongSelf.controllerNode.state.withUpdatingAvatar(nil)
|
||||||
|
if let (layout, navigationHeight) = strongSelf.controllerNode.validLayout {
|
||||||
|
strongSelf.controllerNode.containerLayoutUpdated(layout: layout, navigationHeight: navigationHeight, transition: .immediate, additive: false)
|
||||||
|
}
|
||||||
|
case .progress:
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
let presentationData = self.presentationData
|
||||||
|
let actionSheet = ActionSheetController(presentationData: presentationData)
|
||||||
|
let items: [ActionSheetItem] = [
|
||||||
|
ActionSheetButtonItem(title: presentationData.strings.Settings_RemoveConfirmation, color: .destructive, action: { [weak actionSheet] in
|
||||||
|
actionSheet?.dismissAnimated()
|
||||||
|
proceed()
|
||||||
|
})
|
||||||
|
]
|
||||||
|
|
||||||
|
actionSheet.setItemGroups([
|
||||||
|
ActionSheetItemGroup(items: items),
|
||||||
|
ActionSheetItemGroup(items: [
|
||||||
|
ActionSheetButtonItem(title: presentationData.strings.Common_Cancel, color: .accent, font: .bold, action: { [weak actionSheet] in
|
||||||
|
actionSheet?.dismissAnimated()
|
||||||
|
})
|
||||||
|
])
|
||||||
|
])
|
||||||
|
(self.navigationController?.topViewController as? ViewController)?.present(actionSheet, in: .window(.root))
|
||||||
|
}
|
||||||
|
|
||||||
|
public func updateProfilePhoto(_ image: UIImage, mode: PeerInfoAvatarEditingMode) {
|
||||||
|
guard let data = image.jpegData(compressionQuality: 0.6) else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if self.controllerNode.headerNode.isAvatarExpanded {
|
||||||
|
self.controllerNode.headerNode.ignoreCollapse = true
|
||||||
|
self.controllerNode.headerNode.updateIsAvatarExpanded(false, transition: .immediate)
|
||||||
|
self.controllerNode.updateNavigationExpansionPresentation(isExpanded: false, animated: true)
|
||||||
|
}
|
||||||
|
self.controllerNode.scrollNode.view.setContentOffset(CGPoint(), animated: false)
|
||||||
|
|
||||||
|
let resource = LocalFileMediaResource(fileId: Int64.random(in: Int64.min ... Int64.max))
|
||||||
|
self.context.account.postbox.mediaBox.storeResourceData(resource.id, data: data)
|
||||||
|
let representation = TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: 640, height: 640), resource: resource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false, isPersonal: mode == .custom ? true : false)
|
||||||
|
|
||||||
|
if [.suggest, .fallback].contains(mode) {
|
||||||
|
} else {
|
||||||
|
self.controllerNode.state = self.controllerNode.state.withUpdatingAvatar(.image(representation))
|
||||||
|
}
|
||||||
|
|
||||||
|
if let (layout, navigationHeight) = self.controllerNode.validLayout {
|
||||||
|
self.controllerNode.containerLayoutUpdated(layout: layout, navigationHeight: navigationHeight, transition: mode == .custom ? .animated(duration: 0.2, curve: .easeInOut) : .immediate, additive: false)
|
||||||
|
}
|
||||||
|
self.controllerNode.headerNode.ignoreCollapse = false
|
||||||
|
|
||||||
|
let postbox = self.context.account.postbox
|
||||||
|
let signal: Signal<UpdatePeerPhotoStatus, UploadPeerPhotoError>
|
||||||
|
if self.isSettings || self.isMyProfile {
|
||||||
|
if case .fallback = mode {
|
||||||
|
signal = self.context.engine.accountData.updateFallbackPhoto(resource: resource, videoResource: nil, videoStartTimestamp: nil, markup: nil, mapResourceToAvatarSizes: { resource, representations in
|
||||||
|
return mapResourceToAvatarSizes(postbox: postbox, resource: resource, representations: representations)
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
signal = self.context.engine.accountData.updateAccountPhoto(resource: resource, videoResource: nil, videoStartTimestamp: nil, markup: nil, mapResourceToAvatarSizes: { resource, representations in
|
||||||
|
return mapResourceToAvatarSizes(postbox: postbox, resource: resource, representations: representations)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
} else if case .custom = mode {
|
||||||
|
signal = self.context.engine.contacts.updateContactPhoto(peerId: self.peerId, resource: resource, videoResource: nil, videoStartTimestamp: nil, markup: nil, mode: .custom, mapResourceToAvatarSizes: { resource, representations in
|
||||||
|
return mapResourceToAvatarSizes(postbox: postbox, resource: resource, representations: representations)
|
||||||
|
})
|
||||||
|
} else if case .suggest = mode {
|
||||||
|
signal = self.context.engine.contacts.updateContactPhoto(peerId: self.peerId, resource: resource, videoResource: nil, videoStartTimestamp: nil, markup: nil, mode: .suggest, mapResourceToAvatarSizes: { resource, representations in
|
||||||
|
return mapResourceToAvatarSizes(postbox: postbox, resource: resource, representations: representations)
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
signal = self.context.engine.peers.updatePeerPhoto(peerId: self.peerId, photo: self.context.engine.peers.uploadedPeerPhoto(resource: resource), mapResourceToAvatarSizes: { resource, representations in
|
||||||
|
return mapResourceToAvatarSizes(postbox: postbox, resource: resource, representations: representations)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
var dismissStatus: (() -> Void)?
|
||||||
|
if [.suggest, .fallback, .accept].contains(mode) {
|
||||||
|
let statusController = OverlayStatusController(theme: self.presentationData.theme, type: .loading(cancelled: { [weak self] in
|
||||||
|
self?.controllerNode.updateAvatarDisposable.set(nil)
|
||||||
|
dismissStatus?()
|
||||||
|
}))
|
||||||
|
dismissStatus = { [weak statusController] in
|
||||||
|
statusController?.dismiss()
|
||||||
|
}
|
||||||
|
if let topController = self.navigationController?.topViewController as? ViewController {
|
||||||
|
topController.presentInGlobalOverlay(statusController)
|
||||||
|
} else if let topController = self.parentController?.topViewController as? ViewController {
|
||||||
|
topController.presentInGlobalOverlay(statusController)
|
||||||
|
} else {
|
||||||
|
self.presentInGlobalOverlay(statusController)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
self.controllerNode.updateAvatarDisposable.set((signal
|
||||||
|
|> deliverOnMainQueue).startStrict(next: { [weak self] result in
|
||||||
|
guard let strongSelf = self else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
switch result {
|
||||||
|
case .complete:
|
||||||
|
strongSelf.controllerNode.state = strongSelf.controllerNode.state.withUpdatingAvatar(nil).withAvatarUploadProgress(nil)
|
||||||
|
case let .progress(value):
|
||||||
|
strongSelf.controllerNode.state = strongSelf.controllerNode.state.withAvatarUploadProgress(.value(CGFloat(value)))
|
||||||
|
}
|
||||||
|
if let (layout, navigationHeight) = strongSelf.controllerNode.validLayout {
|
||||||
|
strongSelf.controllerNode.containerLayoutUpdated(layout: layout, navigationHeight: navigationHeight, transition: .immediate, additive: false)
|
||||||
|
}
|
||||||
|
|
||||||
|
if case .complete = result {
|
||||||
|
dismissStatus?()
|
||||||
|
|
||||||
|
let _ = (strongSelf.context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: strongSelf.peerId))
|
||||||
|
|> deliverOnMainQueue).startStandalone(next: { [weak self] peer in
|
||||||
|
if let strongSelf = self, let peer {
|
||||||
|
switch mode {
|
||||||
|
case .fallback:
|
||||||
|
(strongSelf.parentController?.topViewController as? ViewController)?.present(UndoOverlayController(presentationData: strongSelf.presentationData, content: .image(image: image, title: nil, text: strongSelf.presentationData.strings.Privacy_ProfilePhoto_PublicPhotoSuccess, round: true, undoText: nil), elevatedLayout: false, animateInAsReplacement: true, action: { _ in return false }), in: .current)
|
||||||
|
case .custom:
|
||||||
|
strongSelf.present(UndoOverlayController(presentationData: strongSelf.presentationData, content: .invitedToVoiceChat(context: strongSelf.context, peer: peer, title: nil, text: strongSelf.presentationData.strings.UserInfo_SetCustomPhoto_SuccessPhotoText(peer.compactDisplayTitle).string, action: nil, duration: 5), elevatedLayout: false, animateInAsReplacement: true, action: { _ in return false }), in: .current)
|
||||||
|
|
||||||
|
let _ = (strongSelf.context.peerChannelMemberCategoriesContextsManager.profilePhotos(postbox: strongSelf.context.account.postbox, network: strongSelf.context.account.network, peerId: strongSelf.peerId, fetch: peerInfoProfilePhotos(context: strongSelf.context, peerId: strongSelf.peerId)) |> ignoreValues).startStandalone()
|
||||||
|
case .suggest:
|
||||||
|
if let navigationController = (strongSelf.navigationController as? NavigationController) {
|
||||||
|
strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: .peer(peer), keepStack: .default, completion: { _ in
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
case .accept:
|
||||||
|
(strongSelf.parentController?.topViewController as? ViewController)?.present(UndoOverlayController(presentationData: strongSelf.presentationData, content: .image(image: image, title: strongSelf.presentationData.strings.Conversation_SuggestedPhotoSuccess, text: strongSelf.presentationData.strings.Conversation_SuggestedPhotoSuccessText, round: true, undoText: nil), elevatedLayout: false, animateInAsReplacement: true, action: { [weak self] action in
|
||||||
|
if case .info = action {
|
||||||
|
self?.parentController?.openSettings()
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}), in: .current)
|
||||||
|
default:
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
public func updateProfileVideo(_ image: UIImage, asset: Any?, adjustments: MediaEditorValues?, mode: PeerInfoAvatarEditingMode) {
|
||||||
|
guard let data = image.jpegData(compressionQuality: 0.6) else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if self.controllerNode.headerNode.isAvatarExpanded {
|
||||||
|
self.controllerNode.headerNode.ignoreCollapse = true
|
||||||
|
self.controllerNode.headerNode.updateIsAvatarExpanded(false, transition: .immediate)
|
||||||
|
self.controllerNode.updateNavigationExpansionPresentation(isExpanded: false, animated: true)
|
||||||
|
}
|
||||||
|
self.controllerNode.scrollNode.view.setContentOffset(CGPoint(), animated: false)
|
||||||
|
|
||||||
|
let photoResource = LocalFileMediaResource(fileId: Int64.random(in: Int64.min ... Int64.max))
|
||||||
|
self.context.account.postbox.mediaBox.storeResourceData(photoResource.id, data: data)
|
||||||
|
// let representation = TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: 640, height: 640), resource: photoResource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false, isPersonal: mode == .custom ? true : false)
|
||||||
|
//
|
||||||
|
// var markup: UploadPeerPhotoMarkup? = nil
|
||||||
|
// if let fileId = adjustments?.documentId, let backgroundColors = adjustments?.colors as? [Int32], fileId != 0 {
|
||||||
|
// if let packId = adjustments?.stickerPackId, let accessHash = adjustments?.stickerPackAccessHash, packId != 0 {
|
||||||
|
// markup = .sticker(packReference: .id(id: packId, accessHash: accessHash), fileId: fileId, backgroundColors: backgroundColors)
|
||||||
|
// } else {
|
||||||
|
// markup = .emoji(fileId: fileId, backgroundColors: backgroundColors)
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// var uploadVideo = true
|
||||||
|
// if let _ = markup {
|
||||||
|
// if let data = self.context.currentAppConfiguration.with({ $0 }).data, let uploadVideoValue = data["upload_markup_video"] as? Bool, uploadVideoValue {
|
||||||
|
// uploadVideo = true
|
||||||
|
// } else {
|
||||||
|
// uploadVideo = false
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// if [.suggest, .fallback].contains(mode) {
|
||||||
|
// } else {
|
||||||
|
// self.controllerNode.state = self.controllerNode.state.withUpdatingAvatar(.image(representation))
|
||||||
|
// if !uploadVideo {
|
||||||
|
// self.controllerNode.state = self.controllerNode.state.withAvatarUploadProgress(.indefinite)
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// if let (layout, navigationHeight) = self.controllerNode.validLayout {
|
||||||
|
// self.controllerNode.containerLayoutUpdated(layout: layout, navigationHeight: navigationHeight, transition: mode == .custom ? .animated(duration: 0.2, curve: .easeInOut) : .immediate, additive: false)
|
||||||
|
// }
|
||||||
|
// self.controllerNode.headerNode.ignoreCollapse = false
|
||||||
|
//
|
||||||
|
// var videoStartTimestamp: Double? = nil
|
||||||
|
// if let adjustments = adjustments, adjustments.videoStartValue > 0.0 {
|
||||||
|
// videoStartTimestamp = adjustments.videoStartValue - adjustments.trimStartValue
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// let account = self.context.account
|
||||||
|
// let context = self.context
|
||||||
|
//
|
||||||
|
// let videoResource: Signal<TelegramMediaResource?, UploadPeerPhotoError>
|
||||||
|
// if uploadVideo {
|
||||||
|
// videoResource = Signal<TelegramMediaResource?, UploadPeerPhotoError> { [weak self] subscriber in
|
||||||
|
// let entityRenderer: LegacyPaintEntityRenderer? = adjustments.flatMap { adjustments in
|
||||||
|
// if let paintingData = adjustments.paintingData, paintingData.hasAnimation {
|
||||||
|
// return LegacyPaintEntityRenderer(postbox: account.postbox, adjustments: adjustments)
|
||||||
|
// } else {
|
||||||
|
// return nil
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// let tempFile = EngineTempBox.shared.tempFile(fileName: "video.mp4")
|
||||||
|
// let uploadInterface = LegacyLiveUploadInterface(context: context)
|
||||||
|
// let signal: SSignal
|
||||||
|
// if let url = asset as? URL, url.absoluteString.hasSuffix(".jpg"), let data = try? Data(contentsOf: url, options: [.mappedRead]), let image = UIImage(data: data), let entityRenderer = entityRenderer {
|
||||||
|
// let durationSignal: SSignal = SSignal(generator: { subscriber in
|
||||||
|
// let disposable = (entityRenderer.duration()).start(next: { duration in
|
||||||
|
// subscriber.putNext(duration)
|
||||||
|
// subscriber.putCompletion()
|
||||||
|
// })
|
||||||
|
//
|
||||||
|
// return SBlockDisposable(block: {
|
||||||
|
// disposable.dispose()
|
||||||
|
// })
|
||||||
|
// })
|
||||||
|
// signal = durationSignal.map(toSignal: { duration -> SSignal in
|
||||||
|
// if let duration = duration as? Double {
|
||||||
|
// return TGMediaVideoConverter.renderUIImage(image, duration: duration, adjustments: adjustments, path: tempFile.path, watcher: nil, entityRenderer: entityRenderer)!
|
||||||
|
// } else {
|
||||||
|
// return SSignal.single(nil)
|
||||||
|
// }
|
||||||
|
// })
|
||||||
|
// } else if let asset = asset as? AVAsset {
|
||||||
|
// signal = TGMediaVideoConverter.convert(asset, adjustments: adjustments, path: tempFile.path, watcher: uploadInterface, entityRenderer: entityRenderer)!
|
||||||
|
// } else {
|
||||||
|
// signal = SSignal.complete()
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// let signalDisposable = signal.start(next: { next in
|
||||||
|
// if let result = next as? TGMediaVideoConversionResult {
|
||||||
|
// if let image = result.coverImage, let data = image.jpegData(compressionQuality: 0.7) {
|
||||||
|
// account.postbox.mediaBox.storeResourceData(photoResource.id, data: data)
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// if let timestamp = videoStartTimestamp {
|
||||||
|
// videoStartTimestamp = max(0.0, min(timestamp, result.duration - 0.05))
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// var value = stat()
|
||||||
|
// if stat(result.fileURL.path, &value) == 0 {
|
||||||
|
// if let data = try? Data(contentsOf: result.fileURL) {
|
||||||
|
// let resource: TelegramMediaResource
|
||||||
|
// if let liveUploadData = result.liveUploadData as? LegacyLiveUploadInterfaceResult {
|
||||||
|
// resource = LocalFileMediaResource(fileId: liveUploadData.id)
|
||||||
|
// } else {
|
||||||
|
// resource = LocalFileMediaResource(fileId: Int64.random(in: Int64.min ... Int64.max))
|
||||||
|
// }
|
||||||
|
// account.postbox.mediaBox.storeResourceData(resource.id, data: data, synchronous: true)
|
||||||
|
// subscriber.putNext(resource)
|
||||||
|
//
|
||||||
|
// EngineTempBox.shared.dispose(tempFile)
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// subscriber.putCompletion()
|
||||||
|
// } else if let strongSelf = self, let progress = next as? NSNumber {
|
||||||
|
// Queue.mainQueue().async {
|
||||||
|
// strongSelf.state = strongSelf.state.withAvatarUploadProgress(.value(CGFloat(progress.floatValue * 0.45)))
|
||||||
|
// if let (layout, navigationHeight) = strongSelf.validLayout {
|
||||||
|
// strongSelf.containerLayoutUpdated(layout: layout, navigationHeight: navigationHeight, transition: .immediate, additive: false)
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }, error: { _ in
|
||||||
|
// }, completed: nil)
|
||||||
|
//
|
||||||
|
// let disposable = ActionDisposable {
|
||||||
|
// signalDisposable?.dispose()
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// return ActionDisposable {
|
||||||
|
// disposable.dispose()
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// } else {
|
||||||
|
// videoResource = .single(nil)
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// var dismissStatus: (() -> Void)?
|
||||||
|
// if [.suggest, .fallback, .accept].contains(mode) {
|
||||||
|
// let statusController = OverlayStatusController(theme: self.presentationData.theme, type: .loading(cancelled: { [weak self] in
|
||||||
|
// self?.controllerNode.updateAvatarDisposable.set(nil)
|
||||||
|
// dismissStatus?()
|
||||||
|
// }))
|
||||||
|
// dismissStatus = { [weak statusController] in
|
||||||
|
// statusController?.dismiss()
|
||||||
|
// }
|
||||||
|
// if let topController = self.navigationController?.topViewController as? ViewController {
|
||||||
|
// topController.presentInGlobalOverlay(statusController)
|
||||||
|
// } else if let topController = self.parentController?.topViewController as? ViewController {
|
||||||
|
// topController.presentInGlobalOverlay(statusController)
|
||||||
|
// } else {
|
||||||
|
// self.presentInGlobalOverlay(statusController)
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// let peerId = self.peerId
|
||||||
|
// let isSettings = self.isSettings
|
||||||
|
// let isMyProfile = self.isMyProfile
|
||||||
|
// self.controllerNode.updateAvatarDisposable.set((videoResource
|
||||||
|
// |> mapToSignal { videoResource -> Signal<UpdatePeerPhotoStatus, UploadPeerPhotoError> in
|
||||||
|
// if isSettings || isMyProfile {
|
||||||
|
// if case .fallback = mode {
|
||||||
|
// return context.engine.accountData.updateFallbackPhoto(resource: photoResource, videoResource: videoResource, videoStartTimestamp: videoStartTimestamp, markup: markup, mapResourceToAvatarSizes: { resource, representations in
|
||||||
|
// return mapResourceToAvatarSizes(postbox: account.postbox, resource: resource, representations: representations)
|
||||||
|
// })
|
||||||
|
// } else {
|
||||||
|
// return context.engine.accountData.updateAccountPhoto(resource: photoResource, videoResource: videoResource, videoStartTimestamp: videoStartTimestamp, markup: markup, mapResourceToAvatarSizes: { resource, representations in
|
||||||
|
// return mapResourceToAvatarSizes(postbox: account.postbox, resource: resource, representations: representations)
|
||||||
|
// })
|
||||||
|
// }
|
||||||
|
// } else if case .custom = mode {
|
||||||
|
// return context.engine.contacts.updateContactPhoto(peerId: peerId, resource: photoResource, videoResource: videoResource, videoStartTimestamp: videoStartTimestamp, markup: markup, mode: .custom, mapResourceToAvatarSizes: { resource, representations in
|
||||||
|
// return mapResourceToAvatarSizes(postbox: account.postbox, resource: resource, representations: representations)
|
||||||
|
// })
|
||||||
|
// } else if case .suggest = mode {
|
||||||
|
// return context.engine.contacts.updateContactPhoto(peerId: peerId, resource: photoResource, videoResource: videoResource, videoStartTimestamp: videoStartTimestamp, markup: markup, mode: .suggest, mapResourceToAvatarSizes: { resource, representations in
|
||||||
|
// return mapResourceToAvatarSizes(postbox: account.postbox, resource: resource, representations: representations)
|
||||||
|
// })
|
||||||
|
// } else {
|
||||||
|
// return context.engine.peers.updatePeerPhoto(peerId: peerId, photo: context.engine.peers.uploadedPeerPhoto(resource: photoResource), video: videoResource.flatMap { context.engine.peers.uploadedPeerVideo(resource: $0) |> map(Optional.init) }, videoStartTimestamp: videoStartTimestamp, markup: markup, mapResourceToAvatarSizes: { resource, representations in
|
||||||
|
// return mapResourceToAvatarSizes(postbox: account.postbox, resource: resource, representations: representations)
|
||||||
|
// })
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// |> deliverOnMainQueue).startStrict(next: { [weak self] result in
|
||||||
|
// guard let strongSelf = self else {
|
||||||
|
// return
|
||||||
|
// }
|
||||||
|
// switch result {
|
||||||
|
// case .complete:
|
||||||
|
// strongSelf.controllerNode.state = strongSelf.controllerNode.state.withUpdatingAvatar(nil).withAvatarUploadProgress(nil)
|
||||||
|
// case let .progress(value):
|
||||||
|
// strongSelf.controllerNode.state = strongSelf.controllerNode.state.withAvatarUploadProgress(.value(CGFloat(0.45 + value * 0.55)))
|
||||||
|
// }
|
||||||
|
// if let (layout, navigationHeight) = strongSelf.controllerNode.validLayout {
|
||||||
|
// strongSelf.controllerNode.containerLayoutUpdated(layout: layout, navigationHeight: navigationHeight, transition: .immediate, additive: false)
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// if case .complete = result {
|
||||||
|
// dismissStatus?()
|
||||||
|
//
|
||||||
|
// let _ = (strongSelf.context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: strongSelf.peerId))
|
||||||
|
// |> deliverOnMainQueue).startStandalone(next: { [weak self] peer in
|
||||||
|
// if let strongSelf = self, let peer {
|
||||||
|
// switch mode {
|
||||||
|
// case .fallback:
|
||||||
|
// (strongSelf.parentController?.topViewController as? ViewController)?.present(UndoOverlayController(presentationData: strongSelf.presentationData, content: .image(image: image, title: nil, text: strongSelf.presentationData.strings.Privacy_ProfilePhoto_PublicVideoSuccess, round: true, undoText: nil), elevatedLayout: false, animateInAsReplacement: true, action: { _ in return false }), in: .current)
|
||||||
|
// case .custom:
|
||||||
|
// strongSelf.present(UndoOverlayController(presentationData: strongSelf.presentationData, content: .invitedToVoiceChat(context: strongSelf.context, peer: peer, title: nil, text: strongSelf.presentationData.strings.UserInfo_SetCustomPhoto_SuccessVideoText(peer.compactDisplayTitle).string, action: nil, duration: 5), elevatedLayout: false, animateInAsReplacement: true, action: { _ in return false }), in: .current)
|
||||||
|
//
|
||||||
|
// let _ = (strongSelf.context.peerChannelMemberCategoriesContextsManager.profilePhotos(postbox: strongSelf.context.account.postbox, network: strongSelf.context.account.network, peerId: strongSelf.peerId, fetch: peerInfoProfilePhotos(context: strongSelf.context, peerId: strongSelf.peerId)) |> ignoreValues).startStandalone()
|
||||||
|
// case .suggest:
|
||||||
|
// if let navigationController = (strongSelf.navigationController as? NavigationController) {
|
||||||
|
// strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: .peer(peer), keepStack: .default, completion: { _ in
|
||||||
|
// }))
|
||||||
|
// }
|
||||||
|
// case .accept:
|
||||||
|
// (strongSelf.parentController?.topViewController as? ViewController)?.present(UndoOverlayController(presentationData: strongSelf.presentationData, content: .image(image: image, title: strongSelf.presentationData.strings.Conversation_SuggestedVideoSuccess, text: strongSelf.presentationData.strings.Conversation_SuggestedVideoSuccessText, round: true, undoText: nil), elevatedLayout: false, animateInAsReplacement: true, action: { [weak self] action in
|
||||||
|
// if case .info = action {
|
||||||
|
// self?.parentController?.openSettings()
|
||||||
|
// }
|
||||||
|
// return false
|
||||||
|
// }), in: .current)
|
||||||
|
// default:
|
||||||
|
// break
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// })
|
||||||
|
// }
|
||||||
|
// }))
|
||||||
|
}
|
||||||
|
}
|
@ -381,7 +381,7 @@ public final class PeerInfoGiftsPaneNode: ASDisplayNode, PeerInfoPaneNode, UIScr
|
|||||||
guard let self else {
|
guard let self else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
let controller = self.context.sharedContext.makePremiumGiftController(context: self.context, source: .settings(birthdays), completion: nil)
|
let controller = self.context.sharedContext.makePremiumGiftController(context: self.context, source: .settings(birthdays), transfer: false, completion: nil)
|
||||||
controller.navigationPresentation = .modal
|
controller.navigationPresentation = .modal
|
||||||
self.chatControllerInteraction.navigationController()?.pushViewController(controller)
|
self.chatControllerInteraction.navigationController()?.pushViewController(controller)
|
||||||
})
|
})
|
||||||
|
@ -0,0 +1,31 @@
|
|||||||
|
load("@build_bazel_rules_swift//swift:swift.bzl", "swift_library")
|
||||||
|
|
||||||
|
swift_library(
|
||||||
|
name = "VerifyAlertController",
|
||||||
|
module_name = "VerifyAlertController",
|
||||||
|
srcs = glob([
|
||||||
|
"Sources/**/*.swift",
|
||||||
|
]),
|
||||||
|
copts = [
|
||||||
|
"-warnings-as-errors",
|
||||||
|
],
|
||||||
|
deps = [
|
||||||
|
"//submodules/SSignalKit/SwiftSignalKit:SwiftSignalKit",
|
||||||
|
"//submodules/AsyncDisplayKit:AsyncDisplayKit",
|
||||||
|
"//submodules/Display:Display",
|
||||||
|
"//submodules/Postbox:Postbox",
|
||||||
|
"//submodules/TelegramCore:TelegramCore",
|
||||||
|
"//submodules/AccountContext:AccountContext",
|
||||||
|
"//submodules/TelegramPresentationData:TelegramPresentationData",
|
||||||
|
"//submodules/ComponentFlow",
|
||||||
|
"//submodules/Components/MultilineTextComponent",
|
||||||
|
"//submodules/Components/BalancedTextComponent",
|
||||||
|
"//submodules/Components/ComponentDisplayAdapters",
|
||||||
|
"//submodules/TelegramUI/Components/TextFieldComponent",
|
||||||
|
"//submodules/TextFormat",
|
||||||
|
"//submodules/TelegramUI/Components/PremiumPeerShortcutComponent",
|
||||||
|
],
|
||||||
|
visibility = [
|
||||||
|
"//visibility:public",
|
||||||
|
],
|
||||||
|
)
|
@ -0,0 +1,489 @@
|
|||||||
|
import Foundation
|
||||||
|
import UIKit
|
||||||
|
import SwiftSignalKit
|
||||||
|
import AsyncDisplayKit
|
||||||
|
import Display
|
||||||
|
import Postbox
|
||||||
|
import TelegramCore
|
||||||
|
import TelegramPresentationData
|
||||||
|
import AccountContext
|
||||||
|
import ComponentFlow
|
||||||
|
import MultilineTextComponent
|
||||||
|
import BalancedTextComponent
|
||||||
|
import TextFieldComponent
|
||||||
|
import ComponentDisplayAdapters
|
||||||
|
import TextFormat
|
||||||
|
import PremiumPeerShortcutComponent
|
||||||
|
|
||||||
|
private final class VerifyAlertContentNode: AlertContentNode {
|
||||||
|
private let context: AccountContext
|
||||||
|
private var theme: AlertControllerTheme
|
||||||
|
private var presentationTheme: PresentationTheme
|
||||||
|
private let strings: PresentationStrings
|
||||||
|
private let title: String
|
||||||
|
private let text: String
|
||||||
|
private let peer: EnginePeer
|
||||||
|
private let verifierSettings: BotVerifierSettings
|
||||||
|
private let verifierIcon: TelegramMediaFile?
|
||||||
|
private let hasInput: Bool
|
||||||
|
|
||||||
|
private let titleView = ComponentView<Empty>()
|
||||||
|
private let textView = ComponentView<Empty>()
|
||||||
|
private let shortcut = ComponentView<Empty>()
|
||||||
|
|
||||||
|
private let state = ComponentState()
|
||||||
|
|
||||||
|
private let inputBackgroundNode = ASImageNode()
|
||||||
|
private let inputField = ComponentView<Empty>()
|
||||||
|
private let inputFieldExternalState = TextFieldComponent.ExternalState()
|
||||||
|
private let inputPlaceholderView = ComponentView<Empty>()
|
||||||
|
|
||||||
|
private let actionNodesSeparator: ASDisplayNode
|
||||||
|
private let actionNodes: [TextAlertContentActionNode]
|
||||||
|
private let actionVerticalSeparators: [ASDisplayNode]
|
||||||
|
|
||||||
|
private let disposable = MetaDisposable()
|
||||||
|
|
||||||
|
private var validLayout: CGSize?
|
||||||
|
|
||||||
|
private let hapticFeedback = HapticFeedback()
|
||||||
|
|
||||||
|
var present: (ViewController) -> () = { _ in }
|
||||||
|
|
||||||
|
var complete: (() -> Void)? {
|
||||||
|
didSet {
|
||||||
|
// self.inputFieldNode.complete = self.complete
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override var dismissOnOutsideTap: Bool {
|
||||||
|
return self.isUserInteractionEnabled
|
||||||
|
}
|
||||||
|
|
||||||
|
init(context: AccountContext, theme: AlertControllerTheme, presentationTheme: PresentationTheme, strings: PresentationStrings, actions: [TextAlertAction], title: String, text: String, peer: EnginePeer, verifierSettings: BotVerifierSettings, verifierIcon: TelegramMediaFile?, hasInput: Bool) {
|
||||||
|
self.context = context
|
||||||
|
self.theme = theme
|
||||||
|
self.presentationTheme = presentationTheme
|
||||||
|
self.strings = strings
|
||||||
|
self.title = title
|
||||||
|
self.text = text
|
||||||
|
self.peer = peer
|
||||||
|
self.verifierSettings = verifierSettings
|
||||||
|
self.verifierIcon = verifierIcon
|
||||||
|
self.hasInput = hasInput
|
||||||
|
|
||||||
|
self.actionNodesSeparator = ASDisplayNode()
|
||||||
|
self.actionNodesSeparator.isLayerBacked = true
|
||||||
|
|
||||||
|
self.actionNodes = actions.map { action -> TextAlertContentActionNode in
|
||||||
|
return TextAlertContentActionNode(theme: theme, action: action)
|
||||||
|
}
|
||||||
|
|
||||||
|
var actionVerticalSeparators: [ASDisplayNode] = []
|
||||||
|
if actions.count > 1 {
|
||||||
|
for _ in 0 ..< actions.count - 1 {
|
||||||
|
let separatorNode = ASDisplayNode()
|
||||||
|
separatorNode.isLayerBacked = true
|
||||||
|
actionVerticalSeparators.append(separatorNode)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self.actionVerticalSeparators = actionVerticalSeparators
|
||||||
|
|
||||||
|
super.init()
|
||||||
|
|
||||||
|
self.inputBackgroundNode.displaysAsynchronously = false
|
||||||
|
self.inputBackgroundNode.image = generateStretchableFilledCircleImage(diameter: 16.0, color: presentationTheme.actionSheet.inputHollowBackgroundColor, strokeColor: presentationTheme.actionSheet.inputBorderColor, strokeWidth: UIScreenPixel)
|
||||||
|
|
||||||
|
self.addSubnode(self.actionNodesSeparator)
|
||||||
|
|
||||||
|
if self.hasInput {
|
||||||
|
self.addSubnode(self.inputBackgroundNode)
|
||||||
|
}
|
||||||
|
|
||||||
|
for actionNode in self.actionNodes {
|
||||||
|
self.addSubnode(actionNode)
|
||||||
|
}
|
||||||
|
|
||||||
|
for separatorNode in self.actionVerticalSeparators {
|
||||||
|
self.addSubnode(separatorNode)
|
||||||
|
}
|
||||||
|
|
||||||
|
self.updateTheme(theme)
|
||||||
|
|
||||||
|
self.state._updated = { [weak self] transition, _ in
|
||||||
|
guard let self, let _ = self.validLayout else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
self.requestLayout?(transition.containedViewLayoutTransition)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
deinit {
|
||||||
|
self.disposable.dispose()
|
||||||
|
}
|
||||||
|
|
||||||
|
var textAndEntities: (String, [MessageTextEntity]) {
|
||||||
|
let text = self.inputFieldExternalState.text.string
|
||||||
|
let entities = generateChatInputTextEntities(self.inputFieldExternalState.text)
|
||||||
|
return (text, entities)
|
||||||
|
}
|
||||||
|
|
||||||
|
override func updateTheme(_ theme: AlertControllerTheme) {
|
||||||
|
self.theme = theme
|
||||||
|
|
||||||
|
self.actionNodesSeparator.backgroundColor = theme.separatorColor
|
||||||
|
for actionNode in self.actionNodes {
|
||||||
|
actionNode.updateTheme(theme)
|
||||||
|
}
|
||||||
|
for separatorNode in self.actionVerticalSeparators {
|
||||||
|
separatorNode.backgroundColor = theme.separatorColor
|
||||||
|
}
|
||||||
|
|
||||||
|
if let size = self.validLayout {
|
||||||
|
_ = self.updateLayout(size: size, transition: .immediate)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override func updateLayout(size: CGSize, transition: ContainedViewLayoutTransition) -> CGSize {
|
||||||
|
var size = size
|
||||||
|
size.width = min(size.width, 270.0)
|
||||||
|
let measureSize = CGSize(width: size.width - 16.0 * 2.0, height: CGFloat.greatestFiniteMagnitude)
|
||||||
|
|
||||||
|
let hadValidLayout = self.validLayout != nil
|
||||||
|
|
||||||
|
self.validLayout = size
|
||||||
|
|
||||||
|
var origin: CGPoint = CGPoint(x: 0.0, y: 16.0)
|
||||||
|
let spacing: CGFloat = 5.0
|
||||||
|
|
||||||
|
|
||||||
|
let titleSize = self.titleView.update(
|
||||||
|
transition: .immediate,
|
||||||
|
component: AnyComponent(MultilineTextComponent(
|
||||||
|
text: .plain(NSAttributedString(string: self.title, font: Font.semibold(17.0), textColor: self.theme.primaryColor)),
|
||||||
|
horizontalAlignment: .center,
|
||||||
|
maximumNumberOfLines: 0
|
||||||
|
)),
|
||||||
|
environment: {},
|
||||||
|
containerSize: CGSize(width: measureSize.width, height: 1000.0)
|
||||||
|
)
|
||||||
|
let titleFrame = CGRect(origin: CGPoint(x: floor((size.width - titleSize.width) * 0.5), y: origin.y), size: titleSize)
|
||||||
|
if let titleComponentView = self.titleView.view {
|
||||||
|
if titleComponentView.superview == nil {
|
||||||
|
self.view.addSubview(titleComponentView)
|
||||||
|
}
|
||||||
|
titleComponentView.frame = titleFrame
|
||||||
|
}
|
||||||
|
origin.y += titleSize.height + 5.0
|
||||||
|
|
||||||
|
let textSize = self.textView.update(
|
||||||
|
transition: .immediate,
|
||||||
|
component: AnyComponent(MultilineTextComponent(
|
||||||
|
text: .plain(NSAttributedString(string: self.text, font: Font.regular(13.0), textColor: self.theme.primaryColor)),
|
||||||
|
horizontalAlignment: .center,
|
||||||
|
maximumNumberOfLines: 0
|
||||||
|
)),
|
||||||
|
environment: {},
|
||||||
|
containerSize: CGSize(width: measureSize.width, height: 1000.0)
|
||||||
|
)
|
||||||
|
let textFrame = CGRect(origin: CGPoint(x: floor((size.width - textSize.width) * 0.5), y: origin.y), size: textSize)
|
||||||
|
if let textComponentView = self.textView.view {
|
||||||
|
if textComponentView.superview == nil {
|
||||||
|
self.view.addSubview(textComponentView)
|
||||||
|
}
|
||||||
|
textComponentView.frame = textFrame
|
||||||
|
}
|
||||||
|
origin.y += textSize.height + 17.0
|
||||||
|
|
||||||
|
let shortcutSize = self.shortcut.update(
|
||||||
|
transition: .immediate,
|
||||||
|
component: AnyComponent(PremiumPeerShortcutComponent(
|
||||||
|
context: self.context,
|
||||||
|
theme: self.presentationTheme,
|
||||||
|
peer: self.peer,
|
||||||
|
icon: self.verifierIcon,
|
||||||
|
iconPosition: .left
|
||||||
|
)),
|
||||||
|
environment: {},
|
||||||
|
containerSize: CGSize(width: measureSize.width, height: 1000.0)
|
||||||
|
)
|
||||||
|
let shortcutFrame = CGRect(origin: CGPoint(x: floor((size.width - shortcutSize.width) * 0.5), y: origin.y), size: shortcutSize)
|
||||||
|
if let shortcutComponentView = self.shortcut.view {
|
||||||
|
if shortcutComponentView.superview == nil {
|
||||||
|
self.view.addSubview(shortcutComponentView)
|
||||||
|
}
|
||||||
|
shortcutComponentView.frame = shortcutFrame
|
||||||
|
}
|
||||||
|
origin.y += shortcutSize.height + 17.0
|
||||||
|
|
||||||
|
let actionButtonHeight: CGFloat = 44.0
|
||||||
|
var minActionsWidth: CGFloat = 0.0
|
||||||
|
let maxActionWidth: CGFloat = floor(size.width / CGFloat(self.actionNodes.count))
|
||||||
|
let actionTitleInsets: CGFloat = 8.0
|
||||||
|
|
||||||
|
var effectiveActionLayout = TextAlertContentActionLayout.horizontal
|
||||||
|
for actionNode in self.actionNodes {
|
||||||
|
let actionTitleSize = actionNode.titleNode.updateLayout(CGSize(width: maxActionWidth, height: actionButtonHeight))
|
||||||
|
if case .horizontal = effectiveActionLayout, actionTitleSize.height > actionButtonHeight * 0.6667 {
|
||||||
|
effectiveActionLayout = .vertical
|
||||||
|
}
|
||||||
|
switch effectiveActionLayout {
|
||||||
|
case .horizontal:
|
||||||
|
minActionsWidth += actionTitleSize.width + actionTitleInsets
|
||||||
|
case .vertical:
|
||||||
|
minActionsWidth = max(minActionsWidth, actionTitleSize.width + actionTitleInsets)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let insets = UIEdgeInsets(top: 18.0, left: 18.0, bottom: 9.0, right: 18.0)
|
||||||
|
|
||||||
|
var contentWidth = max(titleSize.width, minActionsWidth)
|
||||||
|
contentWidth = max(contentWidth, 234.0)
|
||||||
|
|
||||||
|
var actionsHeight: CGFloat = 0.0
|
||||||
|
switch effectiveActionLayout {
|
||||||
|
case .horizontal:
|
||||||
|
actionsHeight = actionButtonHeight
|
||||||
|
case .vertical:
|
||||||
|
actionsHeight = actionButtonHeight * CGFloat(self.actionNodes.count)
|
||||||
|
}
|
||||||
|
|
||||||
|
let resultWidth = contentWidth + insets.left + insets.right
|
||||||
|
var resultInputHeight: CGFloat = 0.0
|
||||||
|
|
||||||
|
if self.hasInput {
|
||||||
|
let inputInset: CGFloat = 16.0
|
||||||
|
let inputWidth = resultWidth - inputInset * 2.0
|
||||||
|
|
||||||
|
var characterLimit: Int = 70
|
||||||
|
if let data = self.context.currentAppConfiguration.with({ $0 }).data, let value = data["bot_verification_description_length_limit"] as? Double {
|
||||||
|
characterLimit = Int(value)
|
||||||
|
}
|
||||||
|
|
||||||
|
let inputFieldSize = self.inputField.update(
|
||||||
|
transition: .immediate,
|
||||||
|
component: AnyComponent(TextFieldComponent(
|
||||||
|
context: self.context,
|
||||||
|
theme: self.presentationTheme,
|
||||||
|
strings: self.strings,
|
||||||
|
externalState: self.inputFieldExternalState,
|
||||||
|
fontSize: 14.0,
|
||||||
|
textColor: self.presentationTheme.actionSheet.inputTextColor,
|
||||||
|
accentColor: self.presentationTheme.actionSheet.controlAccentColor,
|
||||||
|
insets: UIEdgeInsets(top: 8.0, left: 2.0, bottom: 8.0, right: 2.0),
|
||||||
|
hideKeyboard: false,
|
||||||
|
customInputView: nil,
|
||||||
|
resetText: nil,
|
||||||
|
isOneLineWhenUnfocused: false,
|
||||||
|
characterLimit: characterLimit,
|
||||||
|
emptyLineHandling: .oneConsecutive,
|
||||||
|
formatMenuAvailability: .none,
|
||||||
|
returnKeyType: .default,
|
||||||
|
lockedFormatAction: {
|
||||||
|
},
|
||||||
|
present: { [weak self] c in
|
||||||
|
self?.present(c)
|
||||||
|
},
|
||||||
|
paste: { _ in
|
||||||
|
},
|
||||||
|
returnKeyAction: nil,
|
||||||
|
backspaceKeyAction: nil
|
||||||
|
)),
|
||||||
|
environment: {},
|
||||||
|
containerSize: CGSize(width: inputWidth, height: 270.0)
|
||||||
|
)
|
||||||
|
self.inputField.parentState = self.state
|
||||||
|
let inputFieldFrame = CGRect(origin: CGPoint(x: inputInset, y: origin.y), size: inputFieldSize)
|
||||||
|
if let inputFieldView = self.inputField.view as? TextFieldComponent.View {
|
||||||
|
if inputFieldView.superview == nil {
|
||||||
|
self.view.addSubview(inputFieldView)
|
||||||
|
}
|
||||||
|
transition.updateFrame(view: inputFieldView, frame: inputFieldFrame)
|
||||||
|
transition.updateFrame(node: self.inputBackgroundNode, frame: inputFieldFrame)
|
||||||
|
|
||||||
|
if !hadValidLayout {
|
||||||
|
inputFieldView.activateInput()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let placeholderText = self.verifierSettings.customDescription ?? "This page is verified by \(self.verifierSettings.companyName)"
|
||||||
|
|
||||||
|
//TODO:localize
|
||||||
|
let inputPlaceholderSize = self.inputPlaceholderView.update(
|
||||||
|
transition: .immediate,
|
||||||
|
component: AnyComponent(
|
||||||
|
MultilineTextComponent(text: .plain(NSAttributedString(
|
||||||
|
string: placeholderText,
|
||||||
|
font: Font.regular(14.0),
|
||||||
|
textColor: self.presentationTheme.actionSheet.inputPlaceholderColor
|
||||||
|
)))
|
||||||
|
),
|
||||||
|
environment: {},
|
||||||
|
containerSize: CGSize(width: inputWidth - 32.0, height: 240.0)
|
||||||
|
)
|
||||||
|
let inputPlaceholderFrame = CGRect(origin: CGPoint(x: inputInset + 10.0, y: floorToScreenPixels(inputFieldFrame.midY - inputPlaceholderSize.height / 2.0)), size: inputPlaceholderSize)
|
||||||
|
if let inputPlaceholderView = self.inputPlaceholderView.view {
|
||||||
|
if inputPlaceholderView.superview == nil {
|
||||||
|
inputPlaceholderView.isUserInteractionEnabled = false
|
||||||
|
self.view.addSubview(inputPlaceholderView)
|
||||||
|
}
|
||||||
|
inputPlaceholderView.frame = inputPlaceholderFrame
|
||||||
|
inputPlaceholderView.isHidden = self.inputFieldExternalState.hasText
|
||||||
|
}
|
||||||
|
resultInputHeight = inputFieldSize.height + 17.0
|
||||||
|
}
|
||||||
|
|
||||||
|
let resultSize = CGSize(width: resultWidth, height: titleSize.height + textSize.height + shortcutSize.height + spacing + resultInputHeight + 22.0 + actionsHeight + insets.top + insets.bottom)
|
||||||
|
|
||||||
|
transition.updateFrame(node: self.actionNodesSeparator, frame: CGRect(origin: CGPoint(x: 0.0, y: resultSize.height - actionsHeight - UIScreenPixel), size: CGSize(width: resultSize.width, height: UIScreenPixel)))
|
||||||
|
|
||||||
|
var actionOffset: CGFloat = 0.0
|
||||||
|
let actionWidth: CGFloat = floor(resultSize.width / CGFloat(self.actionNodes.count))
|
||||||
|
var separatorIndex = -1
|
||||||
|
var nodeIndex = 0
|
||||||
|
for actionNode in self.actionNodes {
|
||||||
|
if separatorIndex >= 0 {
|
||||||
|
let separatorNode = self.actionVerticalSeparators[separatorIndex]
|
||||||
|
switch effectiveActionLayout {
|
||||||
|
case .horizontal:
|
||||||
|
transition.updateFrame(node: separatorNode, frame: CGRect(origin: CGPoint(x: actionOffset - UIScreenPixel, y: resultSize.height - actionsHeight), size: CGSize(width: UIScreenPixel, height: actionsHeight - UIScreenPixel)))
|
||||||
|
case .vertical:
|
||||||
|
transition.updateFrame(node: separatorNode, frame: CGRect(origin: CGPoint(x: 0.0, y: resultSize.height - actionsHeight + actionOffset - UIScreenPixel), size: CGSize(width: resultSize.width, height: UIScreenPixel)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
separatorIndex += 1
|
||||||
|
|
||||||
|
let currentActionWidth: CGFloat
|
||||||
|
switch effectiveActionLayout {
|
||||||
|
case .horizontal:
|
||||||
|
if nodeIndex == self.actionNodes.count - 1 {
|
||||||
|
currentActionWidth = resultSize.width - actionOffset
|
||||||
|
} else {
|
||||||
|
currentActionWidth = actionWidth
|
||||||
|
}
|
||||||
|
case .vertical:
|
||||||
|
currentActionWidth = resultSize.width
|
||||||
|
}
|
||||||
|
|
||||||
|
let actionNodeFrame: CGRect
|
||||||
|
switch effectiveActionLayout {
|
||||||
|
case .horizontal:
|
||||||
|
actionNodeFrame = CGRect(origin: CGPoint(x: actionOffset, y: resultSize.height - actionsHeight), size: CGSize(width: currentActionWidth, height: actionButtonHeight))
|
||||||
|
actionOffset += currentActionWidth
|
||||||
|
case .vertical:
|
||||||
|
actionNodeFrame = CGRect(origin: CGPoint(x: 0.0, y: resultSize.height - actionsHeight + actionOffset), size: CGSize(width: currentActionWidth, height: actionButtonHeight))
|
||||||
|
actionOffset += actionButtonHeight
|
||||||
|
}
|
||||||
|
|
||||||
|
transition.updateFrame(node: actionNode, frame: actionNodeFrame)
|
||||||
|
|
||||||
|
nodeIndex += 1
|
||||||
|
}
|
||||||
|
|
||||||
|
return resultSize
|
||||||
|
}
|
||||||
|
|
||||||
|
func deactivateInput() {
|
||||||
|
if let inputFieldView = self.inputField.view as? TextFieldComponent.View {
|
||||||
|
inputFieldView.deactivateInput()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func animateError() {
|
||||||
|
if let inputFieldView = self.inputField.view as? TextFieldComponent.View {
|
||||||
|
inputFieldView.layer.addShakeAnimation()
|
||||||
|
}
|
||||||
|
|
||||||
|
self.hapticFeedback.error()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public func verifyAlertController(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)? = nil, peer: EnginePeer, verifierSettings: BotVerifierSettings, verifierIcon: TelegramMediaFile?, apply: @escaping (String) -> Void) -> AlertController {
|
||||||
|
let presentationData = updatedPresentationData?.initial ?? context.sharedContext.currentPresentationData.with { $0 }
|
||||||
|
|
||||||
|
var dismissImpl: ((Bool) -> Void)?
|
||||||
|
var applyImpl: (() -> Void)?
|
||||||
|
|
||||||
|
//TODO:localize
|
||||||
|
let actions: [TextAlertAction] = [TextAlertAction(type: .genericAction, title: presentationData.strings.Common_Cancel, action: {
|
||||||
|
dismissImpl?(true)
|
||||||
|
}), TextAlertAction(type: .defaultAction, title: "Verify", action: {
|
||||||
|
dismissImpl?(true)
|
||||||
|
applyImpl?()
|
||||||
|
})]
|
||||||
|
|
||||||
|
//TODO:localize
|
||||||
|
let contentNode = VerifyAlertContentNode(context: context, theme: AlertControllerTheme(presentationData: presentationData), presentationTheme: presentationData.theme, strings: presentationData.strings, actions: actions, title: "Verify Account", text: "Do you want to verify this account with your verification mark and description?", peer: peer, verifierSettings: verifierSettings, verifierIcon: verifierIcon, hasInput: true)
|
||||||
|
contentNode.complete = {
|
||||||
|
applyImpl?()
|
||||||
|
}
|
||||||
|
applyImpl = { [weak contentNode] in
|
||||||
|
guard let contentNode = contentNode else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
let (text, _) = contentNode.textAndEntities
|
||||||
|
apply(text)
|
||||||
|
}
|
||||||
|
|
||||||
|
let controller = AlertController(theme: AlertControllerTheme(presentationData: presentationData), contentNode: contentNode)
|
||||||
|
let presentationDataDisposable = (updatedPresentationData?.signal ?? context.sharedContext.presentationData).start(next: { [weak controller] presentationData in
|
||||||
|
controller?.theme = AlertControllerTheme(presentationData: presentationData)
|
||||||
|
})
|
||||||
|
controller.dismissed = { _ in
|
||||||
|
presentationDataDisposable.dispose()
|
||||||
|
}
|
||||||
|
dismissImpl = { [weak controller] animated in
|
||||||
|
contentNode.deactivateInput()
|
||||||
|
if animated {
|
||||||
|
controller?.dismissAnimated()
|
||||||
|
} else {
|
||||||
|
controller?.dismiss()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
contentNode.present = { [weak controller] c in
|
||||||
|
controller?.present(c, in: .window(.root))
|
||||||
|
}
|
||||||
|
|
||||||
|
return controller
|
||||||
|
}
|
||||||
|
|
||||||
|
public func removeVerificationAlertController(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)? = nil, peer: EnginePeer, verifierSettings: BotVerifierSettings, verifierIcon: TelegramMediaFile?, completion: @escaping () -> Void) -> AlertController {
|
||||||
|
let presentationData = updatedPresentationData?.initial ?? context.sharedContext.currentPresentationData.with { $0 }
|
||||||
|
|
||||||
|
var dismissImpl: ((Bool) -> Void)?
|
||||||
|
var applyImpl: (() -> Void)?
|
||||||
|
|
||||||
|
//TODO:localize
|
||||||
|
let actions: [TextAlertAction] = [TextAlertAction(type: .genericAction, title: presentationData.strings.Common_Cancel, action: {
|
||||||
|
dismissImpl?(true)
|
||||||
|
}), TextAlertAction(type: .defaultDestructiveAction, title: "Remove", action: {
|
||||||
|
dismissImpl?(true)
|
||||||
|
applyImpl?()
|
||||||
|
})]
|
||||||
|
|
||||||
|
//TODO:localize
|
||||||
|
let contentNode = VerifyAlertContentNode(context: context, theme: AlertControllerTheme(presentationData: presentationData), presentationTheme: presentationData.theme, strings: presentationData.strings, actions: actions, title: "Remove Verification", text: "This account is already verified by you. Do you want to remove verification?", peer: peer, verifierSettings: verifierSettings, verifierIcon: verifierIcon, hasInput: false)
|
||||||
|
applyImpl = {
|
||||||
|
completion()
|
||||||
|
}
|
||||||
|
|
||||||
|
let controller = AlertController(theme: AlertControllerTheme(presentationData: presentationData), contentNode: contentNode)
|
||||||
|
let presentationDataDisposable = (updatedPresentationData?.signal ?? context.sharedContext.presentationData).start(next: { [weak controller] presentationData in
|
||||||
|
controller?.theme = AlertControllerTheme(presentationData: presentationData)
|
||||||
|
})
|
||||||
|
controller.dismissed = { _ in
|
||||||
|
presentationDataDisposable.dispose()
|
||||||
|
}
|
||||||
|
dismissImpl = { [weak controller] animated in
|
||||||
|
if animated {
|
||||||
|
controller?.dismissAnimated()
|
||||||
|
} else {
|
||||||
|
controller?.dismiss()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
contentNode.present = { [weak controller] c in
|
||||||
|
controller?.present(c, in: .window(.root))
|
||||||
|
}
|
||||||
|
return controller
|
||||||
|
}
|
@ -11,21 +11,29 @@ import EmojiTextAttachmentView
|
|||||||
import TextFormat
|
import TextFormat
|
||||||
|
|
||||||
public final class PremiumPeerShortcutComponent: Component {
|
public final class PremiumPeerShortcutComponent: Component {
|
||||||
|
public enum IconPosition {
|
||||||
|
case left
|
||||||
|
case right
|
||||||
|
}
|
||||||
|
|
||||||
let context: AccountContext
|
let context: AccountContext
|
||||||
let theme: PresentationTheme
|
let theme: PresentationTheme
|
||||||
let peer: EnginePeer
|
let peer: EnginePeer
|
||||||
let icon: TelegramMediaFile?
|
let icon: TelegramMediaFile?
|
||||||
|
let iconPosition: IconPosition
|
||||||
|
|
||||||
public init(
|
public init(
|
||||||
context: AccountContext,
|
context: AccountContext,
|
||||||
theme: PresentationTheme,
|
theme: PresentationTheme,
|
||||||
peer: EnginePeer,
|
peer: EnginePeer,
|
||||||
icon: TelegramMediaFile? = nil
|
icon: TelegramMediaFile? = nil,
|
||||||
|
iconPosition: IconPosition = .right
|
||||||
) {
|
) {
|
||||||
self.context = context
|
self.context = context
|
||||||
self.theme = theme
|
self.theme = theme
|
||||||
self.peer = peer
|
self.peer = peer
|
||||||
self.icon = icon
|
self.icon = icon
|
||||||
|
self.iconPosition = iconPosition
|
||||||
}
|
}
|
||||||
|
|
||||||
public static func ==(lhs: PremiumPeerShortcutComponent, rhs: PremiumPeerShortcutComponent) -> Bool {
|
public static func ==(lhs: PremiumPeerShortcutComponent, rhs: PremiumPeerShortcutComponent) -> Bool {
|
||||||
@ -38,6 +46,9 @@ public final class PremiumPeerShortcutComponent: Component {
|
|||||||
if lhs.peer != rhs.peer {
|
if lhs.peer != rhs.peer {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
if lhs.iconPosition != rhs.iconPosition {
|
||||||
|
return false
|
||||||
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -91,18 +102,18 @@ public final class PremiumPeerShortcutComponent: Component {
|
|||||||
containerSize: CGSize(width: availableSize.width - 50.0, height: availableSize.height)
|
containerSize: CGSize(width: availableSize.width - 50.0, height: availableSize.height)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
let iconSize = CGSize(width: 20.0, height: 20.0)
|
||||||
|
let iconSpacing: CGFloat = 2.0
|
||||||
var size = CGSize(width: 30.0 + textSize.width + 20.0, height: 32.0)
|
var size = CGSize(width: 30.0 + textSize.width + 20.0, height: 32.0)
|
||||||
if let view = self.text.view {
|
if let view = self.text.view {
|
||||||
if view.superview == nil {
|
if view.superview == nil {
|
||||||
self.addSubview(view)
|
self.addSubview(view)
|
||||||
}
|
}
|
||||||
let textFrame = CGRect(origin: CGPoint(x: 38.0, y: floorToScreenPixels((size.height - textSize.height) / 2.0)), size: textSize)
|
let textFrame = CGRect(origin: CGPoint(x: component.iconPosition == .left ? 38.0 + iconSize.width + iconSpacing : 38.0, y: floorToScreenPixels((size.height - textSize.height) / 2.0)), size: textSize)
|
||||||
view.frame = textFrame
|
view.frame = textFrame
|
||||||
}
|
}
|
||||||
|
|
||||||
if let icon = component.icon {
|
if let icon = component.icon {
|
||||||
let iconSize = CGSize(width: 20.0, height: 20.0)
|
|
||||||
let iconSpacing: CGFloat = 2.0
|
|
||||||
let animationLayer: InlineStickerItemLayer
|
let animationLayer: InlineStickerItemLayer
|
||||||
if let current = self.animationLayer {
|
if let current = self.animationLayer {
|
||||||
animationLayer = current
|
animationLayer = current
|
||||||
@ -132,7 +143,7 @@ public final class PremiumPeerShortcutComponent: Component {
|
|||||||
self.layer.addSublayer(animationLayer)
|
self.layer.addSublayer(animationLayer)
|
||||||
self.animationLayer = animationLayer
|
self.animationLayer = animationLayer
|
||||||
}
|
}
|
||||||
animationLayer.frame = CGRect(origin: CGPoint(x: size.width - 7.0, y: floorToScreenPixels((size.height - iconSize.height) / 2.0)), size: iconSize)
|
animationLayer.frame = CGRect(origin: CGPoint(x: component.iconPosition == .left ? 38.0 : size.width - 7.0, y: floorToScreenPixels((size.height - iconSize.height) / 2.0)), size: iconSize)
|
||||||
size.width += iconSize.width + iconSpacing
|
size.width += iconSize.width + iconSpacing
|
||||||
} else if let animationLayer = self.animationLayer {
|
} else if let animationLayer = self.animationLayer {
|
||||||
self.animationLayer = nil
|
self.animationLayer = nil
|
||||||
|
@ -223,7 +223,7 @@ final class PeerNameColorProfilePreviewItemNode: ListViewItemNode {
|
|||||||
transition: .immediate,
|
transition: .immediate,
|
||||||
component: AnyComponent(PeerInfoCoverComponent(
|
component: AnyComponent(PeerInfoCoverComponent(
|
||||||
context: item.context,
|
context: item.context,
|
||||||
peer: item.peer,
|
subject: item.peer.flatMap { .peer($0) },
|
||||||
files: item.files,
|
files: item.files,
|
||||||
isDark: item.theme.overallDarkAppearance,
|
isDark: item.theme.overallDarkAppearance,
|
||||||
avatarCenter: avatarFrame.center,
|
avatarCenter: avatarFrame.center,
|
||||||
|
@ -585,7 +585,7 @@ final class ThemeGridSearchContentNode: SearchDisplayControllerContentNode {
|
|||||||
entries.append(.query(i, queries[i]))
|
entries.append(.query(i, queries[i]))
|
||||||
}
|
}
|
||||||
|
|
||||||
let header = ChatListSearchItemHeader(type: .recentPeers, theme: presentationData.theme, strings: presentationData.strings, actionTitle: presentationData.strings.WebSearch_RecentSectionClear, action: {
|
let header = ChatListSearchItemHeader(type: .recentPeers, theme: presentationData.theme, strings: presentationData.strings, actionTitle: presentationData.strings.WebSearch_RecentSectionClear, action: { _ in
|
||||||
let _ = clearRecentWallpaperSearchQueries(engine: strongSelf.context.engine).start()
|
let _ = clearRecentWallpaperSearchQueries(engine: strongSelf.context.engine).start()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -40,7 +40,6 @@ swift_library(
|
|||||||
"//submodules/TelegramUI/Components/CameraButtonComponent",
|
"//submodules/TelegramUI/Components/CameraButtonComponent",
|
||||||
"//submodules/ContextUI",
|
"//submodules/ContextUI",
|
||||||
"//submodules/UndoUI",
|
"//submodules/UndoUI",
|
||||||
"//submodules/GalleryUI",
|
|
||||||
"//submodules/TelegramUI/Components/TextLoadingEffect",
|
"//submodules/TelegramUI/Components/TextLoadingEffect",
|
||||||
],
|
],
|
||||||
visibility = [
|
visibility = [
|
||||||
|
@ -23,7 +23,6 @@ import BundleIconComponent
|
|||||||
import LottieComponent
|
import LottieComponent
|
||||||
import LottieComponentResourceContent
|
import LottieComponentResourceContent
|
||||||
import UndoUI
|
import UndoUI
|
||||||
import GalleryUI
|
|
||||||
import TextLoadingEffect
|
import TextLoadingEffect
|
||||||
import TelegramStringFormatting
|
import TelegramStringFormatting
|
||||||
|
|
||||||
@ -752,9 +751,7 @@ public class StickerPickerScreen: ViewController {
|
|||||||
|
|
||||||
let message = Message(stableId: 0, stableVersion: 0, id: MessageId(peerId: PeerId(0), namespace: Namespaces.Message.Local, id: 0), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: 0, flags: [], tags: [], globalTags: [], localTags: [], customTags: [], forwardInfo: nil, author: nil, text: "", attributes: [], media: [file.media], peers: SimpleDictionary(), associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil, associatedStories: [:])
|
let message = Message(stableId: 0, stableVersion: 0, id: MessageId(peerId: PeerId(0), namespace: Namespaces.Message.Local, id: 0), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: 0, flags: [], tags: [], globalTags: [], localTags: [], customTags: [], forwardInfo: nil, author: nil, text: "", attributes: [], media: [file.media], peers: SimpleDictionary(), associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil, associatedStories: [:])
|
||||||
|
|
||||||
let gallery = GalleryController(context: context, source: .standaloneMessage(message, nil), streamSingleVideo: true, replaceRootController: { _, _ in
|
let gallery = context.sharedContext.makeGalleryController(context: context, source: .standaloneMessage(message, nil), streamSingleVideo: true, isPreview: true)
|
||||||
}, baseNavigationController: nil)
|
|
||||||
gallery.setHintWillBePresentedInPreviewingContext(true)
|
|
||||||
|
|
||||||
var items: [ContextMenuItem] = []
|
var items: [ContextMenuItem] = []
|
||||||
items.append(.action(ContextMenuActionItem(text: presentationData.strings.MediaEditor_AddGif, icon: { theme in
|
items.append(.action(ContextMenuActionItem(text: presentationData.strings.MediaEditor_AddGif, icon: { theme in
|
||||||
@ -2886,7 +2883,7 @@ private final class ContextControllerContentSourceImpl: ContextControllerContent
|
|||||||
}
|
}
|
||||||
|
|
||||||
func animatedIn() {
|
func animatedIn() {
|
||||||
if let controller = self.controller as? GalleryController {
|
if let controller = self.controller as? GalleryControllerProtocol {
|
||||||
controller.viewDidAppear(false)
|
controller.viewDidAppear(false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2098,13 +2098,13 @@ public class StoryContainerScreen: ViewControllerComponentContainer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func dismissWithoutTransitionOut() {
|
func dismissWithoutTransitionOut(completion: (() -> Void)? = nil) {
|
||||||
self.focusedItemPromise.set(.single(nil))
|
self.focusedItemPromise.set(.single(nil))
|
||||||
|
|
||||||
if let componentView = self.node.hostView.componentView as? StoryContainerScreenComponent.View {
|
if let componentView = self.node.hostView.componentView as? StoryContainerScreenComponent.View {
|
||||||
componentView.dismissWithoutTransitionOut = true
|
componentView.dismissWithoutTransitionOut = true
|
||||||
}
|
}
|
||||||
self.dismiss()
|
self.dismiss(completion: completion)
|
||||||
}
|
}
|
||||||
|
|
||||||
override public func dismiss(completion: (() -> Void)? = nil) {
|
override public func dismiss(completion: (() -> Void)? = nil) {
|
||||||
@ -2121,6 +2121,7 @@ public class StoryContainerScreen: ViewControllerComponentContainer {
|
|||||||
self?.dismiss(animated: false)
|
self?.dismiss(animated: false)
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
|
completion?()
|
||||||
self.dismiss(animated: false)
|
self.dismiss(animated: false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2677,64 +2677,43 @@ final class StoryItemSetContainerSendMessage {
|
|||||||
navigationController: navigationController,
|
navigationController: navigationController,
|
||||||
forceExternal: forceExternal,
|
forceExternal: forceExternal,
|
||||||
forceUpdate: false,
|
forceUpdate: false,
|
||||||
openPeer: { [weak self, weak view] peerId, navigation in
|
openPeer: { [weak view] peerId, navigation in
|
||||||
guard let self, let view, let component = view.component, let controller = component.controller() as? StoryContainerScreen else {
|
guard let view, let component = view.component, let controller = component.controller() as? StoryContainerScreen, let navigationController = controller.navigationController as? NavigationController else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
let context = component.context
|
||||||
switch navigation {
|
controller.dismissWithoutTransitionOut(completion: {
|
||||||
case let .chat(_, subject, peekData):
|
switch navigation {
|
||||||
if let navigationController = controller.navigationController as? NavigationController {
|
case let .chat(_, subject, peekData):
|
||||||
if case let .channel(channel) = peerId, channel.flags.contains(.isForum) {
|
if case let .channel(channel) = peerId, channel.flags.contains(.isForum) {
|
||||||
controller.dismissWithoutTransitionOut()
|
context.sharedContext.navigateToForumChannel(context: context, peerId: peerId.id, navigationController: navigationController)
|
||||||
component.context.sharedContext.navigateToForumChannel(context: component.context, peerId: peerId.id, navigationController: navigationController)
|
|
||||||
} else {
|
} else {
|
||||||
component.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: component.context, chatLocation: .peer(peerId), subject: subject, keepStack: .always, peekData: peekData, pushController: { [weak controller, weak navigationController] chatController, animated, completion in
|
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(peerId), subject: subject, keepStack: .always, peekData: peekData, pushController: { [weak navigationController] chatController, animated, completion in
|
||||||
guard let controller, let navigationController else {
|
Queue.mainQueue().justDispatch {
|
||||||
return
|
navigationController?.pushViewController(chatController)
|
||||||
}
|
|
||||||
if "".isEmpty {
|
|
||||||
navigationController.pushViewController(chatController)
|
|
||||||
} else {
|
|
||||||
var viewControllers = navigationController.viewControllers
|
|
||||||
if let index = viewControllers.firstIndex(where: { $0 === controller }) {
|
|
||||||
viewControllers.insert(chatController, at: index)
|
|
||||||
} else {
|
|
||||||
viewControllers.append(chatController)
|
|
||||||
}
|
|
||||||
navigationController.setViewControllers(viewControllers, animated: animated)
|
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
}
|
case .info:
|
||||||
case .info:
|
let _ = (context.account.postbox.loadedPeerWithId(peerId.id)
|
||||||
self.navigationActionDisposable.set((component.context.account.postbox.loadedPeerWithId(peerId.id)
|
|> take(1)
|
||||||
|> take(1)
|
|> deliverOnMainQueue).start(next: { [weak navigationController] peer in
|
||||||
|> deliverOnMainQueue).start(next: { [weak view] peer in
|
if peer.restrictionText(platform: "ios", contentSettings: context.currentContentSettings.with { $0 }) == nil {
|
||||||
guard let view, let component = view.component else {
|
if let infoController = context.sharedContext.makePeerInfoController(context: context, updatedPresentationData: nil, peer: peer, mode: .generic, avatarInitiallyExpanded: false, fromChat: false, requestsContext: nil) {
|
||||||
return
|
navigationController?.pushViewController(infoController)
|
||||||
}
|
}
|
||||||
if peer.restrictionText(platform: "ios", contentSettings: component.context.currentContentSettings.with { $0 }) == nil {
|
|
||||||
if let infoController = component.context.sharedContext.makePeerInfoController(context: component.context, updatedPresentationData: nil, peer: peer, mode: .generic, avatarInitiallyExpanded: false, fromChat: false, requestsContext: nil) {
|
|
||||||
component.controller()?.push(infoController)
|
|
||||||
}
|
}
|
||||||
}
|
})
|
||||||
}))
|
case let .withBotStartPayload(startPayload):
|
||||||
case let .withBotStartPayload(startPayload):
|
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(peerId), botStart: startPayload, keepStack: .always))
|
||||||
if let navigationController = controller.navigationController as? NavigationController {
|
case let .withAttachBot(attachBotStart):
|
||||||
component.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: component.context, chatLocation: .peer(peerId), botStart: startPayload, keepStack: .always))
|
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(peerId), attachBotStart: attachBotStart))
|
||||||
|
case let .withBotApp(botAppStart):
|
||||||
|
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(peerId), botAppStart: botAppStart))
|
||||||
|
default:
|
||||||
|
break
|
||||||
}
|
}
|
||||||
case let .withAttachBot(attachBotStart):
|
})
|
||||||
if let navigationController = controller.navigationController as? NavigationController {
|
|
||||||
component.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: component.context, chatLocation: .peer(peerId), attachBotStart: attachBotStart))
|
|
||||||
}
|
|
||||||
case let .withBotApp(botAppStart):
|
|
||||||
if let navigationController = controller.navigationController as? NavigationController {
|
|
||||||
component.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: component.context, chatLocation: .peer(peerId), botAppStart: botAppStart))
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
break
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
sendFile: nil,
|
sendFile: nil,
|
||||||
sendSticker: nil,
|
sendSticker: nil,
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"images" : [
|
"images" : [
|
||||||
{
|
{
|
||||||
"filename" : "verifybadge1_16 (1).pdf",
|
"filename" : "ver (2).pdf",
|
||||||
"idiom" : "universal"
|
"idiom" : "universal"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user