mirror of
https://github.com/TelegramMessenger/Telegram-iOS.git
synced 2026-07-06 03:33:41 +02:00
Merge commit '4b8d87b05f'
This commit is contained in:
commit
b8400f435f
70 changed files with 3314 additions and 432 deletions
BIN
Telegram/Telegram-iOS/Resources/Cake.tgs
Normal file
BIN
Telegram/Telegram-iOS/Resources/Cake.tgs
Normal file
Binary file not shown.
|
|
@ -15058,3 +15058,22 @@ Error: %8$@";
|
|||
"Gift.UpgradeCost.AdditionalDescription" = "Users who upgrade their gifts first get collectibles with shorter numbers.";
|
||||
"Gift.UpgradeCost.Done" = "Understood";
|
||||
|
||||
"UserInfo.SuggestBirthdate" = "Suggest Date of Birth";
|
||||
|
||||
"SuggestBirthdate.Suggest.Title" = "%@'s Date of Birth";
|
||||
"SuggestBirthdate.Suggest.Action" = "Suggest Date of Birth";
|
||||
"SuggestBirthdate.Accept.Title" = "Date of Birth";
|
||||
"SuggestBirthdate.Accept.HideYear" = "Hide the Year";
|
||||
"SuggestBirthdate.Accept.Action" = "Add to My Profile";
|
||||
"SuggestBirthdate.Accept.Added" = "Date of birth added.";
|
||||
|
||||
"Notification.SuggestBirthdate" = "Suggested Date of Birth";
|
||||
|
||||
"Conversation.SuggestedBirthdateText" = "**%@** suggests you to add you date of birth:.";
|
||||
"Conversation.SuggestedBirthdateTextYou" = "You suggested **%@** to add a date of birth:";
|
||||
"Conversation.SuggestedBirthdate.Day" = "Day";
|
||||
"Conversation.SuggestedBirthdate.Month" = "Month";
|
||||
"Conversation.SuggestedBirthdate.Year" = "Year";
|
||||
"Conversation.SuggestedBirthdate.View" = "View";
|
||||
|
||||
"PeerInfo.ChangeProfileColor" = "Change Profile Color";
|
||||
|
|
|
|||
|
|
@ -1361,6 +1361,10 @@ public protocol SharedAccountContext: AnyObject {
|
|||
|
||||
func makeForumSettingsScreen(context: AccountContext, peerId: EnginePeer.Id) -> ViewController
|
||||
|
||||
func makeBirthdayPickerScreen(context: AccountContext, settings: Promise<AccountPrivacySettings?>, openSettings: @escaping () -> Void, completion: @escaping (TelegramBirthday) -> Void) -> ViewController
|
||||
func makeBirthdaySuggestionScreen(context: AccountContext, peerId: EnginePeer.Id, completion: @escaping (TelegramBirthday) -> Void) -> ViewController
|
||||
func makeBirthdayAcceptSuggestionScreen(context: AccountContext, birthday: TelegramBirthday, settings: Promise<AccountPrivacySettings?>, openSettings: @escaping () -> Void, completion: @escaping (TelegramBirthday) -> Void) -> ViewController
|
||||
|
||||
func makeDebugSettingsController(context: AccountContext?) -> ViewController?
|
||||
|
||||
func openCreateGroupCallUI(context: AccountContext, peerIds: [EnginePeer.Id], parentController: ViewController)
|
||||
|
|
|
|||
|
|
@ -6205,25 +6205,31 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
|||
settingsPromise = Promise()
|
||||
settingsPromise.set(.single(nil) |> then(context.engine.privacy.requestAccountPrivacySettings() |> map(Optional.init)))
|
||||
}
|
||||
let controller = BirthdayPickerScreen(context: context, settings: settingsPromise.get(), openSettings: { [weak self] in
|
||||
guard let self else {
|
||||
return
|
||||
|
||||
let controller = context.sharedContext.makeBirthdayPickerScreen(
|
||||
context: context,
|
||||
settings: settingsPromise,
|
||||
openSettings: { [weak self] in
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
self.context.sharedContext.makeBirthdayPrivacyController(context: self.context, settings: settingsPromise, openedFromBirthdayScreen: true, present: { [weak self] c in
|
||||
self?.push(c)
|
||||
})
|
||||
},
|
||||
completion: { [weak self] value in
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
|
||||
let _ = context.engine.accountData.updateBirthday(birthday: value).startStandalone()
|
||||
|
||||
let presentationData = self.context.sharedContext.currentPresentationData.with { $0 }
|
||||
self.present(UndoOverlayController(presentationData: presentationData, content: .actionSucceeded(title: nil, text: self.presentationData.strings.Birthday_Added, cancel: nil, destructive: false), elevatedLayout: false, action: { _ in
|
||||
return true
|
||||
}), in: .current)
|
||||
}
|
||||
self.context.sharedContext.makeBirthdayPrivacyController(context: self.context, settings: settingsPromise, openedFromBirthdayScreen: true, present: { [weak self] c in
|
||||
self?.push(c)
|
||||
})
|
||||
}, completion: { [weak self] value in
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
|
||||
let _ = context.engine.accountData.updateBirthday(birthday: value).startStandalone()
|
||||
|
||||
let presentationData = self.context.sharedContext.currentPresentationData.with { $0 }
|
||||
self.present(UndoOverlayController(presentationData: presentationData, content: .actionSucceeded(title: nil, text: self.presentationData.strings.Birthday_Added, cancel: nil, destructive: false), elevatedLayout: false, action: { _ in
|
||||
return true
|
||||
}), in: .current)
|
||||
})
|
||||
)
|
||||
self.push(controller)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ swift_library(
|
|||
"//submodules/Components/BalancedTextComponent",
|
||||
"//submodules/Markdown",
|
||||
"//submodules/TelegramUI/Components/Premium/PremiumStarComponent",
|
||||
"//submodules/TelegramUI/Components/GlassBackgroundComponent",
|
||||
],
|
||||
visibility = [
|
||||
"//visibility:public",
|
||||
|
|
|
|||
|
|
@ -4,6 +4,8 @@ import AsyncDisplayKit
|
|||
import Display
|
||||
import TelegramPresentationData
|
||||
import AccountContext
|
||||
import ComponentFlow
|
||||
import GlassBackgroundComponent
|
||||
|
||||
private func generateBackgroundImage(foreground: UIColor, diameter: CGFloat, sideInset: CGFloat) -> UIImage? {
|
||||
return generateImage(CGSize(width: diameter + sideInset * 2.0, height: diameter + sideInset * 2.0), rotatedContext: { size, context in
|
||||
|
|
@ -41,6 +43,8 @@ final class ReactionContextBackgroundNode: ASDisplayNode {
|
|||
private let smallCircleSize: CGFloat
|
||||
|
||||
private let backgroundView: BlurredBackgroundView
|
||||
private let glassBackgroundView: GlassBackgroundView?
|
||||
|
||||
private let backgroundTintView: UIView
|
||||
private let backgroundTintMaskOuterContainer: UIView
|
||||
let backgroundTintMaskContainer: UIView
|
||||
|
|
@ -57,11 +61,16 @@ final class ReactionContextBackgroundNode: ASDisplayNode {
|
|||
|
||||
private var theme: PresentationTheme?
|
||||
|
||||
init(largeCircleSize: CGFloat, smallCircleSize: CGFloat, maskNode: ASDisplayNode) {
|
||||
init(glass: Bool, largeCircleSize: CGFloat, smallCircleSize: CGFloat, maskNode: ASDisplayNode) {
|
||||
self.largeCircleSize = largeCircleSize
|
||||
self.smallCircleSize = smallCircleSize
|
||||
|
||||
self.backgroundView = BlurredBackgroundView(color: nil, enableBlur: true)
|
||||
if glass {
|
||||
self.glassBackgroundView = GlassBackgroundView()
|
||||
} else {
|
||||
self.glassBackgroundView = nil
|
||||
}
|
||||
|
||||
self.backgroundTintView = UIView()
|
||||
self.backgroundTintMaskContainer = UIView()
|
||||
|
|
@ -108,16 +117,22 @@ final class ReactionContextBackgroundNode: ASDisplayNode {
|
|||
|
||||
self.backgroundTintMaskOuterContainer.backgroundColor = .white
|
||||
|
||||
self.view.addSubview(self.backgroundView)
|
||||
self.backgroundView.addSubview(self.backgroundTintView)
|
||||
|
||||
if let glassBackgroundView = self.glassBackgroundView {
|
||||
self.view.addSubview(glassBackgroundView)
|
||||
glassBackgroundView.addSubview(self.backgroundTintView)
|
||||
//glassBackgroundView.maskContentView.layer.addSublayer(self.maskLayer)
|
||||
} else {
|
||||
self.backgroundView.layer.mask = self.maskLayer
|
||||
self.view.addSubview(self.backgroundView)
|
||||
self.backgroundView.addSubview(self.backgroundTintView)
|
||||
}
|
||||
|
||||
self.maskLayer.addSublayer(self.smallCircleLayer)
|
||||
self.maskLayer.addSublayer(self.largeCircleLayer)
|
||||
self.maskLayer.addSublayer(self.backgroundClippingLayer)
|
||||
|
||||
self.backgroundClippingLayer.addSublayer(self.backgroundMaskNode.layer)
|
||||
|
||||
self.backgroundView.layer.mask = self.maskLayer
|
||||
}
|
||||
|
||||
func updateIsIntersectingContent(isIntersectingContent: Bool, transition: ContainedViewLayoutTransition) {
|
||||
|
|
@ -218,7 +233,16 @@ final class ReactionContextBackgroundNode: ASDisplayNode {
|
|||
transition.updateFrame(view: self.backgroundView, frame: contentBounds, beginWithCurrentState: true)
|
||||
self.backgroundView.update(size: contentBounds.size, transition: transition)
|
||||
|
||||
transition.updateFrame(view: self.backgroundTintView, frame: CGRect(origin: CGPoint(x: 0.0, y: 0.0), size: CGSize(width: contentBounds.width, height: contentBounds.height)))
|
||||
if let glassBackgroundView = self.glassBackgroundView {
|
||||
var glassBackgroundFrame = contentBounds.insetBy(dx: 10.0, dy: 10.0)
|
||||
glassBackgroundFrame.size.height -= 8.0
|
||||
transition.updateFrame(view: glassBackgroundView, frame: glassBackgroundFrame, beginWithCurrentState: true)
|
||||
glassBackgroundView.update(size: glassBackgroundFrame.size, cornerRadius: 23.0, isDark: true, tintColor: .init(kind: .custom, color: UIColor(rgb: 0x1b1d22)), transition: ComponentTransition(transition))
|
||||
|
||||
transition.updateFrame(view: self.backgroundTintView, frame: CGRect(origin: CGPoint(x: 0.0, y: 0.0), size: CGSize(width: contentBounds.width, height: contentBounds.height)).insetBy(dx: -10.0, dy: -10.0))
|
||||
} else {
|
||||
transition.updateFrame(view: self.backgroundTintView, frame: CGRect(origin: CGPoint(x: 0.0, y: 0.0), size: CGSize(width: contentBounds.width, height: contentBounds.height)))
|
||||
}
|
||||
transition.updateFrame(view: self.backgroundTintMaskOuterContainer, frame: CGRect(origin: CGPoint(x: 0.0, y: 0.0), size: contentBounds.size))
|
||||
transition.updateFrame(view: self.backgroundTintMaskContainer, frame: CGRect(origin: CGPoint(x: 10.0, y: 10.0), size: contentBounds.size))
|
||||
transition.updateFrame(view: self.vibrantExpandedContentContainer, frame: CGRect(origin: CGPoint(x: 10.0, y: 10.0), size: contentBounds.size))
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ import GZip
|
|||
import BalancedTextComponent
|
||||
import Markdown
|
||||
import PremiumStarComponent
|
||||
import GlassBackgroundComponent
|
||||
|
||||
public final class ReactionItem {
|
||||
public struct Reaction: Equatable {
|
||||
|
|
@ -487,7 +488,12 @@ public final class ReactionContextNode: ASDisplayNode, ASScrollViewDelegate {
|
|||
}
|
||||
}
|
||||
|
||||
public init(context: AccountContext, animationCache: AnimationCache, presentationData: PresentationData, items: [ReactionContextItem], selectedItems: Set<AnyHashable>, title: String? = nil, reactionsLocked: Bool, alwaysAllowPremiumReactions: Bool, allPresetReactionsAreAvailable: Bool, getEmojiContent: ((AnimationCache, MultiAnimationRenderer) -> Signal<EmojiPagerContentComponent, NoError>)?, isExpandedUpdated: @escaping (ContainedViewLayoutTransition) -> Void, requestLayout: @escaping (ContainedViewLayoutTransition) -> Void, requestUpdateOverlayWantsToBeBelowKeyboard: @escaping (ContainedViewLayoutTransition) -> Void) {
|
||||
public enum Style {
|
||||
case legacy
|
||||
case glass
|
||||
}
|
||||
|
||||
public init(context: AccountContext, animationCache: AnimationCache, presentationData: PresentationData, style: Style = .legacy, items: [ReactionContextItem], selectedItems: Set<AnyHashable>, title: String? = nil, reactionsLocked: Bool, alwaysAllowPremiumReactions: Bool, allPresetReactionsAreAvailable: Bool, getEmojiContent: ((AnimationCache, MultiAnimationRenderer) -> Signal<EmojiPagerContentComponent, NoError>)?, isExpandedUpdated: @escaping (ContainedViewLayoutTransition) -> Void, requestLayout: @escaping (ContainedViewLayoutTransition) -> Void, requestUpdateOverlayWantsToBeBelowKeyboard: @escaping (ContainedViewLayoutTransition) -> Void) {
|
||||
self.context = context
|
||||
self.presentationData = presentationData
|
||||
self.items = items
|
||||
|
|
@ -503,7 +509,7 @@ public final class ReactionContextNode: ASDisplayNode, ASScrollViewDelegate {
|
|||
(self.animationRenderer as? MultiAnimationRendererImpl)?.useYuvA = context.sharedContext.immediateExperimentalUISettings.compressedEmojiCache
|
||||
|
||||
self.backgroundMaskNode = ASDisplayNode()
|
||||
self.backgroundNode = ReactionContextBackgroundNode(largeCircleSize: largeCircleSize, smallCircleSize: smallCircleSize, maskNode: self.backgroundMaskNode)
|
||||
self.backgroundNode = ReactionContextBackgroundNode(glass: style == .glass, largeCircleSize: largeCircleSize, smallCircleSize: smallCircleSize, maskNode: self.backgroundMaskNode)
|
||||
self.leftBackgroundMaskNode = ASDisplayNode()
|
||||
self.leftBackgroundMaskNode.backgroundColor = .black
|
||||
self.rightBackgroundMaskNode = ASDisplayNode()
|
||||
|
|
|
|||
|
|
@ -612,6 +612,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
|
|||
dict[1007897979] = { return Api.MessageAction.parse_messageActionSetMessagesTTL($0) }
|
||||
dict[-229775366] = { return Api.MessageAction.parse_messageActionStarGift($0) }
|
||||
dict[-1787656893] = { return Api.MessageAction.parse_messageActionStarGiftUnique($0) }
|
||||
dict[747579941] = { return Api.MessageAction.parse_messageActionSuggestBirthday($0) }
|
||||
dict[1474192222] = { return Api.MessageAction.parse_messageActionSuggestProfilePhoto($0) }
|
||||
dict[-293988970] = { return Api.MessageAction.parse_messageActionSuggestedPostApproval($0) }
|
||||
dict[1777932024] = { return Api.MessageAction.parse_messageActionSuggestedPostRefund($0) }
|
||||
|
|
|
|||
|
|
@ -395,6 +395,7 @@ public extension Api {
|
|||
case messageActionSetMessagesTTL(flags: Int32, period: Int32, autoSettingFrom: Int64?)
|
||||
case messageActionStarGift(flags: Int32, gift: Api.StarGift, message: Api.TextWithEntities?, convertStars: Int64?, upgradeMsgId: Int32?, upgradeStars: Int64?, fromId: Api.Peer?, peer: Api.Peer?, savedId: Int64?, prepaidUpgradeHash: String?, giftMsgId: Int32?)
|
||||
case messageActionStarGiftUnique(flags: Int32, gift: Api.StarGift, canExportAt: Int32?, transferStars: Int64?, fromId: Api.Peer?, peer: Api.Peer?, savedId: Int64?, resaleAmount: Api.StarsAmount?, canTransferAt: Int32?, canResellAt: Int32?, dropOriginalDetailsStars: Int64?)
|
||||
case messageActionSuggestBirthday(birthday: Api.Birthday)
|
||||
case messageActionSuggestProfilePhoto(photo: Api.Photo)
|
||||
case messageActionSuggestedPostApproval(flags: Int32, rejectComment: String?, scheduleDate: Int32?, price: Api.StarsAmount?)
|
||||
case messageActionSuggestedPostRefund(flags: Int32)
|
||||
|
|
@ -815,6 +816,12 @@ public extension Api {
|
|||
if Int(flags) & Int(1 << 10) != 0 {serializeInt32(canResellAt!, buffer: buffer, boxed: false)}
|
||||
if Int(flags) & Int(1 << 12) != 0 {serializeInt64(dropOriginalDetailsStars!, buffer: buffer, boxed: false)}
|
||||
break
|
||||
case .messageActionSuggestBirthday(let birthday):
|
||||
if boxed {
|
||||
buffer.appendInt32(747579941)
|
||||
}
|
||||
birthday.serialize(buffer, true)
|
||||
break
|
||||
case .messageActionSuggestProfilePhoto(let photo):
|
||||
if boxed {
|
||||
buffer.appendInt32(1474192222)
|
||||
|
|
@ -998,6 +1005,8 @@ public extension Api {
|
|||
return ("messageActionStarGift", [("flags", flags as Any), ("gift", gift as Any), ("message", message as Any), ("convertStars", convertStars as Any), ("upgradeMsgId", upgradeMsgId as Any), ("upgradeStars", upgradeStars as Any), ("fromId", fromId as Any), ("peer", peer as Any), ("savedId", savedId as Any), ("prepaidUpgradeHash", prepaidUpgradeHash as Any), ("giftMsgId", giftMsgId as Any)])
|
||||
case .messageActionStarGiftUnique(let flags, let gift, let canExportAt, let transferStars, let fromId, let peer, let savedId, let resaleAmount, let canTransferAt, let canResellAt, let dropOriginalDetailsStars):
|
||||
return ("messageActionStarGiftUnique", [("flags", flags as Any), ("gift", gift as Any), ("canExportAt", canExportAt as Any), ("transferStars", transferStars as Any), ("fromId", fromId as Any), ("peer", peer as Any), ("savedId", savedId as Any), ("resaleAmount", resaleAmount as Any), ("canTransferAt", canTransferAt as Any), ("canResellAt", canResellAt as Any), ("dropOriginalDetailsStars", dropOriginalDetailsStars as Any)])
|
||||
case .messageActionSuggestBirthday(let birthday):
|
||||
return ("messageActionSuggestBirthday", [("birthday", birthday as Any)])
|
||||
case .messageActionSuggestProfilePhoto(let photo):
|
||||
return ("messageActionSuggestProfilePhoto", [("photo", photo as Any)])
|
||||
case .messageActionSuggestedPostApproval(let flags, let rejectComment, let scheduleDate, let price):
|
||||
|
|
@ -1831,6 +1840,19 @@ public extension Api {
|
|||
return nil
|
||||
}
|
||||
}
|
||||
public static func parse_messageActionSuggestBirthday(_ reader: BufferReader) -> MessageAction? {
|
||||
var _1: Api.Birthday?
|
||||
if let signature = reader.readInt32() {
|
||||
_1 = Api.parse(reader, signature: signature) as? Api.Birthday
|
||||
}
|
||||
let _c1 = _1 != nil
|
||||
if _c1 {
|
||||
return Api.MessageAction.messageActionSuggestBirthday(birthday: _1!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
public static func parse_messageActionSuggestProfilePhoto(_ reader: BufferReader) -> MessageAction? {
|
||||
var _1: Api.Photo?
|
||||
if let signature = reader.readInt32() {
|
||||
|
|
|
|||
|
|
@ -12464,3 +12464,19 @@ public extension Api.functions.users {
|
|||
})
|
||||
}
|
||||
}
|
||||
public extension Api.functions.users {
|
||||
static func suggestBirthday(id: Api.InputUser, birthday: Api.Birthday) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Updates>) {
|
||||
let buffer = Buffer()
|
||||
buffer.appendInt32(-61656206)
|
||||
id.serialize(buffer, true)
|
||||
birthday.serialize(buffer, true)
|
||||
return (FunctionDescription(name: "users.suggestBirthday", parameters: [("id", String(describing: id)), ("birthday", String(describing: birthday))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.Updates? in
|
||||
let reader = BufferReader(buffer)
|
||||
var result: Api.Updates?
|
||||
if let signature = reader.readInt32() {
|
||||
result = Api.parse(reader, signature: signature) as? Api.Updates
|
||||
}
|
||||
return result
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -123,6 +123,12 @@ swift_library(
|
|||
"//submodules/InviteLinksUI",
|
||||
"//third-party/td:TdBinding",
|
||||
"//submodules/TelegramUI/Components/AnimatedTextComponent",
|
||||
"//submodules/TelegramUI/Components/GlassBackgroundComponent",
|
||||
"//submodules/ChatPresentationInterfaceState",
|
||||
"//submodules/TelegramUI/Components/MessageInputPanelComponent",
|
||||
"//submodules/TelegramUI/Components/TextFieldComponent",
|
||||
"//submodules/ReactionSelectionNode",
|
||||
"//submodules/TelegramUI/Components/EntityKeyboard",
|
||||
],
|
||||
visibility = [
|
||||
"//visibility:public",
|
||||
|
|
|
|||
|
|
@ -0,0 +1,288 @@
|
|||
import Foundation
|
||||
import Display
|
||||
import UIKit
|
||||
import ComponentFlow
|
||||
import SwiftSignalKit
|
||||
import TelegramCore
|
||||
import AvatarNode
|
||||
import GlassBackgroundComponent
|
||||
import MultilineTextComponent
|
||||
import MultilineTextWithEntitiesComponent
|
||||
import AccountContext
|
||||
import TextFormat
|
||||
import TelegramPresentationData
|
||||
import ReactionSelectionNode
|
||||
|
||||
final class MessageItemComponent: Component {
|
||||
private let context: AccountContext
|
||||
private let peer: EnginePeer
|
||||
private let text: String
|
||||
private let entities: [MessageTextEntity]
|
||||
private let availableReactions: [ReactionItem]?
|
||||
private let avatarTapped: () -> Void
|
||||
|
||||
init(
|
||||
context: AccountContext,
|
||||
peer: EnginePeer,
|
||||
text: String,
|
||||
entities: [MessageTextEntity],
|
||||
availableReactions: [ReactionItem]?,
|
||||
avatarTapped: @escaping () -> Void = {}
|
||||
) {
|
||||
self.context = context
|
||||
self.peer = peer
|
||||
self.text = text
|
||||
self.entities = entities
|
||||
self.availableReactions = availableReactions
|
||||
self.avatarTapped = avatarTapped
|
||||
}
|
||||
|
||||
static func == (lhs: MessageItemComponent, rhs: MessageItemComponent) -> Bool {
|
||||
if lhs.context !== rhs.context {
|
||||
return false
|
||||
}
|
||||
if lhs.peer != rhs.peer {
|
||||
return false
|
||||
}
|
||||
if lhs.text != rhs.text {
|
||||
return false
|
||||
}
|
||||
if lhs.entities != rhs.entities {
|
||||
return false
|
||||
}
|
||||
if (lhs.availableReactions ?? []).isEmpty != (rhs.availableReactions ?? []).isEmpty {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
final class View: UIView {
|
||||
private let container: UIView
|
||||
private let background: GlassBackgroundView
|
||||
private let avatarNode: AvatarNode
|
||||
private let text: ComponentView<Empty>
|
||||
weak var standaloneReactionAnimation: StandaloneReactionAnimation?
|
||||
|
||||
private var component: MessageItemComponent?
|
||||
|
||||
override init(frame: CGRect) {
|
||||
self.container = UIView()
|
||||
self.container.transform = CGAffineTransform(scaleX: 1.0, y: -1.0)
|
||||
|
||||
self.background = GlassBackgroundView()
|
||||
|
||||
self.avatarNode = AvatarNode(font: avatarPlaceholderFont(size: 10.0))
|
||||
|
||||
self.text = ComponentView()
|
||||
|
||||
super.init(frame: frame)
|
||||
|
||||
self.addSubview(self.container)
|
||||
self.container.addSubview(self.background)
|
||||
self.container.addSubview(self.avatarNode.view)
|
||||
}
|
||||
|
||||
required init?(coder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
func animateFrom(globalFrame: CGRect, cornerRadius: CGFloat, textSnapshotView: UIView, transition: ComponentTransition) {
|
||||
guard let superview = self.superview?.superview?.superview else {
|
||||
return
|
||||
}
|
||||
|
||||
let originalCenter = self.container.center
|
||||
let originalTransform = self.container.transform
|
||||
|
||||
let superviewCenter = self.convert(self.container.center, to: superview)
|
||||
self.container.center = superviewCenter
|
||||
self.container.transform = .identity
|
||||
superview.addSubview(self.container)
|
||||
|
||||
self.container.addSubview(textSnapshotView)
|
||||
transition.setAlpha(view: textSnapshotView, alpha: 0.0, completion: { _ in
|
||||
textSnapshotView.removeFromSuperview()
|
||||
})
|
||||
transition.setPosition(view: textSnapshotView, position: CGPoint(x: textSnapshotView.center.x + 71.0, y: textSnapshotView.center.y))
|
||||
|
||||
let initialSize = self.background.frame.size
|
||||
self.background.update(size: globalFrame.size, cornerRadius: cornerRadius, isDark: true, tintColor: .init(kind: .custom, color: UIColor(rgb: 0x1b1d22)), transition: .immediate)
|
||||
self.background.update(size: initialSize, cornerRadius: 18.0, isDark: true, tintColor: .init(kind: .custom, color: UIColor(rgb: 0x1b1d22)), transition: transition)
|
||||
|
||||
let deltaX = (globalFrame.width - self.container.frame.width) / 2.0
|
||||
let deltaY = (globalFrame.height - self.container.frame.height) / 2.0
|
||||
let fromFrame = superview.convert(globalFrame, from: nil).offsetBy(dx: -deltaX, dy: -deltaY)
|
||||
|
||||
self.container.center = fromFrame.center
|
||||
transition.setPosition(view: self.container, position: superviewCenter, completion: { _ in
|
||||
self.container.center = originalCenter
|
||||
self.container.transform = originalTransform
|
||||
self.insertSubview(self.container, at: 0)
|
||||
})
|
||||
|
||||
if let textView = self.text.view {
|
||||
transition.animatePosition(view: textView, from: CGPoint(x: -71.0, y: 0.0), to: .zero, additive: true)
|
||||
transition.animateAlpha(view: textView, from: 0.0, to: 1.0)
|
||||
}
|
||||
transition.animateAlpha(view: self.avatarNode.view, from: 0.0, to: 1.0)
|
||||
transition.animateScale(view: self.avatarNode.view, from: 0.01, to: 1.0)
|
||||
}
|
||||
|
||||
func update(component: MessageItemComponent, availableSize: CGSize, state: EmptyComponentState, environment: Environment<Empty>, transition: ComponentTransition) -> CGSize {
|
||||
let isFirstTime = self.component == nil
|
||||
var transition = transition
|
||||
if isFirstTime {
|
||||
transition = .immediate
|
||||
}
|
||||
self.component = component
|
||||
|
||||
let theme = defaultDarkPresentationTheme
|
||||
|
||||
let textFont = Font.regular(14.0)
|
||||
let boldTextFont = Font.semibold(14.0)
|
||||
let textColor: UIColor = .white
|
||||
let linkColor: UIColor = UIColor(rgb: 0x59b6fa)
|
||||
|
||||
let minimalHeight: CGFloat = 36.0
|
||||
let cornerRadius = minimalHeight * 0.5
|
||||
let avatarInset: CGFloat = 4.0
|
||||
let avatarSize = CGSize(width: minimalHeight - avatarInset * 2.0, height: minimalHeight - avatarInset * 2.0)
|
||||
let avatarSpacing: CGFloat = 10.0
|
||||
let rightInset: CGFloat = 13.0
|
||||
|
||||
let avatarFrame = CGRect(origin: CGPoint(x: avatarInset, y: avatarInset), size: avatarSize)
|
||||
if component.peer.smallProfileImage != nil {
|
||||
self.avatarNode.setPeerV2(
|
||||
context: component.context,
|
||||
theme: theme,
|
||||
peer: component.peer,
|
||||
authorOfMessage: nil,
|
||||
overrideImage: nil,
|
||||
emptyColor: nil,
|
||||
clipStyle: .round,
|
||||
synchronousLoad: true,
|
||||
displayDimensions: avatarSize
|
||||
)
|
||||
} else {
|
||||
self.avatarNode.setPeer(
|
||||
context: component.context,
|
||||
theme: theme,
|
||||
peer: component.peer,
|
||||
clipStyle: .round,
|
||||
synchronousLoad: true,
|
||||
displayDimensions: avatarSize
|
||||
)
|
||||
}
|
||||
if self.avatarNode.bounds.isEmpty {
|
||||
self.avatarNode.frame = avatarFrame
|
||||
} else {
|
||||
transition.setFrame(view: self.avatarNode.view, frame: avatarFrame)
|
||||
}
|
||||
|
||||
let attributedText = stringWithAppliedEntities(component.text, entities: component.entities, baseColor: textColor, linkColor: linkColor, baseFont: textFont, linkFont: textFont, boldFont: boldTextFont, italicFont: textFont, boldItalicFont: boldTextFont, fixedFont: textFont, blockQuoteFont: textFont, message: nil).mutableCopy() as! NSMutableAttributedString
|
||||
attributedText.insert(NSAttributedString(string: component.peer.compactDisplayTitle + " ", font: boldTextFont, textColor: textColor), at: 0)
|
||||
|
||||
let textSize = self.text.update(
|
||||
transition: transition,
|
||||
component: AnyComponent(MultilineTextWithEntitiesComponent(
|
||||
context: component.context,
|
||||
animationCache: component.context.animationCache,
|
||||
animationRenderer: component.context.animationRenderer,
|
||||
placeholderColor: .white,
|
||||
text: .plain(attributedText),
|
||||
maximumNumberOfLines: 0,
|
||||
lineSpacing: 0.0
|
||||
)),
|
||||
environment: {},
|
||||
containerSize: CGSize(width: availableSize.width - avatarInset - avatarSize.width - avatarSpacing - rightInset, height: .greatestFiniteMagnitude)
|
||||
)
|
||||
|
||||
let size = CGSize(width: avatarInset + avatarSize.width + avatarSpacing + textSize.width + rightInset, height: max(minimalHeight, textSize.height + 15.0))
|
||||
|
||||
let textFrame = CGRect(origin: CGPoint(x: avatarInset + avatarSize.width + avatarSpacing, y: floorToScreenPixels((size.height - textSize.height) / 2.0)), size: textSize)
|
||||
if let textView = self.text.view {
|
||||
if textView.superview == nil {
|
||||
self.container.addSubview(textView)
|
||||
}
|
||||
transition.setFrame(view: textView, frame: textFrame)
|
||||
}
|
||||
|
||||
transition.setFrame(view: self.container, frame: CGRect(origin: CGPoint(), size: size))
|
||||
|
||||
self.background.update(size: size, cornerRadius: cornerRadius, isDark: true, tintColor: .init(kind: .custom, color: UIColor(rgb: 0x1b1d22)), transition: transition)
|
||||
transition.setFrame(view: self.background, frame: CGRect(origin: CGPoint(), size: size))
|
||||
|
||||
if isFirstTime, let availableReactions = component.availableReactions, let textView = self.text.view {
|
||||
var reactionItem: ReactionItem?
|
||||
for item in availableReactions {
|
||||
if case .builtin(component.text.strippedEmoji) = item.reaction.rawValue {
|
||||
reactionItem = item
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if let reactionItem {
|
||||
Queue.mainQueue().justDispatch {
|
||||
guard let listView = self.superview else {
|
||||
return
|
||||
}
|
||||
|
||||
let emojiTargetView = UIView(frame: CGRect(origin: CGPoint(x: textView.frame.width - 44.0, y: 0.0), size: CGSize(width: 44.0, height: 44.0)))
|
||||
emojiTargetView.isUserInteractionEnabled = false
|
||||
textView.addSubview(emojiTargetView)
|
||||
|
||||
let standaloneReactionAnimation = StandaloneReactionAnimation(genericReactionEffect: nil, useDirectRendering: false)
|
||||
self.container.addSubview(standaloneReactionAnimation.view)
|
||||
|
||||
if let standaloneReactionAnimation = self.standaloneReactionAnimation {
|
||||
self.standaloneReactionAnimation = nil
|
||||
standaloneReactionAnimation.view.removeFromSuperview()
|
||||
}
|
||||
self.standaloneReactionAnimation = standaloneReactionAnimation
|
||||
|
||||
standaloneReactionAnimation.frame = listView.bounds
|
||||
standaloneReactionAnimation.animateReactionSelection(
|
||||
context: component.context,
|
||||
theme: theme,
|
||||
animationCache: component.context.animationCache,
|
||||
reaction: reactionItem,
|
||||
avatarPeers: [],
|
||||
playHaptic: true,
|
||||
isLarge: false,
|
||||
hideCenterAnimation: true,
|
||||
targetView: emojiTargetView,
|
||||
addStandaloneReactionAnimation: { [weak self] standaloneReactionAnimation in
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
|
||||
if let standaloneReactionAnimation = self.standaloneReactionAnimation {
|
||||
self.standaloneReactionAnimation = nil
|
||||
standaloneReactionAnimation.view.removeFromSuperview()
|
||||
}
|
||||
self.standaloneReactionAnimation = standaloneReactionAnimation
|
||||
|
||||
standaloneReactionAnimation.frame = self.bounds
|
||||
listView.addSubview(standaloneReactionAnimation.view)
|
||||
},
|
||||
completion: { [weak standaloneReactionAnimation] in
|
||||
standaloneReactionAnimation?.view.removeFromSuperview()
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return size
|
||||
}
|
||||
}
|
||||
|
||||
func makeView() -> View {
|
||||
return View()
|
||||
}
|
||||
|
||||
func update(view: View, availableSize: CGSize, state: EmptyComponentState, environment: Environment<EnvironmentType>, transition: ComponentTransition) -> CGSize {
|
||||
return view.update(component: self, availableSize: availableSize, state: state, environment: environment, transition: transition)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,261 @@
|
|||
import Foundation
|
||||
import Display
|
||||
import UIKit
|
||||
import ComponentFlow
|
||||
import SwiftSignalKit
|
||||
import TelegramCore
|
||||
import AccountContext
|
||||
import ReactionSelectionNode
|
||||
|
||||
final class MessageListComponent: Component {
|
||||
struct Item: Equatable {
|
||||
let id: AnyHashable
|
||||
let peer: EnginePeer
|
||||
let text: String
|
||||
let entities: [MessageTextEntity]
|
||||
}
|
||||
|
||||
class SendActionTransition {
|
||||
public let textSnapshotView: UIView
|
||||
public let globalFrame: CGRect
|
||||
public let cornerRadius: CGFloat
|
||||
|
||||
init(textSnapshotView: UIView, globalFrame: CGRect, cornerRadius: CGFloat) {
|
||||
self.textSnapshotView = textSnapshotView
|
||||
self.globalFrame = globalFrame
|
||||
self.cornerRadius = cornerRadius
|
||||
}
|
||||
}
|
||||
|
||||
private let context: AccountContext
|
||||
private let items: [Item]
|
||||
private let availableReactions: [ReactionItem]?
|
||||
private let sendActionTransition: SendActionTransition?
|
||||
|
||||
init(
|
||||
context: AccountContext,
|
||||
items: [Item],
|
||||
availableReactions: [ReactionItem]?,
|
||||
sendActionTransition: SendActionTransition?
|
||||
) {
|
||||
self.context = context
|
||||
self.items = items
|
||||
self.availableReactions = availableReactions
|
||||
self.sendActionTransition = sendActionTransition
|
||||
}
|
||||
|
||||
static func == (lhs: MessageListComponent, rhs: MessageListComponent) -> Bool {
|
||||
if lhs.context !== rhs.context {
|
||||
return false
|
||||
}
|
||||
if lhs.items != rhs.items {
|
||||
return false
|
||||
}
|
||||
if (lhs.availableReactions ?? []).isEmpty != (rhs.availableReactions ?? []).isEmpty {
|
||||
return false
|
||||
}
|
||||
if lhs.sendActionTransition !== rhs.sendActionTransition {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
private final class ScrollView: UIScrollView {
|
||||
override func touchesShouldCancel(in view: UIView) -> Bool {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
final class View: UIView, UIScrollViewDelegate {
|
||||
private let scrollView: ScrollView
|
||||
|
||||
private var component: MessageListComponent?
|
||||
private weak var state: EmptyComponentState?
|
||||
private var isUpdating: Bool = false
|
||||
|
||||
private var nextSendActionTransition: MessageListComponent.SendActionTransition?
|
||||
|
||||
private var itemViews: [AnyHashable: ComponentView<Empty>] = [:]
|
||||
|
||||
private let topInset: CGFloat = 8.0
|
||||
private let bottomInset: CGFloat = 8.0
|
||||
private let itemSpacing: CGFloat = 6.0
|
||||
|
||||
private var ignoreScrolling: Bool = false
|
||||
|
||||
override init(frame: CGRect) {
|
||||
self.scrollView = ScrollView()
|
||||
|
||||
super.init(frame: frame)
|
||||
|
||||
self.scrollView.delaysContentTouches = false
|
||||
self.scrollView.canCancelContentTouches = true
|
||||
self.scrollView.contentInsetAdjustmentBehavior = .never
|
||||
if #available(iOS 13.0, *) {
|
||||
self.scrollView.automaticallyAdjustsScrollIndicatorInsets = false
|
||||
}
|
||||
self.scrollView.showsVerticalScrollIndicator = false
|
||||
self.scrollView.showsHorizontalScrollIndicator = false
|
||||
self.scrollView.alwaysBounceHorizontal = false
|
||||
self.scrollView.alwaysBounceVertical = true
|
||||
self.scrollView.scrollsToTop = false
|
||||
self.scrollView.delegate = self
|
||||
self.scrollView.clipsToBounds = false
|
||||
self.scrollView.transform = CGAffineTransform(scaleX: 1.0, y: -1.0)
|
||||
|
||||
self.addSubview(self.scrollView)
|
||||
}
|
||||
|
||||
required init?(coder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
func scrollViewDidScroll(_ scrollView: UIScrollView) {
|
||||
|
||||
}
|
||||
|
||||
private func isAtBottom(tolerance: CGFloat = 1.0) -> Bool {
|
||||
let bottomY = -self.scrollView.adjustedContentInset.top
|
||||
return self.scrollView.contentOffset.y <= bottomY + tolerance
|
||||
}
|
||||
|
||||
private func scrollToBottom(animated: Bool) {
|
||||
let targetY = -self.scrollView.adjustedContentInset.top
|
||||
if animated {
|
||||
self.scrollView.setContentOffset(CGPoint(x: 0, y: targetY), animated: true)
|
||||
} else {
|
||||
self.scrollView.contentOffset = CGPoint(x: 0, y: targetY)
|
||||
}
|
||||
}
|
||||
|
||||
func update(component: MessageListComponent, availableSize: CGSize, state: EmptyComponentState, environment: Environment<Empty>, transition: ComponentTransition) -> CGSize {
|
||||
self.component = component
|
||||
self.state = state
|
||||
|
||||
if let _ = component.sendActionTransition {
|
||||
self.nextSendActionTransition = component.sendActionTransition
|
||||
}
|
||||
|
||||
let originalTransition = transition
|
||||
transition.setFrame(view: self.scrollView, frame: CGRect(origin: .zero, size: availableSize))
|
||||
|
||||
let previousContentHeight = self.scrollView.contentSize.height
|
||||
let wasAtBottom = self.isAtBottom(tolerance: 1.0)
|
||||
|
||||
let maxWidth: CGFloat = 300.0
|
||||
|
||||
var measured: [(id: AnyHashable, size: CGSize, item: MessageListComponent.Item, itemTransition: ComponentTransition)] = []
|
||||
measured.reserveCapacity(component.items.count)
|
||||
|
||||
for item in component.items {
|
||||
var itemTransition = transition
|
||||
let key = item.id
|
||||
let container = self.itemViews[key] ?? {
|
||||
itemTransition = .immediate
|
||||
let v = ComponentView<Empty>()
|
||||
self.itemViews[key] = v
|
||||
return v
|
||||
}()
|
||||
|
||||
let size = container.update(
|
||||
transition: transition,
|
||||
component: AnyComponent(MessageItemComponent(
|
||||
context: component.context,
|
||||
peer: item.peer,
|
||||
text: item.text,
|
||||
entities: item.entities,
|
||||
availableReactions: component.availableReactions
|
||||
)),
|
||||
environment: {},
|
||||
containerSize: CGSize(width: maxWidth, height: .greatestFiniteMagnitude)
|
||||
)
|
||||
measured.append((id: key, size: size, item: item, itemTransition: itemTransition))
|
||||
}
|
||||
|
||||
let itemsHeight: CGFloat = measured.reduce(0) { $0 + $1.size.height } +
|
||||
CGFloat(max(0, measured.count - 1)) * self.itemSpacing
|
||||
let contentHeight = self.topInset + itemsHeight + self.bottomInset
|
||||
|
||||
var y = self.bottomInset
|
||||
|
||||
var validKeys = Set<AnyHashable>()
|
||||
for (index, entry) in measured.enumerated() {
|
||||
validKeys.insert(entry.id)
|
||||
if let itemView = self.itemViews[entry.id]?.view {
|
||||
var customAnimation = false
|
||||
if entry.item.peer.id == component.context.account.peerId, let _ = self.nextSendActionTransition {
|
||||
customAnimation = true
|
||||
}
|
||||
let itemFrame = CGRect(
|
||||
origin: CGPoint(x: floor((availableSize.width - entry.size.width) / 2.0), y: y),
|
||||
size: entry.size
|
||||
)
|
||||
|
||||
if itemView.superview == nil {
|
||||
if !originalTransition.animation.isImmediate && !customAnimation {
|
||||
originalTransition.animateAlpha(view: itemView, from: 0.0, to: 1.0)
|
||||
originalTransition.animateScale(view: itemView, from: 0.01, to: 1.0)
|
||||
}
|
||||
if customAnimation, let nextSendActionTransition = self.nextSendActionTransition {
|
||||
self.nextSendActionTransition = nil
|
||||
itemView.frame = itemFrame
|
||||
if let itemView = itemView as? MessageItemComponent.View {
|
||||
itemView.isHidden = true
|
||||
Queue.mainQueue().justDispatch {
|
||||
itemView.animateFrom(globalFrame: nextSendActionTransition.globalFrame, cornerRadius: nextSendActionTransition.cornerRadius, textSnapshotView: nextSendActionTransition.textSnapshotView, transition: originalTransition)
|
||||
itemView.isHidden = false
|
||||
}
|
||||
}
|
||||
}
|
||||
self.scrollView.addSubview(itemView)
|
||||
}
|
||||
entry.itemTransition.setFrame(view: itemView, frame: itemFrame)
|
||||
}
|
||||
y += entry.size.height
|
||||
if index != measured.count - 1 { y += self.itemSpacing }
|
||||
}
|
||||
|
||||
let finalContentHeight = max(availableSize.height, contentHeight)
|
||||
self.scrollView.contentSize = CGSize(width: availableSize.width, height: finalContentHeight)
|
||||
|
||||
let delta = self.scrollView.contentSize.height - previousContentHeight
|
||||
if !wasAtBottom && abs(delta) > .ulpOfOne {
|
||||
self.scrollView.contentOffset.y += delta
|
||||
} else if wasAtBottom {
|
||||
self.scrollToBottom(animated: false)
|
||||
}
|
||||
|
||||
if self.itemViews.count > validKeys.count {
|
||||
let toRemove = self.itemViews.keys.filter { !validKeys.contains($0) }
|
||||
for key in toRemove {
|
||||
if let itemView = self.itemViews[key]?.view {
|
||||
if transition.animation.isImmediate {
|
||||
itemView.removeFromSuperview()
|
||||
} else {
|
||||
transition.setAlpha(view: itemView, alpha: 0.0, completion: { _ in
|
||||
itemView.removeFromSuperview()
|
||||
})
|
||||
transition.setScale(view: itemView, scale: 0.01)
|
||||
}
|
||||
}
|
||||
self.itemViews.removeValue(forKey: key)
|
||||
}
|
||||
}
|
||||
|
||||
if wasAtBottom {
|
||||
self.scrollToBottom(animated: false)
|
||||
}
|
||||
|
||||
return availableSize
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func makeView() -> View {
|
||||
return View()
|
||||
}
|
||||
|
||||
func update(view: View, availableSize: CGSize, state: EmptyComponentState, environment: Environment<EnvironmentType>, transition: ComponentTransition) -> CGSize {
|
||||
return view.update(component: self, availableSize: availableSize, state: state, environment: environment, transition: transition)
|
||||
}
|
||||
}
|
||||
|
|
@ -929,6 +929,7 @@ public final class PresentationGroupCallImpl: PresentationGroupCall {
|
|||
reference: .id(id: initialCall.description.id, accessHash: initialCall.description.accessHash),
|
||||
e2eContext: self.e2eContext
|
||||
)
|
||||
self.messagesStatePromise.set(self.messagesContext!.state)
|
||||
}
|
||||
|
||||
var sharedAudioContext = sharedAudioContext
|
||||
|
|
@ -2639,6 +2640,7 @@ public final class PresentationGroupCallImpl: PresentationGroupCall {
|
|||
}
|
||||
}))
|
||||
|
||||
self.isFailedEventDisposable?.dispose()
|
||||
self.isFailedEventDisposable = (participantsContext.isFailedEvent
|
||||
|> filter { $0 }
|
||||
|> take(1)
|
||||
|
|
@ -2983,7 +2985,7 @@ public final class PresentationGroupCallImpl: PresentationGroupCall {
|
|||
self.messagesContext?.send(text: "test\(UInt32.random(in: 0 ... UInt32.max))", entities: [])
|
||||
return
|
||||
}*/
|
||||
|
||||
|
||||
if self.isMutedValue == action {
|
||||
return
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import MultilineTextComponent
|
|||
import TelegramPresentationData
|
||||
import AppBundle
|
||||
import TelegramAudio
|
||||
import GlassBackgroundComponent
|
||||
|
||||
final class VideoChatActionButtonComponent: Component {
|
||||
enum Content: Equatable {
|
||||
|
|
@ -34,12 +35,14 @@ final class VideoChatActionButtonComponent: Component {
|
|||
case audio(audio: Audio)
|
||||
case video
|
||||
case rotateCamera
|
||||
case message
|
||||
case leave
|
||||
}
|
||||
|
||||
case audio(audio: Audio, isEnabled: Bool)
|
||||
case video(isActive: Bool)
|
||||
case rotateCamera
|
||||
case message
|
||||
case leave
|
||||
|
||||
fileprivate var iconType: IconType {
|
||||
|
|
@ -59,6 +62,8 @@ final class VideoChatActionButtonComponent: Component {
|
|||
return .video
|
||||
case .rotateCamera:
|
||||
return .rotateCamera
|
||||
case .message:
|
||||
return .message
|
||||
case .leave:
|
||||
return .leave
|
||||
}
|
||||
|
|
@ -108,7 +113,7 @@ final class VideoChatActionButtonComponent: Component {
|
|||
|
||||
final class View: HighlightTrackingButton {
|
||||
private let icon = ComponentView<Empty>()
|
||||
private let background: UIImageView
|
||||
private let background: GlassBackgroundView
|
||||
private let title = ComponentView<Empty>()
|
||||
|
||||
private var component: VideoChatActionButtonComponent?
|
||||
|
|
@ -117,7 +122,7 @@ final class VideoChatActionButtonComponent: Component {
|
|||
private var contentImage: UIImage?
|
||||
|
||||
override init(frame: CGRect) {
|
||||
self.background = UIImageView()
|
||||
self.background = GlassBackgroundView()
|
||||
|
||||
super.init(frame: frame)
|
||||
}
|
||||
|
|
@ -137,6 +142,8 @@ final class VideoChatActionButtonComponent: Component {
|
|||
|
||||
let alphaTransition: ComponentTransition = transition.animation.isImmediate ? .immediate : .easeInOut(duration: 0.2)
|
||||
|
||||
let genericBackgroundColor = UIColor(rgb: 0x1b1d22)
|
||||
|
||||
let titleText: String
|
||||
let backgroundColor: UIColor
|
||||
let iconDiameter: CGFloat
|
||||
|
|
@ -158,11 +165,11 @@ final class VideoChatActionButtonComponent: Component {
|
|||
}
|
||||
switch component.microphoneState {
|
||||
case .connecting:
|
||||
backgroundColor = UIColor(white: 0.1, alpha: 1.0)
|
||||
backgroundColor = genericBackgroundColor
|
||||
case .muted:
|
||||
backgroundColor = !isActive ? UIColor(rgb: 0x002E5D) : UIColor(rgb: 0x027FFF)
|
||||
backgroundColor = !isActive ? genericBackgroundColor : UIColor(rgb: 0x027FFF)
|
||||
case .unmuted:
|
||||
backgroundColor = !isActive ? UIColor(rgb: 0x124B21) : UIColor(rgb: 0x34C659)
|
||||
backgroundColor = !isActive ? genericBackgroundColor : UIColor(rgb: 0x34C659)
|
||||
case .raiseHand, .scheduled:
|
||||
backgroundColor = !isActive ? UIColor(rgb: 0x23306B) : UIColor(rgb: 0x3252EF)
|
||||
}
|
||||
|
|
@ -171,20 +178,20 @@ final class VideoChatActionButtonComponent: Component {
|
|||
titleText = component.strings.VoiceChat_Video
|
||||
switch component.microphoneState {
|
||||
case .connecting:
|
||||
backgroundColor = UIColor(white: 0.1, alpha: 1.0)
|
||||
backgroundColor = genericBackgroundColor
|
||||
case .muted:
|
||||
backgroundColor = !isActive ? UIColor(rgb: 0x002E5D) : UIColor(rgb: 0x027FFF)
|
||||
backgroundColor = !isActive ? genericBackgroundColor : UIColor(rgb: 0x027FFF)
|
||||
case .unmuted:
|
||||
backgroundColor = !isActive ? UIColor(rgb: 0x124B21) : UIColor(rgb: 0x34C659)
|
||||
backgroundColor = !isActive ? genericBackgroundColor : UIColor(rgb: 0x34C659)
|
||||
case .raiseHand, .scheduled:
|
||||
backgroundColor = UIColor(rgb: 0x3252EF)
|
||||
}
|
||||
iconDiameter = 60.0
|
||||
iconDiameter = 58.0
|
||||
case .rotateCamera:
|
||||
titleText = ""
|
||||
switch component.microphoneState {
|
||||
case .connecting:
|
||||
backgroundColor = UIColor(white: 0.1, alpha: 1.0)
|
||||
backgroundColor = genericBackgroundColor
|
||||
case .muted:
|
||||
backgroundColor = UIColor(rgb: 0x027FFF)
|
||||
case .unmuted:
|
||||
|
|
@ -193,9 +200,14 @@ final class VideoChatActionButtonComponent: Component {
|
|||
backgroundColor = UIColor(rgb: 0x3252EF)
|
||||
}
|
||||
iconDiameter = 60.0
|
||||
case .message:
|
||||
//TODO:localize
|
||||
titleText = "message"
|
||||
backgroundColor = genericBackgroundColor
|
||||
iconDiameter = 56.0
|
||||
case .leave:
|
||||
titleText = component.strings.VoiceChat_Leave
|
||||
backgroundColor = UIColor(rgb: 0x47191E)
|
||||
backgroundColor = UIColor(rgb: 0x330d0b)
|
||||
iconDiameter = 22.0
|
||||
}
|
||||
|
||||
|
|
@ -225,6 +237,8 @@ final class VideoChatActionButtonComponent: Component {
|
|||
self.contentImage = UIImage(bundleImageName: "Call/CallCameraButton")?.precomposed().withRenderingMode(.alwaysTemplate)
|
||||
case .rotateCamera:
|
||||
self.contentImage = UIImage(bundleImageName: "Call/CallSwitchCameraButton")?.precomposed().withRenderingMode(.alwaysTemplate)
|
||||
case .message:
|
||||
self.contentImage = UIImage(bundleImageName: "Call/CallMessageButton")?.precomposed().withRenderingMode(.alwaysTemplate)
|
||||
case .leave:
|
||||
self.contentImage = generateImage(CGSize(width: 28.0, height: 28.0), opaque: false, rotatedContext: { size, context in
|
||||
let bounds = CGRect(origin: CGPoint(), size: size)
|
||||
|
|
@ -256,20 +270,20 @@ final class VideoChatActionButtonComponent: Component {
|
|||
|
||||
let size = CGSize(width: availableSize.width, height: availableSize.height)
|
||||
|
||||
if self.background.superview == nil {
|
||||
self.addSubview(self.background)
|
||||
self.background.image = generateStretchableFilledCircleImage(diameter: 56.0, color: .white)?.withRenderingMode(.alwaysTemplate)
|
||||
self.background.tintColor = backgroundColor
|
||||
}
|
||||
transition.setFrame(view: self.background, frame: CGRect(origin: CGPoint(), size: size))
|
||||
|
||||
let tintTransition: ComponentTransition
|
||||
if !transition.animation.isImmediate {
|
||||
tintTransition = .easeInOut(duration: 0.2)
|
||||
} else {
|
||||
if self.background.superview == nil {
|
||||
tintTransition = .immediate
|
||||
self.insertSubview(self.background, at: 0)
|
||||
} else {
|
||||
if !transition.animation.isImmediate {
|
||||
tintTransition = .easeInOut(duration: 0.2)
|
||||
} else {
|
||||
tintTransition = .immediate
|
||||
}
|
||||
}
|
||||
tintTransition.setTintColor(layer: self.background.layer, color: backgroundColor)
|
||||
|
||||
self.background.update(size: size, cornerRadius: size.width * 0.5, isDark: true, tintColor: .init(kind: .custom, color: backgroundColor), transition: tintTransition)
|
||||
transition.setFrame(view: self.background, frame: CGRect(origin: CGPoint(), size: size))
|
||||
|
||||
let titleFrame = CGRect(origin: CGPoint(x: floor((size.width - titleSize.width) * 0.5), y: size.height + 8.0), size: titleSize)
|
||||
if let titleView = self.title.view {
|
||||
|
|
|
|||
|
|
@ -1463,7 +1463,7 @@ final class VideoChatParticipantsComponent: Component {
|
|||
transition.setFrame(layer: self.listItemViewSeparatorContainer, frame: CGRect(origin: CGPoint(), size: itemLayout.listItemContainerFrame().size))
|
||||
|
||||
if self.expandedGridItemContainer.frame != expandedGridItemContainerFrame {
|
||||
self.expandedGridItemContainer.layer.cornerRadius = 10.0
|
||||
self.expandedGridItemContainer.layer.cornerRadius = 16.0
|
||||
|
||||
transition.setFrame(view: self.expandedGridItemContainer, frame: expandedGridItemContainerFrame, completion: { [weak self] completed in
|
||||
guard let self, completed else {
|
||||
|
|
@ -1934,7 +1934,7 @@ final class VideoChatParticipantsComponent: Component {
|
|||
transition: transition,
|
||||
component: AnyComponent(RoundedRectangle(
|
||||
color: UIColor(white: 0.1, alpha: 1.0),
|
||||
cornerRadius: 10.0
|
||||
cornerRadius: 16.0
|
||||
)),
|
||||
environment: {},
|
||||
containerSize: CGSize(width: itemLayout.listFrame.width - itemLayout.layout.mainColumn.insets.left - itemLayout.layout.mainColumn.insets.right, height: itemLayout.list.contentHeight())
|
||||
|
|
@ -2018,7 +2018,7 @@ final class VideoChatParticipantsComponent: Component {
|
|||
self.scrollViewClippingContainer.update(params: SolidRoundedCornersContainer.Params(
|
||||
size: itemLayout.scrollClippingFrame.size,
|
||||
color: .black,
|
||||
cornerRadius: 10.0,
|
||||
cornerRadius: 16.0,
|
||||
smoothCorners: false
|
||||
), transition: transition)
|
||||
|
||||
|
|
@ -2059,7 +2059,7 @@ final class VideoChatParticipantsComponent: Component {
|
|||
self.separateVideoScrollViewClippingContainer.update(params: SolidRoundedCornersContainer.Params(
|
||||
size: itemLayout.separateVideoScrollClippingFrame.size,
|
||||
color: .black,
|
||||
cornerRadius: 10.0,
|
||||
cornerRadius: 16.0,
|
||||
smoothCorners: false
|
||||
), transition: transition)
|
||||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -201,7 +201,7 @@ final class VideoChatTitleComponent: Component {
|
|||
|
||||
self.tapRecognizer?.isEnabled = component.longTapAction != nil || component.tapAction != nil
|
||||
|
||||
let spacing: CGFloat = 1.0
|
||||
let spacing: CGFloat = 0.0
|
||||
|
||||
var maxTitleWidth = availableSize.width
|
||||
if component.isRecording {
|
||||
|
|
@ -219,7 +219,7 @@ final class VideoChatTitleComponent: Component {
|
|||
|
||||
let statusComponent: AnyComponent<Empty>
|
||||
statusComponent = AnyComponent(AnimatedTextComponent(
|
||||
font: Font.regular(13.0),
|
||||
font: Font.regular(12.0),
|
||||
color: UIColor(white: 1.0, alpha: 0.5),
|
||||
items: component.status
|
||||
))
|
||||
|
|
|
|||
|
|
@ -175,8 +175,15 @@ func parseTelegramGroupOrChannel(chat: Api.Chat) -> Peer? {
|
|||
case let .peerColor(_, color, backgroundEmojiIdValue):
|
||||
nameColorIndex = color
|
||||
backgroundEmojiId = backgroundEmojiIdValue
|
||||
case .peerColorCollectible, .inputPeerColorCollectible:
|
||||
//TODO:release
|
||||
case let .peerColorCollectible(_, collectibleId, giftEmojiId, backgroundEmojiId, accentColor, colors, darkAccentColor, darkColors):
|
||||
let _ = collectibleId
|
||||
let _ = giftEmojiId
|
||||
let _ = backgroundEmojiId
|
||||
let _ = accentColor
|
||||
let _ = colors
|
||||
let _ = darkAccentColor
|
||||
let _ = darkColors
|
||||
case .inputPeerColorCollectible:
|
||||
break
|
||||
}
|
||||
}
|
||||
|
|
@ -188,8 +195,7 @@ func parseTelegramGroupOrChannel(chat: Api.Chat) -> Peer? {
|
|||
case let .peerColor(_, color, backgroundEmojiIdValue):
|
||||
profileColorIndex = color
|
||||
profileBackgroundEmojiId = backgroundEmojiIdValue
|
||||
case .peerColorCollectible, .inputPeerColorCollectible:
|
||||
//TODO:release
|
||||
default:
|
||||
break
|
||||
}
|
||||
}
|
||||
|
|
@ -260,8 +266,15 @@ func mergeGroupOrChannel(lhs: Peer?, rhs: Api.Chat) -> Peer? {
|
|||
case let .peerColor(_, color, backgroundEmojiIdValue):
|
||||
nameColorIndex = color
|
||||
backgroundEmojiId = backgroundEmojiIdValue
|
||||
case .peerColorCollectible, .inputPeerColorCollectible:
|
||||
//TODO:release
|
||||
case let .peerColorCollectible(_, collectibleId, giftEmojiId, backgroundEmojiId, accentColor, colors, darkAccentColor, darkColors):
|
||||
let _ = collectibleId
|
||||
let _ = giftEmojiId
|
||||
let _ = backgroundEmojiId
|
||||
let _ = accentColor
|
||||
let _ = colors
|
||||
let _ = darkAccentColor
|
||||
let _ = darkColors
|
||||
case .inputPeerColorCollectible:
|
||||
break
|
||||
}
|
||||
}
|
||||
|
|
@ -273,8 +286,7 @@ func mergeGroupOrChannel(lhs: Peer?, rhs: Api.Chat) -> Peer? {
|
|||
case let .peerColor(_, color, backgroundEmojiIdValue):
|
||||
profileColorIndex = color
|
||||
profileBackgroundEmojiId = backgroundEmojiIdValue
|
||||
case .peerColorCollectible, .inputPeerColorCollectible:
|
||||
//TODO:release
|
||||
default:
|
||||
break
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -232,7 +232,7 @@ func apiMessagePeerIds(_ message: Api.Message) -> [PeerId] {
|
|||
}
|
||||
|
||||
switch action {
|
||||
case .messageActionChannelCreate, .messageActionChatDeletePhoto, .messageActionChatEditPhoto, .messageActionChatEditTitle, .messageActionEmpty, .messageActionPinMessage, .messageActionHistoryClear, .messageActionGameScore, .messageActionPaymentSent, .messageActionPaymentSentMe, .messageActionPhoneCall, .messageActionScreenshotTaken, .messageActionCustomAction, .messageActionBotAllowed, .messageActionSecureValuesSent, .messageActionSecureValuesSentMe, .messageActionContactSignUp, .messageActionGroupCall, .messageActionSetMessagesTTL, .messageActionGroupCallScheduled, .messageActionSetChatTheme, .messageActionChatJoinedByRequest, .messageActionWebViewDataSent, .messageActionWebViewDataSentMe, .messageActionGiftPremium, .messageActionGiftStars, .messageActionTopicCreate, .messageActionTopicEdit, .messageActionSuggestProfilePhoto, .messageActionSetChatWallPaper, .messageActionGiveawayLaunch, .messageActionGiveawayResults, .messageActionBoostApply, .messageActionRequestedPeerSentMe, .messageActionStarGift, .messageActionStarGiftUnique, .messageActionPaidMessagesRefunded, .messageActionPaidMessagesPrice, .messageActionTodoCompletions, .messageActionTodoAppendTasks, .messageActionSuggestedPostApproval, .messageActionGiftTon, .messageActionSuggestedPostSuccess, .messageActionSuggestedPostRefund:
|
||||
case .messageActionChannelCreate, .messageActionChatDeletePhoto, .messageActionChatEditPhoto, .messageActionChatEditTitle, .messageActionEmpty, .messageActionPinMessage, .messageActionHistoryClear, .messageActionGameScore, .messageActionPaymentSent, .messageActionPaymentSentMe, .messageActionPhoneCall, .messageActionScreenshotTaken, .messageActionCustomAction, .messageActionBotAllowed, .messageActionSecureValuesSent, .messageActionSecureValuesSentMe, .messageActionContactSignUp, .messageActionGroupCall, .messageActionSetMessagesTTL, .messageActionGroupCallScheduled, .messageActionSetChatTheme, .messageActionChatJoinedByRequest, .messageActionWebViewDataSent, .messageActionWebViewDataSentMe, .messageActionGiftPremium, .messageActionGiftStars, .messageActionTopicCreate, .messageActionTopicEdit, .messageActionSuggestProfilePhoto, .messageActionSetChatWallPaper, .messageActionGiveawayLaunch, .messageActionGiveawayResults, .messageActionBoostApply, .messageActionRequestedPeerSentMe, .messageActionStarGift, .messageActionStarGiftUnique, .messageActionPaidMessagesRefunded, .messageActionPaidMessagesPrice, .messageActionTodoCompletions, .messageActionTodoAppendTasks, .messageActionSuggestedPostApproval, .messageActionGiftTon, .messageActionSuggestedPostSuccess, .messageActionSuggestedPostRefund, .messageActionSuggestBirthday:
|
||||
break
|
||||
case let .messageActionChannelMigrateFrom(_, chatId):
|
||||
result.append(PeerId(namespace: Namespaces.Peer.CloudGroup, id: PeerId.Id._internalFromInt64Value(chatId)))
|
||||
|
|
|
|||
|
|
@ -272,6 +272,8 @@ func telegramMediaActionFromApiAction(_ action: Api.MessageAction) -> TelegramMe
|
|||
return TelegramMediaAction(action: .suggestedPostSuccess(amount: CurrencyAmount(apiAmount: price)))
|
||||
case let .messageActionSuggestedPostRefund(flags):
|
||||
return TelegramMediaAction(action: .suggestedPostRefund(TelegramMediaActionType.SuggestedPostRefund(isUserInitiated: (flags & (1 << 0)) != 0)))
|
||||
case let .messageActionSuggestBirthday(birthday):
|
||||
return TelegramMediaAction(action: .suggestedBirthday(TelegramBirthday(apiBirthday: birthday)))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -133,8 +133,15 @@ extension TelegramUser {
|
|||
case let .peerColor(_, color, backgroundEmojiIdValue):
|
||||
nameColorIndex = color
|
||||
backgroundEmojiId = backgroundEmojiIdValue
|
||||
case .peerColorCollectible, .inputPeerColorCollectible:
|
||||
//TODO:release
|
||||
case let .peerColorCollectible(_, collectibleId, giftEmojiId, backgroundEmojiId, accentColor, colors, darkAccentColor, darkColors):
|
||||
let _ = collectibleId
|
||||
let _ = giftEmojiId
|
||||
let _ = backgroundEmojiId
|
||||
let _ = accentColor
|
||||
let _ = colors
|
||||
let _ = darkAccentColor
|
||||
let _ = darkColors
|
||||
case .inputPeerColorCollectible:
|
||||
break
|
||||
}
|
||||
}
|
||||
|
|
@ -146,8 +153,7 @@ extension TelegramUser {
|
|||
case let .peerColor(_, color, backgroundEmojiIdValue):
|
||||
profileColorIndex = color
|
||||
profileBackgroundEmojiId = backgroundEmojiIdValue
|
||||
case .peerColorCollectible, .inputPeerColorCollectible:
|
||||
//TODO:release
|
||||
default:
|
||||
break
|
||||
}
|
||||
}
|
||||
|
|
@ -248,8 +254,15 @@ extension TelegramUser {
|
|||
case let .peerColor(_, color, backgroundEmojiIdValue):
|
||||
nameColorIndex = color
|
||||
backgroundEmojiId = backgroundEmojiIdValue
|
||||
case .peerColorCollectible, .inputPeerColorCollectible:
|
||||
//TODO:release
|
||||
case let .peerColorCollectible(_, collectibleId, giftEmojiId, backgroundEmojiId, accentColor, colors, darkAccentColor, darkColors):
|
||||
let _ = collectibleId
|
||||
let _ = giftEmojiId
|
||||
let _ = backgroundEmojiId
|
||||
let _ = accentColor
|
||||
let _ = colors
|
||||
let _ = darkAccentColor
|
||||
let _ = darkColors
|
||||
case .inputPeerColorCollectible:
|
||||
break
|
||||
}
|
||||
}
|
||||
|
|
@ -261,8 +274,7 @@ extension TelegramUser {
|
|||
case let .peerColor(_, color, backgroundEmojiIdValue):
|
||||
profileColorIndex = color
|
||||
profileBackgroundEmojiId = backgroundEmojiIdValue
|
||||
case .peerColorCollectible, .inputPeerColorCollectible:
|
||||
//TODO:release
|
||||
default:
|
||||
break
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1539,7 +1539,7 @@ public final class AccountViewTracker {
|
|||
let peerId = slice[i].0
|
||||
let value = result[i]
|
||||
transaction.updatePeerCachedData(peerIds: Set([peerId]), update: { _, cachedData in
|
||||
var cachedData = cachedData as? CachedUserData ?? CachedUserData(about: nil, botInfo: nil, editableBotInfo: nil, peerStatusSettings: nil, pinnedMessageId: nil, isBlocked: false, commonGroupCount: 0, voiceCallsAvailable: true, videoCallsAvailable: true, callsPrivate: true, canPinMessages: true, hasScheduledMessages: true, autoremoveTimeout: .unknown, chatTheme: nil, photo: .unknown, personalPhoto: .unknown, fallbackPhoto: .unknown, voiceMessagesAvailable: true, wallpaper: nil, flags: [], businessHours: nil, businessLocation: nil, greetingMessage: nil, awayMessage: nil, connectedBot: nil, businessIntro: .unknown, birthday: nil, personalChannel: .unknown, botPreview: nil, starGiftsCount: nil, starRefProgram: nil, verification: nil, sendPaidMessageStars: nil, disallowedGifts: [], botGroupAdminRights: nil, botChannelAdminRights: nil, starRating: nil, pendingStarRating: nil, mainProfileTab: nil, savedMusic: nil)
|
||||
var cachedData = cachedData as? CachedUserData ?? CachedUserData(about: nil, botInfo: nil, editableBotInfo: nil, peerStatusSettings: nil, pinnedMessageId: nil, isBlocked: false, commonGroupCount: 0, voiceCallsAvailable: true, videoCallsAvailable: true, callsPrivate: true, canPinMessages: true, hasScheduledMessages: true, autoremoveTimeout: .unknown, chatTheme: nil, photo: .unknown, personalPhoto: .unknown, fallbackPhoto: .unknown, voiceMessagesAvailable: true, wallpaper: nil, flags: [], businessHours: nil, businessLocation: nil, greetingMessage: nil, awayMessage: nil, connectedBot: nil, businessIntro: .unknown, birthday: nil, personalChannel: .unknown, botPreview: nil, starGiftsCount: nil, starRefProgram: nil, verification: nil, sendPaidMessageStars: nil, disallowedGifts: [], botGroupAdminRights: nil, botChannelAdminRights: nil, starRating: nil, pendingStarRating: nil, mainProfileTab: nil, savedMusic: nil, note: nil)
|
||||
var flags = cachedData.flags
|
||||
var sendPaidMessageStars = cachedData.sendPaidMessageStars
|
||||
switch value {
|
||||
|
|
|
|||
|
|
@ -1086,6 +1086,48 @@ public final class CachedUserData: CachedPeerData {
|
|||
}
|
||||
}
|
||||
|
||||
public final class Note: Codable, Equatable {
|
||||
private enum CodingKeys: String, CodingKey {
|
||||
case text
|
||||
case entities
|
||||
}
|
||||
|
||||
public let text: String
|
||||
public let entities: [MessageTextEntity]
|
||||
|
||||
public init(text: String, entities: [MessageTextEntity]) {
|
||||
self.text = text
|
||||
self.entities = entities
|
||||
}
|
||||
|
||||
public init(from decoder: any Decoder) throws {
|
||||
let container = try decoder.container(keyedBy: CodingKeys.self)
|
||||
|
||||
self.text = try container.decode(String.self, forKey: .text)
|
||||
self.entities = try container.decode([MessageTextEntity].self, forKey: .entities)
|
||||
}
|
||||
|
||||
public func encode(to encoder: any Encoder) throws {
|
||||
var container = encoder.container(keyedBy: CodingKeys.self)
|
||||
|
||||
try container.encode(self.text, forKey: .text)
|
||||
try container.encode(self.entities, forKey: .entities)
|
||||
}
|
||||
|
||||
public static func ==(lhs: Note, rhs: Note) -> Bool {
|
||||
if lhs === rhs {
|
||||
return true
|
||||
}
|
||||
if lhs.text != rhs.text {
|
||||
return false
|
||||
}
|
||||
if lhs.entities != rhs.entities {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
public let about: String?
|
||||
public let botInfo: BotInfo?
|
||||
public let editableBotInfo: EditableBotInfo?
|
||||
|
|
@ -1126,6 +1168,7 @@ public final class CachedUserData: CachedPeerData {
|
|||
public let pendingStarRating: TelegramStarPendingRating?
|
||||
public let mainProfileTab: TelegramProfileTab?
|
||||
public let savedMusic: TelegramMediaFile?
|
||||
public let note: Note?
|
||||
|
||||
public let peerIds: Set<PeerId>
|
||||
public let messageIds: Set<MessageId>
|
||||
|
|
@ -1174,9 +1217,10 @@ public final class CachedUserData: CachedPeerData {
|
|||
self.pendingStarRating = nil
|
||||
self.mainProfileTab = nil
|
||||
self.savedMusic = nil
|
||||
self.note = nil
|
||||
}
|
||||
|
||||
public init(about: String?, botInfo: BotInfo?, editableBotInfo: EditableBotInfo?, peerStatusSettings: PeerStatusSettings?, pinnedMessageId: MessageId?, isBlocked: Bool, commonGroupCount: Int32, voiceCallsAvailable: Bool, videoCallsAvailable: Bool, callsPrivate: Bool, canPinMessages: Bool, hasScheduledMessages: Bool, autoremoveTimeout: CachedPeerAutoremoveTimeout, chatTheme: ChatTheme?, photo: CachedPeerProfilePhoto, personalPhoto: CachedPeerProfilePhoto, fallbackPhoto: CachedPeerProfilePhoto, voiceMessagesAvailable: Bool, wallpaper: TelegramWallpaper?, flags: CachedUserFlags, businessHours: TelegramBusinessHours?, businessLocation: TelegramBusinessLocation?, greetingMessage: TelegramBusinessGreetingMessage?, awayMessage: TelegramBusinessAwayMessage?, connectedBot: TelegramAccountConnectedBot?, businessIntro: CachedTelegramBusinessIntro, birthday: TelegramBirthday?, personalChannel: CachedTelegramPersonalChannel, botPreview: BotPreview?, starGiftsCount: Int32?, starRefProgram: TelegramStarRefProgram?, verification: PeerVerification?, sendPaidMessageStars: StarsAmount?, disallowedGifts: TelegramDisallowedGifts?, botGroupAdminRights: TelegramChatAdminRights?, botChannelAdminRights: TelegramChatAdminRights?, starRating: TelegramStarRating?, pendingStarRating: TelegramStarPendingRating?, mainProfileTab: TelegramProfileTab?, savedMusic: TelegramMediaFile?) {
|
||||
public init(about: String?, botInfo: BotInfo?, editableBotInfo: EditableBotInfo?, peerStatusSettings: PeerStatusSettings?, pinnedMessageId: MessageId?, isBlocked: Bool, commonGroupCount: Int32, voiceCallsAvailable: Bool, videoCallsAvailable: Bool, callsPrivate: Bool, canPinMessages: Bool, hasScheduledMessages: Bool, autoremoveTimeout: CachedPeerAutoremoveTimeout, chatTheme: ChatTheme?, photo: CachedPeerProfilePhoto, personalPhoto: CachedPeerProfilePhoto, fallbackPhoto: CachedPeerProfilePhoto, voiceMessagesAvailable: Bool, wallpaper: TelegramWallpaper?, flags: CachedUserFlags, businessHours: TelegramBusinessHours?, businessLocation: TelegramBusinessLocation?, greetingMessage: TelegramBusinessGreetingMessage?, awayMessage: TelegramBusinessAwayMessage?, connectedBot: TelegramAccountConnectedBot?, businessIntro: CachedTelegramBusinessIntro, birthday: TelegramBirthday?, personalChannel: CachedTelegramPersonalChannel, botPreview: BotPreview?, starGiftsCount: Int32?, starRefProgram: TelegramStarRefProgram?, verification: PeerVerification?, sendPaidMessageStars: StarsAmount?, disallowedGifts: TelegramDisallowedGifts?, botGroupAdminRights: TelegramChatAdminRights?, botChannelAdminRights: TelegramChatAdminRights?, starRating: TelegramStarRating?, pendingStarRating: TelegramStarPendingRating?, mainProfileTab: TelegramProfileTab?, savedMusic: TelegramMediaFile?, note: Note?) {
|
||||
self.about = about
|
||||
self.botInfo = botInfo
|
||||
self.editableBotInfo = editableBotInfo
|
||||
|
|
@ -1217,6 +1261,7 @@ public final class CachedUserData: CachedPeerData {
|
|||
self.pendingStarRating = pendingStarRating
|
||||
self.mainProfileTab = mainProfileTab
|
||||
self.savedMusic = savedMusic
|
||||
self.note = note
|
||||
|
||||
self.peerIds = Set<PeerId>()
|
||||
|
||||
|
|
@ -1306,12 +1351,14 @@ public final class CachedUserData: CachedPeerData {
|
|||
self.pendingStarRating = decoder.decodeCodable(TelegramStarPendingRating.self, forKey: "pendingStarRating")
|
||||
|
||||
self.mainProfileTab = decoder.decodeCodable(TelegramProfileTab.self, forKey: "mainProfileTab")
|
||||
|
||||
|
||||
if let savedMusic = decoder.decodeObjectForKey("savedMusic", decoder: { TelegramMediaFile(decoder: $0) }) as? TelegramMediaFile {
|
||||
self.savedMusic = savedMusic
|
||||
} else {
|
||||
self.savedMusic = nil
|
||||
}
|
||||
|
||||
self.note = decoder.decodeCodable(Note.self, forKey: "note")
|
||||
}
|
||||
|
||||
public func encode(_ encoder: PostboxEncoder) {
|
||||
|
|
@ -1477,6 +1524,18 @@ public final class CachedUserData: CachedPeerData {
|
|||
} else {
|
||||
encoder.encodeNil(forKey: "mainProfileTab")
|
||||
}
|
||||
|
||||
if let savedMusic = self.savedMusic {
|
||||
encoder.encodeObject(savedMusic, forKey: "savedMusic")
|
||||
} else {
|
||||
encoder.encodeNil(forKey: "savedMusic")
|
||||
}
|
||||
|
||||
if let note = self.note {
|
||||
encoder.encodeCodable(note, forKey: "note")
|
||||
} else {
|
||||
encoder.encodeNil(forKey: "note")
|
||||
}
|
||||
}
|
||||
|
||||
public func isEqual(to: CachedPeerData) -> Bool {
|
||||
|
|
@ -1550,168 +1609,175 @@ public final class CachedUserData: CachedPeerData {
|
|||
if other.savedMusic != self.savedMusic {
|
||||
return false
|
||||
}
|
||||
if other.note != self.note {
|
||||
return false
|
||||
}
|
||||
|
||||
return other.about == self.about && other.botInfo == self.botInfo && other.editableBotInfo == self.editableBotInfo && self.peerStatusSettings == other.peerStatusSettings && self.isBlocked == other.isBlocked && self.commonGroupCount == other.commonGroupCount && self.voiceCallsAvailable == other.voiceCallsAvailable && self.videoCallsAvailable == other.videoCallsAvailable && self.callsPrivate == other.callsPrivate && self.hasScheduledMessages == other.hasScheduledMessages && self.autoremoveTimeout == other.autoremoveTimeout && self.chatTheme == other.chatTheme && self.photo == other.photo && self.personalPhoto == other.personalPhoto && self.fallbackPhoto == other.fallbackPhoto && self.voiceMessagesAvailable == other.voiceMessagesAvailable && self.flags == other.flags && self.wallpaper == other.wallpaper
|
||||
}
|
||||
|
||||
public func withUpdatedAbout(_ about: String?) -> CachedUserData {
|
||||
return CachedUserData(about: about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, chatTheme: self.chatTheme, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: self.businessLocation, greetingMessage: self.greetingMessage, awayMessage: self.awayMessage, connectedBot: self.connectedBot, businessIntro: self.businessIntro, birthday: self.birthday, personalChannel: self.personalChannel, botPreview: self.botPreview, starGiftsCount: self.starGiftsCount, starRefProgram: self.starRefProgram, verification: self.verification, sendPaidMessageStars: self.sendPaidMessageStars, disallowedGifts: self.disallowedGifts, botGroupAdminRights: self.botGroupAdminRights, botChannelAdminRights: self.botChannelAdminRights, starRating: self.starRating, pendingStarRating: self.pendingStarRating, mainProfileTab: self.mainProfileTab, savedMusic: self.savedMusic)
|
||||
return CachedUserData(about: about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, chatTheme: self.chatTheme, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: self.businessLocation, greetingMessage: self.greetingMessage, awayMessage: self.awayMessage, connectedBot: self.connectedBot, businessIntro: self.businessIntro, birthday: self.birthday, personalChannel: self.personalChannel, botPreview: self.botPreview, starGiftsCount: self.starGiftsCount, starRefProgram: self.starRefProgram, verification: self.verification, sendPaidMessageStars: self.sendPaidMessageStars, disallowedGifts: self.disallowedGifts, botGroupAdminRights: self.botGroupAdminRights, botChannelAdminRights: self.botChannelAdminRights, starRating: self.starRating, pendingStarRating: self.pendingStarRating, mainProfileTab: self.mainProfileTab, savedMusic: self.savedMusic, note: self.note)
|
||||
}
|
||||
|
||||
public func withUpdatedBotInfo(_ botInfo: BotInfo?) -> CachedUserData {
|
||||
return CachedUserData(about: self.about, botInfo: botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, chatTheme: self.chatTheme, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: self.businessLocation, greetingMessage: self.greetingMessage, awayMessage: self.awayMessage, connectedBot: self.connectedBot, businessIntro: self.businessIntro, birthday: self.birthday, personalChannel: self.personalChannel, botPreview: self.botPreview, starGiftsCount: self.starGiftsCount, starRefProgram: self.starRefProgram, verification: self.verification, sendPaidMessageStars: self.sendPaidMessageStars, disallowedGifts: self.disallowedGifts, botGroupAdminRights: self.botGroupAdminRights, botChannelAdminRights: self.botChannelAdminRights, starRating: self.starRating, pendingStarRating: self.pendingStarRating, mainProfileTab: self.mainProfileTab, savedMusic: self.savedMusic)
|
||||
return CachedUserData(about: self.about, botInfo: botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, chatTheme: self.chatTheme, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: self.businessLocation, greetingMessage: self.greetingMessage, awayMessage: self.awayMessage, connectedBot: self.connectedBot, businessIntro: self.businessIntro, birthday: self.birthday, personalChannel: self.personalChannel, botPreview: self.botPreview, starGiftsCount: self.starGiftsCount, starRefProgram: self.starRefProgram, verification: self.verification, sendPaidMessageStars: self.sendPaidMessageStars, disallowedGifts: self.disallowedGifts, botGroupAdminRights: self.botGroupAdminRights, botChannelAdminRights: self.botChannelAdminRights, starRating: self.starRating, pendingStarRating: self.pendingStarRating, mainProfileTab: self.mainProfileTab, savedMusic: self.savedMusic, note: self.note)
|
||||
}
|
||||
|
||||
public func withUpdatedEditableBotInfo(_ editableBotInfo: EditableBotInfo?) -> CachedUserData {
|
||||
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, chatTheme: self.chatTheme, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: self.businessLocation, greetingMessage: self.greetingMessage, awayMessage: self.awayMessage, connectedBot: self.connectedBot, businessIntro: self.businessIntro, birthday: self.birthday, personalChannel: self.personalChannel, botPreview: self.botPreview, starGiftsCount: self.starGiftsCount, starRefProgram: self.starRefProgram, verification: self.verification, sendPaidMessageStars: self.sendPaidMessageStars, disallowedGifts: self.disallowedGifts, botGroupAdminRights: self.botGroupAdminRights, botChannelAdminRights: self.botChannelAdminRights, starRating: self.starRating, pendingStarRating: self.pendingStarRating, mainProfileTab: self.mainProfileTab, savedMusic: self.savedMusic)
|
||||
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, chatTheme: self.chatTheme, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: self.businessLocation, greetingMessage: self.greetingMessage, awayMessage: self.awayMessage, connectedBot: self.connectedBot, businessIntro: self.businessIntro, birthday: self.birthday, personalChannel: self.personalChannel, botPreview: self.botPreview, starGiftsCount: self.starGiftsCount, starRefProgram: self.starRefProgram, verification: self.verification, sendPaidMessageStars: self.sendPaidMessageStars, disallowedGifts: self.disallowedGifts, botGroupAdminRights: self.botGroupAdminRights, botChannelAdminRights: self.botChannelAdminRights, starRating: self.starRating, pendingStarRating: self.pendingStarRating, mainProfileTab: self.mainProfileTab, savedMusic: self.savedMusic, note: self.note)
|
||||
}
|
||||
|
||||
public func withUpdatedPeerStatusSettings(_ peerStatusSettings: PeerStatusSettings) -> CachedUserData {
|
||||
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, chatTheme: self.chatTheme, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: self.businessLocation, greetingMessage: self.greetingMessage, awayMessage: self.awayMessage, connectedBot: self.connectedBot, businessIntro: self.businessIntro, birthday: self.birthday, personalChannel: self.personalChannel, botPreview: self.botPreview, starGiftsCount: self.starGiftsCount, starRefProgram: self.starRefProgram, verification: self.verification, sendPaidMessageStars: self.sendPaidMessageStars, disallowedGifts: self.disallowedGifts, botGroupAdminRights: self.botGroupAdminRights, botChannelAdminRights: self.botChannelAdminRights, starRating: self.starRating, pendingStarRating: self.pendingStarRating, mainProfileTab: self.mainProfileTab, savedMusic: self.savedMusic)
|
||||
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, chatTheme: self.chatTheme, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: self.businessLocation, greetingMessage: self.greetingMessage, awayMessage: self.awayMessage, connectedBot: self.connectedBot, businessIntro: self.businessIntro, birthday: self.birthday, personalChannel: self.personalChannel, botPreview: self.botPreview, starGiftsCount: self.starGiftsCount, starRefProgram: self.starRefProgram, verification: self.verification, sendPaidMessageStars: self.sendPaidMessageStars, disallowedGifts: self.disallowedGifts, botGroupAdminRights: self.botGroupAdminRights, botChannelAdminRights: self.botChannelAdminRights, starRating: self.starRating, pendingStarRating: self.pendingStarRating, mainProfileTab: self.mainProfileTab, savedMusic: self.savedMusic, note: self.note)
|
||||
}
|
||||
|
||||
public func withUpdatedPinnedMessageId(_ pinnedMessageId: MessageId?) -> CachedUserData {
|
||||
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, chatTheme: self.chatTheme, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: self.businessLocation, greetingMessage: self.greetingMessage, awayMessage: self.awayMessage, connectedBot: self.connectedBot, businessIntro: self.businessIntro, birthday: self.birthday, personalChannel: self.personalChannel, botPreview: self.botPreview, starGiftsCount: self.starGiftsCount, starRefProgram: self.starRefProgram, verification: self.verification, sendPaidMessageStars: self.sendPaidMessageStars, disallowedGifts: self.disallowedGifts, botGroupAdminRights: self.botGroupAdminRights, botChannelAdminRights: self.botChannelAdminRights, starRating: self.starRating, pendingStarRating: self.pendingStarRating, mainProfileTab: self.mainProfileTab, savedMusic: self.savedMusic)
|
||||
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, chatTheme: self.chatTheme, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: self.businessLocation, greetingMessage: self.greetingMessage, awayMessage: self.awayMessage, connectedBot: self.connectedBot, businessIntro: self.businessIntro, birthday: self.birthday, personalChannel: self.personalChannel, botPreview: self.botPreview, starGiftsCount: self.starGiftsCount, starRefProgram: self.starRefProgram, verification: self.verification, sendPaidMessageStars: self.sendPaidMessageStars, disallowedGifts: self.disallowedGifts, botGroupAdminRights: self.botGroupAdminRights, botChannelAdminRights: self.botChannelAdminRights, starRating: self.starRating, pendingStarRating: self.pendingStarRating, mainProfileTab: self.mainProfileTab, savedMusic: self.savedMusic, note: self.note)
|
||||
}
|
||||
|
||||
public func withUpdatedIsBlocked(_ isBlocked: Bool) -> CachedUserData {
|
||||
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, chatTheme: self.chatTheme, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: self.businessLocation, greetingMessage: self.greetingMessage, awayMessage: self.awayMessage, connectedBot: self.connectedBot, businessIntro: self.businessIntro, birthday: self.birthday, personalChannel: self.personalChannel, botPreview: self.botPreview, starGiftsCount: self.starGiftsCount, starRefProgram: self.starRefProgram, verification: self.verification, sendPaidMessageStars: self.sendPaidMessageStars, disallowedGifts: self.disallowedGifts, botGroupAdminRights: self.botGroupAdminRights, botChannelAdminRights: self.botChannelAdminRights, starRating: self.starRating, pendingStarRating: self.pendingStarRating, mainProfileTab: self.mainProfileTab, savedMusic: self.savedMusic)
|
||||
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, chatTheme: self.chatTheme, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: self.businessLocation, greetingMessage: self.greetingMessage, awayMessage: self.awayMessage, connectedBot: self.connectedBot, businessIntro: self.businessIntro, birthday: self.birthday, personalChannel: self.personalChannel, botPreview: self.botPreview, starGiftsCount: self.starGiftsCount, starRefProgram: self.starRefProgram, verification: self.verification, sendPaidMessageStars: self.sendPaidMessageStars, disallowedGifts: self.disallowedGifts, botGroupAdminRights: self.botGroupAdminRights, botChannelAdminRights: self.botChannelAdminRights, starRating: self.starRating, pendingStarRating: self.pendingStarRating, mainProfileTab: self.mainProfileTab, savedMusic: self.savedMusic, note: self.note)
|
||||
}
|
||||
|
||||
public func withUpdatedCommonGroupCount(_ commonGroupCount: Int32) -> CachedUserData {
|
||||
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, chatTheme: self.chatTheme, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: self.businessLocation, greetingMessage: self.greetingMessage, awayMessage: self.awayMessage, connectedBot: self.connectedBot, businessIntro: self.businessIntro, birthday: self.birthday, personalChannel: self.personalChannel, botPreview: self.botPreview, starGiftsCount: self.starGiftsCount, starRefProgram: self.starRefProgram, verification: self.verification, sendPaidMessageStars: self.sendPaidMessageStars, disallowedGifts: self.disallowedGifts, botGroupAdminRights: self.botGroupAdminRights, botChannelAdminRights: self.botChannelAdminRights, starRating: self.starRating, pendingStarRating: self.pendingStarRating, mainProfileTab: self.mainProfileTab, savedMusic: self.savedMusic)
|
||||
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, chatTheme: self.chatTheme, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: self.businessLocation, greetingMessage: self.greetingMessage, awayMessage: self.awayMessage, connectedBot: self.connectedBot, businessIntro: self.businessIntro, birthday: self.birthday, personalChannel: self.personalChannel, botPreview: self.botPreview, starGiftsCount: self.starGiftsCount, starRefProgram: self.starRefProgram, verification: self.verification, sendPaidMessageStars: self.sendPaidMessageStars, disallowedGifts: self.disallowedGifts, botGroupAdminRights: self.botGroupAdminRights, botChannelAdminRights: self.botChannelAdminRights, starRating: self.starRating, pendingStarRating: self.pendingStarRating, mainProfileTab: self.mainProfileTab, savedMusic: self.savedMusic, note: self.note)
|
||||
}
|
||||
|
||||
public func withUpdatedVoiceCallsAvailable(_ voiceCallsAvailable: Bool) -> CachedUserData {
|
||||
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, chatTheme: self.chatTheme, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: self.businessLocation, greetingMessage: self.greetingMessage, awayMessage: self.awayMessage, connectedBot: self.connectedBot, businessIntro: self.businessIntro, birthday: self.birthday, personalChannel: self.personalChannel, botPreview: self.botPreview, starGiftsCount: self.starGiftsCount, starRefProgram: self.starRefProgram, verification: self.verification, sendPaidMessageStars: self.sendPaidMessageStars, disallowedGifts: self.disallowedGifts, botGroupAdminRights: self.botGroupAdminRights, botChannelAdminRights: self.botChannelAdminRights, starRating: self.starRating, pendingStarRating: self.pendingStarRating, mainProfileTab: self.mainProfileTab, savedMusic: self.savedMusic)
|
||||
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, chatTheme: self.chatTheme, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: self.businessLocation, greetingMessage: self.greetingMessage, awayMessage: self.awayMessage, connectedBot: self.connectedBot, businessIntro: self.businessIntro, birthday: self.birthday, personalChannel: self.personalChannel, botPreview: self.botPreview, starGiftsCount: self.starGiftsCount, starRefProgram: self.starRefProgram, verification: self.verification, sendPaidMessageStars: self.sendPaidMessageStars, disallowedGifts: self.disallowedGifts, botGroupAdminRights: self.botGroupAdminRights, botChannelAdminRights: self.botChannelAdminRights, starRating: self.starRating, pendingStarRating: self.pendingStarRating, mainProfileTab: self.mainProfileTab, savedMusic: self.savedMusic, note: self.note)
|
||||
}
|
||||
|
||||
public func withUpdatedVideoCallsAvailable(_ videoCallsAvailable: Bool) -> CachedUserData {
|
||||
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, chatTheme: self.chatTheme, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: self.businessLocation, greetingMessage: self.greetingMessage, awayMessage: self.awayMessage, connectedBot: self.connectedBot, businessIntro: self.businessIntro, birthday: self.birthday, personalChannel: self.personalChannel, botPreview: self.botPreview, starGiftsCount: self.starGiftsCount, starRefProgram: self.starRefProgram, verification: self.verification, sendPaidMessageStars: self.sendPaidMessageStars, disallowedGifts: self.disallowedGifts, botGroupAdminRights: self.botGroupAdminRights, botChannelAdminRights: self.botChannelAdminRights, starRating: self.starRating, pendingStarRating: self.pendingStarRating, mainProfileTab: self.mainProfileTab, savedMusic: self.savedMusic)
|
||||
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, chatTheme: self.chatTheme, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: self.businessLocation, greetingMessage: self.greetingMessage, awayMessage: self.awayMessage, connectedBot: self.connectedBot, businessIntro: self.businessIntro, birthday: self.birthday, personalChannel: self.personalChannel, botPreview: self.botPreview, starGiftsCount: self.starGiftsCount, starRefProgram: self.starRefProgram, verification: self.verification, sendPaidMessageStars: self.sendPaidMessageStars, disallowedGifts: self.disallowedGifts, botGroupAdminRights: self.botGroupAdminRights, botChannelAdminRights: self.botChannelAdminRights, starRating: self.starRating, pendingStarRating: self.pendingStarRating, mainProfileTab: self.mainProfileTab, savedMusic: self.savedMusic, note: self.note)
|
||||
}
|
||||
|
||||
public func withUpdatedCallsPrivate(_ callsPrivate: Bool) -> CachedUserData {
|
||||
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, chatTheme: self.chatTheme, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: self.businessLocation, greetingMessage: self.greetingMessage, awayMessage: self.awayMessage, connectedBot: self.connectedBot, businessIntro: self.businessIntro, birthday: self.birthday, personalChannel: self.personalChannel, botPreview: self.botPreview, starGiftsCount: self.starGiftsCount, starRefProgram: self.starRefProgram, verification: self.verification, sendPaidMessageStars: self.sendPaidMessageStars, disallowedGifts: self.disallowedGifts, botGroupAdminRights: self.botGroupAdminRights, botChannelAdminRights: self.botChannelAdminRights, starRating: self.starRating, pendingStarRating: self.pendingStarRating, mainProfileTab: self.mainProfileTab, savedMusic: self.savedMusic)
|
||||
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, chatTheme: self.chatTheme, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: self.businessLocation, greetingMessage: self.greetingMessage, awayMessage: self.awayMessage, connectedBot: self.connectedBot, businessIntro: self.businessIntro, birthday: self.birthday, personalChannel: self.personalChannel, botPreview: self.botPreview, starGiftsCount: self.starGiftsCount, starRefProgram: self.starRefProgram, verification: self.verification, sendPaidMessageStars: self.sendPaidMessageStars, disallowedGifts: self.disallowedGifts, botGroupAdminRights: self.botGroupAdminRights, botChannelAdminRights: self.botChannelAdminRights, starRating: self.starRating, pendingStarRating: self.pendingStarRating, mainProfileTab: self.mainProfileTab, savedMusic: self.savedMusic, note: self.note)
|
||||
}
|
||||
|
||||
public func withUpdatedCanPinMessages(_ canPinMessages: Bool) -> CachedUserData {
|
||||
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, chatTheme: self.chatTheme, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: self.businessLocation, greetingMessage: self.greetingMessage, awayMessage: self.awayMessage, connectedBot: self.connectedBot, businessIntro: self.businessIntro, birthday: self.birthday, personalChannel: self.personalChannel, botPreview: self.botPreview, starGiftsCount: self.starGiftsCount, starRefProgram: self.starRefProgram, verification: self.verification, sendPaidMessageStars: self.sendPaidMessageStars, disallowedGifts: self.disallowedGifts, botGroupAdminRights: self.botGroupAdminRights, botChannelAdminRights: self.botChannelAdminRights, starRating: self.starRating, pendingStarRating: self.pendingStarRating, mainProfileTab: self.mainProfileTab, savedMusic: self.savedMusic)
|
||||
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, chatTheme: self.chatTheme, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: self.businessLocation, greetingMessage: self.greetingMessage, awayMessage: self.awayMessage, connectedBot: self.connectedBot, businessIntro: self.businessIntro, birthday: self.birthday, personalChannel: self.personalChannel, botPreview: self.botPreview, starGiftsCount: self.starGiftsCount, starRefProgram: self.starRefProgram, verification: self.verification, sendPaidMessageStars: self.sendPaidMessageStars, disallowedGifts: self.disallowedGifts, botGroupAdminRights: self.botGroupAdminRights, botChannelAdminRights: self.botChannelAdminRights, starRating: self.starRating, pendingStarRating: self.pendingStarRating, mainProfileTab: self.mainProfileTab, savedMusic: self.savedMusic, note: self.note)
|
||||
}
|
||||
|
||||
public func withUpdatedHasScheduledMessages(_ hasScheduledMessages: Bool) -> CachedUserData {
|
||||
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, chatTheme: self.chatTheme, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: self.businessLocation, greetingMessage: self.greetingMessage, awayMessage: self.awayMessage, connectedBot: self.connectedBot, businessIntro: self.businessIntro, birthday: self.birthday, personalChannel: self.personalChannel, botPreview: self.botPreview, starGiftsCount: self.starGiftsCount, starRefProgram: self.starRefProgram, verification: self.verification, sendPaidMessageStars: self.sendPaidMessageStars, disallowedGifts: self.disallowedGifts, botGroupAdminRights: self.botGroupAdminRights, botChannelAdminRights: self.botChannelAdminRights, starRating: self.starRating, pendingStarRating: self.pendingStarRating, mainProfileTab: self.mainProfileTab, savedMusic: self.savedMusic)
|
||||
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, chatTheme: self.chatTheme, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: self.businessLocation, greetingMessage: self.greetingMessage, awayMessage: self.awayMessage, connectedBot: self.connectedBot, businessIntro: self.businessIntro, birthday: self.birthday, personalChannel: self.personalChannel, botPreview: self.botPreview, starGiftsCount: self.starGiftsCount, starRefProgram: self.starRefProgram, verification: self.verification, sendPaidMessageStars: self.sendPaidMessageStars, disallowedGifts: self.disallowedGifts, botGroupAdminRights: self.botGroupAdminRights, botChannelAdminRights: self.botChannelAdminRights, starRating: self.starRating, pendingStarRating: self.pendingStarRating, mainProfileTab: self.mainProfileTab, savedMusic: self.savedMusic, note: self.note)
|
||||
}
|
||||
|
||||
public func withUpdatedAutoremoveTimeout(_ autoremoveTimeout: CachedPeerAutoremoveTimeout) -> CachedUserData {
|
||||
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: autoremoveTimeout, chatTheme: self.chatTheme, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: self.businessLocation, greetingMessage: self.greetingMessage, awayMessage: self.awayMessage, connectedBot: self.connectedBot, businessIntro: self.businessIntro, birthday: self.birthday, personalChannel: self.personalChannel, botPreview: self.botPreview, starGiftsCount: self.starGiftsCount, starRefProgram: self.starRefProgram, verification: self.verification, sendPaidMessageStars: self.sendPaidMessageStars, disallowedGifts: self.disallowedGifts, botGroupAdminRights: self.botGroupAdminRights, botChannelAdminRights: self.botChannelAdminRights, starRating: self.starRating, pendingStarRating: self.pendingStarRating, mainProfileTab: self.mainProfileTab, savedMusic: self.savedMusic)
|
||||
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: autoremoveTimeout, chatTheme: self.chatTheme, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: self.businessLocation, greetingMessage: self.greetingMessage, awayMessage: self.awayMessage, connectedBot: self.connectedBot, businessIntro: self.businessIntro, birthday: self.birthday, personalChannel: self.personalChannel, botPreview: self.botPreview, starGiftsCount: self.starGiftsCount, starRefProgram: self.starRefProgram, verification: self.verification, sendPaidMessageStars: self.sendPaidMessageStars, disallowedGifts: self.disallowedGifts, botGroupAdminRights: self.botGroupAdminRights, botChannelAdminRights: self.botChannelAdminRights, starRating: self.starRating, pendingStarRating: self.pendingStarRating, mainProfileTab: self.mainProfileTab, savedMusic: self.savedMusic, note: self.note)
|
||||
}
|
||||
|
||||
public func withUpdatedChatTheme(_ chatTheme: ChatTheme?) -> CachedUserData {
|
||||
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, chatTheme: chatTheme, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: self.businessLocation, greetingMessage: self.greetingMessage, awayMessage: self.awayMessage, connectedBot: self.connectedBot, businessIntro: self.businessIntro, birthday: self.birthday, personalChannel: self.personalChannel, botPreview: self.botPreview, starGiftsCount: self.starGiftsCount, starRefProgram: self.starRefProgram, verification: self.verification, sendPaidMessageStars: self.sendPaidMessageStars, disallowedGifts: self.disallowedGifts, botGroupAdminRights: self.botGroupAdminRights, botChannelAdminRights: self.botChannelAdminRights, starRating: self.starRating, pendingStarRating: self.pendingStarRating, mainProfileTab: self.mainProfileTab, savedMusic: self.savedMusic)
|
||||
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, chatTheme: chatTheme, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: self.businessLocation, greetingMessage: self.greetingMessage, awayMessage: self.awayMessage, connectedBot: self.connectedBot, businessIntro: self.businessIntro, birthday: self.birthday, personalChannel: self.personalChannel, botPreview: self.botPreview, starGiftsCount: self.starGiftsCount, starRefProgram: self.starRefProgram, verification: self.verification, sendPaidMessageStars: self.sendPaidMessageStars, disallowedGifts: self.disallowedGifts, botGroupAdminRights: self.botGroupAdminRights, botChannelAdminRights: self.botChannelAdminRights, starRating: self.starRating, pendingStarRating: self.pendingStarRating, mainProfileTab: self.mainProfileTab, savedMusic: self.savedMusic, note: self.note)
|
||||
}
|
||||
|
||||
public func withUpdatedPhoto(_ photo: CachedPeerProfilePhoto) -> CachedUserData {
|
||||
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, chatTheme: self.chatTheme, photo: photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: self.businessLocation, greetingMessage: self.greetingMessage, awayMessage: self.awayMessage, connectedBot: self.connectedBot, businessIntro: self.businessIntro, birthday: self.birthday, personalChannel: self.personalChannel, botPreview: self.botPreview, starGiftsCount: self.starGiftsCount, starRefProgram: self.starRefProgram, verification: self.verification, sendPaidMessageStars: self.sendPaidMessageStars, disallowedGifts: self.disallowedGifts, botGroupAdminRights: self.botGroupAdminRights, botChannelAdminRights: self.botChannelAdminRights, starRating: self.starRating, pendingStarRating: self.pendingStarRating, mainProfileTab: self.mainProfileTab, savedMusic: self.savedMusic)
|
||||
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, chatTheme: self.chatTheme, photo: photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: self.businessLocation, greetingMessage: self.greetingMessage, awayMessage: self.awayMessage, connectedBot: self.connectedBot, businessIntro: self.businessIntro, birthday: self.birthday, personalChannel: self.personalChannel, botPreview: self.botPreview, starGiftsCount: self.starGiftsCount, starRefProgram: self.starRefProgram, verification: self.verification, sendPaidMessageStars: self.sendPaidMessageStars, disallowedGifts: self.disallowedGifts, botGroupAdminRights: self.botGroupAdminRights, botChannelAdminRights: self.botChannelAdminRights, starRating: self.starRating, pendingStarRating: self.pendingStarRating, mainProfileTab: self.mainProfileTab, savedMusic: self.savedMusic, note: self.note)
|
||||
}
|
||||
|
||||
public func withUpdatedPersonalPhoto(_ personalPhoto: CachedPeerProfilePhoto) -> CachedUserData {
|
||||
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, chatTheme: self.chatTheme, photo: self.photo, personalPhoto: personalPhoto, fallbackPhoto: self.fallbackPhoto, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: self.businessLocation, greetingMessage: self.greetingMessage, awayMessage: self.awayMessage, connectedBot: self.connectedBot, businessIntro: self.businessIntro, birthday: self.birthday, personalChannel: self.personalChannel, botPreview: self.botPreview, starGiftsCount: self.starGiftsCount, starRefProgram: self.starRefProgram, verification: self.verification, sendPaidMessageStars: self.sendPaidMessageStars, disallowedGifts: self.disallowedGifts, botGroupAdminRights: self.botGroupAdminRights, botChannelAdminRights: self.botChannelAdminRights, starRating: self.starRating, pendingStarRating: self.pendingStarRating, mainProfileTab: self.mainProfileTab, savedMusic: self.savedMusic)
|
||||
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, chatTheme: self.chatTheme, photo: self.photo, personalPhoto: personalPhoto, fallbackPhoto: self.fallbackPhoto, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: self.businessLocation, greetingMessage: self.greetingMessage, awayMessage: self.awayMessage, connectedBot: self.connectedBot, businessIntro: self.businessIntro, birthday: self.birthday, personalChannel: self.personalChannel, botPreview: self.botPreview, starGiftsCount: self.starGiftsCount, starRefProgram: self.starRefProgram, verification: self.verification, sendPaidMessageStars: self.sendPaidMessageStars, disallowedGifts: self.disallowedGifts, botGroupAdminRights: self.botGroupAdminRights, botChannelAdminRights: self.botChannelAdminRights, starRating: self.starRating, pendingStarRating: self.pendingStarRating, mainProfileTab: self.mainProfileTab, savedMusic: self.savedMusic, note: self.note)
|
||||
}
|
||||
|
||||
public func withUpdatedFallbackPhoto(_ fallbackPhoto: CachedPeerProfilePhoto) -> CachedUserData {
|
||||
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, chatTheme: self.chatTheme, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: fallbackPhoto, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: self.businessLocation, greetingMessage: self.greetingMessage, awayMessage: self.awayMessage, connectedBot: self.connectedBot, businessIntro: self.businessIntro, birthday: self.birthday, personalChannel: self.personalChannel, botPreview: self.botPreview, starGiftsCount: self.starGiftsCount, starRefProgram: self.starRefProgram, verification: self.verification, sendPaidMessageStars: self.sendPaidMessageStars, disallowedGifts: self.disallowedGifts, botGroupAdminRights: self.botGroupAdminRights, botChannelAdminRights: self.botChannelAdminRights, starRating: self.starRating, pendingStarRating: self.pendingStarRating, mainProfileTab: self.mainProfileTab, savedMusic: self.savedMusic)
|
||||
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, chatTheme: self.chatTheme, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: fallbackPhoto, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: self.businessLocation, greetingMessage: self.greetingMessage, awayMessage: self.awayMessage, connectedBot: self.connectedBot, businessIntro: self.businessIntro, birthday: self.birthday, personalChannel: self.personalChannel, botPreview: self.botPreview, starGiftsCount: self.starGiftsCount, starRefProgram: self.starRefProgram, verification: self.verification, sendPaidMessageStars: self.sendPaidMessageStars, disallowedGifts: self.disallowedGifts, botGroupAdminRights: self.botGroupAdminRights, botChannelAdminRights: self.botChannelAdminRights, starRating: self.starRating, pendingStarRating: self.pendingStarRating, mainProfileTab: self.mainProfileTab, savedMusic: self.savedMusic, note: self.note)
|
||||
}
|
||||
|
||||
public func withUpdatedVoiceMessagesAvailable(_ voiceMessagesAvailable: Bool) -> CachedUserData {
|
||||
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, chatTheme: self.chatTheme, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, voiceMessagesAvailable: voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: self.businessLocation, greetingMessage: self.greetingMessage, awayMessage: self.awayMessage, connectedBot: self.connectedBot, businessIntro: self.businessIntro, birthday: self.birthday, personalChannel: self.personalChannel, botPreview: self.botPreview, starGiftsCount: self.starGiftsCount, starRefProgram: self.starRefProgram, verification: self.verification, sendPaidMessageStars: self.sendPaidMessageStars, disallowedGifts: self.disallowedGifts, botGroupAdminRights: self.botGroupAdminRights, botChannelAdminRights: self.botChannelAdminRights, starRating: self.starRating, pendingStarRating: self.pendingStarRating, mainProfileTab: self.mainProfileTab, savedMusic: self.savedMusic)
|
||||
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, chatTheme: self.chatTheme, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, voiceMessagesAvailable: voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: self.businessLocation, greetingMessage: self.greetingMessage, awayMessage: self.awayMessage, connectedBot: self.connectedBot, businessIntro: self.businessIntro, birthday: self.birthday, personalChannel: self.personalChannel, botPreview: self.botPreview, starGiftsCount: self.starGiftsCount, starRefProgram: self.starRefProgram, verification: self.verification, sendPaidMessageStars: self.sendPaidMessageStars, disallowedGifts: self.disallowedGifts, botGroupAdminRights: self.botGroupAdminRights, botChannelAdminRights: self.botChannelAdminRights, starRating: self.starRating, pendingStarRating: self.pendingStarRating, mainProfileTab: self.mainProfileTab, savedMusic: self.savedMusic, note: self.note)
|
||||
}
|
||||
|
||||
public func withUpdatedWallpaper(_ wallpaper: TelegramWallpaper?) -> CachedUserData {
|
||||
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, chatTheme: self.chatTheme, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: self.businessLocation, greetingMessage: self.greetingMessage, awayMessage: self.awayMessage, connectedBot: self.connectedBot, businessIntro: self.businessIntro, birthday: self.birthday, personalChannel: self.personalChannel, botPreview: self.botPreview, starGiftsCount: self.starGiftsCount, starRefProgram: self.starRefProgram, verification: self.verification, sendPaidMessageStars: self.sendPaidMessageStars, disallowedGifts: self.disallowedGifts, botGroupAdminRights: self.botGroupAdminRights, botChannelAdminRights: self.botChannelAdminRights, starRating: self.starRating, pendingStarRating: self.pendingStarRating, mainProfileTab: self.mainProfileTab, savedMusic: self.savedMusic)
|
||||
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, chatTheme: self.chatTheme, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: self.businessLocation, greetingMessage: self.greetingMessage, awayMessage: self.awayMessage, connectedBot: self.connectedBot, businessIntro: self.businessIntro, birthday: self.birthday, personalChannel: self.personalChannel, botPreview: self.botPreview, starGiftsCount: self.starGiftsCount, starRefProgram: self.starRefProgram, verification: self.verification, sendPaidMessageStars: self.sendPaidMessageStars, disallowedGifts: self.disallowedGifts, botGroupAdminRights: self.botGroupAdminRights, botChannelAdminRights: self.botChannelAdminRights, starRating: self.starRating, pendingStarRating: self.pendingStarRating, mainProfileTab: self.mainProfileTab, savedMusic: self.savedMusic, note: self.note)
|
||||
}
|
||||
|
||||
public func withUpdatedFlags(_ flags: CachedUserFlags) -> CachedUserData {
|
||||
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, chatTheme: self.chatTheme, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: flags, businessHours: self.businessHours, businessLocation: self.businessLocation, greetingMessage: self.greetingMessage, awayMessage: self.awayMessage, connectedBot: self.connectedBot, businessIntro: self.businessIntro, birthday: self.birthday, personalChannel: self.personalChannel, botPreview: self.botPreview, starGiftsCount: self.starGiftsCount, starRefProgram: self.starRefProgram, verification: self.verification, sendPaidMessageStars: self.sendPaidMessageStars, disallowedGifts: self.disallowedGifts, botGroupAdminRights: self.botGroupAdminRights, botChannelAdminRights: self.botChannelAdminRights, starRating: self.starRating, pendingStarRating: self.pendingStarRating, mainProfileTab: self.mainProfileTab, savedMusic: self.savedMusic)
|
||||
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, chatTheme: self.chatTheme, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: flags, businessHours: self.businessHours, businessLocation: self.businessLocation, greetingMessage: self.greetingMessage, awayMessage: self.awayMessage, connectedBot: self.connectedBot, businessIntro: self.businessIntro, birthday: self.birthday, personalChannel: self.personalChannel, botPreview: self.botPreview, starGiftsCount: self.starGiftsCount, starRefProgram: self.starRefProgram, verification: self.verification, sendPaidMessageStars: self.sendPaidMessageStars, disallowedGifts: self.disallowedGifts, botGroupAdminRights: self.botGroupAdminRights, botChannelAdminRights: self.botChannelAdminRights, starRating: self.starRating, pendingStarRating: self.pendingStarRating, mainProfileTab: self.mainProfileTab, savedMusic: self.savedMusic, note: self.note)
|
||||
}
|
||||
|
||||
public func withUpdatedBusinessHours(_ businessHours: TelegramBusinessHours?) -> CachedUserData {
|
||||
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, chatTheme: self.chatTheme, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: businessHours, businessLocation: self.businessLocation, greetingMessage: self.greetingMessage, awayMessage: self.awayMessage, connectedBot: self.connectedBot, businessIntro: self.businessIntro, birthday: self.birthday, personalChannel: self.personalChannel, botPreview: self.botPreview, starGiftsCount: self.starGiftsCount, starRefProgram: self.starRefProgram, verification: self.verification, sendPaidMessageStars: self.sendPaidMessageStars, disallowedGifts: self.disallowedGifts, botGroupAdminRights: self.botGroupAdminRights, botChannelAdminRights: self.botChannelAdminRights, starRating: self.starRating, pendingStarRating: self.pendingStarRating, mainProfileTab: self.mainProfileTab, savedMusic: self.savedMusic)
|
||||
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, chatTheme: self.chatTheme, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: businessHours, businessLocation: self.businessLocation, greetingMessage: self.greetingMessage, awayMessage: self.awayMessage, connectedBot: self.connectedBot, businessIntro: self.businessIntro, birthday: self.birthday, personalChannel: self.personalChannel, botPreview: self.botPreview, starGiftsCount: self.starGiftsCount, starRefProgram: self.starRefProgram, verification: self.verification, sendPaidMessageStars: self.sendPaidMessageStars, disallowedGifts: self.disallowedGifts, botGroupAdminRights: self.botGroupAdminRights, botChannelAdminRights: self.botChannelAdminRights, starRating: self.starRating, pendingStarRating: self.pendingStarRating, mainProfileTab: self.mainProfileTab, savedMusic: self.savedMusic, note: self.note)
|
||||
}
|
||||
|
||||
public func withUpdatedBusinessLocation(_ businessLocation: TelegramBusinessLocation?) -> CachedUserData {
|
||||
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, chatTheme: self.chatTheme, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: businessLocation, greetingMessage: self.greetingMessage, awayMessage: self.awayMessage, connectedBot: self.connectedBot, businessIntro: self.businessIntro, birthday: self.birthday, personalChannel: self.personalChannel, botPreview: self.botPreview, starGiftsCount: self.starGiftsCount, starRefProgram: self.starRefProgram, verification: self.verification, sendPaidMessageStars: self.sendPaidMessageStars, disallowedGifts: self.disallowedGifts, botGroupAdminRights: self.botGroupAdminRights, botChannelAdminRights: self.botChannelAdminRights, starRating: self.starRating, pendingStarRating: self.pendingStarRating, mainProfileTab: self.mainProfileTab, savedMusic: self.savedMusic)
|
||||
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, chatTheme: self.chatTheme, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: businessLocation, greetingMessage: self.greetingMessage, awayMessage: self.awayMessage, connectedBot: self.connectedBot, businessIntro: self.businessIntro, birthday: self.birthday, personalChannel: self.personalChannel, botPreview: self.botPreview, starGiftsCount: self.starGiftsCount, starRefProgram: self.starRefProgram, verification: self.verification, sendPaidMessageStars: self.sendPaidMessageStars, disallowedGifts: self.disallowedGifts, botGroupAdminRights: self.botGroupAdminRights, botChannelAdminRights: self.botChannelAdminRights, starRating: self.starRating, pendingStarRating: self.pendingStarRating, mainProfileTab: self.mainProfileTab, savedMusic: self.savedMusic, note: self.note)
|
||||
}
|
||||
|
||||
public func withUpdatedGreetingMessage(_ greetingMessage: TelegramBusinessGreetingMessage?) -> CachedUserData {
|
||||
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, chatTheme: self.chatTheme, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: self.businessLocation, greetingMessage: greetingMessage, awayMessage: self.awayMessage, connectedBot: self.connectedBot, businessIntro: self.businessIntro, birthday: self.birthday, personalChannel: self.personalChannel, botPreview: self.botPreview, starGiftsCount: self.starGiftsCount, starRefProgram: self.starRefProgram, verification: self.verification, sendPaidMessageStars: self.sendPaidMessageStars, disallowedGifts: self.disallowedGifts, botGroupAdminRights: self.botGroupAdminRights, botChannelAdminRights: self.botChannelAdminRights, starRating: self.starRating, pendingStarRating: self.pendingStarRating, mainProfileTab: self.mainProfileTab, savedMusic: self.savedMusic)
|
||||
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, chatTheme: self.chatTheme, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: self.businessLocation, greetingMessage: greetingMessage, awayMessage: self.awayMessage, connectedBot: self.connectedBot, businessIntro: self.businessIntro, birthday: self.birthday, personalChannel: self.personalChannel, botPreview: self.botPreview, starGiftsCount: self.starGiftsCount, starRefProgram: self.starRefProgram, verification: self.verification, sendPaidMessageStars: self.sendPaidMessageStars, disallowedGifts: self.disallowedGifts, botGroupAdminRights: self.botGroupAdminRights, botChannelAdminRights: self.botChannelAdminRights, starRating: self.starRating, pendingStarRating: self.pendingStarRating, mainProfileTab: self.mainProfileTab, savedMusic: self.savedMusic, note: self.note)
|
||||
}
|
||||
|
||||
public func withUpdatedAwayMessage(_ awayMessage: TelegramBusinessAwayMessage?) -> CachedUserData {
|
||||
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, chatTheme: self.chatTheme, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: self.businessLocation, greetingMessage: self.greetingMessage, awayMessage: awayMessage, connectedBot: self.connectedBot, businessIntro: self.businessIntro, birthday: self.birthday, personalChannel: self.personalChannel, botPreview: self.botPreview, starGiftsCount: self.starGiftsCount, starRefProgram: self.starRefProgram, verification: self.verification, sendPaidMessageStars: self.sendPaidMessageStars, disallowedGifts: self.disallowedGifts, botGroupAdminRights: self.botGroupAdminRights, botChannelAdminRights: self.botChannelAdminRights, starRating: self.starRating, pendingStarRating: self.pendingStarRating, mainProfileTab: self.mainProfileTab, savedMusic: self.savedMusic)
|
||||
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, chatTheme: self.chatTheme, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: self.businessLocation, greetingMessage: self.greetingMessage, awayMessage: awayMessage, connectedBot: self.connectedBot, businessIntro: self.businessIntro, birthday: self.birthday, personalChannel: self.personalChannel, botPreview: self.botPreview, starGiftsCount: self.starGiftsCount, starRefProgram: self.starRefProgram, verification: self.verification, sendPaidMessageStars: self.sendPaidMessageStars, disallowedGifts: self.disallowedGifts, botGroupAdminRights: self.botGroupAdminRights, botChannelAdminRights: self.botChannelAdminRights, starRating: self.starRating, pendingStarRating: self.pendingStarRating, mainProfileTab: self.mainProfileTab, savedMusic: self.savedMusic, note: self.note)
|
||||
}
|
||||
|
||||
public func withUpdatedConnectedBot(_ connectedBot: TelegramAccountConnectedBot?) -> CachedUserData {
|
||||
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, chatTheme: self.chatTheme, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: self.businessLocation, greetingMessage: self.greetingMessage, awayMessage: self.awayMessage, connectedBot: connectedBot, businessIntro: self.businessIntro, birthday: self.birthday, personalChannel: self.personalChannel, botPreview: self.botPreview, starGiftsCount: self.starGiftsCount, starRefProgram: self.starRefProgram, verification: self.verification, sendPaidMessageStars: self.sendPaidMessageStars, disallowedGifts: self.disallowedGifts, botGroupAdminRights: self.botGroupAdminRights, botChannelAdminRights: self.botChannelAdminRights, starRating: self.starRating, pendingStarRating: self.pendingStarRating, mainProfileTab: self.mainProfileTab, savedMusic: self.savedMusic)
|
||||
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, chatTheme: self.chatTheme, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: self.businessLocation, greetingMessage: self.greetingMessage, awayMessage: self.awayMessage, connectedBot: connectedBot, businessIntro: self.businessIntro, birthday: self.birthday, personalChannel: self.personalChannel, botPreview: self.botPreview, starGiftsCount: self.starGiftsCount, starRefProgram: self.starRefProgram, verification: self.verification, sendPaidMessageStars: self.sendPaidMessageStars, disallowedGifts: self.disallowedGifts, botGroupAdminRights: self.botGroupAdminRights, botChannelAdminRights: self.botChannelAdminRights, starRating: self.starRating, pendingStarRating: self.pendingStarRating, mainProfileTab: self.mainProfileTab, savedMusic: self.savedMusic, note: self.note)
|
||||
}
|
||||
|
||||
public func withUpdatedBusinessIntro(_ businessIntro: TelegramBusinessIntro?) -> CachedUserData {
|
||||
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, chatTheme: self.chatTheme, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: self.businessLocation, greetingMessage: self.greetingMessage, awayMessage: self.awayMessage, connectedBot: self.connectedBot, businessIntro: .known(businessIntro), birthday: self.birthday, personalChannel: self.personalChannel, botPreview: self.botPreview, starGiftsCount: self.starGiftsCount, starRefProgram: self.starRefProgram, verification: self.verification, sendPaidMessageStars: self.sendPaidMessageStars, disallowedGifts: self.disallowedGifts, botGroupAdminRights: self.botGroupAdminRights, botChannelAdminRights: self.botChannelAdminRights, starRating: self.starRating, pendingStarRating: self.pendingStarRating, mainProfileTab: self.mainProfileTab, savedMusic: self.savedMusic)
|
||||
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, chatTheme: self.chatTheme, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: self.businessLocation, greetingMessage: self.greetingMessage, awayMessage: self.awayMessage, connectedBot: self.connectedBot, businessIntro: .known(businessIntro), birthday: self.birthday, personalChannel: self.personalChannel, botPreview: self.botPreview, starGiftsCount: self.starGiftsCount, starRefProgram: self.starRefProgram, verification: self.verification, sendPaidMessageStars: self.sendPaidMessageStars, disallowedGifts: self.disallowedGifts, botGroupAdminRights: self.botGroupAdminRights, botChannelAdminRights: self.botChannelAdminRights, starRating: self.starRating, pendingStarRating: self.pendingStarRating, mainProfileTab: self.mainProfileTab, savedMusic: self.savedMusic, note: self.note)
|
||||
}
|
||||
|
||||
public func withUpdatedBirthday(_ birthday: TelegramBirthday?) -> CachedUserData {
|
||||
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, chatTheme: self.chatTheme, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: self.businessLocation, greetingMessage: self.greetingMessage, awayMessage: self.awayMessage, connectedBot: self.connectedBot, businessIntro: self.businessIntro, birthday: birthday, personalChannel: self.personalChannel, botPreview: self.botPreview, starGiftsCount: self.starGiftsCount, starRefProgram: self.starRefProgram, verification: self.verification, sendPaidMessageStars: self.sendPaidMessageStars, disallowedGifts: self.disallowedGifts, botGroupAdminRights: self.botGroupAdminRights, botChannelAdminRights: self.botChannelAdminRights, starRating: self.starRating, pendingStarRating: self.pendingStarRating, mainProfileTab: self.mainProfileTab, savedMusic: self.savedMusic)
|
||||
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, chatTheme: self.chatTheme, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: self.businessLocation, greetingMessage: self.greetingMessage, awayMessage: self.awayMessage, connectedBot: self.connectedBot, businessIntro: self.businessIntro, birthday: birthday, personalChannel: self.personalChannel, botPreview: self.botPreview, starGiftsCount: self.starGiftsCount, starRefProgram: self.starRefProgram, verification: self.verification, sendPaidMessageStars: self.sendPaidMessageStars, disallowedGifts: self.disallowedGifts, botGroupAdminRights: self.botGroupAdminRights, botChannelAdminRights: self.botChannelAdminRights, starRating: self.starRating, pendingStarRating: self.pendingStarRating, mainProfileTab: self.mainProfileTab, savedMusic: self.savedMusic, note: self.note)
|
||||
}
|
||||
|
||||
public func withUpdatedPersonalChannel(_ personalChannel: TelegramPersonalChannel?) -> CachedUserData {
|
||||
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, chatTheme: self.chatTheme, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: self.businessLocation, greetingMessage: self.greetingMessage, awayMessage: self.awayMessage, connectedBot: self.connectedBot, businessIntro: self.businessIntro, birthday: self.birthday, personalChannel: .known(personalChannel), botPreview: self.botPreview, starGiftsCount: self.starGiftsCount, starRefProgram: self.starRefProgram, verification: self.verification, sendPaidMessageStars: self.sendPaidMessageStars, disallowedGifts: self.disallowedGifts, botGroupAdminRights: self.botGroupAdminRights, botChannelAdminRights: self.botChannelAdminRights, starRating: self.starRating, pendingStarRating: self.pendingStarRating, mainProfileTab: self.mainProfileTab, savedMusic: self.savedMusic)
|
||||
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, chatTheme: self.chatTheme, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: self.businessLocation, greetingMessage: self.greetingMessage, awayMessage: self.awayMessage, connectedBot: self.connectedBot, businessIntro: self.businessIntro, birthday: self.birthday, personalChannel: .known(personalChannel), botPreview: self.botPreview, starGiftsCount: self.starGiftsCount, starRefProgram: self.starRefProgram, verification: self.verification, sendPaidMessageStars: self.sendPaidMessageStars, disallowedGifts: self.disallowedGifts, botGroupAdminRights: self.botGroupAdminRights, botChannelAdminRights: self.botChannelAdminRights, starRating: self.starRating, pendingStarRating: self.pendingStarRating, mainProfileTab: self.mainProfileTab, savedMusic: self.savedMusic, note: self.note)
|
||||
}
|
||||
|
||||
public func withUpdatedBotPreview(_ botPreview: BotPreview?) -> CachedUserData {
|
||||
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, chatTheme: self.chatTheme, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: self.businessLocation, greetingMessage: self.greetingMessage, awayMessage: self.awayMessage, connectedBot: self.connectedBot, businessIntro: self.businessIntro, birthday: self.birthday, personalChannel: self.personalChannel, botPreview: botPreview, starGiftsCount: self.starGiftsCount, starRefProgram: self.starRefProgram, verification: self.verification, sendPaidMessageStars: self.sendPaidMessageStars, disallowedGifts: self.disallowedGifts, botGroupAdminRights: self.botGroupAdminRights, botChannelAdminRights: self.botChannelAdminRights, starRating: self.starRating, pendingStarRating: self.pendingStarRating, mainProfileTab: self.mainProfileTab, savedMusic: self.savedMusic)
|
||||
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, chatTheme: self.chatTheme, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: self.businessLocation, greetingMessage: self.greetingMessage, awayMessage: self.awayMessage, connectedBot: self.connectedBot, businessIntro: self.businessIntro, birthday: self.birthday, personalChannel: self.personalChannel, botPreview: botPreview, starGiftsCount: self.starGiftsCount, starRefProgram: self.starRefProgram, verification: self.verification, sendPaidMessageStars: self.sendPaidMessageStars, disallowedGifts: self.disallowedGifts, botGroupAdminRights: self.botGroupAdminRights, botChannelAdminRights: self.botChannelAdminRights, starRating: self.starRating, pendingStarRating: self.pendingStarRating, mainProfileTab: self.mainProfileTab, savedMusic: self.savedMusic, note: self.note)
|
||||
}
|
||||
|
||||
public func withUpdatedStarGiftsCount(_ starGiftsCount: Int32?) -> CachedUserData {
|
||||
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, chatTheme: self.chatTheme, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: self.businessLocation, greetingMessage: self.greetingMessage, awayMessage: self.awayMessage, connectedBot: self.connectedBot, businessIntro: self.businessIntro, birthday: self.birthday, personalChannel: self.personalChannel, botPreview: self.botPreview, starGiftsCount: starGiftsCount, starRefProgram: self.starRefProgram, verification: self.verification, sendPaidMessageStars: self.sendPaidMessageStars, disallowedGifts: self.disallowedGifts, botGroupAdminRights: self.botGroupAdminRights, botChannelAdminRights: self.botChannelAdminRights, starRating: self.starRating, pendingStarRating: self.pendingStarRating, mainProfileTab: self.mainProfileTab, savedMusic: self.savedMusic)
|
||||
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, chatTheme: self.chatTheme, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: self.businessLocation, greetingMessage: self.greetingMessage, awayMessage: self.awayMessage, connectedBot: self.connectedBot, businessIntro: self.businessIntro, birthday: self.birthday, personalChannel: self.personalChannel, botPreview: self.botPreview, starGiftsCount: starGiftsCount, starRefProgram: self.starRefProgram, verification: self.verification, sendPaidMessageStars: self.sendPaidMessageStars, disallowedGifts: self.disallowedGifts, botGroupAdminRights: self.botGroupAdminRights, botChannelAdminRights: self.botChannelAdminRights, starRating: self.starRating, pendingStarRating: self.pendingStarRating, mainProfileTab: self.mainProfileTab, savedMusic: self.savedMusic, note: self.note)
|
||||
}
|
||||
|
||||
public func withUpdatedStarRefProgram(_ starRefProgram: TelegramStarRefProgram?) -> CachedUserData {
|
||||
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, chatTheme: self.chatTheme, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: self.businessLocation, greetingMessage: self.greetingMessage, awayMessage: self.awayMessage, connectedBot: self.connectedBot, businessIntro: self.businessIntro, birthday: self.birthday, personalChannel: self.personalChannel, botPreview: self.botPreview, starGiftsCount: self.starGiftsCount, starRefProgram: starRefProgram, verification: self.verification, sendPaidMessageStars: self.sendPaidMessageStars, disallowedGifts: self.disallowedGifts, botGroupAdminRights: self.botGroupAdminRights, botChannelAdminRights: self.botChannelAdminRights, starRating: self.starRating, pendingStarRating: self.pendingStarRating, mainProfileTab: self.mainProfileTab, savedMusic: self.savedMusic)
|
||||
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, chatTheme: self.chatTheme, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: self.businessLocation, greetingMessage: self.greetingMessage, awayMessage: self.awayMessage, connectedBot: self.connectedBot, businessIntro: self.businessIntro, birthday: self.birthday, personalChannel: self.personalChannel, botPreview: self.botPreview, starGiftsCount: self.starGiftsCount, starRefProgram: starRefProgram, verification: self.verification, sendPaidMessageStars: self.sendPaidMessageStars, disallowedGifts: self.disallowedGifts, botGroupAdminRights: self.botGroupAdminRights, botChannelAdminRights: self.botChannelAdminRights, starRating: self.starRating, pendingStarRating: self.pendingStarRating, mainProfileTab: self.mainProfileTab, savedMusic: self.savedMusic, note: self.note)
|
||||
}
|
||||
|
||||
public func withUpdatedVerification(_ verification: PeerVerification?) -> CachedUserData {
|
||||
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, chatTheme: self.chatTheme, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: self.businessLocation, greetingMessage: self.greetingMessage, awayMessage: self.awayMessage, connectedBot: self.connectedBot, businessIntro: self.businessIntro, birthday: self.birthday, personalChannel: self.personalChannel, botPreview: self.botPreview, starGiftsCount: self.starGiftsCount, starRefProgram: self.starRefProgram, verification: verification, sendPaidMessageStars: self.sendPaidMessageStars, disallowedGifts: self.disallowedGifts, botGroupAdminRights: self.botGroupAdminRights, botChannelAdminRights: self.botChannelAdminRights, starRating: self.starRating, pendingStarRating: self.pendingStarRating, mainProfileTab: self.mainProfileTab, savedMusic: self.savedMusic)
|
||||
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, chatTheme: self.chatTheme, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: self.businessLocation, greetingMessage: self.greetingMessage, awayMessage: self.awayMessage, connectedBot: self.connectedBot, businessIntro: self.businessIntro, birthday: self.birthday, personalChannel: self.personalChannel, botPreview: self.botPreview, starGiftsCount: self.starGiftsCount, starRefProgram: self.starRefProgram, verification: verification, sendPaidMessageStars: self.sendPaidMessageStars, disallowedGifts: self.disallowedGifts, botGroupAdminRights: self.botGroupAdminRights, botChannelAdminRights: self.botChannelAdminRights, starRating: self.starRating, pendingStarRating: self.pendingStarRating, mainProfileTab: self.mainProfileTab, savedMusic: self.savedMusic, note: self.note)
|
||||
}
|
||||
|
||||
public func withUpdatedSendPaidMessageStars(_ sendPaidMessageStars: StarsAmount?) -> CachedUserData {
|
||||
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, chatTheme: self.chatTheme, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: self.businessLocation, greetingMessage: self.greetingMessage, awayMessage: self.awayMessage, connectedBot: self.connectedBot, businessIntro: self.businessIntro, birthday: self.birthday, personalChannel: self.personalChannel, botPreview: self.botPreview, starGiftsCount: self.starGiftsCount, starRefProgram: self.starRefProgram, verification: self.verification, sendPaidMessageStars: sendPaidMessageStars, disallowedGifts: self.disallowedGifts, botGroupAdminRights: self.botGroupAdminRights, botChannelAdminRights: self.botChannelAdminRights, starRating: self.starRating, pendingStarRating: self.pendingStarRating, mainProfileTab: self.mainProfileTab, savedMusic: self.savedMusic)
|
||||
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, chatTheme: self.chatTheme, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: self.businessLocation, greetingMessage: self.greetingMessage, awayMessage: self.awayMessage, connectedBot: self.connectedBot, businessIntro: self.businessIntro, birthday: self.birthday, personalChannel: self.personalChannel, botPreview: self.botPreview, starGiftsCount: self.starGiftsCount, starRefProgram: self.starRefProgram, verification: self.verification, sendPaidMessageStars: sendPaidMessageStars, disallowedGifts: self.disallowedGifts, botGroupAdminRights: self.botGroupAdminRights, botChannelAdminRights: self.botChannelAdminRights, starRating: self.starRating, pendingStarRating: self.pendingStarRating, mainProfileTab: self.mainProfileTab, savedMusic: self.savedMusic, note: self.note)
|
||||
}
|
||||
|
||||
public func withUpdatedDisallowedGifts(_ disallowedGifts: TelegramDisallowedGifts) -> CachedUserData {
|
||||
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, chatTheme: self.chatTheme, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: self.businessLocation, greetingMessage: self.greetingMessage, awayMessage: self.awayMessage, connectedBot: self.connectedBot, businessIntro: self.businessIntro, birthday: self.birthday, personalChannel: self.personalChannel, botPreview: self.botPreview, starGiftsCount: self.starGiftsCount, starRefProgram: self.starRefProgram, verification: self.verification, sendPaidMessageStars: self.sendPaidMessageStars, disallowedGifts: disallowedGifts, botGroupAdminRights: self.botGroupAdminRights, botChannelAdminRights: self.botChannelAdminRights, starRating: self.starRating, pendingStarRating: self.pendingStarRating, mainProfileTab: self.mainProfileTab, savedMusic: self.savedMusic)
|
||||
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, chatTheme: self.chatTheme, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: self.businessLocation, greetingMessage: self.greetingMessage, awayMessage: self.awayMessage, connectedBot: self.connectedBot, businessIntro: self.businessIntro, birthday: self.birthday, personalChannel: self.personalChannel, botPreview: self.botPreview, starGiftsCount: self.starGiftsCount, starRefProgram: self.starRefProgram, verification: self.verification, sendPaidMessageStars: self.sendPaidMessageStars, disallowedGifts: disallowedGifts, botGroupAdminRights: self.botGroupAdminRights, botChannelAdminRights: self.botChannelAdminRights, starRating: self.starRating, pendingStarRating: self.pendingStarRating, mainProfileTab: self.mainProfileTab, savedMusic: self.savedMusic, note: self.note)
|
||||
}
|
||||
|
||||
public func withUpdatedBotGroupAdminRights(_ botGroupAdminRights: TelegramChatAdminRights?) -> CachedUserData {
|
||||
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, chatTheme: self.chatTheme, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: self.businessLocation, greetingMessage: self.greetingMessage, awayMessage: self.awayMessage, connectedBot: self.connectedBot, businessIntro: self.businessIntro, birthday: self.birthday, personalChannel: self.personalChannel, botPreview: self.botPreview, starGiftsCount: self.starGiftsCount, starRefProgram: self.starRefProgram, verification: self.verification, sendPaidMessageStars: self.sendPaidMessageStars, disallowedGifts: disallowedGifts, botGroupAdminRights: botGroupAdminRights, botChannelAdminRights: self.botChannelAdminRights, starRating: self.starRating, pendingStarRating: self.pendingStarRating, mainProfileTab: self.mainProfileTab, savedMusic: self.savedMusic)
|
||||
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, chatTheme: self.chatTheme, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: self.businessLocation, greetingMessage: self.greetingMessage, awayMessage: self.awayMessage, connectedBot: self.connectedBot, businessIntro: self.businessIntro, birthday: self.birthday, personalChannel: self.personalChannel, botPreview: self.botPreview, starGiftsCount: self.starGiftsCount, starRefProgram: self.starRefProgram, verification: self.verification, sendPaidMessageStars: self.sendPaidMessageStars, disallowedGifts: disallowedGifts, botGroupAdminRights: botGroupAdminRights, botChannelAdminRights: self.botChannelAdminRights, starRating: self.starRating, pendingStarRating: self.pendingStarRating, mainProfileTab: self.mainProfileTab, savedMusic: self.savedMusic, note: self.note)
|
||||
}
|
||||
|
||||
public func withUpdatedBotChannelAdminRights(_ botChannelAdminRights: TelegramChatAdminRights?) -> CachedUserData {
|
||||
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, chatTheme: self.chatTheme, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: self.businessLocation, greetingMessage: self.greetingMessage, awayMessage: self.awayMessage, connectedBot: self.connectedBot, businessIntro: self.businessIntro, birthday: self.birthday, personalChannel: self.personalChannel, botPreview: self.botPreview, starGiftsCount: self.starGiftsCount, starRefProgram: self.starRefProgram, verification: self.verification, sendPaidMessageStars: self.sendPaidMessageStars, disallowedGifts: disallowedGifts, botGroupAdminRights: self.botGroupAdminRights, botChannelAdminRights: botChannelAdminRights, starRating: self.starRating, pendingStarRating: self.pendingStarRating, mainProfileTab: self.mainProfileTab, savedMusic: self.savedMusic)
|
||||
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, chatTheme: self.chatTheme, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: self.businessLocation, greetingMessage: self.greetingMessage, awayMessage: self.awayMessage, connectedBot: self.connectedBot, businessIntro: self.businessIntro, birthday: self.birthday, personalChannel: self.personalChannel, botPreview: self.botPreview, starGiftsCount: self.starGiftsCount, starRefProgram: self.starRefProgram, verification: self.verification, sendPaidMessageStars: self.sendPaidMessageStars, disallowedGifts: disallowedGifts, botGroupAdminRights: self.botGroupAdminRights, botChannelAdminRights: botChannelAdminRights, starRating: self.starRating, pendingStarRating: self.pendingStarRating, mainProfileTab: self.mainProfileTab, savedMusic: self.savedMusic, note: self.note)
|
||||
}
|
||||
|
||||
public func withUpdatedStarRating(_ starRating: TelegramStarRating?) -> CachedUserData {
|
||||
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, chatTheme: self.chatTheme, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: self.businessLocation, greetingMessage: self.greetingMessage, awayMessage: self.awayMessage, connectedBot: self.connectedBot, businessIntro: self.businessIntro, birthday: self.birthday, personalChannel: self.personalChannel, botPreview: self.botPreview, starGiftsCount: self.starGiftsCount, starRefProgram: self.starRefProgram, verification: self.verification, sendPaidMessageStars: self.sendPaidMessageStars, disallowedGifts: disallowedGifts, botGroupAdminRights: self.botGroupAdminRights, botChannelAdminRights: self.botChannelAdminRights, starRating: starRating, pendingStarRating: self.pendingStarRating, mainProfileTab: self.mainProfileTab, savedMusic: self.savedMusic)
|
||||
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, chatTheme: self.chatTheme, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: self.businessLocation, greetingMessage: self.greetingMessage, awayMessage: self.awayMessage, connectedBot: self.connectedBot, businessIntro: self.businessIntro, birthday: self.birthday, personalChannel: self.personalChannel, botPreview: self.botPreview, starGiftsCount: self.starGiftsCount, starRefProgram: self.starRefProgram, verification: self.verification, sendPaidMessageStars: self.sendPaidMessageStars, disallowedGifts: disallowedGifts, botGroupAdminRights: self.botGroupAdminRights, botChannelAdminRights: self.botChannelAdminRights, starRating: starRating, pendingStarRating: self.pendingStarRating, mainProfileTab: self.mainProfileTab, savedMusic: self.savedMusic, note: self.note)
|
||||
}
|
||||
|
||||
public func withUpdatedPendingStarRating(_ pendingStarRating: TelegramStarPendingRating?) -> CachedUserData {
|
||||
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, chatTheme: self.chatTheme, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: self.businessLocation, greetingMessage: self.greetingMessage, awayMessage: self.awayMessage, connectedBot: self.connectedBot, businessIntro: self.businessIntro, birthday: self.birthday, personalChannel: self.personalChannel, botPreview: self.botPreview, starGiftsCount: self.starGiftsCount, starRefProgram: self.starRefProgram, verification: self.verification, sendPaidMessageStars: self.sendPaidMessageStars, disallowedGifts: disallowedGifts, botGroupAdminRights: self.botGroupAdminRights, botChannelAdminRights: self.botChannelAdminRights, starRating: self.starRating, pendingStarRating: pendingStarRating, mainProfileTab: self.mainProfileTab, savedMusic: self.savedMusic)
|
||||
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, chatTheme: self.chatTheme, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: self.businessLocation, greetingMessage: self.greetingMessage, awayMessage: self.awayMessage, connectedBot: self.connectedBot, businessIntro: self.businessIntro, birthday: self.birthday, personalChannel: self.personalChannel, botPreview: self.botPreview, starGiftsCount: self.starGiftsCount, starRefProgram: self.starRefProgram, verification: self.verification, sendPaidMessageStars: self.sendPaidMessageStars, disallowedGifts: disallowedGifts, botGroupAdminRights: self.botGroupAdminRights, botChannelAdminRights: self.botChannelAdminRights, starRating: self.starRating, pendingStarRating: pendingStarRating, mainProfileTab: self.mainProfileTab, savedMusic: self.savedMusic, note: self.note)
|
||||
}
|
||||
|
||||
public func withUpdatedMainProfileTab(_ mainProfileTab: TelegramProfileTab?) -> CachedUserData {
|
||||
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, chatTheme: self.chatTheme, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: self.businessLocation, greetingMessage: self.greetingMessage, awayMessage: self.awayMessage, connectedBot: self.connectedBot, businessIntro: self.businessIntro, birthday: self.birthday, personalChannel: self.personalChannel, botPreview: self.botPreview, starGiftsCount: self.starGiftsCount, starRefProgram: self.starRefProgram, verification: self.verification, sendPaidMessageStars: self.sendPaidMessageStars, disallowedGifts: disallowedGifts, botGroupAdminRights: self.botGroupAdminRights, botChannelAdminRights: self.botChannelAdminRights, starRating: self.starRating, pendingStarRating: self.pendingStarRating, mainProfileTab: mainProfileTab, savedMusic: self.savedMusic)
|
||||
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, chatTheme: self.chatTheme, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: self.businessLocation, greetingMessage: self.greetingMessage, awayMessage: self.awayMessage, connectedBot: self.connectedBot, businessIntro: self.businessIntro, birthday: self.birthday, personalChannel: self.personalChannel, botPreview: self.botPreview, starGiftsCount: self.starGiftsCount, starRefProgram: self.starRefProgram, verification: self.verification, sendPaidMessageStars: self.sendPaidMessageStars, disallowedGifts: disallowedGifts, botGroupAdminRights: self.botGroupAdminRights, botChannelAdminRights: self.botChannelAdminRights, starRating: self.starRating, pendingStarRating: self.pendingStarRating, mainProfileTab: mainProfileTab, savedMusic: self.savedMusic, note: self.note)
|
||||
}
|
||||
|
||||
public func withUpdatedSavedMusic(_ savedMusic: TelegramMediaFile?) -> CachedUserData {
|
||||
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, chatTheme: self.chatTheme, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: self.businessLocation, greetingMessage: self.greetingMessage, awayMessage: self.awayMessage, connectedBot: self.connectedBot, businessIntro: self.businessIntro, birthday: self.birthday, personalChannel: self.personalChannel, botPreview: self.botPreview, starGiftsCount: self.starGiftsCount, starRefProgram: self.starRefProgram, verification: self.verification, sendPaidMessageStars: self.sendPaidMessageStars, disallowedGifts: disallowedGifts, botGroupAdminRights: self.botGroupAdminRights, botChannelAdminRights: self.botChannelAdminRights, starRating: self.starRating, pendingStarRating: self.pendingStarRating, mainProfileTab: self.mainProfileTab, savedMusic: savedMusic)
|
||||
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, chatTheme: self.chatTheme, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: self.businessLocation, greetingMessage: self.greetingMessage, awayMessage: self.awayMessage, connectedBot: self.connectedBot, businessIntro: self.businessIntro, birthday: self.birthday, personalChannel: self.personalChannel, botPreview: self.botPreview, starGiftsCount: self.starGiftsCount, starRefProgram: self.starRefProgram, verification: self.verification, sendPaidMessageStars: self.sendPaidMessageStars, disallowedGifts: disallowedGifts, botGroupAdminRights: self.botGroupAdminRights, botChannelAdminRights: self.botChannelAdminRights, starRating: self.starRating, pendingStarRating: self.pendingStarRating, mainProfileTab: self.mainProfileTab, savedMusic: savedMusic, note: self.note)
|
||||
}
|
||||
|
||||
public func withUpdatedNote(_ note: Note?) -> CachedUserData {
|
||||
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, chatTheme: self.chatTheme, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: self.businessLocation, greetingMessage: self.greetingMessage, awayMessage: self.awayMessage, connectedBot: self.connectedBot, businessIntro: self.businessIntro, birthday: self.birthday, personalChannel: self.personalChannel, botPreview: self.botPreview, starGiftsCount: self.starGiftsCount, starRefProgram: self.starRefProgram, verification: self.verification, sendPaidMessageStars: self.sendPaidMessageStars, disallowedGifts: disallowedGifts, botGroupAdminRights: self.botGroupAdminRights, botChannelAdminRights: self.botChannelAdminRights, starRating: self.starRating, pendingStarRating: self.pendingStarRating, mainProfileTab: self.mainProfileTab, savedMusic: self.savedMusic, note: note)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -254,6 +254,7 @@ public enum TelegramMediaActionType: PostboxCoding, Equatable {
|
|||
case giftTon(currency: String, amount: Int64, cryptoCurrency: String?, cryptoAmount: Int64?, transactionId: String?)
|
||||
case suggestedPostSuccess(amount: CurrencyAmount)
|
||||
case suggestedPostRefund(SuggestedPostRefund)
|
||||
case suggestedBirthday(TelegramBirthday)
|
||||
|
||||
public init(decoder: PostboxDecoder) {
|
||||
let rawValue: Int32 = decoder.decodeInt32ForKey("_rawValue", orElse: 0)
|
||||
|
|
@ -419,6 +420,8 @@ public enum TelegramMediaActionType: PostboxCoding, Equatable {
|
|||
self = .suggestedPostSuccess(amount: decoder.decodeCodable(CurrencyAmount.self, forKey: "amt") ?? CurrencyAmount(amount: .zero, currency: .stars))
|
||||
case 54:
|
||||
self = .suggestedPostRefund(decoder.decodeCodable(SuggestedPostRefund.self, forKey: "s") ?? SuggestedPostRefund(isUserInitiated: true))
|
||||
case 55:
|
||||
self = .suggestedBirthday(decoder.decodeCodable(TelegramBirthday.self, forKey: "birthday") ?? TelegramBirthday(day: 1, month: 1, year: nil))
|
||||
default:
|
||||
self = .unknown
|
||||
}
|
||||
|
|
@ -874,6 +877,9 @@ public enum TelegramMediaActionType: PostboxCoding, Equatable {
|
|||
case let .suggestedPostRefund(status):
|
||||
encoder.encodeInt32(54, forKey: "_rawValue")
|
||||
encoder.encodeCodable(status, forKey: "s")
|
||||
case let .suggestedBirthday(birthday):
|
||||
encoder.encodeInt32(55, forKey: "_rawValue")
|
||||
encoder.encodeCodable(birthday, forKey: "birthday")
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -64,17 +64,21 @@ func _internal_updateNameColorAndEmoji(account: Account, nameColor: PeerNameColo
|
|||
|> switchToLatest
|
||||
|> castError(UpdateNameColorAndEmojiError.self)
|
||||
|> mapToSignal { _ -> Signal<Void, UpdateNameColorAndEmojiError> in
|
||||
let flagsReplies: Int32 = (1 << 0) | (1 << 2)
|
||||
|
||||
var flagsProfile: Int32 = (1 << 0) | (1 << 1)
|
||||
if profileColor != nil {
|
||||
flagsProfile |= (1 << 2)
|
||||
var flagsReplies: Int32 = (1 << 0)
|
||||
if let _ = backgroundEmojiId {
|
||||
flagsReplies |= (1 << 1)
|
||||
}
|
||||
|
||||
//TODO:release
|
||||
var flagsProfile: Int32 = 0
|
||||
if let _ = profileColor {
|
||||
flagsProfile |= (1 << 0)
|
||||
}
|
||||
if let _ = profileBackgroundEmojiId {
|
||||
flagsProfile |= (1 << 1)
|
||||
}
|
||||
|
||||
return combineLatest(
|
||||
account.network.request(Api.functions.account.updateColor(flags: 0 << 0, color: .peerColor(flags: flagsReplies, color: nameColor.rawValue, backgroundEmojiId: backgroundEmojiId ?? 0))),
|
||||
account.network.request(Api.functions.account.updateColor(flags: 0 << 1, color: .peerColor(flags: flagsProfile, color: profileColor?.rawValue, backgroundEmojiId: profileBackgroundEmojiId ?? 0)))
|
||||
account.network.request(Api.functions.account.updateColor(flags: (1 << 2), color: .peerColor(flags: flagsReplies, color: nameColor.rawValue, backgroundEmojiId: backgroundEmojiId))),
|
||||
account.network.request(Api.functions.account.updateColor(flags: (1 << 1) | (1 << 2), color: .peerColor(flags: flagsProfile, color: profileColor?.rawValue ?? 0, backgroundEmojiId: profileBackgroundEmojiId)))
|
||||
)
|
||||
|> mapError { _ -> UpdateNameColorAndEmojiError in
|
||||
return .generic
|
||||
|
|
|
|||
|
|
@ -3395,12 +3395,16 @@ public final class GroupCallMessagesContext {
|
|||
public let author: EnginePeer?
|
||||
public let text: String
|
||||
public let entities: [MessageTextEntity]
|
||||
public let date: Int32
|
||||
public let lifetime: Int32
|
||||
|
||||
public init(id: Int64, author: EnginePeer?, text: String, entities: [MessageTextEntity]) {
|
||||
public init(id: Int64, author: EnginePeer?, text: String, entities: [MessageTextEntity], date: Int32, lifetime: Int32) {
|
||||
self.id = id
|
||||
self.author = author
|
||||
self.text = text
|
||||
self.entities = entities
|
||||
self.date = date
|
||||
self.lifetime = lifetime
|
||||
}
|
||||
|
||||
public static func ==(lhs: Message, rhs: Message) -> Bool {
|
||||
|
|
@ -3419,6 +3423,12 @@ public final class GroupCallMessagesContext {
|
|||
if lhs.entities != rhs.entities {
|
||||
return false
|
||||
}
|
||||
if lhs.date != rhs.date {
|
||||
return false
|
||||
}
|
||||
if lhs.lifetime != rhs.lifetime {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
|
@ -3432,6 +3442,8 @@ public final class GroupCallMessagesContext {
|
|||
}
|
||||
|
||||
private final class Impl {
|
||||
private let defaultMessageLifetime: Int32 = 10
|
||||
|
||||
let queue: Queue
|
||||
let account: Account
|
||||
let callId: Int64
|
||||
|
|
@ -3450,6 +3462,8 @@ public final class GroupCallMessagesContext {
|
|||
var updatesDisposable: Disposable?
|
||||
let sendMessageDisposables = DisposableSet()
|
||||
|
||||
private var messageLifeTimer: SwiftSignalKit.Timer?
|
||||
|
||||
init(queue: Queue, account: Account, callId: Int64, reference: InternalGroupCallReference, e2eContext: ConferenceCallE2EContext?) {
|
||||
self.queue = queue
|
||||
self.account = account
|
||||
|
|
@ -3465,6 +3479,7 @@ public final class GroupCallMessagesContext {
|
|||
guard let self else {
|
||||
return
|
||||
}
|
||||
let currentTime = Int32(CFAbsoluteTimeGetCurrent())
|
||||
var addedMessages: [(authorId: PeerId, text: String, entities: [MessageTextEntity])] = []
|
||||
var addedOpaqueMessages: [(authorId: PeerId, data: Data)] = []
|
||||
for update in updates {
|
||||
|
|
@ -3506,28 +3521,40 @@ public final class GroupCallMessagesContext {
|
|||
guard let decryptedMessage else {
|
||||
continue
|
||||
}
|
||||
guard let text = String(data: decryptedMessage, encoding: .utf8) else {
|
||||
continue
|
||||
let buffer = Buffer(data: decryptedMessage)
|
||||
let bufferReader = BufferReader(buffer)
|
||||
if bufferReader.readInt32() == 1964978502 {
|
||||
if let textWithEntities = Api.TextWithEntities.parse_textWithEntities(bufferReader) {
|
||||
switch textWithEntities {
|
||||
case let .textWithEntities(text, entities):
|
||||
let messageId = self.nextId
|
||||
self.nextId += 1
|
||||
messages.append(Message(
|
||||
id: messageId,
|
||||
author: transaction.getPeer(addedOpaqueMessage.authorId).flatMap(EnginePeer.init),
|
||||
text: text,
|
||||
entities: messageTextEntitiesFromApiEntities(entities),
|
||||
date: currentTime,
|
||||
lifetime: self.defaultMessageLifetime
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let messageId = self.nextId
|
||||
self.nextId += 1
|
||||
messages.append(Message(
|
||||
id: messageId,
|
||||
author: transaction.getPeer(addedOpaqueMessage.authorId).flatMap(EnginePeer.init),
|
||||
text: text,
|
||||
entities: []
|
||||
))
|
||||
}
|
||||
} else {
|
||||
for addedMessage in addedMessages {
|
||||
if addedMessage.authorId == account.peerId {
|
||||
continue
|
||||
}
|
||||
let messageId = self.nextId
|
||||
self.nextId += 1
|
||||
messages.append(Message(
|
||||
id: messageId,
|
||||
author: transaction.getPeer(addedMessage.authorId).flatMap(EnginePeer.init),
|
||||
text: addedMessage.text,
|
||||
entities: addedMessage.entities
|
||||
entities: addedMessage.entities,
|
||||
date: currentTime,
|
||||
lifetime: self.defaultMessageLifetime
|
||||
))
|
||||
}
|
||||
}
|
||||
|
|
@ -3543,11 +3570,28 @@ public final class GroupCallMessagesContext {
|
|||
})
|
||||
}
|
||||
})
|
||||
|
||||
let timer = SwiftSignalKit.Timer(timeout: 1.0, repeat: true, completion: { [weak self] in
|
||||
self?.messageLifetimeTick()
|
||||
}, queue: self.queue)
|
||||
self.messageLifeTimer = timer
|
||||
timer.start()
|
||||
}
|
||||
|
||||
deinit {
|
||||
self.updatesDisposable?.dispose()
|
||||
self.sendMessageDisposables.dispose()
|
||||
self.messageLifeTimer?.invalidate()
|
||||
}
|
||||
|
||||
private func messageLifetimeTick() {
|
||||
let now = Int32(CFAbsoluteTimeGetCurrent())
|
||||
let filtered = self.state.messages.filter { now - $0.date < $0.lifetime }
|
||||
if filtered.count != self.state.messages.count {
|
||||
var state = self.state
|
||||
state.messages = filtered
|
||||
self.state = state
|
||||
}
|
||||
}
|
||||
|
||||
func send(text: String, entities: [MessageTextEntity]) {
|
||||
|
|
@ -3559,6 +3603,7 @@ public final class GroupCallMessagesContext {
|
|||
guard let self else {
|
||||
return
|
||||
}
|
||||
let currentTime = Int32(CFAbsoluteTimeGetCurrent())
|
||||
|
||||
let messageId = self.nextId
|
||||
self.nextId += 1
|
||||
|
|
@ -3568,12 +3613,16 @@ public final class GroupCallMessagesContext {
|
|||
id: messageId,
|
||||
author: accountPeer.flatMap(EnginePeer.init),
|
||||
text: text,
|
||||
entities: entities
|
||||
entities: entities,
|
||||
date: currentTime,
|
||||
lifetime: self.defaultMessageLifetime
|
||||
))
|
||||
self.state = state
|
||||
|
||||
if let e2eContext = self.e2eContext {
|
||||
let messageData = text.data(using: .utf8)!
|
||||
let buffer = Buffer()
|
||||
Api.TextWithEntities.textWithEntities(text: text, entities: apiEntitiesFromMessageTextEntities(entities, associatedPeers: SimpleDictionary())).serialize(buffer, true)
|
||||
let messageData = buffer.makeData()
|
||||
let encryptedMessage = e2eContext.state.with({ state -> Data? in
|
||||
guard let state = state.state else {
|
||||
return nil
|
||||
|
|
|
|||
|
|
@ -34,6 +34,10 @@ public extension TelegramEngine {
|
|||
return _internal_updateContactPhoto(account: self.account, peerId: peerId, resource: resource, videoResource: videoResource, videoStartTimestamp: videoStartTimestamp, markup: markup, mode: mode, mapResourceToAvatarSizes: mapResourceToAvatarSizes)
|
||||
}
|
||||
|
||||
public func updateContactNote(peerId: PeerId, text: String, entities: [MessageTextEntity]) -> Signal<Never, UpdateContactNoteError> {
|
||||
return _internal_updateContactNote(account: self.account, peerId: peerId, text: text, entities: entities)
|
||||
}
|
||||
|
||||
public func deviceContactsImportedByCount(contacts: [(String, [DeviceContactNormalizedPhoneNumber])]) -> Signal<[String: Int32], NoError> {
|
||||
return _internal_deviceContactsImportedByCount(postbox: self.account.postbox, contacts: contacts)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,3 +27,32 @@ func _internal_updateContactName(account: Account, peerId: PeerId, firstName: St
|
|||
|> mapError { _ -> UpdateContactNameError in }
|
||||
|> switchToLatest
|
||||
}
|
||||
|
||||
public enum UpdateContactNoteError {
|
||||
case generic
|
||||
}
|
||||
|
||||
func _internal_updateContactNote(account: Account, peerId: PeerId, text: String, entities: [MessageTextEntity]) -> Signal<Never, UpdateContactNoteError> {
|
||||
return account.postbox.transaction { transaction -> Signal<Void, UpdateContactNoteError> in
|
||||
if let peer = transaction.getPeer(peerId) as? TelegramUser, let inputUser = apiInputUser(peer) {
|
||||
return account.network.request(Api.functions.contacts.updateContactNote(id: inputUser, note: .textWithEntities(text: text, entities: apiEntitiesFromMessageTextEntities(entities, associatedPeers: SimpleDictionary()))))
|
||||
|> mapError { _ -> UpdateContactNoteError in
|
||||
return .generic
|
||||
}
|
||||
|> mapToSignal { result -> Signal<Void, UpdateContactNoteError> in
|
||||
return account.postbox.transaction { transaction in
|
||||
transaction.updatePeerCachedData(peerIds: Set([peerId]), update: { peerId, cachedData in
|
||||
let cachedData = cachedData as? CachedUserData ?? CachedUserData()
|
||||
return cachedData.withUpdatedNote(!text.isEmpty ? CachedUserData.Note(text: text, entities: entities) : nil)
|
||||
})
|
||||
}
|
||||
|> castError(UpdateContactNoteError.self)
|
||||
}
|
||||
} else {
|
||||
return .fail(.generic)
|
||||
}
|
||||
}
|
||||
|> mapError { _ -> UpdateContactNoteError in }
|
||||
|> switchToLatest
|
||||
|> ignoreValues
|
||||
}
|
||||
|
|
|
|||
|
|
@ -529,13 +529,12 @@ private class AdMessagesHistoryContextImpl {
|
|||
|
||||
var nameColorIndex: Int32?
|
||||
var backgroundEmojiId: Int64?
|
||||
if let color = color {
|
||||
if let color {
|
||||
switch color {
|
||||
case let .peerColor(_, color, backgroundEmojiIdValue):
|
||||
nameColorIndex = color
|
||||
backgroundEmojiId = backgroundEmojiIdValue
|
||||
case .peerColorCollectible, .inputPeerColorCollectible:
|
||||
//TODO:release
|
||||
default:
|
||||
break
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -320,6 +320,7 @@ public enum StarGift: Equatable, Codable, PostboxCoding {
|
|||
case valueCurrency
|
||||
case flags
|
||||
case themePeerId
|
||||
case peerColor
|
||||
}
|
||||
|
||||
public struct Flags: OptionSet {
|
||||
|
|
@ -958,7 +959,8 @@ extension StarGift {
|
|||
return nil
|
||||
}
|
||||
self = .generic(StarGift.Gift(id: id, title: title, file: file, price: stars, convertStars: convertStars, availability: availability, soldOut: soldOut, flags: flags, upgradeStars: upgradeStars, releasedBy: releasedBy?.peerId, perUserLimit: perUserLimit, lockedUntilDate: lockedUntilDate))
|
||||
case let .starGiftUnique(apiFlags, id, giftId, title, slug, num, ownerPeerId, ownerName, ownerAddress, attributes, availabilityIssued, availabilityTotal, giftAddress, resellAmounts, releasedBy, valueAmount, valueCurrency, themePeer, _):
|
||||
case let .starGiftUnique(apiFlags, id, giftId, title, slug, num, ownerPeerId, ownerName, ownerAddress, attributes, availabilityIssued, availabilityTotal, giftAddress, resellAmounts, releasedBy, valueAmount, valueCurrency, themePeer, peerColor):
|
||||
let _ = peerColor
|
||||
let owner: StarGift.UniqueGift.Owner
|
||||
if let ownerAddress {
|
||||
owner = .address(ownerAddress)
|
||||
|
|
|
|||
|
|
@ -384,54 +384,20 @@ func channelAdminLogEvents(accountPeerId: PeerId, postbox: Postbox, network: Net
|
|||
case let .channelAdminLogEventActionToggleAntiSpam(newValue):
|
||||
action = .toggleAntiSpam(isEnabled: newValue == .boolTrue)
|
||||
case let .channelAdminLogEventActionChangePeerColor(prevValue, newValue):
|
||||
var prevColorIndex: Int32
|
||||
var prevEmojiId: Int64?
|
||||
switch prevValue {
|
||||
case let .peerColor(_, color, backgroundEmojiIdValue):
|
||||
prevColorIndex = color ?? 0
|
||||
prevEmojiId = backgroundEmojiIdValue
|
||||
case .peerColorCollectible, .inputPeerColorCollectible:
|
||||
//TODO:release
|
||||
prevColorIndex = 0
|
||||
break
|
||||
guard case let .peerColor(_, prevColor, prevBackgroundEmojiIdValue) = prevValue, case let .peerColor(_, newColor, newBackgroundEmojiIdValue) = newValue else {
|
||||
continue
|
||||
}
|
||||
let prevColorIndex = prevColor ?? 0
|
||||
let prevEmojiId = prevBackgroundEmojiIdValue
|
||||
|
||||
var newColorIndex: Int32
|
||||
var newEmojiId: Int64?
|
||||
switch newValue {
|
||||
case let .peerColor(_, color, backgroundEmojiIdValue):
|
||||
newColorIndex = color ?? 0
|
||||
newEmojiId = backgroundEmojiIdValue
|
||||
case .peerColorCollectible, .inputPeerColorCollectible:
|
||||
//TODO:release
|
||||
newColorIndex = 0
|
||||
break
|
||||
}
|
||||
let newColorIndex = newColor ?? 0
|
||||
let newEmojiId = newBackgroundEmojiIdValue
|
||||
|
||||
action = .changeNameColor(prevColor: PeerNameColor(rawValue: prevColorIndex), prevIcon: prevEmojiId, newColor: PeerNameColor(rawValue: newColorIndex), newIcon: newEmojiId)
|
||||
case let .channelAdminLogEventActionChangeProfilePeerColor(prevValue, newValue):
|
||||
var prevColorIndex: Int32?
|
||||
var prevEmojiId: Int64?
|
||||
switch prevValue {
|
||||
case let .peerColor(_, color, backgroundEmojiIdValue):
|
||||
prevColorIndex = color
|
||||
prevEmojiId = backgroundEmojiIdValue
|
||||
case .peerColorCollectible, .inputPeerColorCollectible:
|
||||
//TODO:release
|
||||
break
|
||||
guard case let .peerColor(_, prevColorIndex, prevEmojiId) = prevValue, case let .peerColor(_, newColorIndex, newEmojiId) = newValue else {
|
||||
continue
|
||||
}
|
||||
|
||||
var newColorIndex: Int32?
|
||||
var newEmojiId: Int64?
|
||||
switch newValue {
|
||||
case let .peerColor(_, color, backgroundEmojiIdValue):
|
||||
newColorIndex = color
|
||||
newEmojiId = backgroundEmojiIdValue
|
||||
case .peerColorCollectible, .inputPeerColorCollectible:
|
||||
//TODO:release
|
||||
break
|
||||
}
|
||||
|
||||
action = .changeProfileColor(prevColor: prevColorIndex.flatMap(PeerNameColor.init(rawValue:)), prevIcon: prevEmojiId, newColor: newColorIndex.flatMap(PeerNameColor.init(rawValue:)), newIcon: newEmojiId)
|
||||
case let .channelAdminLogEventActionChangeWallpaper(prevValue, newValue):
|
||||
let prev: TelegramWallpaper?
|
||||
|
|
|
|||
|
|
@ -0,0 +1,27 @@
|
|||
import Foundation
|
||||
import Postbox
|
||||
import SwiftSignalKit
|
||||
import TelegramApi
|
||||
import MtProtoKit
|
||||
|
||||
public enum SuggestBirthdayError {
|
||||
case generic
|
||||
}
|
||||
|
||||
func _internal_suggestBirthday(account: Account, peerId: EnginePeer.Id, birthday: TelegramBirthday) -> Signal<Never, SuggestBirthdayError> {
|
||||
return account.postbox.loadedPeerWithId(peerId)
|
||||
|> castError(SuggestBirthdayError.self)
|
||||
|> mapToSignal { peer in
|
||||
guard let inputUser = apiInputUser(peer) else {
|
||||
return .complete()
|
||||
}
|
||||
return account.network.request(Api.functions.users.suggestBirthday(id: inputUser, birthday: birthday.apiBirthday))
|
||||
|> mapError { _ in
|
||||
return .generic
|
||||
}
|
||||
|> mapToSignal { updates in
|
||||
account.stateManager.addUpdates(updates)
|
||||
return .complete()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -923,6 +923,10 @@ public extension TelegramEngine {
|
|||
public func removeSavedMusic(file: FileMediaReference) -> Signal<Never, NoError> {
|
||||
return _internal_removeSavedMusic(account: self.account, file: file)
|
||||
}
|
||||
|
||||
public func suggestBirthday(peerId: EnginePeer.Id, birthday: TelegramBirthday) -> Signal<Never, SuggestBirthdayError> {
|
||||
return _internal_suggestBirthday(account: self.account, peerId: peerId, birthday: birthday)
|
||||
}
|
||||
|
||||
public func getNextUnreadChannel(peerId: PeerId, chatListFilterId: Int32?, getFilterPredicate: @escaping (ChatListFilterData) -> ChatListFilterPredicate) -> Signal<(peer: EnginePeer, unreadCount: Int, location: NextUnreadChannelLocation)?, NoError> {
|
||||
let startTime = CFAbsoluteTimeGetCurrent()
|
||||
|
|
|
|||
|
|
@ -277,7 +277,7 @@ func _internal_fetchAndUpdateCachedPeerData(accountPeerId: PeerId, peerId rawPee
|
|||
previous = CachedUserData()
|
||||
}
|
||||
switch fullUser {
|
||||
case let .userFull(userFullFlags, userFullFlags2, _, userFullAbout, userFullSettings, personalPhoto, profilePhoto, fallbackPhoto, _, userFullBotInfo, userFullPinnedMsgId, userFullCommonChatsCount, _, userFullTtlPeriod, userFullChatTheme, _, groupAdminRights, channelAdminRights, userWallpaper, _, businessWorkHours, businessLocation, greetingMessage, awayMessage, businessIntro, birthday, personalChannelId, personalChannelMessage, starGiftsCount, starRefProgram, verification, sendPaidMessageStars, disallowedStarGifts, starsRating, starsMyPendingRating, starsMyPendingRatingDate, mainTab, savedMusic, _):
|
||||
case let .userFull(userFullFlags, userFullFlags2, _, userFullAbout, userFullSettings, personalPhoto, profilePhoto, fallbackPhoto, _, userFullBotInfo, userFullPinnedMsgId, userFullCommonChatsCount, _, userFullTtlPeriod, userFullChatTheme, _, groupAdminRights, channelAdminRights, userWallpaper, _, businessWorkHours, businessLocation, greetingMessage, awayMessage, businessIntro, birthday, personalChannelId, personalChannelMessage, starGiftsCount, starRefProgram, verification, sendPaidMessageStars, disallowedStarGifts, starsRating, starsMyPendingRating, starsMyPendingRatingDate, mainTab, savedMusic, note):
|
||||
let botInfo = userFullBotInfo.flatMap(BotInfo.init(apiBotInfo:))
|
||||
let isBlocked = (userFullFlags & (1 << 0)) != 0
|
||||
let voiceCallsAvailable = (userFullFlags & (1 << 4)) != 0
|
||||
|
|
@ -436,6 +436,14 @@ func _internal_fetchAndUpdateCachedPeerData(accountPeerId: PeerId, peerId rawPee
|
|||
|
||||
let mappedChatTheme: ChatTheme? = userFullChatTheme.flatMap { ChatTheme(apiChatTheme: $0) }
|
||||
|
||||
var mappedNote: CachedUserData.Note?
|
||||
if let note {
|
||||
switch note {
|
||||
case let .textWithEntities(text, entities):
|
||||
mappedNote = CachedUserData.Note(text: text, entities: messageTextEntitiesFromApiEntities(entities))
|
||||
}
|
||||
}
|
||||
|
||||
return previous.withUpdatedAbout(userFullAbout)
|
||||
.withUpdatedBotInfo(botInfo)
|
||||
.withUpdatedEditableBotInfo(editableBotInfo)
|
||||
|
|
@ -476,6 +484,7 @@ func _internal_fetchAndUpdateCachedPeerData(accountPeerId: PeerId, peerId rawPee
|
|||
.withUpdatedPendingStarRating(pendingRating)
|
||||
.withUpdatedMainProfileTab(mappedMainProfileTab)
|
||||
.withUpdatedSavedMusic(mappedSavedMusic)
|
||||
.withUpdatedNote(mappedNote)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1011,6 +1011,9 @@ public func universalServiceMessageString(presentationData: (PresentationTheme,
|
|||
} else {
|
||||
attributedString = NSAttributedString(string: strings.Notification_SuggestedProfileVideo, font: titleFont, textColor: primaryTextColor)
|
||||
}
|
||||
case let .suggestedBirthday(birthday):
|
||||
let _ = birthday
|
||||
attributedString = NSAttributedString(string: strings.Notification_SuggestBirthdate, font: titleFont, textColor: primaryTextColor)
|
||||
case .attachMenuBotAllowed:
|
||||
attributedString = NSAttributedString(string: strings.Notification_BotWriteAllowed, font: titleFont, textColor: primaryTextColor)
|
||||
case let .requestedPeer(_, peerIds):
|
||||
|
|
|
|||
|
|
@ -0,0 +1,34 @@
|
|||
load("@build_bazel_rules_swift//swift:swift.bzl", "swift_library")
|
||||
|
||||
swift_library(
|
||||
name = "ChatMessageBirthdateSuggestionContentNode",
|
||||
module_name = "ChatMessageBirthdateSuggestionContentNode",
|
||||
srcs = glob([
|
||||
"Sources/**/*.swift",
|
||||
]),
|
||||
copts = [
|
||||
"-warnings-as-errors",
|
||||
],
|
||||
deps = [
|
||||
"//submodules/AsyncDisplayKit",
|
||||
"//submodules/Display",
|
||||
"//submodules/SSignalKit/SwiftSignalKit",
|
||||
"//submodules/Postbox",
|
||||
"//submodules/TelegramCore",
|
||||
"//submodules/AccountContext",
|
||||
"//submodules/TelegramPresentationData",
|
||||
"//submodules/TelegramUIPreferences",
|
||||
"//submodules/TextFormat",
|
||||
"//submodules/LocalizedPeerData",
|
||||
"//submodules/TelegramStringFormatting",
|
||||
"//submodules/WallpaperBackgroundNode",
|
||||
"//submodules/ReactionSelectionNode",
|
||||
"//submodules/Markdown",
|
||||
"//submodules/TelegramUI/Components/Chat/ChatMessageBubbleContentNode",
|
||||
"//submodules/TelegramUI/Components/Chat/ChatMessageItemCommon",
|
||||
"//submodules/TelegramUI/Components/ChatControllerInteraction",
|
||||
],
|
||||
visibility = [
|
||||
"//visibility:public",
|
||||
],
|
||||
)
|
||||
|
|
@ -0,0 +1,390 @@
|
|||
import Foundation
|
||||
import UIKit
|
||||
import AsyncDisplayKit
|
||||
import Display
|
||||
import SwiftSignalKit
|
||||
import Postbox
|
||||
import TelegramCore
|
||||
import AccountContext
|
||||
import TelegramPresentationData
|
||||
import TelegramUIPreferences
|
||||
import TextFormat
|
||||
import TelegramStringFormatting
|
||||
import WallpaperBackgroundNode
|
||||
import Markdown
|
||||
import ChatMessageBubbleContentNode
|
||||
import ChatMessageItemCommon
|
||||
import ChatControllerInteraction
|
||||
import AnimatedStickerNode
|
||||
import TelegramAnimatedStickerNode
|
||||
|
||||
public class ChatMessageBirthdateSuggestionContentNode: ChatMessageBubbleContentNode {
|
||||
private var mediaBackgroundContent: WallpaperBubbleBackgroundNode?
|
||||
private let mediaBackgroundNode: NavigationBackgroundNode
|
||||
|
||||
private let animationNode: AnimatedStickerNode
|
||||
|
||||
private let subtitleNode: TextNode
|
||||
|
||||
private let dayTitleNode: TextNode
|
||||
private let dayValueNode: TextNode
|
||||
|
||||
private let monthTitleNode: TextNode
|
||||
private let monthValueNode: TextNode
|
||||
|
||||
private let yearTitleNode: TextNode
|
||||
private let yearValueNode: TextNode
|
||||
|
||||
private let buttonNode: HighlightTrackingButtonNode
|
||||
private let buttonTitleNode: TextNode
|
||||
|
||||
private var absoluteRect: (CGRect, CGSize)?
|
||||
|
||||
required public init() {
|
||||
self.mediaBackgroundNode = NavigationBackgroundNode(color: .clear)
|
||||
self.mediaBackgroundNode.clipsToBounds = true
|
||||
self.mediaBackgroundNode.cornerRadius = 27.0
|
||||
|
||||
self.animationNode = DefaultAnimatedStickerNodeImpl()
|
||||
|
||||
self.subtitleNode = TextNode()
|
||||
self.subtitleNode.isUserInteractionEnabled = false
|
||||
self.subtitleNode.displaysAsynchronously = false
|
||||
|
||||
self.dayTitleNode = TextNode()
|
||||
self.dayTitleNode.isUserInteractionEnabled = false
|
||||
self.dayTitleNode.displaysAsynchronously = false
|
||||
|
||||
self.dayValueNode = TextNode()
|
||||
self.dayValueNode.isUserInteractionEnabled = false
|
||||
self.dayValueNode.displaysAsynchronously = false
|
||||
|
||||
self.monthTitleNode = TextNode()
|
||||
self.monthTitleNode.isUserInteractionEnabled = false
|
||||
self.monthTitleNode.displaysAsynchronously = false
|
||||
|
||||
self.monthValueNode = TextNode()
|
||||
self.monthValueNode.isUserInteractionEnabled = false
|
||||
self.monthValueNode.displaysAsynchronously = false
|
||||
|
||||
self.yearTitleNode = TextNode()
|
||||
self.yearTitleNode.isUserInteractionEnabled = false
|
||||
self.yearTitleNode.displaysAsynchronously = false
|
||||
|
||||
self.yearValueNode = TextNode()
|
||||
self.yearValueNode.isUserInteractionEnabled = false
|
||||
self.yearValueNode.displaysAsynchronously = false
|
||||
|
||||
self.buttonNode = HighlightTrackingButtonNode()
|
||||
self.buttonNode.clipsToBounds = true
|
||||
self.buttonNode.cornerRadius = 17.0
|
||||
|
||||
self.buttonTitleNode = TextNode()
|
||||
self.buttonTitleNode.isUserInteractionEnabled = false
|
||||
self.buttonTitleNode.displaysAsynchronously = false
|
||||
|
||||
super.init()
|
||||
|
||||
self.addSubnode(self.mediaBackgroundNode)
|
||||
|
||||
self.addSubnode(self.animationNode)
|
||||
|
||||
self.addSubnode(self.subtitleNode)
|
||||
|
||||
self.addSubnode(self.dayTitleNode)
|
||||
self.addSubnode(self.dayValueNode)
|
||||
|
||||
self.addSubnode(self.monthTitleNode)
|
||||
self.addSubnode(self.monthValueNode)
|
||||
|
||||
self.addSubnode(self.yearTitleNode)
|
||||
self.addSubnode(self.yearValueNode)
|
||||
|
||||
self.addSubnode(self.buttonNode)
|
||||
self.addSubnode(self.buttonTitleNode)
|
||||
|
||||
self.buttonNode.highligthedChanged = { [weak self] highlighted in
|
||||
if let strongSelf = self {
|
||||
if highlighted {
|
||||
strongSelf.buttonNode.layer.removeAnimation(forKey: "opacity")
|
||||
strongSelf.buttonNode.alpha = 0.4
|
||||
strongSelf.buttonTitleNode.layer.removeAnimation(forKey: "opacity")
|
||||
strongSelf.buttonTitleNode.alpha = 0.4
|
||||
} else {
|
||||
strongSelf.buttonNode.alpha = 1.0
|
||||
strongSelf.buttonNode.layer.animateAlpha(from: 0.4, to: 1.0, duration: 0.2)
|
||||
strongSelf.buttonTitleNode.alpha = 1.0
|
||||
strongSelf.buttonTitleNode.layer.animateAlpha(from: 0.4, to: 1.0, duration: 0.2)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
self.buttonNode.addTarget(self, action: #selector(self.buttonPressed), forControlEvents: .touchUpInside)
|
||||
}
|
||||
|
||||
required public init?(coder aDecoder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
@objc private func buttonPressed() {
|
||||
guard let item = self.item else {
|
||||
return
|
||||
}
|
||||
let _ = item.controllerInteraction.openMessage(item.message, OpenMessageParams(mode: .default))
|
||||
}
|
||||
|
||||
override public func asyncLayoutContent() -> (_ item: ChatMessageBubbleContentItem, _ layoutConstants: ChatMessageItemLayoutConstants, _ preparePosition: ChatMessageBubblePreparePosition, _ messageSelection: Bool?, _ constrainedSize: CGSize, _ avatarInset: CGFloat) -> (ChatMessageBubbleContentProperties, unboundSize: CGSize?, maxWidth: CGFloat, layout: (CGSize, ChatMessageBubbleContentPosition) -> (CGFloat, (CGFloat) -> (CGSize, (ListViewItemUpdateAnimation, Bool, ListViewItemApply?) -> Void))) {
|
||||
let makeSubtitleLayout = TextNode.asyncLayout(self.subtitleNode)
|
||||
|
||||
let makeDayTitleLayout = TextNode.asyncLayout(self.dayTitleNode)
|
||||
let makeDayValueLayout = TextNode.asyncLayout(self.dayValueNode)
|
||||
let makeMonthTitleLayout = TextNode.asyncLayout(self.monthTitleNode)
|
||||
let makeMonthValueLayout = TextNode.asyncLayout(self.monthValueNode)
|
||||
let makeYearTitleLayout = TextNode.asyncLayout(self.yearTitleNode)
|
||||
let makeYearValueLayout = TextNode.asyncLayout(self.yearValueNode)
|
||||
|
||||
let makeButtonTitleLayout = TextNode.asyncLayout(self.buttonTitleNode)
|
||||
|
||||
return { item, layoutConstants, _, _, _, _ in
|
||||
let contentProperties = ChatMessageBubbleContentProperties(hidesSimpleAuthorHeader: true, headerSpacing: 0.0, hidesBackground: .always, forceFullCorners: false, forceAlignment: .center)
|
||||
|
||||
return (contentProperties, nil, CGFloat.greatestFiniteMagnitude, { constrainedSize, position in
|
||||
let width: CGFloat = 186.0
|
||||
|
||||
var day: Int32 = 1
|
||||
var month: Int32 = 1
|
||||
var year: Int32?
|
||||
|
||||
if let action = item.message.media.first(where: { $0 is TelegramMediaAction }) as? TelegramMediaAction, case let .suggestedBirthday(birthday) = action.action {
|
||||
day = birthday.day
|
||||
month = birthday.month
|
||||
year = birthday.year
|
||||
}
|
||||
|
||||
let primaryTextColor = serviceMessageColorComponents(theme: item.presentationData.theme.theme, wallpaper: item.presentationData.theme.wallpaper).primaryText
|
||||
let subtitleColor = primaryTextColor.withAlphaComponent(item.presentationData.theme.theme.overallDarkAppearance ? 0.7 : 0.8)
|
||||
|
||||
let peerName = item.message.peers[item.message.id.peerId].flatMap { EnginePeer($0).compactDisplayTitle } ?? ""
|
||||
let text: String
|
||||
|
||||
let fromYou = item.message.author?.id == item.context.account.peerId
|
||||
if fromYou {
|
||||
text = item.presentationData.strings.Conversation_SuggestedBirthdateTextYou(peerName).string
|
||||
} else {
|
||||
text = item.presentationData.strings.Conversation_SuggestedBirthdateText(peerName).string
|
||||
}
|
||||
|
||||
let body = MarkdownAttributeSet(font: Font.regular(13.0), textColor: primaryTextColor)
|
||||
let bold = MarkdownAttributeSet(font: Font.semibold(13.0), textColor: primaryTextColor)
|
||||
let subtitle = parseMarkdownIntoAttributedString(text, attributes: MarkdownAttributes(body: body, bold: bold, link: body, linkAttribute: { _ in
|
||||
return nil
|
||||
}), textAlignment: .center)
|
||||
|
||||
let (subtitleLayout, subtitleApply) = makeSubtitleLayout(TextNodeLayoutArguments(attributedString: subtitle, backgroundColor: nil, maximumNumberOfLines: 0, truncationType: .end, constrainedSize: CGSize(width: width - 32.0, height: CGFloat.greatestFiniteMagnitude), alignment: .center, cutout: nil, insets: UIEdgeInsets()))
|
||||
|
||||
let titleFont = Font.regular(13.0)
|
||||
let valueFont = Font.semibold(13.0)
|
||||
|
||||
let (dayTitleLayout, dayTitleApply) = makeDayTitleLayout(TextNodeLayoutArguments(attributedString: NSAttributedString(string: item.presentationData.strings.Conversation_SuggestedBirthdate_Day, font: titleFont, textColor: subtitleColor), backgroundColor: nil, maximumNumberOfLines: 1, truncationType: .end, constrainedSize: CGSize(width: width - 32.0, height: CGFloat.greatestFiniteMagnitude), alignment: .center, cutout: nil, insets: UIEdgeInsets()))
|
||||
|
||||
let (dayValueLayout, dayValueApply) = makeDayValueLayout(TextNodeLayoutArguments(attributedString: NSAttributedString(string: "\(day)", font: valueFont, textColor: primaryTextColor), backgroundColor: nil, maximumNumberOfLines: 1, truncationType: .end, constrainedSize: CGSize(width: width - 32.0, height: CGFloat.greatestFiniteMagnitude), alignment: .center, cutout: nil, insets: UIEdgeInsets()))
|
||||
|
||||
let (monthTitleLayout, monthTitleApply) = makeMonthTitleLayout(TextNodeLayoutArguments(attributedString: NSAttributedString(string: item.presentationData.strings.Conversation_SuggestedBirthdate_Month, font: titleFont, textColor: subtitleColor), backgroundColor: nil, maximumNumberOfLines: 1, truncationType: .end, constrainedSize: CGSize(width: width - 32.0, height: CGFloat.greatestFiniteMagnitude), alignment: .center, cutout: nil, insets: UIEdgeInsets()))
|
||||
|
||||
let (monthValueLayout, monthValueApply) = makeMonthValueLayout(TextNodeLayoutArguments(attributedString: NSAttributedString(string: stringForMonth(strings: item.presentationData.strings, month: month - 1), font: valueFont, textColor: primaryTextColor), backgroundColor: nil, maximumNumberOfLines: 1, truncationType: .end, constrainedSize: CGSize(width: width - 32.0, height: CGFloat.greatestFiniteMagnitude), alignment: .center, cutout: nil, insets: UIEdgeInsets()))
|
||||
|
||||
let (yearTitleLayout, yearTitleApply) = makeYearTitleLayout(TextNodeLayoutArguments(attributedString: NSAttributedString(string: item.presentationData.strings.Conversation_SuggestedBirthdate_Year, font: titleFont, textColor: subtitleColor), backgroundColor: nil, maximumNumberOfLines: 1, truncationType: .end, constrainedSize: CGSize(width: width - 32.0, height: CGFloat.greatestFiniteMagnitude), alignment: .center, cutout: nil, insets: UIEdgeInsets()))
|
||||
|
||||
let (yearValueLayout, yearValueApply) = makeYearValueLayout(TextNodeLayoutArguments(attributedString: NSAttributedString(string: year.flatMap { "\($0)" } ?? "", font: valueFont, textColor: primaryTextColor), backgroundColor: nil, maximumNumberOfLines: 1, truncationType: .end, constrainedSize: CGSize(width: width - 32.0, height: CGFloat.greatestFiniteMagnitude), alignment: .center, cutout: nil, insets: UIEdgeInsets()))
|
||||
|
||||
let (buttonTitleLayout, buttonTitleApply) = makeButtonTitleLayout(TextNodeLayoutArguments(attributedString: NSAttributedString(string: item.presentationData.strings.Conversation_SuggestedBirthdate_View, font: Font.semibold(15.0), textColor: primaryTextColor, paragraphAlignment: .center), backgroundColor: nil, maximumNumberOfLines: 0, truncationType: .end, constrainedSize: CGSize(width: width - 32.0, height: CGFloat.greatestFiniteMagnitude), alignment: .center, cutout: nil, insets: UIEdgeInsets()))
|
||||
|
||||
var backgroundSize = CGSize(width: width, height: subtitleLayout.size.height + 160.0)
|
||||
if !fromYou {
|
||||
backgroundSize.height += 44.0
|
||||
}
|
||||
|
||||
return (backgroundSize.width, { boundingWidth in
|
||||
return (backgroundSize, { [weak self] animation, synchronousLoads, _ in
|
||||
if let strongSelf = self {
|
||||
let isFirstTime = strongSelf.item == nil
|
||||
strongSelf.item = item
|
||||
|
||||
let mediaBackgroundFrame = CGRect(origin: CGPoint(x: floorToScreenPixels((backgroundSize.width - width) / 2.0), y: 0.0), size: backgroundSize)
|
||||
strongSelf.mediaBackgroundNode.frame = mediaBackgroundFrame
|
||||
|
||||
strongSelf.mediaBackgroundNode.updateColor(color: selectDateFillStaticColor(theme: item.presentationData.theme.theme, wallpaper: item.presentationData.theme.wallpaper), enableBlur: item.controllerInteraction.enableFullTranslucency && dateFillNeedsBlur(theme: item.presentationData.theme.theme, wallpaper: item.presentationData.theme.wallpaper), transition: .immediate)
|
||||
strongSelf.mediaBackgroundNode.update(size: mediaBackgroundFrame.size, transition: .immediate)
|
||||
strongSelf.buttonNode.backgroundColor = item.presentationData.theme.theme.overallDarkAppearance ? UIColor(rgb: 0xffffff, alpha: 0.12) : UIColor(rgb: 0x000000, alpha: 0.12)
|
||||
|
||||
if item.presentationData.theme.theme.overallDarkAppearance {
|
||||
strongSelf.dayTitleNode.layer.compositingFilter = nil
|
||||
strongSelf.monthTitleNode.layer.compositingFilter = nil
|
||||
strongSelf.yearTitleNode.layer.compositingFilter = nil
|
||||
} else {
|
||||
strongSelf.dayTitleNode.layer.compositingFilter = "overlayBlendMode"
|
||||
strongSelf.monthTitleNode.layer.compositingFilter = "overlayBlendMode"
|
||||
strongSelf.yearTitleNode.layer.compositingFilter = "overlayBlendMode"
|
||||
}
|
||||
|
||||
let _ = subtitleApply()
|
||||
|
||||
let _ = dayTitleApply()
|
||||
let _ = monthTitleApply()
|
||||
let _ = yearTitleApply()
|
||||
|
||||
let _ = dayValueApply()
|
||||
let _ = monthValueApply()
|
||||
let _ = yearValueApply()
|
||||
|
||||
let _ = buttonTitleApply()
|
||||
|
||||
let iconSize = CGSize(width: 80.0, height: 80.0)
|
||||
|
||||
let animationFrame = CGRect(origin: CGPoint(x: mediaBackgroundFrame.minX + floorToScreenPixels((mediaBackgroundFrame.width - iconSize.width) / 2.0), y: mediaBackgroundFrame.minY + 8.0), size: iconSize)
|
||||
strongSelf.animationNode.frame = animationFrame
|
||||
if isFirstTime {
|
||||
strongSelf.animationNode.setup(source: AnimatedStickerNodeLocalFileSource(name: "Cake"), width: 384, height: 384, playbackMode: .once, mode: .direct(cachePathPrefix: nil))
|
||||
strongSelf.animationNode.visibility = true
|
||||
}
|
||||
strongSelf.animationNode.updateLayout(size: iconSize)
|
||||
|
||||
let subtitleFrame = CGRect(origin: CGPoint(x: mediaBackgroundFrame.minX + floorToScreenPixels((mediaBackgroundFrame.width - subtitleLayout.size.width) / 2.0) , y: mediaBackgroundFrame.minY + 96.0), size: subtitleLayout.size)
|
||||
strongSelf.subtitleNode.frame = subtitleFrame
|
||||
|
||||
let titleOriginY = subtitleFrame.maxY + 11.0
|
||||
let valueOriginY = titleOriginY + 19.0
|
||||
|
||||
let minX = mediaBackgroundFrame.minX
|
||||
let maxX = mediaBackgroundFrame.maxX
|
||||
let width = mediaBackgroundFrame.width
|
||||
|
||||
let dayColWidth = max(dayTitleLayout.size.width, dayValueLayout.size.width)
|
||||
let monthColWidth = max(monthTitleLayout.size.width, monthValueLayout.size.width)
|
||||
let yearColW = max(yearTitleLayout.size.width, yearValueLayout.size.width)
|
||||
|
||||
func centerX(inLeft left: CGFloat, right: CGFloat, contentWidth: CGFloat) -> CGFloat {
|
||||
return left + floorToScreenPixels((right - left - contentWidth) * 0.5)
|
||||
}
|
||||
|
||||
if yearValueLayout.size.width > 0.0 {
|
||||
strongSelf.yearTitleNode.isHidden = false
|
||||
strongSelf.yearValueNode.isHidden = false
|
||||
|
||||
let monthLeft = centerX(inLeft: minX, right: maxX, contentWidth: monthColWidth)
|
||||
let monthRight = monthLeft + monthColWidth
|
||||
|
||||
let dayLeft = centerX(inLeft: minX, right: monthLeft, contentWidth: dayColWidth)
|
||||
let yearLeft = centerX(inLeft: monthRight, right: maxX, contentWidth: yearColW)
|
||||
|
||||
strongSelf.dayTitleNode.frame = CGRect(
|
||||
origin: CGPoint(x: dayLeft + floorToScreenPixels((dayColWidth - dayTitleLayout.size.width) * 0.5), y: titleOriginY),
|
||||
size: dayTitleLayout.size
|
||||
)
|
||||
strongSelf.dayValueNode.frame = CGRect(
|
||||
origin: CGPoint(x: dayLeft + floorToScreenPixels((dayColWidth - dayValueLayout.size.width) * 0.5), y: valueOriginY),
|
||||
size: dayValueLayout.size
|
||||
)
|
||||
|
||||
strongSelf.monthTitleNode.frame = CGRect(
|
||||
origin: CGPoint(x: monthLeft + floorToScreenPixels((monthColWidth - monthTitleLayout.size.width) * 0.5), y: titleOriginY),
|
||||
size: monthTitleLayout.size
|
||||
)
|
||||
strongSelf.monthValueNode.frame = CGRect(
|
||||
origin: CGPoint(x: monthLeft + floorToScreenPixels((monthColWidth - monthValueLayout.size.width) * 0.5), y: valueOriginY),
|
||||
size: monthValueLayout.size
|
||||
)
|
||||
|
||||
strongSelf.yearTitleNode.frame = CGRect(
|
||||
origin: CGPoint(x: yearLeft + floorToScreenPixels((yearColW - yearTitleLayout.size.width) * 0.5), y: titleOriginY),
|
||||
size: yearTitleLayout.size
|
||||
)
|
||||
strongSelf.yearValueNode.frame = CGRect(
|
||||
origin: CGPoint(x: yearLeft + floorToScreenPixels((yearColW - yearValueLayout.size.width) * 0.5), y: valueOriginY),
|
||||
size: yearValueLayout.size
|
||||
)
|
||||
} else {
|
||||
strongSelf.yearTitleNode.isHidden = true
|
||||
strongSelf.yearValueNode.isHidden = true
|
||||
|
||||
let spacing: CGFloat = 16.0
|
||||
let totalWidth = dayColWidth + monthColWidth + spacing
|
||||
let dayLeft = minX + floorToScreenPixels((width - totalWidth) / 2.0)
|
||||
let monthLeft = dayLeft + dayColWidth + spacing
|
||||
|
||||
strongSelf.dayTitleNode.frame = CGRect(
|
||||
origin: CGPoint(x: dayLeft + floorToScreenPixels((dayColWidth - dayTitleLayout.size.width) * 0.5), y: titleOriginY),
|
||||
size: dayTitleLayout.size
|
||||
)
|
||||
strongSelf.dayValueNode.frame = CGRect(
|
||||
origin: CGPoint(x: dayLeft + floorToScreenPixels((dayColWidth - dayValueLayout.size.width) * 0.5), y: valueOriginY),
|
||||
size: dayValueLayout.size
|
||||
)
|
||||
|
||||
strongSelf.monthTitleNode.frame = CGRect(
|
||||
origin: CGPoint(x: monthLeft + floorToScreenPixels((monthColWidth - monthTitleLayout.size.width) * 0.5), y: titleOriginY),
|
||||
size: monthTitleLayout.size
|
||||
)
|
||||
strongSelf.monthValueNode.frame = CGRect(
|
||||
origin: CGPoint(x: monthLeft + floorToScreenPixels((monthColWidth - monthValueLayout.size.width) * 0.5), y: valueOriginY),
|
||||
size: monthValueLayout.size
|
||||
)
|
||||
}
|
||||
|
||||
strongSelf.buttonNode.isHidden = fromYou
|
||||
strongSelf.buttonTitleNode.isHidden = fromYou
|
||||
|
||||
let buttonSize = CGSize(width: buttonTitleLayout.size.width + 38.0, height: 34.0)
|
||||
let buttonFrame = CGRect(origin: CGPoint(x: mediaBackgroundFrame.minX + floorToScreenPixels((mediaBackgroundFrame.width - buttonSize.width) / 2.0), y: mediaBackgroundFrame.maxY - buttonSize.height - 16.0), size: buttonSize)
|
||||
strongSelf.buttonNode.frame = buttonFrame
|
||||
|
||||
let buttonTitleFrame = CGRect(origin: CGPoint(x: mediaBackgroundFrame.minX + floorToScreenPixels((mediaBackgroundFrame.width - buttonTitleLayout.size.width) / 2.0), y: floorToScreenPixels(buttonFrame.midY - buttonTitleLayout.size.height / 2.0)), size: buttonTitleLayout.size)
|
||||
strongSelf.buttonTitleNode.frame = buttonTitleFrame
|
||||
|
||||
if item.controllerInteraction.presentationContext.backgroundNode?.hasExtraBubbleBackground() == true {
|
||||
if strongSelf.mediaBackgroundContent == nil, let backgroundContent = item.controllerInteraction.presentationContext.backgroundNode?.makeBubbleBackground(for: .free) {
|
||||
strongSelf.mediaBackgroundNode.isHidden = true
|
||||
backgroundContent.clipsToBounds = true
|
||||
backgroundContent.allowsGroupOpacity = true
|
||||
backgroundContent.cornerRadius = 27.0
|
||||
|
||||
strongSelf.mediaBackgroundContent = backgroundContent
|
||||
strongSelf.insertSubnode(backgroundContent, at: 0)
|
||||
}
|
||||
|
||||
strongSelf.mediaBackgroundContent?.frame = mediaBackgroundFrame
|
||||
} else {
|
||||
strongSelf.mediaBackgroundNode.isHidden = false
|
||||
strongSelf.mediaBackgroundContent?.removeFromSupernode()
|
||||
strongSelf.mediaBackgroundContent = nil
|
||||
}
|
||||
|
||||
if let (rect, size) = strongSelf.absoluteRect {
|
||||
strongSelf.updateAbsoluteRect(rect, within: size)
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
override public func updateAbsoluteRect(_ rect: CGRect, within containerSize: CGSize) {
|
||||
self.absoluteRect = (rect, containerSize)
|
||||
|
||||
if let mediaBackgroundContent = self.mediaBackgroundContent {
|
||||
var backgroundFrame = mediaBackgroundContent.frame
|
||||
backgroundFrame.origin.x += rect.minX
|
||||
backgroundFrame.origin.y += rect.minY
|
||||
mediaBackgroundContent.update(rect: backgroundFrame, within: containerSize, transition: .immediate)
|
||||
}
|
||||
}
|
||||
|
||||
override public func tapActionAtPoint(_ point: CGPoint, gesture: TapLongTapOrDoubleTapGesture, isEstimating: Bool) -> ChatMessageBubbleContentTapAction {
|
||||
if self.mediaBackgroundNode.frame.contains(point) {
|
||||
return ChatMessageBubbleContentTapAction(content: .openMessage)
|
||||
} else {
|
||||
return ChatMessageBubbleContentTapAction(content: .none)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -74,6 +74,7 @@ swift_library(
|
|||
"//submodules/TelegramUI/Components/Chat/ChatMessageMapBubbleContentNode",
|
||||
"//submodules/TelegramUI/Components/Chat/ChatMessageMediaBubbleContentNode",
|
||||
"//submodules/TelegramUI/Components/Chat/ChatMessageProfilePhotoSuggestionContentNode",
|
||||
"//submodules/TelegramUI/Components/Chat/ChatMessageBirthdateSuggestionContentNode",
|
||||
"//submodules/TelegramUI/Components/Chat/ChatMessageRestrictedBubbleContentNode",
|
||||
"//submodules/TelegramUI/Components/Chat/ChatMessageStoryMentionContentNode",
|
||||
"//submodules/TelegramUI/Components/Chat/ChatMessageUnsupportedBubbleContentNode",
|
||||
|
|
|
|||
|
|
@ -64,6 +64,7 @@ import ChatMessageInvoiceBubbleContentNode
|
|||
import ChatMessageMapBubbleContentNode
|
||||
import ChatMessageMediaBubbleContentNode
|
||||
import ChatMessageProfilePhotoSuggestionContentNode
|
||||
import ChatMessageBirthdateSuggestionContentNode
|
||||
import ChatMessageRestrictedBubbleContentNode
|
||||
import ChatMessageStoryMentionContentNode
|
||||
import ChatMessageUnsupportedBubbleContentNode
|
||||
|
|
@ -243,6 +244,8 @@ private func contentNodeMessagesAndClassesForItem(_ item: ChatMessageItem) -> ([
|
|||
needReactions = false
|
||||
} else if case let .setChatTheme(chatTheme) = action.action, case .gift = chatTheme {
|
||||
result.append((message, ChatMessageGiftBubbleContentNode.self, itemAttributes, BubbleItemAttributes(isAttachment: false, neighborType: .text, neighborSpacing: .default)))
|
||||
} else if case .suggestedBirthday = action.action {
|
||||
result.append((message, ChatMessageBirthdateSuggestionContentNode.self, itemAttributes, BubbleItemAttributes(isAttachment: false, neighborType: .text, neighborSpacing: .default)))
|
||||
} else {
|
||||
if !canAddMessageReactions(message: message) {
|
||||
needReactions = false
|
||||
|
|
@ -295,7 +298,7 @@ private func contentNodeMessagesAndClassesForItem(_ item: ChatMessageItem) -> ([
|
|||
if let updatingMedia = itemAttributes.updatingMedia {
|
||||
messageText = updatingMedia.text
|
||||
}
|
||||
|
||||
|
||||
if !messageText.isEmpty || isUnsupportedMedia || isStoryWithText {
|
||||
if !skipText {
|
||||
if case .group = item.content, !isFile {
|
||||
|
|
|
|||
|
|
@ -434,7 +434,8 @@ private final class GiftPurchaseAlertContentNode: AlertContentNode {
|
|||
}
|
||||
|
||||
if let actionNode = self.actionNodes.first {
|
||||
actionNode.isHidden = true
|
||||
actionNode.isUserInteractionEnabled = false
|
||||
actionNode.isHidden = false
|
||||
|
||||
let indicatorSize = CGSize(width: 22.0, height: 22.0)
|
||||
transition.updateFrame(node: activityIndicator, frame: CGRect(origin: CGPoint(x: actionNode.frame.minX + floor((actionNode.frame.width - indicatorSize.width) / 2.0), y: actionNode.frame.minY + floor((actionNode.frame.height - indicatorSize.height) / 2.0)), size: indicatorSize))
|
||||
|
|
|
|||
|
|
@ -410,7 +410,8 @@ private final class GiftTransferAlertContentNode: AlertContentNode {
|
|||
}
|
||||
|
||||
if let actionNode = self.actionNodes.first {
|
||||
actionNode.isHidden = true
|
||||
actionNode.isUserInteractionEnabled = false
|
||||
actionNode.isHidden = false
|
||||
|
||||
let indicatorSize = CGSize(width: 22.0, height: 22.0)
|
||||
transition.updateFrame(node: activityIndicator, frame: CGRect(origin: CGPoint(x: actionNode.frame.minX + floor((actionNode.frame.width - indicatorSize.width) / 2.0), y: actionNode.frame.minY + floor((actionNode.frame.height - indicatorSize.height) / 2.0)), size: indicatorSize))
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ private final class ContentContainer: UIView {
|
|||
}
|
||||
}
|
||||
|
||||
public final class GlassBackgroundView: UIView {
|
||||
public class GlassBackgroundView: UIView {
|
||||
public protocol ContentView: UIView {
|
||||
var tintMask: UIView { get }
|
||||
}
|
||||
|
|
@ -780,3 +780,40 @@ public extension GlassBackgroundView {
|
|||
})!.stretchableImage(withLeftCapWidth: Int(size.width * 0.5), topCapHeight: Int(size.height * 0.5))
|
||||
}
|
||||
}
|
||||
|
||||
public final class GlassBackgroundComponent: Component {
|
||||
private let size: CGSize
|
||||
private let tintColor: GlassBackgroundView.TintColor
|
||||
|
||||
public init(size: CGSize, tintColor: GlassBackgroundView.TintColor) {
|
||||
self.size = size
|
||||
self.tintColor = tintColor
|
||||
}
|
||||
|
||||
public static func == (lhs: GlassBackgroundComponent, rhs: GlassBackgroundComponent) -> Bool {
|
||||
if lhs.size != rhs.size {
|
||||
return false
|
||||
}
|
||||
if lhs.tintColor != rhs.tintColor {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
public final class View: GlassBackgroundView {
|
||||
func update(component: GlassBackgroundComponent, availableSize: CGSize, state: EmptyComponentState, environment: Environment<Empty>, transition: ComponentTransition) -> CGSize {
|
||||
self.update(size: component.size, cornerRadius: component.size.height / 2.0, isDark: true, tintColor: component.tintColor, transition: transition)
|
||||
self.frame = CGRect(origin: .zero, size: component.size)
|
||||
|
||||
return component.size
|
||||
}
|
||||
}
|
||||
|
||||
public func makeView() -> View {
|
||||
return View()
|
||||
}
|
||||
|
||||
public func update(view: View, availableSize: CGSize, state: EmptyComponentState, environment: Environment<EnvironmentType>, transition: ComponentTransition) -> CGSize {
|
||||
return view.update(component: self, availableSize: availableSize, state: state, environment: environment, transition: transition)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -229,7 +229,7 @@ public class LegacyMessageInputPanelNode: ASDisplayNode, TGCaptionPanelView {
|
|||
areVoiceMessagesAvailable: false,
|
||||
presentController: self.present,
|
||||
presentInGlobalOverlay: self.presentInGlobalOverlay,
|
||||
sendMessageAction: { [weak self] in
|
||||
sendMessageAction: { [weak self] _ in
|
||||
if let self {
|
||||
self.sendPressed?(self.caption())
|
||||
let _ = self.dismissInput()
|
||||
|
|
|
|||
|
|
@ -1397,7 +1397,7 @@ final class MediaEditorScreenComponent: Component {
|
|||
}
|
||||
controller.presentInGlobalOverlay(c)
|
||||
},
|
||||
sendMessageAction: { [weak self] in
|
||||
sendMessageAction: { [weak self] _ in
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
|
|
|
|||
|
|
@ -260,7 +260,7 @@ final class StoryPreviewComponent: Component {
|
|||
areVoiceMessagesAvailable: false,
|
||||
presentController: { _ in },
|
||||
presentInGlobalOverlay: { _ in },
|
||||
sendMessageAction: { },
|
||||
sendMessageAction: { _ in },
|
||||
sendMessageOptionsAction: nil,
|
||||
sendStickerAction: { _ in },
|
||||
setMediaRecordingActive: { _, _, _, _ in },
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ swift_library(
|
|||
"//submodules/ContextUI",
|
||||
"//submodules/Components/ReactionButtonListComponent",
|
||||
"//submodules/TelegramCore",
|
||||
"//submodules/TelegramUI/Components/GlassBackgroundComponent",
|
||||
],
|
||||
visibility = [
|
||||
"//visibility:public",
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ import MoreHeaderButton
|
|||
import ContextUI
|
||||
import ReactionButtonListComponent
|
||||
import LottieComponent
|
||||
import GlassBackgroundComponent
|
||||
|
||||
private class ButtonIcon: Equatable {
|
||||
enum IconType: Equatable {
|
||||
|
|
@ -24,6 +25,7 @@ private class ButtonIcon: Equatable {
|
|||
case forward
|
||||
case like
|
||||
case repost
|
||||
case close
|
||||
}
|
||||
|
||||
let icon: IconType
|
||||
|
|
@ -32,7 +34,7 @@ private class ButtonIcon: Equatable {
|
|||
self.icon = icon
|
||||
}
|
||||
|
||||
var image: UIImage? {
|
||||
func image(withBackground: Bool) -> UIImage? {
|
||||
switch icon {
|
||||
case .delete:
|
||||
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Delete"), color: .white)
|
||||
|
|
@ -46,6 +48,8 @@ private class ButtonIcon: Equatable {
|
|||
return generateTintedImage(image: UIImage(bundleImageName: "Media Editor/RemoveRecordedVideo"), color: .white)
|
||||
case .repost:
|
||||
return generateTintedImage(image: UIImage(bundleImageName: "Stories/InputRepost"), color: .white)
|
||||
case .close:
|
||||
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Input/Search/DownButton"), color: .white)
|
||||
case .apply:
|
||||
return generateImage(CGSize(width: 33.0, height: 33.0), contextGenerator: { size, context in
|
||||
context.clear(CGRect(origin: CGPoint(), size: size))
|
||||
|
|
@ -62,10 +66,19 @@ private class ButtonIcon: Equatable {
|
|||
case .send:
|
||||
return generateImage(CGSize(width: 33.0, height: 33.0), rotatedContext: { size, context in
|
||||
context.clear(CGRect(origin: CGPoint(), size: size))
|
||||
context.setFillColor(UIColor.white.cgColor)
|
||||
context.fillEllipse(in: CGRect(origin: CGPoint(), size: size))
|
||||
|
||||
if withBackground {
|
||||
context.setFillColor(UIColor.white.cgColor)
|
||||
context.fillEllipse(in: CGRect(origin: CGPoint(), size: size))
|
||||
}
|
||||
|
||||
context.setBlendMode(.copy)
|
||||
context.setStrokeColor(UIColor.clear.cgColor)
|
||||
|
||||
if withBackground {
|
||||
context.setStrokeColor(UIColor.clear.cgColor)
|
||||
} else {
|
||||
context.setStrokeColor(UIColor.white.cgColor)
|
||||
}
|
||||
context.setLineWidth(2.0)
|
||||
context.setLineCap(.round)
|
||||
context.setLineJoin(.round)
|
||||
|
|
@ -111,6 +124,8 @@ private extension MessageInputActionButtonComponent.Mode {
|
|||
return ButtonIcon(icon: .apply)
|
||||
case .send:
|
||||
return ButtonIcon(icon: .send)
|
||||
case .close:
|
||||
return ButtonIcon(icon: .close)
|
||||
case .stars:
|
||||
return nil
|
||||
default:
|
||||
|
|
@ -137,14 +152,21 @@ public final class MessageInputActionButtonComponent: Component {
|
|||
case repost
|
||||
case captionUp
|
||||
case captionDown
|
||||
case close
|
||||
}
|
||||
|
||||
public enum Action {
|
||||
case down
|
||||
case up
|
||||
}
|
||||
|
||||
public enum Style {
|
||||
case legacy
|
||||
case glass
|
||||
}
|
||||
|
||||
public let mode: Mode
|
||||
public let style: Style
|
||||
public let storyId: Int32?
|
||||
public let action: (Mode, Action, Bool) -> Void
|
||||
public let longPressAction: ((UIView, ContextGesture?) -> Void)?
|
||||
|
|
@ -163,6 +185,7 @@ public final class MessageInputActionButtonComponent: Component {
|
|||
|
||||
public init(
|
||||
mode: Mode,
|
||||
style: Style = .legacy,
|
||||
storyId: Int32?,
|
||||
action: @escaping (Mode, Action, Bool) -> Void,
|
||||
longPressAction: ((UIView, ContextGesture?) -> Void)?,
|
||||
|
|
@ -180,6 +203,7 @@ public final class MessageInputActionButtonComponent: Component {
|
|||
hasShadow: Bool = false
|
||||
) {
|
||||
self.mode = mode
|
||||
self.style = style
|
||||
self.storyId = storyId
|
||||
self.action = action
|
||||
self.longPressAction = longPressAction
|
||||
|
|
@ -201,6 +225,9 @@ public final class MessageInputActionButtonComponent: Component {
|
|||
if lhs.mode != rhs.mode {
|
||||
return false
|
||||
}
|
||||
if lhs.style != rhs.style {
|
||||
return false
|
||||
}
|
||||
if lhs.storyId != rhs.storyId {
|
||||
return false
|
||||
}
|
||||
|
|
@ -231,6 +258,7 @@ public final class MessageInputActionButtonComponent: Component {
|
|||
public let button: HighlightTrackingButtonNode
|
||||
public let referenceNode: ContextReferenceContentNode
|
||||
public let containerNode: ContextControllerSourceNode
|
||||
private var backgroundView: GlassBackgroundView?
|
||||
private let sendIconView: UIImageView
|
||||
private var reactionHeartView: UIImageView?
|
||||
private var moreButton: MoreHeaderButton?
|
||||
|
|
@ -475,7 +503,7 @@ public final class MessageInputActionButtonComponent: Component {
|
|||
break
|
||||
case .captionUp, .captionDown:
|
||||
sendAlpha = 0.0
|
||||
case .send, .apply, .attach, .delete, .forward, .removeVideoInput, .repost, .stars:
|
||||
case .send, .apply, .attach, .delete, .forward, .removeVideoInput, .repost, .stars, .close:
|
||||
sendAlpha = 1.0
|
||||
case let .like(reaction, _, _):
|
||||
if reaction != nil {
|
||||
|
|
@ -491,9 +519,29 @@ public final class MessageInputActionButtonComponent: Component {
|
|||
microphoneAlpha = 0.4
|
||||
}
|
||||
|
||||
if component.style == .glass, [.send, .close].contains(component.mode) {
|
||||
let backgroundView: GlassBackgroundView
|
||||
if let current = self.backgroundView {
|
||||
backgroundView = current
|
||||
} else {
|
||||
backgroundView = GlassBackgroundView()
|
||||
self.button.view.insertSubview(backgroundView, at: 0)
|
||||
self.backgroundView = backgroundView
|
||||
}
|
||||
|
||||
var tintColor = UIColor(rgb: 0x1b1d22)
|
||||
if case .send = component.mode {
|
||||
tintColor = UIColor(rgb: 0x0187ee)
|
||||
}
|
||||
let buttonSize = CGSize(width: 40.0, height: 40.0)
|
||||
backgroundView.update(size: buttonSize, cornerRadius: buttonSize.height / 2.0, isDark: true, tintColor: .init(kind: .custom, color: tintColor), transition: transition)
|
||||
backgroundView.frame = CGRect(origin: .zero, size: buttonSize)
|
||||
}
|
||||
|
||||
if self.sendIconView.image == nil || previousComponent?.mode.icon != component.mode.icon {
|
||||
if let image = component.mode.icon?.image {
|
||||
if case .send = component.mode {
|
||||
if let image = component.mode.icon?.image(withBackground: component.style == .legacy) {
|
||||
switch component.mode {
|
||||
case .send, .close:
|
||||
if !transition.animation.isImmediate {
|
||||
if let snapshotView = self.sendIconView.snapshotView(afterScreenUpdates: false) {
|
||||
snapshotView.frame = self.sendIconView.frame
|
||||
|
|
@ -509,6 +557,8 @@ public final class MessageInputActionButtonComponent: Component {
|
|||
transition.animateScale(view: self.sendIconView, from: 0.01, to: 1.0)
|
||||
}
|
||||
}
|
||||
default:
|
||||
break
|
||||
}
|
||||
self.sendIconView.image = image
|
||||
} else {
|
||||
|
|
@ -674,7 +724,7 @@ public final class MessageInputActionButtonComponent: Component {
|
|||
|
||||
if previousComponent?.mode != component.mode {
|
||||
switch component.mode {
|
||||
case .none, .send, .apply, .voiceInput, .attach, .delete, .forward, .unavailableVoiceInput, .more, .like, .repost, .captionUp, .captionDown, .stars:
|
||||
case .none, .send, .apply, .voiceInput, .attach, .delete, .forward, .unavailableVoiceInput, .more, .like, .repost, .captionUp, .captionDown, .stars, .close:
|
||||
micButton.updateMode(mode: .audio, animated: !transition.animation.isImmediate)
|
||||
case .videoInput, .removeVideoInput:
|
||||
micButton.updateMode(mode: .video, animated: !transition.animation.isImmediate)
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ swift_library(
|
|||
"//submodules/TelegramUI/Components/ContextReferenceButtonComponent",
|
||||
"//submodules/TelegramUI/Components/Stories/ForwardInfoPanelComponent",
|
||||
"//submodules/TelegramUI/Components/PlainButtonComponent",
|
||||
"//submodules/TelegramUI/Components/GlassBackgroundComponent",
|
||||
],
|
||||
visibility = [
|
||||
"//visibility:public",
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ import ContextReferenceButtonComponent
|
|||
import ForwardInfoPanelComponent
|
||||
import MultilineTextComponent
|
||||
import PlainButtonComponent
|
||||
import GlassBackgroundComponent
|
||||
|
||||
private var sharedIsReduceTransparencyEnabled = UIAccessibility.isReduceTransparencyEnabled
|
||||
|
||||
|
|
@ -48,6 +49,7 @@ public final class MessageInputPanelComponent: Component {
|
|||
case story
|
||||
case editor
|
||||
case media
|
||||
case glass
|
||||
}
|
||||
|
||||
public enum InputMode: Hashable {
|
||||
|
|
@ -141,7 +143,7 @@ public final class MessageInputPanelComponent: Component {
|
|||
}
|
||||
|
||||
public final class ExternalState {
|
||||
public fileprivate(set) var isEditing: Bool = false
|
||||
public var isEditing: Bool = false
|
||||
public fileprivate(set) var hasText: Bool = false
|
||||
public fileprivate(set) var isKeyboardHidden: Bool = false
|
||||
|
||||
|
|
@ -154,6 +156,18 @@ public final class MessageInputPanelComponent: Component {
|
|||
}
|
||||
}
|
||||
|
||||
public final class SendActionTransition {
|
||||
public let textSnapshotView: UIView
|
||||
public let globalFrame: CGRect
|
||||
public let cornerRadius: CGFloat
|
||||
|
||||
init(textSnapshotView: UIView, globalFrame: CGRect, cornerRadius: CGFloat) {
|
||||
self.textSnapshotView = textSnapshotView
|
||||
self.globalFrame = globalFrame
|
||||
self.cornerRadius = cornerRadius
|
||||
}
|
||||
}
|
||||
|
||||
public let externalState: ExternalState
|
||||
public let context: AccountContext
|
||||
public let theme: PresentationTheme
|
||||
|
|
@ -170,7 +184,7 @@ public final class MessageInputPanelComponent: Component {
|
|||
public let areVoiceMessagesAvailable: Bool
|
||||
public let presentController: (ViewController) -> Void
|
||||
public let presentInGlobalOverlay: (ViewController) -> Void
|
||||
public let sendMessageAction: () -> Void
|
||||
public let sendMessageAction: (SendActionTransition?) -> Void
|
||||
public let sendMessageOptionsAction: ((UIView, ContextGesture?) -> Void)?
|
||||
public let sendStickerAction: (TelegramMediaFile) -> Void
|
||||
public let setMediaRecordingActive: ((Bool, Bool, Bool, UIView?) -> Void)?
|
||||
|
|
@ -229,7 +243,7 @@ public final class MessageInputPanelComponent: Component {
|
|||
areVoiceMessagesAvailable: Bool,
|
||||
presentController: @escaping (ViewController) -> Void,
|
||||
presentInGlobalOverlay: @escaping (ViewController) -> Void,
|
||||
sendMessageAction: @escaping () -> Void,
|
||||
sendMessageAction: @escaping (SendActionTransition?) -> Void,
|
||||
sendMessageOptionsAction: ((UIView, ContextGesture?) -> Void)?,
|
||||
sendStickerAction: @escaping (TelegramMediaFile) -> Void,
|
||||
setMediaRecordingActive: ((Bool, Bool, Bool, UIView?) -> Void)?,
|
||||
|
|
@ -464,6 +478,7 @@ public final class MessageInputPanelComponent: Component {
|
|||
public final class View: UIView {
|
||||
private let fieldBackgroundView: BlurredBackgroundView
|
||||
private let fieldBackgroundTint: UIView
|
||||
private var fieldGlassBackgroundView: GlassBackgroundView?
|
||||
private let gradientView: UIImageView
|
||||
private let bottomGradientView: UIView
|
||||
|
||||
|
|
@ -773,12 +788,18 @@ public final class MessageInputPanelComponent: Component {
|
|||
insets.right = 41.0
|
||||
}
|
||||
|
||||
var textFieldSideInset = 9.0
|
||||
if case .media = component.style {
|
||||
let textFieldSideInset: CGFloat
|
||||
switch component.style {
|
||||
case .media, .glass:
|
||||
textFieldSideInset = 8.0
|
||||
default:
|
||||
textFieldSideInset = 9.0
|
||||
}
|
||||
|
||||
let mediaInsets = UIEdgeInsets(top: insets.top, left: textFieldSideInset, bottom: insets.bottom, right: 41.0)
|
||||
var mediaInsets = UIEdgeInsets(top: insets.top, left: textFieldSideInset, bottom: insets.bottom, right: 41.0)
|
||||
if case .glass = component.style {
|
||||
mediaInsets.right = 54.0
|
||||
}
|
||||
|
||||
let baseFieldHeight: CGFloat = 40.0
|
||||
|
||||
|
|
@ -1025,6 +1046,8 @@ public final class MessageInputPanelComponent: Component {
|
|||
var fieldBackgroundFrame: CGRect
|
||||
if hasMediaRecording {
|
||||
fieldBackgroundFrame = CGRect(origin: CGPoint(x: mediaInsets.left, y: insets.top), size: CGSize(width: availableSize.width - mediaInsets.left - mediaInsets.right, height: fieldFrame.height))
|
||||
} else if case .glass = component.style {
|
||||
fieldBackgroundFrame = CGRect(origin: CGPoint(x: mediaInsets.left, y: insets.top), size: CGSize(width: availableSize.width - mediaInsets.left - mediaInsets.right, height: fieldFrame.height))
|
||||
} else if isEditing || component.style == .editor || component.style == .media {
|
||||
fieldBackgroundFrame = fieldFrame
|
||||
} else {
|
||||
|
|
@ -1042,6 +1065,24 @@ public final class MessageInputPanelComponent: Component {
|
|||
|
||||
//transition.setFrame(view: self.vibrancyEffectView, frame: CGRect(origin: CGPoint(), size: fieldBackgroundFrame.size))
|
||||
|
||||
switch component.style {
|
||||
case .glass:
|
||||
if self.fieldGlassBackgroundView == nil {
|
||||
let fieldGlassBackgroundView = GlassBackgroundView(frame: fieldBackgroundFrame)
|
||||
self.insertSubview(fieldGlassBackgroundView, aboveSubview: self.fieldBackgroundView)
|
||||
self.fieldGlassBackgroundView = fieldGlassBackgroundView
|
||||
|
||||
self.fieldBackgroundView.isHidden = true
|
||||
self.fieldBackgroundTint.isHidden = true
|
||||
}
|
||||
if let fieldGlassBackgroundView = self.fieldGlassBackgroundView {
|
||||
fieldGlassBackgroundView.update(size: fieldBackgroundFrame.size, cornerRadius: baseFieldHeight * 0.5, isDark: true, tintColor: .init(kind: .custom, color: UIColor(rgb: 0x1b1d22)), transition: transition)
|
||||
transition.setFrame(view: fieldGlassBackgroundView, frame: fieldBackgroundFrame)
|
||||
}
|
||||
default:
|
||||
break
|
||||
}
|
||||
|
||||
transition.setFrame(view: self.fieldBackgroundView, frame: fieldBackgroundFrame)
|
||||
self.fieldBackgroundView.update(size: fieldBackgroundFrame.size, cornerRadius: headerHeight > 0.0 ? 18.0 : baseFieldHeight * 0.5, transition: transition.containedViewLayoutTransition)
|
||||
transition.setFrame(view: self.fieldBackgroundTint, frame: fieldBackgroundFrame)
|
||||
|
|
@ -1063,7 +1104,7 @@ public final class MessageInputPanelComponent: Component {
|
|||
transition.setAlpha(view: self.bottomGradientView, alpha: component.displayGradient ? 1.0 : 0.0)
|
||||
|
||||
let placeholderOriginX: CGFloat
|
||||
if isEditing || component.style == .story {
|
||||
if isEditing || component.style == .story || component.style == .glass {
|
||||
placeholderOriginX = 16.0
|
||||
} else {
|
||||
placeholderOriginX = floorToScreenPixels(fieldBackgroundFrame.minX + (fieldBackgroundFrame.width - placeholderSize.width) / 2.0)
|
||||
|
|
@ -1456,6 +1497,7 @@ public final class MessageInputPanelComponent: Component {
|
|||
}
|
||||
}
|
||||
|
||||
var inputActionButtonAvailableSize = CGSize(width: 33.0, height: 33.0)
|
||||
var inputActionButtonAlpha = 1.0
|
||||
let inputActionButtonMode: MessageInputActionButtonComponent.Mode
|
||||
if case .editor = component.style {
|
||||
|
|
@ -1469,12 +1511,19 @@ public final class MessageInputPanelComponent: Component {
|
|||
if !isEditing {
|
||||
inputActionButtonAlpha = 0.0
|
||||
}
|
||||
} else if case .glass = component.style {
|
||||
inputActionButtonAvailableSize = CGSize(width: 40.0, height: 40.0)
|
||||
if self.textFieldExternalState.hasText {
|
||||
inputActionButtonMode = .send
|
||||
} else {
|
||||
inputActionButtonMode = .close
|
||||
}
|
||||
} else {
|
||||
if hasMediaEditing {
|
||||
inputActionButtonMode = .send
|
||||
} else {
|
||||
if self.textFieldExternalState.hasText {
|
||||
if let sendPaidMessageStars = component.sendPaidMessageStars, "".isEmpty {
|
||||
if let sendPaidMessageStars = component.sendPaidMessageStars, !"".isEmpty {
|
||||
inputActionButtonMode = .stars(sendPaidMessageStars.value)
|
||||
} else {
|
||||
inputActionButtonMode = .send
|
||||
|
|
@ -1494,6 +1543,7 @@ public final class MessageInputPanelComponent: Component {
|
|||
transition: transition,
|
||||
component: AnyComponent(MessageInputActionButtonComponent(
|
||||
mode: inputActionButtonMode,
|
||||
style: component.style == .glass ? .glass : .legacy,
|
||||
storyId: component.storyItem?.id,
|
||||
action: { [weak self] mode, action, sendAction in
|
||||
guard let self, let component = self.component else {
|
||||
|
|
@ -1503,19 +1553,29 @@ public final class MessageInputPanelComponent: Component {
|
|||
switch mode {
|
||||
case .none:
|
||||
break
|
||||
case .close:
|
||||
component.sendMessageAction(nil)
|
||||
case .send, .stars:
|
||||
if case .up = action {
|
||||
if component.recordedAudioPreview != nil {
|
||||
component.sendMessageAction()
|
||||
component.sendMessageAction(nil)
|
||||
} else if component.hasRecordedVideoPreview {
|
||||
component.sendMessageAction()
|
||||
component.sendMessageAction(nil)
|
||||
} else if case let .text(string) = self.getSendMessageInput(), string.string.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
|
||||
} else {
|
||||
if let maxLength = component.maxLength, self.textFieldExternalState.textLength > maxLength {
|
||||
self.animateError()
|
||||
component.presentTextLengthLimitTooltip?()
|
||||
} else {
|
||||
component.sendMessageAction()
|
||||
var sendActionTransition: MessageInputPanelComponent.SendActionTransition?
|
||||
if let snapshotView = self.textClippingView.snapshotView(afterScreenUpdates: false), let backgroundView = self.fieldGlassBackgroundView {
|
||||
sendActionTransition = MessageInputPanelComponent.SendActionTransition(
|
||||
textSnapshotView: snapshotView,
|
||||
globalFrame: backgroundView.convert(backgroundView.bounds, to: nil),
|
||||
cornerRadius: baseFieldHeight * 0.5
|
||||
)
|
||||
}
|
||||
component.sendMessageAction(sendActionTransition)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1525,7 +1585,7 @@ public final class MessageInputPanelComponent: Component {
|
|||
self.animateError()
|
||||
component.presentTextLengthLimitTooltip?()
|
||||
} else {
|
||||
component.sendMessageAction()
|
||||
component.sendMessageAction(nil)
|
||||
}
|
||||
}
|
||||
case .voiceInput, .videoInput:
|
||||
|
|
@ -1587,7 +1647,7 @@ public final class MessageInputPanelComponent: Component {
|
|||
hasShadow: component.style == .editor
|
||||
)),
|
||||
environment: {},
|
||||
containerSize: CGSize(width: 33.0, height: 33.0)
|
||||
containerSize: inputActionButtonAvailableSize
|
||||
)
|
||||
|
||||
let hasLikeAction: Bool
|
||||
|
|
@ -1617,8 +1677,13 @@ public final class MessageInputPanelComponent: Component {
|
|||
inputActionButtonOriginX -= 46.0
|
||||
}
|
||||
} else {
|
||||
if component.setMediaRecordingActive != nil || isEditing {
|
||||
inputActionButtonOriginX = fieldBackgroundFrame.maxX + floorToScreenPixels((41.0 - inputActionButtonSize.width) * 0.5)
|
||||
if component.setMediaRecordingActive != nil || isEditing || component.style == .glass {
|
||||
switch component.style {
|
||||
case .glass:
|
||||
inputActionButtonOriginX = fieldBackgroundFrame.maxX + 6.0
|
||||
default:
|
||||
inputActionButtonOriginX = fieldBackgroundFrame.maxX + floorToScreenPixels((41.0 - inputActionButtonSize.width) * 0.5)
|
||||
}
|
||||
} else {
|
||||
inputActionButtonOriginX = size.width
|
||||
}
|
||||
|
|
|
|||
|
|
@ -165,6 +165,7 @@ swift_library(
|
|||
"//submodules/TelegramUI/Components/BottomButtonPanelComponent",
|
||||
"//submodules/TelegramUI/Components/MarqueeComponent",
|
||||
"//submodules/TelegramUI/Components/MediaManager/PeerMessagesMediaPlaylist",
|
||||
"//submodules/TelegramUI/Components/TextFieldComponent",
|
||||
"//submodules/TelegramUI/Components/EdgeEffect",
|
||||
],
|
||||
visibility = [
|
||||
|
|
|
|||
|
|
@ -65,7 +65,9 @@ final class PeerInfoScreenLabeledValueItem: PeerInfoScreenItem {
|
|||
let id: AnyHashable
|
||||
let context: AccountContext?
|
||||
let label: String
|
||||
let rightLabel: String?
|
||||
let text: String
|
||||
let entities: [MessageTextEntity]
|
||||
let additionalText: String?
|
||||
let textColor: PeerInfoScreenLabeledValueTextColor
|
||||
let textBehavior: PeerInfoScreenLabeledValueTextBehavior
|
||||
|
|
@ -83,7 +85,9 @@ final class PeerInfoScreenLabeledValueItem: PeerInfoScreenItem {
|
|||
id: AnyHashable,
|
||||
context: AccountContext? = nil,
|
||||
label: String,
|
||||
rightLabel: String? = nil,
|
||||
text: String,
|
||||
entities: [MessageTextEntity] = [],
|
||||
additionalText: String? = nil,
|
||||
textColor: PeerInfoScreenLabeledValueTextColor = .primary,
|
||||
textBehavior: PeerInfoScreenLabeledValueTextBehavior = .singleLine,
|
||||
|
|
@ -100,7 +104,9 @@ final class PeerInfoScreenLabeledValueItem: PeerInfoScreenItem {
|
|||
self.id = id
|
||||
self.context = context
|
||||
self.label = label
|
||||
self.rightLabel = rightLabel
|
||||
self.text = text
|
||||
self.entities = entities
|
||||
self.additionalText = additionalText
|
||||
self.textColor = textColor
|
||||
self.textBehavior = textBehavior
|
||||
|
|
@ -150,6 +156,7 @@ private final class PeerInfoScreenLabeledValueItemNode: PeerInfoScreenItemNode {
|
|||
private let selectionNode: PeerInfoScreenSelectableBackgroundNode
|
||||
private let maskNode: ASImageNode
|
||||
private let labelNode: ImmediateTextNode
|
||||
private let rightLabelNode: ImmediateTextNode
|
||||
private let textNode: ImmediateTextNode
|
||||
private let additionalTextNode: ImmediateTextNode
|
||||
private let measureTextNode: ImmediateTextNode
|
||||
|
|
@ -200,6 +207,10 @@ private final class PeerInfoScreenLabeledValueItemNode: PeerInfoScreenItemNode {
|
|||
self.labelNode.displaysAsynchronously = false
|
||||
self.labelNode.isUserInteractionEnabled = false
|
||||
|
||||
self.rightLabelNode = ImmediateTextNode()
|
||||
self.rightLabelNode.displaysAsynchronously = false
|
||||
self.rightLabelNode.isUserInteractionEnabled = false
|
||||
|
||||
self.textNode = ImmediateTextNode()
|
||||
self.textNode.displaysAsynchronously = false
|
||||
self.textNode.isUserInteractionEnabled = false
|
||||
|
|
@ -250,6 +261,7 @@ private final class PeerInfoScreenLabeledValueItemNode: PeerInfoScreenItemNode {
|
|||
self.contextSourceNode.contentNode.addSubnode(self.extractedBackgroundImageNode)
|
||||
|
||||
self.contextSourceNode.contentNode.addSubnode(self.labelNode)
|
||||
self.contextSourceNode.contentNode.addSubnode(self.rightLabelNode)
|
||||
self.contextSourceNode.contentNode.addSubnode(self.textNode)
|
||||
self.contextSourceNode.contentNode.addSubnode(self.additionalTextNode)
|
||||
|
||||
|
|
@ -488,6 +500,8 @@ private final class PeerInfoScreenLabeledValueItemNode: PeerInfoScreenItemNode {
|
|||
|
||||
self.labelNode.attributedText = NSAttributedString(string: item.label, font: Font.regular(14.0), textColor: presentationData.theme.list.itemPrimaryTextColor)
|
||||
|
||||
self.rightLabelNode.attributedText = NSAttributedString(string: item.rightLabel ?? "", font: Font.regular(14.0), textColor: presentationData.theme.list.itemSecondaryTextColor)
|
||||
|
||||
if let icon = item.icon {
|
||||
let iconImage: UIImage?
|
||||
switch icon {
|
||||
|
|
@ -541,26 +555,32 @@ private final class PeerInfoScreenLabeledValueItemNode: PeerInfoScreenItemNode {
|
|||
text = trimToLineCount(text, lineCount: 3)
|
||||
}
|
||||
|
||||
let fontSize: CGFloat = 17.0
|
||||
let baseFont = Font.regular(fontSize)
|
||||
let linkFont = baseFont
|
||||
let boldFont = Font.medium(fontSize)
|
||||
let italicFont = Font.italic(fontSize)
|
||||
let boldItalicFont = Font.semiboldItalic(fontSize)
|
||||
let titleFixedFont = Font.monospace(fontSize)
|
||||
|
||||
func createAttributedText(_ text: String) -> NSAttributedString {
|
||||
if enabledEntities.isEmpty {
|
||||
return NSAttributedString(string: text, font: Font.regular(17.0), textColor: textColorValue)
|
||||
return NSAttributedString(string: text, font: baseFont, textColor: textColorValue)
|
||||
} else {
|
||||
let fontSize: CGFloat = 17.0
|
||||
|
||||
let baseFont = Font.regular(fontSize)
|
||||
let linkFont = baseFont
|
||||
let boldFont = Font.medium(fontSize)
|
||||
let italicFont = Font.italic(fontSize)
|
||||
let boldItalicFont = Font.semiboldItalic(fontSize)
|
||||
let titleFixedFont = Font.monospace(fontSize)
|
||||
|
||||
let entities = generateTextEntities(text, enabledTypes: enabledEntities)
|
||||
return stringWithAppliedEntities(text, entities: entities, baseColor: textColorValue, linkColor: presentationData.theme.list.itemAccentColor, baseFont: baseFont, linkFont: linkFont, boldFont: boldFont, italicFont: italicFont, boldItalicFont: boldItalicFont, fixedFont: titleFixedFont, blockQuoteFont: baseFont, message: nil)
|
||||
}
|
||||
}
|
||||
|
||||
self.measureTextNode.maximumNumberOfLines = 0
|
||||
self.measureTextNode.attributedText = createAttributedText(originalText)
|
||||
|
||||
if !item.entities.isEmpty {
|
||||
self.measureTextNode.attributedText = stringWithAppliedEntities(originalText, entities: item.entities, baseColor: textColorValue, linkColor: presentationData.theme.list.itemAccentColor, baseFont: baseFont, linkFont: linkFont, boldFont: boldFont, italicFont: italicFont, boldItalicFont: boldItalicFont, fixedFont: titleFixedFont, blockQuoteFont: baseFont, message: nil)
|
||||
self.textNode.attributedText = stringWithAppliedEntities(text, entities: item.entities, baseColor: textColorValue, linkColor: presentationData.theme.list.itemAccentColor, baseFont: baseFont, linkFont: linkFont, boldFont: boldFont, italicFont: italicFont, boldItalicFont: boldItalicFont, fixedFont: titleFixedFont, blockQuoteFont: baseFont, message: nil)
|
||||
} else {
|
||||
self.measureTextNode.attributedText = createAttributedText(originalText)
|
||||
self.textNode.attributedText = createAttributedText(text)
|
||||
}
|
||||
|
||||
let textLayout = self.measureTextNode.updateLayoutInfo(CGSize(width: width - sideInset * 2.0 - additionalSideInset, height: .greatestFiniteMagnitude))
|
||||
var collapsedNumberOfLines = 3
|
||||
|
|
@ -568,7 +588,7 @@ private final class PeerInfoScreenLabeledValueItemNode: PeerInfoScreenItemNode {
|
|||
collapsedNumberOfLines = 4
|
||||
}
|
||||
|
||||
self.textNode.attributedText = createAttributedText(text)
|
||||
|
||||
|
||||
maxNumberOfLines = self.isExpanded ? maxLines : collapsedNumberOfLines
|
||||
self.textNode.maximumNumberOfLines = maxNumberOfLines
|
||||
|
|
@ -576,6 +596,7 @@ private final class PeerInfoScreenLabeledValueItemNode: PeerInfoScreenItemNode {
|
|||
|
||||
|
||||
let labelSize = self.labelNode.updateLayout(CGSize(width: width - sideInset * 2.0, height: .greatestFiniteMagnitude))
|
||||
let rightLabelSize = self.rightLabelNode.updateLayout(CGSize(width: width - sideInset * 2.0, height: .greatestFiniteMagnitude))
|
||||
let textLayout = self.textNode.updateLayoutInfo(CGSize(width: width - sideInset * 2.0 - additionalSideInset, height: .greatestFiniteMagnitude))
|
||||
let textSize = textLayout.size
|
||||
|
||||
|
|
@ -601,6 +622,7 @@ private final class PeerInfoScreenLabeledValueItemNode: PeerInfoScreenItemNode {
|
|||
var topOffset = 11.0
|
||||
var height = topOffset * 2.0
|
||||
let labelFrame = CGRect(origin: CGPoint(x: sideInset, y: topOffset), size: labelSize)
|
||||
let rightLabelFrame = CGRect(origin: CGPoint(x: width - sideInset - rightLabelSize.width, y: topOffset), size: rightLabelSize)
|
||||
if labelSize.height > 0.0 {
|
||||
topOffset += labelSize.height + 3.0
|
||||
height += labelSize.height + 3.0
|
||||
|
|
@ -653,6 +675,7 @@ private final class PeerInfoScreenLabeledValueItemNode: PeerInfoScreenItemNode {
|
|||
self.expandBackgroundNode.image = generateExpandBackground(size: expandBackgroundFrame.size, color: presentationData.theme.list.itemBlocksBackgroundColor)
|
||||
|
||||
transition.updateFrame(node: self.labelNode, frame: labelFrame)
|
||||
transition.updateFrame(node: self.rightLabelNode, frame: rightLabelFrame)
|
||||
|
||||
var textTransition = transition
|
||||
if self.textNode.frame.size != textFrame.size {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,121 @@
|
|||
import Foundation
|
||||
import UIKit
|
||||
import AsyncDisplayKit
|
||||
import Display
|
||||
import TelegramPresentationData
|
||||
import TelegramCore
|
||||
import AccountContext
|
||||
import ComponentFlow
|
||||
import TextFieldComponent
|
||||
|
||||
final class PeerInfoScreenNoteListItem: PeerInfoScreenItem {
|
||||
let id: AnyHashable
|
||||
let initialValue: NSAttributedString
|
||||
let valueUpdated: (NSAttributedString) -> Void
|
||||
let requestLayout: (Bool) -> Void
|
||||
|
||||
init(
|
||||
id: AnyHashable,
|
||||
initialValue: NSAttributedString,
|
||||
valueUpdated: @escaping (NSAttributedString) -> Void,
|
||||
requestLayout: @escaping (Bool) -> Void
|
||||
) {
|
||||
self.id = id
|
||||
self.initialValue = initialValue
|
||||
self.valueUpdated = valueUpdated
|
||||
self.requestLayout = requestLayout
|
||||
}
|
||||
|
||||
func node() -> PeerInfoScreenItemNode {
|
||||
return PeerInfoScreenNoteListItemNode()
|
||||
}
|
||||
}
|
||||
|
||||
private final class PeerInfoScreenNoteListItemNode: PeerInfoScreenItemNode {
|
||||
private let maskNode: ASImageNode
|
||||
private let textField = ComponentView<Empty>()
|
||||
private let textFieldExternalState = TextFieldComponent.ExternalState()
|
||||
|
||||
private let state = EmptyComponentState()
|
||||
|
||||
private let bottomSeparatorNode: ASDisplayNode
|
||||
|
||||
private var item: PeerInfoScreenNoteListItem?
|
||||
private var presentationData: PresentationData?
|
||||
private var theme: PresentationTheme?
|
||||
|
||||
override init() {
|
||||
self.maskNode = ASImageNode()
|
||||
self.maskNode.isUserInteractionEnabled = false
|
||||
|
||||
self.bottomSeparatorNode = ASDisplayNode()
|
||||
self.bottomSeparatorNode.isLayerBacked = true
|
||||
|
||||
super.init()
|
||||
|
||||
self.addSubnode(self.bottomSeparatorNode)
|
||||
|
||||
self.addSubnode(self.maskNode)
|
||||
}
|
||||
|
||||
override func update(context: AccountContext, width: CGFloat, safeInsets: UIEdgeInsets, presentationData: PresentationData, item: PeerInfoScreenItem, topItem: PeerInfoScreenItem?, bottomItem: PeerInfoScreenItem?, hasCorners: Bool, transition: ContainedViewLayoutTransition) -> CGFloat {
|
||||
guard let item = item as? PeerInfoScreenNoteListItem else {
|
||||
return 10.0
|
||||
}
|
||||
|
||||
var resetText: NSAttributedString?
|
||||
if self.item == nil {
|
||||
resetText = item.initialValue
|
||||
}
|
||||
|
||||
self.item = item
|
||||
self.presentationData = presentationData
|
||||
self.theme = presentationData.theme
|
||||
|
||||
let sideInset: CGFloat = 1.0 + safeInsets.left
|
||||
|
||||
self.bottomSeparatorNode.backgroundColor = presentationData.theme.list.itemBlocksSeparatorColor
|
||||
|
||||
self.state._updated = { [weak self] transition, _ in
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
self.item?.requestLayout(!transition.animation.isImmediate)
|
||||
}
|
||||
|
||||
var characterLimit: Int = 128
|
||||
if let data = context.currentAppConfiguration.with({ $0 }).data, let value = data["contact_note_length_limit"] as? Double {
|
||||
characterLimit = Int(value)
|
||||
}
|
||||
|
||||
self.textField.parentState = self.state
|
||||
let textFieldSize = self.textField.update(
|
||||
transition: .immediate,
|
||||
component: AnyComponent(TextFieldComponent(context: context, theme: presentationData.theme, strings: presentationData.strings, externalState: self.textFieldExternalState, fontSize: 17.0, textColor: presentationData.theme.list.itemPrimaryTextColor, accentColor: presentationData.theme.list.itemAccentColor, insets: UIEdgeInsets(top: 9.0, left: 8.0, bottom: 10.0, right: 8.0), hideKeyboard: false, customInputView: nil, placeholder: NSAttributedString(string: "Add notes", font: Font.regular(17.0), textColor: presentationData.theme.list.itemPlaceholderTextColor), resetText: resetText, isOneLineWhenUnfocused: false, characterLimit: characterLimit, formatMenuAvailability: .available([.bold, .italic, .underline, .strikethrough, .spoiler]), lockedFormatAction: {}, present: { c in }, paste: { _ in })),
|
||||
environment: {},
|
||||
containerSize: CGSize(width: width - sideInset * 2.0, height: .greatestFiniteMagnitude)
|
||||
)
|
||||
let textFieldFrame = CGRect(origin: CGPoint(x: sideInset, y: 3.0), size: textFieldSize)
|
||||
let height: CGFloat = 4.0 + textFieldSize.height
|
||||
if let textFieldView = self.textField.view {
|
||||
if textFieldView.superview == nil {
|
||||
self.view.addSubview(textFieldView)
|
||||
}
|
||||
transition.updateFrame(view: textFieldView, frame: textFieldFrame)
|
||||
}
|
||||
item.valueUpdated(self.textFieldExternalState.text)
|
||||
|
||||
transition.updateFrame(node: self.bottomSeparatorNode, frame: CGRect(origin: CGPoint(x: sideInset, y: height - UIScreenPixel), size: CGSize(width: width - sideInset, height: UIScreenPixel)))
|
||||
transition.updateAlpha(node: self.bottomSeparatorNode, alpha: bottomItem == nil ? 0.0 : 1.0)
|
||||
|
||||
let hasCorners = hasCorners && (topItem == nil || bottomItem == nil)
|
||||
let hasTopCorners = hasCorners && topItem == nil
|
||||
let hasBottomCorners = hasCorners && bottomItem == nil
|
||||
|
||||
self.maskNode.image = hasCorners ? PresentationResourcesItemList.cornersImage(presentationData.theme, top: hasTopCorners, bottom: hasBottomCorners) : nil
|
||||
self.maskNode.frame = CGRect(origin: CGPoint(x: safeInsets.left, y: 0.0), size: CGSize(width: width - safeInsets.left - safeInsets.right, height: height))
|
||||
self.bottomSeparatorNode.isHidden = hasBottomCorners
|
||||
|
||||
return height
|
||||
}
|
||||
}
|
||||
|
|
@ -34,6 +34,7 @@ final class PeerInfoState {
|
|||
let paneIsReordering: Bool
|
||||
let updatingAvatar: PeerInfoUpdatingAvatar?
|
||||
let updatingBio: String?
|
||||
let updatingNote: NSAttributedString?
|
||||
let avatarUploadProgress: AvatarUploadProgress?
|
||||
let highlightedButton: PeerInfoHeaderButtonKey?
|
||||
let isEditingBirthDate: Bool
|
||||
|
|
@ -47,6 +48,7 @@ final class PeerInfoState {
|
|||
paneIsReordering: Bool,
|
||||
updatingAvatar: PeerInfoUpdatingAvatar?,
|
||||
updatingBio: String?,
|
||||
updatingNote: NSAttributedString?,
|
||||
avatarUploadProgress: AvatarUploadProgress?,
|
||||
highlightedButton: PeerInfoHeaderButtonKey?,
|
||||
isEditingBirthDate: Bool,
|
||||
|
|
@ -59,6 +61,7 @@ final class PeerInfoState {
|
|||
self.paneIsReordering = paneIsReordering
|
||||
self.updatingAvatar = updatingAvatar
|
||||
self.updatingBio = updatingBio
|
||||
self.updatingNote = updatingNote
|
||||
self.avatarUploadProgress = avatarUploadProgress
|
||||
self.highlightedButton = highlightedButton
|
||||
self.isEditingBirthDate = isEditingBirthDate
|
||||
|
|
@ -74,6 +77,7 @@ final class PeerInfoState {
|
|||
paneIsReordering: self.paneIsReordering,
|
||||
updatingAvatar: self.updatingAvatar,
|
||||
updatingBio: self.updatingBio,
|
||||
updatingNote: self.updatingNote,
|
||||
avatarUploadProgress: self.avatarUploadProgress,
|
||||
highlightedButton: self.highlightedButton,
|
||||
isEditingBirthDate: self.isEditingBirthDate,
|
||||
|
|
@ -90,6 +94,7 @@ final class PeerInfoState {
|
|||
paneIsReordering: self.paneIsReordering,
|
||||
updatingAvatar: self.updatingAvatar,
|
||||
updatingBio: self.updatingBio,
|
||||
updatingNote: self.updatingNote,
|
||||
avatarUploadProgress: self.avatarUploadProgress,
|
||||
highlightedButton: self.highlightedButton,
|
||||
isEditingBirthDate: self.isEditingBirthDate,
|
||||
|
|
@ -106,6 +111,7 @@ final class PeerInfoState {
|
|||
paneIsReordering: self.paneIsReordering,
|
||||
updatingAvatar: self.updatingAvatar,
|
||||
updatingBio: self.updatingBio,
|
||||
updatingNote: self.updatingNote,
|
||||
avatarUploadProgress: self.avatarUploadProgress,
|
||||
highlightedButton: self.highlightedButton,
|
||||
isEditingBirthDate: self.isEditingBirthDate,
|
||||
|
|
@ -122,6 +128,7 @@ final class PeerInfoState {
|
|||
paneIsReordering: paneIsReordering,
|
||||
updatingAvatar: self.updatingAvatar,
|
||||
updatingBio: self.updatingBio,
|
||||
updatingNote: self.updatingNote,
|
||||
avatarUploadProgress: self.avatarUploadProgress,
|
||||
highlightedButton: self.highlightedButton,
|
||||
isEditingBirthDate: self.isEditingBirthDate,
|
||||
|
|
@ -138,6 +145,7 @@ final class PeerInfoState {
|
|||
paneIsReordering: self.paneIsReordering,
|
||||
updatingAvatar: updatingAvatar,
|
||||
updatingBio: self.updatingBio,
|
||||
updatingNote: self.updatingNote,
|
||||
avatarUploadProgress: self.avatarUploadProgress,
|
||||
highlightedButton: self.highlightedButton,
|
||||
isEditingBirthDate: self.isEditingBirthDate,
|
||||
|
|
@ -154,6 +162,24 @@ final class PeerInfoState {
|
|||
paneIsReordering: self.paneIsReordering,
|
||||
updatingAvatar: self.updatingAvatar,
|
||||
updatingBio: updatingBio,
|
||||
updatingNote: self.updatingNote,
|
||||
avatarUploadProgress: self.avatarUploadProgress,
|
||||
highlightedButton: self.highlightedButton,
|
||||
isEditingBirthDate: self.isEditingBirthDate,
|
||||
updatingBirthDate: self.updatingBirthDate,
|
||||
personalChannels: self.personalChannels
|
||||
)
|
||||
}
|
||||
|
||||
func withUpdatingNote(_ updatingNote: NSAttributedString?) -> PeerInfoState {
|
||||
return PeerInfoState(
|
||||
isEditing: self.isEditing,
|
||||
selectedMessageIds: self.selectedMessageIds,
|
||||
selectedStoryIds: self.selectedStoryIds,
|
||||
paneIsReordering: self.paneIsReordering,
|
||||
updatingAvatar: self.updatingAvatar,
|
||||
updatingBio: self.updatingBio,
|
||||
updatingNote: updatingNote,
|
||||
avatarUploadProgress: self.avatarUploadProgress,
|
||||
highlightedButton: self.highlightedButton,
|
||||
isEditingBirthDate: self.isEditingBirthDate,
|
||||
|
|
@ -170,6 +196,7 @@ final class PeerInfoState {
|
|||
paneIsReordering: self.paneIsReordering,
|
||||
updatingAvatar: self.updatingAvatar,
|
||||
updatingBio: self.updatingBio,
|
||||
updatingNote: self.updatingNote,
|
||||
avatarUploadProgress: avatarUploadProgress,
|
||||
highlightedButton: self.highlightedButton,
|
||||
isEditingBirthDate: self.isEditingBirthDate,
|
||||
|
|
@ -186,6 +213,7 @@ final class PeerInfoState {
|
|||
paneIsReordering: self.paneIsReordering,
|
||||
updatingAvatar: self.updatingAvatar,
|
||||
updatingBio: self.updatingBio,
|
||||
updatingNote: self.updatingNote,
|
||||
avatarUploadProgress: self.avatarUploadProgress,
|
||||
highlightedButton: highlightedButton,
|
||||
isEditingBirthDate: self.isEditingBirthDate,
|
||||
|
|
@ -202,6 +230,7 @@ final class PeerInfoState {
|
|||
paneIsReordering: self.paneIsReordering,
|
||||
updatingAvatar: self.updatingAvatar,
|
||||
updatingBio: self.updatingBio,
|
||||
updatingNote: self.updatingNote,
|
||||
avatarUploadProgress: self.avatarUploadProgress,
|
||||
highlightedButton: self.highlightedButton,
|
||||
isEditingBirthDate: isEditingBirthDate,
|
||||
|
|
@ -218,6 +247,7 @@ final class PeerInfoState {
|
|||
paneIsReordering: self.paneIsReordering,
|
||||
updatingAvatar: self.updatingAvatar,
|
||||
updatingBio: self.updatingBio,
|
||||
updatingNote: self.updatingNote,
|
||||
avatarUploadProgress: self.avatarUploadProgress,
|
||||
highlightedButton: self.highlightedButton,
|
||||
isEditingBirthDate: self.isEditingBirthDate,
|
||||
|
|
@ -234,6 +264,7 @@ final class PeerInfoState {
|
|||
paneIsReordering: self.paneIsReordering,
|
||||
updatingAvatar: self.updatingAvatar,
|
||||
updatingBio: self.updatingBio,
|
||||
updatingNote: self.updatingNote,
|
||||
avatarUploadProgress: self.avatarUploadProgress,
|
||||
highlightedButton: self.highlightedButton,
|
||||
isEditingBirthDate: self.isEditingBirthDate,
|
||||
|
|
|
|||
|
|
@ -540,6 +540,7 @@ private enum PeerInfoSettingsSection {
|
|||
case logout
|
||||
case rememberPassword
|
||||
case emojiStatus
|
||||
case profileColor
|
||||
case powerSaving
|
||||
case businessSetup
|
||||
case profile
|
||||
|
|
@ -567,6 +568,7 @@ private final class PeerInfoInteraction {
|
|||
let editingOpenSoundSettings: () -> Void
|
||||
let editingToggleShowMessageText: (Bool) -> Void
|
||||
let requestDeleteContact: () -> Void
|
||||
let suggestBirthdate: () -> Void
|
||||
let suggestPhoto: () -> Void
|
||||
let setCustomPhoto: () -> Void
|
||||
let resetCustomPhoto: () -> Void
|
||||
|
|
@ -605,6 +607,7 @@ private final class PeerInfoInteraction {
|
|||
let logoutAccount: (AccountRecordId) -> Void
|
||||
let accountContextMenu: (AccountRecordId, ASDisplayNode, ContextGesture?) -> Void
|
||||
let updateBio: (String) -> Void
|
||||
let updateNote: (NSAttributedString) -> Void
|
||||
let openDeletePeer: () -> Void
|
||||
let openFaq: (String?) -> Void
|
||||
let openAddMember: () -> Void
|
||||
|
|
@ -640,6 +643,7 @@ private final class PeerInfoInteraction {
|
|||
editingOpenSoundSettings: @escaping () -> Void,
|
||||
editingToggleShowMessageText: @escaping (Bool) -> Void,
|
||||
requestDeleteContact: @escaping () -> Void,
|
||||
suggestBirthdate: @escaping () -> Void,
|
||||
suggestPhoto: @escaping () -> Void,
|
||||
setCustomPhoto: @escaping () -> Void,
|
||||
resetCustomPhoto: @escaping () -> Void,
|
||||
|
|
@ -679,6 +683,7 @@ private final class PeerInfoInteraction {
|
|||
logoutAccount: @escaping (AccountRecordId) -> Void,
|
||||
accountContextMenu: @escaping (AccountRecordId, ASDisplayNode, ContextGesture?) -> Void,
|
||||
updateBio: @escaping (String) -> Void,
|
||||
updateNote: @escaping (NSAttributedString) -> Void,
|
||||
openDeletePeer: @escaping () -> Void,
|
||||
openFaq: @escaping (String?) -> Void,
|
||||
openAddMember: @escaping () -> Void,
|
||||
|
|
@ -713,6 +718,7 @@ private final class PeerInfoInteraction {
|
|||
self.editingOpenSoundSettings = editingOpenSoundSettings
|
||||
self.editingToggleShowMessageText = editingToggleShowMessageText
|
||||
self.requestDeleteContact = requestDeleteContact
|
||||
self.suggestBirthdate = suggestBirthdate
|
||||
self.suggestPhoto = suggestPhoto
|
||||
self.setCustomPhoto = setCustomPhoto
|
||||
self.resetCustomPhoto = resetCustomPhoto
|
||||
|
|
@ -752,6 +758,7 @@ private final class PeerInfoInteraction {
|
|||
self.logoutAccount = logoutAccount
|
||||
self.accountContextMenu = accountContextMenu
|
||||
self.updateBio = updateBio
|
||||
self.updateNote = updateNote
|
||||
self.openDeletePeer = openDeletePeer
|
||||
self.openFaq = openFaq
|
||||
self.openAddMember = openAddMember
|
||||
|
|
@ -810,13 +817,10 @@ private func settingsItems(data: PeerInfoScreenData?, context: AccountContext, p
|
|||
}
|
||||
|
||||
let setPhotoTitle: String
|
||||
let displaySetPhoto: Bool
|
||||
if let peer = data.peer, !peer.profileImageRepresentations.isEmpty {
|
||||
setPhotoTitle = presentationData.strings.Settings_ChangeProfilePhoto
|
||||
displaySetPhoto = true
|
||||
} else {
|
||||
setPhotoTitle = presentationData.strings.Settings_SetProfilePhotoOrVideo
|
||||
displaySetPhoto = true
|
||||
}
|
||||
|
||||
var setStatusTitle: String = ""
|
||||
|
|
@ -838,15 +842,18 @@ private func settingsItems(data: PeerInfoScreenData?, context: AccountContext, p
|
|||
items[.edit]!.append(PeerInfoScreenActionItem(id: 0, text: setStatusTitle, icon: UIImage(bundleImageName: hasEmojiStatus ? "Settings/EditEmojiStatus" : "Settings/SetEmojiStatus"), action: {
|
||||
interaction.openSettings(.emojiStatus)
|
||||
}))
|
||||
}
|
||||
|
||||
if displaySetPhoto {
|
||||
items[.edit]!.append(PeerInfoScreenActionItem(id: 1, text: setPhotoTitle, icon: UIImage(bundleImageName: "Settings/SetAvatar"), action: {
|
||||
interaction.openSettings(.avatar)
|
||||
|
||||
items[.edit]!.append(PeerInfoScreenActionItem(id: 1, text: presentationData.strings.PeerInfo_ChangeProfileColor, icon: UIImage(bundleImageName: "Premium/BoostPerk/CoverColor"), action: {
|
||||
interaction.openSettings(.profileColor)
|
||||
}))
|
||||
}
|
||||
|
||||
items[.edit]!.append(PeerInfoScreenActionItem(id: 2, text: setPhotoTitle, icon: UIImage(bundleImageName: "Settings/SetAvatar"), action: {
|
||||
interaction.openSettings(.avatar)
|
||||
}))
|
||||
|
||||
if let peer = data.peer, (peer.addressName ?? "").isEmpty {
|
||||
items[.edit]!.append(PeerInfoScreenActionItem(id: 2, text: presentationData.strings.Settings_SetUsername, icon: UIImage(bundleImageName: "Settings/SetUsername"), action: {
|
||||
items[.edit]!.append(PeerInfoScreenActionItem(id: 3, text: presentationData.strings.Settings_SetUsername, icon: UIImage(bundleImageName: "Settings/SetUsername"), action: {
|
||||
interaction.openSettings(.username)
|
||||
}))
|
||||
}
|
||||
|
|
@ -1415,6 +1422,10 @@ private func infoItems(data: PeerInfoScreenData?, context: AccountContext, prese
|
|||
if let about = cachedData.about, !about.isEmpty {
|
||||
hasAbout = true
|
||||
}
|
||||
var hasNote = false
|
||||
if let note = cachedData.note, !note.text.isEmpty {
|
||||
hasNote = true
|
||||
}
|
||||
|
||||
var hasWebApp = false
|
||||
if let botInfo = user.botInfo, botInfo.flags.contains(.hasWebApp) {
|
||||
|
|
@ -1429,7 +1440,7 @@ private func infoItems(data: PeerInfoScreenData?, context: AccountContext, prese
|
|||
items[currentPeerInfoSection]!.append(PeerInfoScreenLabeledValueItem(id: 0, label: user.botInfo == nil ? presentationData.strings.Profile_About : presentationData.strings.Profile_BotInfo, text: user.botInfo != nil ? presentationData.strings.UserInfo_ScamBotWarning : presentationData.strings.UserInfo_ScamUserWarning, textColor: .primary, textBehavior: .multiLine(maxLines: 100, enabledEntities: user.botInfo != nil ? enabledPrivateBioEntities : []), action: nil, requestLayout: { animated in
|
||||
interaction.requestLayout(animated)
|
||||
}))
|
||||
} else if hasAbout || hasWebApp {
|
||||
} else if hasAbout || hasNote || hasWebApp {
|
||||
var actionButton: PeerInfoScreenLabeledValueItem.Button?
|
||||
if hasWebApp {
|
||||
actionButton = PeerInfoScreenLabeledValueItem.Button(title: presentationData.strings.PeerInfo_OpenAppButton, action: {
|
||||
|
|
@ -1464,16 +1475,23 @@ private func infoItems(data: PeerInfoScreenData?, context: AccountContext, prese
|
|||
})
|
||||
}
|
||||
|
||||
var label: String = ""
|
||||
if let about = cachedData.about, !about.isEmpty {
|
||||
label = user.botInfo == nil ? presentationData.strings.Profile_About : presentationData.strings.Profile_BotInfo
|
||||
if hasAbout || hasWebApp {
|
||||
var label: String = ""
|
||||
if let about = cachedData.about, !about.isEmpty {
|
||||
label = user.botInfo == nil ? presentationData.strings.Profile_About : presentationData.strings.Profile_BotInfo
|
||||
}
|
||||
items[currentPeerInfoSection]!.append(PeerInfoScreenLabeledValueItem(id: 0, label: label, text: cachedData.about ?? "", textColor: .primary, textBehavior: .multiLine(maxLines: 100, enabledEntities: user.isPremium ? enabledPublicBioEntities : enabledPrivateBioEntities), action: isMyProfile ? { node, _ in
|
||||
bioContextAction(node, nil, nil)
|
||||
} : nil, linkItemAction: bioLinkAction, button: actionButton, contextAction: bioContextAction, requestLayout: { animated in
|
||||
interaction.requestLayout(animated)
|
||||
}))
|
||||
}
|
||||
|
||||
items[currentPeerInfoSection]!.append(PeerInfoScreenLabeledValueItem(id: 0, label: label, text: cachedData.about ?? "", textColor: .primary, textBehavior: .multiLine(maxLines: 100, enabledEntities: user.isPremium ? enabledPublicBioEntities : enabledPrivateBioEntities), action: isMyProfile ? { node, _ in
|
||||
bioContextAction(node, nil, nil)
|
||||
} : nil, linkItemAction: bioLinkAction, button: actionButton, contextAction: bioContextAction, requestLayout: { animated in
|
||||
interaction.requestLayout(animated)
|
||||
}))
|
||||
if let note = cachedData.note, !note.text.isEmpty {
|
||||
items[currentPeerInfoSection]!.append(PeerInfoScreenLabeledValueItem(id: 0, label: "notes", rightLabel: "only visible to you", text: note.text, entities: note.entities, textColor: .primary, textBehavior: .multiLine(maxLines: 100, enabledEntities: []), action: nil, linkItemAction: bioLinkAction, button: nil, contextAction: bioContextAction, requestLayout: { animated in
|
||||
interaction.requestLayout(animated)
|
||||
}))
|
||||
}
|
||||
|
||||
if let botInfo = user.botInfo, botInfo.flags.contains(.canEdit) {
|
||||
items[currentPeerInfoSection]!.append(PeerInfoScreenCommentItem(id: 800, text: presentationData.strings.PeerInfo_AppFooterAdmin, linkAction: { action in
|
||||
|
|
@ -2067,6 +2085,7 @@ private func editingItems(data: PeerInfoScreenData?, boostStatus: ChannelBoostSt
|
|||
case notifications
|
||||
case groupLocation
|
||||
case peerPublicSettings
|
||||
case peerNote
|
||||
case peerDataSettings
|
||||
case peerVerifySettings
|
||||
case peerSettings
|
||||
|
|
@ -2082,20 +2101,24 @@ private func editingItems(data: PeerInfoScreenData?, boostStatus: ChannelBoostSt
|
|||
|
||||
if let data = data {
|
||||
if let user = data.peer as? TelegramUser {
|
||||
let ItemSuggest = 0
|
||||
let ItemCustom = 1
|
||||
let ItemReset = 2
|
||||
let ItemInfo = 3
|
||||
let ItemDelete = 4
|
||||
let ItemUsername = 5
|
||||
let ItemAffiliateProgram = 6
|
||||
let ItemNote = 0
|
||||
let ItemNoteInfo = 1
|
||||
|
||||
let ItemVerify = 8
|
||||
let ItemSuggestBirthdate = 2
|
||||
let ItemSuggestPhoto = 3
|
||||
let ItemCustomPhoto = 4
|
||||
let ItemReset = 5
|
||||
let ItemInfo = 6
|
||||
let ItemDelete = 7
|
||||
let ItemUsername = 8
|
||||
let ItemAffiliateProgram = 9
|
||||
|
||||
let ItemIntro = 8
|
||||
let ItemCommands = 9
|
||||
let ItemBotSettings = 10
|
||||
let ItemBotInfo = 11
|
||||
let ItemVerify = 10
|
||||
|
||||
let ItemIntro = 11
|
||||
let ItemCommands = 12
|
||||
let ItemBotSettings = 13
|
||||
let ItemBotInfo = 14
|
||||
|
||||
if let botInfo = user.botInfo, botInfo.flags.contains(.canEdit) {
|
||||
items[.peerDataSettings]!.append(PeerInfoScreenDisclosureItem(id: ItemUsername, label: .text("@\(user.addressName ?? "")"), text: presentationData.strings.PeerInfo_Bot_Username, icon: PresentationResourcesSettings.bot, action: {
|
||||
|
|
@ -2144,12 +2167,34 @@ private func editingItems(data: PeerInfoScreenData?, boostStatus: ChannelBoostSt
|
|||
} else if !user.flags.contains(.isSupport) {
|
||||
let compactName = EnginePeer(user).compactDisplayTitle
|
||||
|
||||
if let cachedData = data.cachedData as? CachedUserData, let _ = cachedData.sendPaidMessageStars {
|
||||
if let cachedData = data.cachedData as? CachedUserData {
|
||||
//TODO:localize
|
||||
items[.peerNote]!.append(PeerInfoScreenNoteListItem(
|
||||
id: ItemNote,
|
||||
initialValue: chatInputStateStringWithAppliedEntities(cachedData.note?.text ?? "", entities: cachedData.note?.entities ?? []),
|
||||
valueUpdated: { value in
|
||||
interaction.updateNote(value)
|
||||
},
|
||||
requestLayout: { animated in
|
||||
interaction.requestLayout(animated)
|
||||
}
|
||||
))
|
||||
|
||||
} else {
|
||||
items[.peerDataSettings]!.append(PeerInfoScreenActionItem(id: ItemSuggest, text: presentationData.strings.UserInfo_SuggestPhoto(compactName).string, color: .accent, icon: UIImage(bundleImageName: "Peer Info/SuggestAvatar"), action: {
|
||||
interaction.suggestPhoto()
|
||||
}))
|
||||
items[.peerNote]!.append(PeerInfoScreenCommentItem(id: ItemNoteInfo, text: "Notes are only visible to you."))
|
||||
|
||||
if let _ = cachedData.sendPaidMessageStars {
|
||||
|
||||
} else {
|
||||
if cachedData.birthday == nil {
|
||||
items[.peerDataSettings]!.append(PeerInfoScreenActionItem(id: ItemSuggestBirthdate, text: presentationData.strings.UserInfo_SuggestBirthdate, color: .accent, icon: UIImage(bundleImageName: "Contact List/AddBirthdayIcon"), action: {
|
||||
interaction.suggestBirthdate()
|
||||
}))
|
||||
}
|
||||
|
||||
items[.peerDataSettings]!.append(PeerInfoScreenActionItem(id: ItemSuggestPhoto, text: presentationData.strings.UserInfo_SuggestPhoto(compactName).string, color: .accent, icon: UIImage(bundleImageName: "Peer Info/SuggestAvatar"), action: {
|
||||
interaction.suggestPhoto()
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
let setText: String
|
||||
|
|
@ -2159,7 +2204,7 @@ private func editingItems(data: PeerInfoScreenData?, boostStatus: ChannelBoostSt
|
|||
setText = presentationData.strings.UserInfo_SetCustomPhoto(compactName).string
|
||||
}
|
||||
|
||||
items[.peerDataSettings]!.append(PeerInfoScreenActionItem(id: ItemCustom, text: setText, color: .accent, icon: UIImage(bundleImageName: "Settings/SetAvatar"), action: {
|
||||
items[.peerDataSettings]!.append(PeerInfoScreenActionItem(id: ItemCustomPhoto, text: setText, color: .accent, icon: UIImage(bundleImageName: "Settings/SetAvatar"), action: {
|
||||
interaction.setCustomPhoto()
|
||||
}))
|
||||
|
||||
|
|
@ -2972,6 +3017,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro
|
|||
paneIsReordering: false,
|
||||
updatingAvatar: nil,
|
||||
updatingBio: nil,
|
||||
updatingNote: nil,
|
||||
avatarUploadProgress: nil,
|
||||
highlightedButton: nil,
|
||||
isEditingBirthDate: false,
|
||||
|
|
@ -3097,6 +3143,9 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro
|
|||
requestDeleteContact: { [weak self] in
|
||||
self?.requestDeleteContact()
|
||||
},
|
||||
suggestBirthdate: { [weak self] in
|
||||
self?.suggestBirthdate()
|
||||
},
|
||||
suggestPhoto: { [weak self] in
|
||||
self?.suggestPhoto()
|
||||
},
|
||||
|
|
@ -3214,6 +3263,11 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro
|
|||
updateBio: { [weak self] bio in
|
||||
self?.updateBio(bio)
|
||||
},
|
||||
updateNote: { [weak self] note in
|
||||
if let self {
|
||||
self.state = self.state.withUpdatingNote(note)
|
||||
}
|
||||
},
|
||||
openDeletePeer: { [weak self] in
|
||||
self?.openDeletePeer()
|
||||
},
|
||||
|
|
@ -4451,7 +4505,22 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro
|
|||
let firstName = strongSelf.headerNode.editingContentNode.editingTextForKey(.firstName) ?? ""
|
||||
let lastName = strongSelf.headerNode.editingContentNode.editingTextForKey(.lastName) ?? ""
|
||||
|
||||
if (peer.firstName ?? "") != firstName || (peer.lastName ?? "") != lastName {
|
||||
let note = strongSelf.state.updatingNote
|
||||
|
||||
let firstNameUpdated = (peer.firstName ?? "") != firstName
|
||||
let lastNameUpdated = (peer.lastName ?? "") != lastName
|
||||
var noteUpdated = false
|
||||
|
||||
if let cachedData = data.cachedData as? CachedUserData {
|
||||
if let note {
|
||||
let updatedEntities = generateChatInputTextEntities(note)
|
||||
if note.string != (cachedData.note?.text ?? "") || updatedEntities != (cachedData.note?.entities ?? []) {
|
||||
noteUpdated = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if firstNameUpdated || lastNameUpdated || noteUpdated {
|
||||
if firstName.isEmpty && lastName.isEmpty {
|
||||
strongSelf.hapticFeedback.error()
|
||||
strongSelf.headerNode.editingContentNode.shakeTextForKey(.firstName)
|
||||
|
|
@ -4466,8 +4535,32 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro
|
|||
}
|
||||
strongSelf.controller?.present(statusController, in: .window(.root))
|
||||
|
||||
strongSelf.activeActionDisposable.set((context.engine.contacts.updateContactName(peerId: peer.id, firstName: firstName, lastName: lastName)
|
||||
|> deliverOnMainQueue).startStrict(error: { _ in
|
||||
enum ContactUpdateError {
|
||||
case generic
|
||||
}
|
||||
let nameUpdateSignal: Signal<Never, ContactUpdateError>
|
||||
if firstNameUpdated || lastNameUpdated {
|
||||
nameUpdateSignal = context.engine.contacts.updateContactName(peerId: peer.id, firstName: firstName, lastName: lastName)
|
||||
|> mapError { _ -> ContactUpdateError in
|
||||
return .generic
|
||||
}
|
||||
|> ignoreValues
|
||||
} else {
|
||||
nameUpdateSignal = .complete()
|
||||
}
|
||||
|
||||
let noteUpdateSignal: Signal<Never, ContactUpdateError>
|
||||
if noteUpdated, let note {
|
||||
let entities = generateChatInputTextEntities(note)
|
||||
noteUpdateSignal = context.engine.contacts.updateContactNote(peerId: peer.id, text: note.string, entities: entities)
|
||||
|> mapError { _ -> ContactUpdateError in
|
||||
return .generic
|
||||
}
|
||||
} else {
|
||||
noteUpdateSignal = .complete()
|
||||
}
|
||||
|
||||
strongSelf.activeActionDisposable.set(combineLatest(queue: Queue.mainQueue(), nameUpdateSignal, noteUpdateSignal).startStrict(error: { _ in
|
||||
dismissStatus?()
|
||||
|
||||
guard let strongSelf = self else {
|
||||
|
|
@ -4482,7 +4575,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro
|
|||
}
|
||||
let context = strongSelf.context
|
||||
|
||||
let _ = (getUserPeer(engine: strongSelf.context.engine, peerId: peer.id)
|
||||
let _ = (getUserPeer(engine: context.engine, peerId: peer.id)
|
||||
|> mapToSignal { peer -> Signal<Void, NoError> in
|
||||
guard case let .user(peer) = peer, let phone = peer.phone, !phone.isEmpty else {
|
||||
return .complete()
|
||||
|
|
@ -4633,7 +4726,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro
|
|||
strongSelf.headerNode.navigationButtonContainer.performAction?(.cancel, nil, nil)
|
||||
}
|
||||
} else {
|
||||
strongSelf.state = strongSelf.state.withIsEditing(false).withUpdatingBio(nil).withUpdatingBirthDate(nil).withIsEditingBirthDate(false)
|
||||
strongSelf.state = strongSelf.state.withIsEditing(false).withUpdatingBio(nil).withUpdatingBirthDate(nil).withIsEditingBirthDate(false).withUpdatingNote(nil)
|
||||
if let (layout, navigationHeight) = strongSelf.validLayout {
|
||||
strongSelf.scrollNode.view.setContentOffset(CGPoint(), animated: false)
|
||||
strongSelf.containerLayoutUpdated(layout: layout, navigationHeight: navigationHeight, transition: .immediate, additive: false)
|
||||
|
|
@ -7607,7 +7700,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro
|
|||
strongSelf.controller?.present(UndoOverlayController(presentationData: presentationData, content: .forward(savedMessages: savedMessages, text: text), elevatedLayout: false, animateInAsReplacement: true, action: { action in
|
||||
if savedMessages, let self, action == .info {
|
||||
let _ = (self.context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: self.context.account.peerId))
|
||||
|> deliverOnMainQueue).start(next: { [weak self] peer in
|
||||
|> deliverOnMainQueue).start(next: { [weak self] peer in
|
||||
guard let self, let peer else {
|
||||
return
|
||||
}
|
||||
|
|
@ -10757,6 +10850,8 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro
|
|||
push(controller)
|
||||
case .emojiStatus:
|
||||
self.headerNode.invokeDisplayPremiumIntro()
|
||||
case .profileColor:
|
||||
self.interaction.editingOpenNameColorSetup()
|
||||
case .powerSaving:
|
||||
push(energySavingSettingsScreen(context: self.context))
|
||||
case .businessSetup:
|
||||
|
|
@ -12214,6 +12309,24 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro
|
|||
peerController.present(controller, in: .window(.root))
|
||||
}
|
||||
|
||||
private func suggestBirthdate() {
|
||||
let controller = context.sharedContext.makeBirthdaySuggestionScreen(
|
||||
context: self.context,
|
||||
peerId: self.peerId,
|
||||
completion: { [weak self] value in
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
|
||||
let _ = self.context.engine.peers.suggestBirthday(peerId: self.peerId, birthday: value).startStandalone()
|
||||
|
||||
self.headerNode.navigationButtonContainer.performAction?(.cancel, nil, nil)
|
||||
self.openChat(peerId: self.peerId)
|
||||
}
|
||||
)
|
||||
self.controller?.push(controller)
|
||||
}
|
||||
|
||||
private func suggestPhoto() {
|
||||
self.controller?.openAvatarForEditing(mode: .suggest)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -935,7 +935,7 @@ public final class PeerInfoGiftsPaneNode: ASDisplayNode, PeerInfoPaneNode, UIScr
|
|||
}
|
||||
|
||||
let bottomContentOffset = max(0.0, self.scrollNode.view.contentSize.height - self.scrollNode.view.contentOffset.y - self.scrollNode.view.frame.height)
|
||||
if interactive, bottomContentOffset < 200.0 {
|
||||
if bottomContentOffset < 200.0 {
|
||||
self.giftsListView.loadMore()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,8 +24,8 @@ swift_library(
|
|||
"//submodules/AppBundle",
|
||||
"//submodules/Components/SheetComponent",
|
||||
"//submodules/PresentationDataUtils",
|
||||
"//submodules/Components/SolidRoundedButtonComponent",
|
||||
"//submodules/TelegramUI/Components/ButtonComponent",
|
||||
"//submodules/TelegramUI/Components/PlainButtonComponent",
|
||||
],
|
||||
visibility = [
|
||||
"//visibility:public",
|
||||
|
|
|
|||
|
|
@ -8,6 +8,14 @@ import AccountContext
|
|||
import ComponentFlow
|
||||
|
||||
public final class BirthdayPickerComponent: Component {
|
||||
public final class TransitionHint {
|
||||
public let animate: Bool
|
||||
|
||||
public init(animate: Bool) {
|
||||
self.animate = animate
|
||||
}
|
||||
}
|
||||
|
||||
public struct Theme: Equatable {
|
||||
let backgroundColor: UIColor
|
||||
let textColor: UIColor
|
||||
|
|
@ -97,7 +105,11 @@ public final class BirthdayPickerComponent: Component {
|
|||
if let year = component.value.year {
|
||||
self.pickerView.selectRow(Int(year - self.minYear), inComponent: PickerComponent.year.rawValue, animated: false)
|
||||
} else {
|
||||
self.pickerView.selectRow(Int(self.maxYear - self.minYear + 1), inComponent: PickerComponent.year.rawValue, animated: false)
|
||||
var animate = false
|
||||
if let hint = transition.userData(TransitionHint.self), hint.animate {
|
||||
animate = true
|
||||
}
|
||||
self.pickerView.selectRow(Int(self.maxYear - self.minYear + 1), inComponent: PickerComponent.year.rawValue, animated: animate)
|
||||
}
|
||||
self.pickerView.selectRow(Int(component.value.month) - 1, inComponent: PickerComponent.month.rawValue, animated: false)
|
||||
self.pickerView.selectRow(Int(component.value.day) - 1, inComponent: PickerComponent.day.rawValue, animated: false)
|
||||
|
|
|
|||
|
|
@ -7,37 +7,54 @@ import MultilineTextComponent
|
|||
import TelegramPresentationData
|
||||
import AppBundle
|
||||
import BundleIconComponent
|
||||
import PlainButtonComponent
|
||||
import Markdown
|
||||
import TelegramCore
|
||||
|
||||
import AccountContext
|
||||
|
||||
public final class BirthdayPickerContentComponent: Component {
|
||||
public let context: AccountContext
|
||||
public let mode: BirthdayPickerScreen.Mode
|
||||
public let theme: PresentationTheme
|
||||
public let strings: PresentationStrings
|
||||
public let settings: Signal<AccountPrivacySettings?, NoError>
|
||||
public let value: TelegramBirthday
|
||||
public let canHideYear: Bool
|
||||
public let updateValue: (TelegramBirthday) -> Void
|
||||
public let dismiss: () -> Void
|
||||
public let openSettings: () -> Void
|
||||
public let requestHideYear: (ComponentTransition) -> Void
|
||||
|
||||
public init(
|
||||
context: AccountContext,
|
||||
mode: BirthdayPickerScreen.Mode,
|
||||
theme: PresentationTheme,
|
||||
strings: PresentationStrings,
|
||||
settings: Signal<AccountPrivacySettings?, NoError>,
|
||||
value: TelegramBirthday,
|
||||
canHideYear: Bool,
|
||||
updateValue: @escaping (TelegramBirthday) -> Void,
|
||||
dismiss: @escaping () -> Void,
|
||||
openSettings: @escaping () -> Void
|
||||
openSettings: @escaping () -> Void,
|
||||
requestHideYear: @escaping (ComponentTransition) -> Void
|
||||
) {
|
||||
self.context = context
|
||||
self.mode = mode
|
||||
self.theme = theme
|
||||
self.strings = strings
|
||||
self.settings = settings
|
||||
self.value = value
|
||||
self.canHideYear = canHideYear
|
||||
self.updateValue = updateValue
|
||||
self.dismiss = dismiss
|
||||
self.openSettings = openSettings
|
||||
self.requestHideYear = requestHideYear
|
||||
}
|
||||
|
||||
public static func ==(lhs: BirthdayPickerContentComponent, rhs: BirthdayPickerContentComponent) -> Bool {
|
||||
if lhs.mode != rhs.mode {
|
||||
return false
|
||||
}
|
||||
if lhs.theme !== rhs.theme {
|
||||
return false
|
||||
}
|
||||
|
|
@ -47,6 +64,9 @@ public final class BirthdayPickerContentComponent: Component {
|
|||
if lhs.value != rhs.value {
|
||||
return false
|
||||
}
|
||||
if lhs.canHideYear != rhs.canHideYear {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
|
|
@ -54,19 +74,23 @@ public final class BirthdayPickerContentComponent: Component {
|
|||
private let title = ComponentView<Empty>()
|
||||
private let picker = ComponentView<Empty>()
|
||||
private let mainText = ComponentView<Empty>()
|
||||
private let hideYear = ComponentView<Empty>()
|
||||
|
||||
private var chevronImage: UIImage?
|
||||
|
||||
private var component: BirthdayPickerContentComponent?
|
||||
private var state: EmptyComponentState?
|
||||
|
||||
private var disposable: Disposable?
|
||||
private var settings: AccountPrivacySettings?
|
||||
private var peer: EnginePeer?
|
||||
|
||||
private var isUpdating = false
|
||||
|
||||
public override init(frame: CGRect) {
|
||||
super.init(frame: frame)
|
||||
}
|
||||
|
||||
|
||||
required init(coder: NSCoder) {
|
||||
preconditionFailure()
|
||||
}
|
||||
|
|
@ -88,15 +112,37 @@ public final class BirthdayPickerContentComponent: Component {
|
|||
defer {
|
||||
self.isUpdating = false
|
||||
}
|
||||
|
||||
|
||||
self.component = component
|
||||
self.state = state
|
||||
|
||||
if self.disposable == nil {
|
||||
let peer: Signal<EnginePeer?, NoError>
|
||||
if case let .suggest(peerId) = component.mode {
|
||||
peer = component.context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId))
|
||||
} else {
|
||||
peer = .single(nil)
|
||||
}
|
||||
self.disposable = combineLatest(queue: Queue.mainQueue(),
|
||||
component.settings,
|
||||
peer
|
||||
).start(next: { [weak self, weak state] settings, peer in
|
||||
if let self {
|
||||
self.settings = settings
|
||||
self.peer = peer
|
||||
if !self.isUpdating {
|
||||
state?.updated()
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
let sideInset: CGFloat = 16.0
|
||||
|
||||
var contentHeight: CGFloat = 0.0
|
||||
|
||||
let titleString = NSMutableAttributedString()
|
||||
titleString.append(NSAttributedString(string: component.strings.Birthday_Title, font: Font.semibold(17.0), textColor: component.theme.list.itemPrimaryTextColor))
|
||||
titleString.append(NSAttributedString(string: self.peer.flatMap { component.strings.SuggestBirthdate_Suggest_Title($0.compactDisplayTitle).string } ?? component.strings.Birthday_Title, font: Font.semibold(17.0), textColor: component.theme.list.itemPrimaryTextColor))
|
||||
|
||||
let titleSize = self.title.update(
|
||||
transition: .immediate,
|
||||
|
|
@ -117,12 +163,20 @@ public final class BirthdayPickerContentComponent: Component {
|
|||
contentHeight += 16.0
|
||||
|
||||
let pickerSize = self.picker.update(
|
||||
transition: .immediate,
|
||||
transition: transition,
|
||||
component: AnyComponent(BirthdayPickerComponent(
|
||||
theme: BirthdayPickerComponent.Theme(presentationTheme: component.theme),
|
||||
strings: component.strings,
|
||||
value: component.value,
|
||||
valueUpdated: component.updateValue
|
||||
valueUpdated: { [weak self] value in
|
||||
guard let self, let component = self.component else {
|
||||
return
|
||||
}
|
||||
component.updateValue(value)
|
||||
if component.canHideYear && value.year == nil {
|
||||
component.requestHideYear(.spring(duration: 0.4))
|
||||
}
|
||||
}
|
||||
)),
|
||||
environment: {},
|
||||
containerSize: CGSize(width: availableSize.width - sideInset * 2.0, height: 226.0)
|
||||
|
|
@ -135,91 +189,110 @@ public final class BirthdayPickerContentComponent: Component {
|
|||
}
|
||||
contentHeight += pickerSize.height
|
||||
contentHeight += 8.0
|
||||
|
||||
if self.disposable == nil {
|
||||
self.disposable = (component.settings
|
||||
|> deliverOnMainQueue).start(next: { [weak self, weak state] settings in
|
||||
if let self {
|
||||
self.settings = settings
|
||||
if !self.isUpdating {
|
||||
state?.updated()
|
||||
}
|
||||
|
||||
switch component.mode {
|
||||
case .generic:
|
||||
var isContacts = true
|
||||
if let settings = self.settings {
|
||||
if case .enableContacts = settings.birthday {
|
||||
} else {
|
||||
isContacts = false
|
||||
}
|
||||
})
|
||||
}
|
||||
var isContacts = true
|
||||
if let settings = self.settings {
|
||||
if case .enableContacts = settings.birthday {
|
||||
} else {
|
||||
isContacts = false
|
||||
}
|
||||
}
|
||||
|
||||
let mainText = NSMutableAttributedString()
|
||||
mainText.append(parseMarkdownIntoAttributedString(isContacts ? component.strings.Birthday_HelpContacts : component.strings.Birthday_Help, attributes: MarkdownAttributes(
|
||||
body: MarkdownAttributeSet(
|
||||
font: Font.regular(13.0),
|
||||
textColor: component.theme.list.itemSecondaryTextColor
|
||||
),
|
||||
bold: MarkdownAttributeSet(
|
||||
font: Font.semibold(13.0),
|
||||
textColor: component.theme.list.itemSecondaryTextColor
|
||||
),
|
||||
link: MarkdownAttributeSet(
|
||||
font: Font.regular(13.0),
|
||||
textColor: component.theme.list.itemAccentColor,
|
||||
additionalAttributes: [:]
|
||||
),
|
||||
linkAttribute: { attributes in
|
||||
return ("URL", "")
|
||||
}
|
||||
)))
|
||||
if self.chevronImage == nil {
|
||||
self.chevronImage = UIImage(bundleImageName: "Contact List/SubtitleArrow")
|
||||
}
|
||||
if let range = mainText.string.range(of: ">"), let chevronImage = self.chevronImage {
|
||||
mainText.addAttribute(.attachment, value: chevronImage, range: NSRange(range, in: mainText.string))
|
||||
}
|
||||
|
||||
let mainTextSize = self.mainText.update(
|
||||
transition: .immediate,
|
||||
component: AnyComponent(MultilineTextComponent(
|
||||
text: .plain(mainText),
|
||||
horizontalAlignment: .center,
|
||||
maximumNumberOfLines: 0,
|
||||
lineSpacing: 0.2,
|
||||
highlightColor: component.theme.list.itemAccentColor.withMultipliedAlpha(0.1),
|
||||
highlightInset: mainText.string.contains(">") ? UIEdgeInsets(top: 0.0, left: 0.0, bottom: 0.0, right: -8.0) : .zero,
|
||||
highlightAction: { attributes in
|
||||
if let _ = attributes[NSAttributedString.Key(rawValue: "URL")] {
|
||||
return NSAttributedString.Key(rawValue: "URL")
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
},
|
||||
tapAction: { [weak self] _, _ in
|
||||
guard let self, let component = self.component else {
|
||||
return
|
||||
}
|
||||
component.openSettings()
|
||||
|
||||
let mainText = NSMutableAttributedString()
|
||||
mainText.append(parseMarkdownIntoAttributedString(isContacts ? component.strings.Birthday_HelpContacts : component.strings.Birthday_Help, attributes: MarkdownAttributes(
|
||||
body: MarkdownAttributeSet(
|
||||
font: Font.regular(13.0),
|
||||
textColor: component.theme.list.itemSecondaryTextColor
|
||||
),
|
||||
bold: MarkdownAttributeSet(
|
||||
font: Font.semibold(13.0),
|
||||
textColor: component.theme.list.itemSecondaryTextColor
|
||||
),
|
||||
link: MarkdownAttributeSet(
|
||||
font: Font.regular(13.0),
|
||||
textColor: component.theme.list.itemAccentColor,
|
||||
additionalAttributes: [:]
|
||||
),
|
||||
linkAttribute: { attributes in
|
||||
return ("URL", "")
|
||||
}
|
||||
)),
|
||||
environment: {},
|
||||
containerSize: CGSize(width: availableSize.width - sideInset * 2.0, height: 1000.0)
|
||||
)
|
||||
if let mainTextView = self.mainText.view {
|
||||
if mainTextView.superview == nil {
|
||||
self.addSubview(mainTextView)
|
||||
)))
|
||||
if self.chevronImage == nil {
|
||||
self.chevronImage = UIImage(bundleImageName: "Contact List/SubtitleArrow")
|
||||
}
|
||||
transition.setFrame(view: mainTextView, frame: CGRect(origin: CGPoint(x: floor((availableSize.width - mainTextSize.width) * 0.5), y: contentHeight), size: mainTextSize))
|
||||
if let range = mainText.string.range(of: ">"), let chevronImage = self.chevronImage {
|
||||
mainText.addAttribute(.attachment, value: chevronImage, range: NSRange(range, in: mainText.string))
|
||||
}
|
||||
|
||||
let mainTextSize = self.mainText.update(
|
||||
transition: .immediate,
|
||||
component: AnyComponent(MultilineTextComponent(
|
||||
text: .plain(mainText),
|
||||
horizontalAlignment: .center,
|
||||
maximumNumberOfLines: 0,
|
||||
lineSpacing: 0.2,
|
||||
highlightColor: component.theme.list.itemAccentColor.withMultipliedAlpha(0.1),
|
||||
highlightInset: mainText.string.contains(">") ? UIEdgeInsets(top: 0.0, left: 0.0, bottom: 0.0, right: -8.0) : .zero,
|
||||
highlightAction: { attributes in
|
||||
if let _ = attributes[NSAttributedString.Key(rawValue: "URL")] {
|
||||
return NSAttributedString.Key(rawValue: "URL")
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
},
|
||||
tapAction: { [weak self] _, _ in
|
||||
guard let self, let component = self.component else {
|
||||
return
|
||||
}
|
||||
component.openSettings()
|
||||
}
|
||||
)),
|
||||
environment: {},
|
||||
containerSize: CGSize(width: availableSize.width - sideInset * 2.0, height: 1000.0)
|
||||
)
|
||||
if let mainTextView = self.mainText.view {
|
||||
if mainTextView.superview == nil {
|
||||
self.addSubview(mainTextView)
|
||||
}
|
||||
transition.setFrame(view: mainTextView, frame: CGRect(origin: CGPoint(x: floor((availableSize.width - mainTextSize.width) * 0.5), y: contentHeight), size: mainTextSize))
|
||||
}
|
||||
contentHeight += mainTextSize.height
|
||||
contentHeight += 12.0
|
||||
case .acceptSuggestion:
|
||||
if component.canHideYear {
|
||||
contentHeight += 21.0
|
||||
let hideYearSize = self.hideYear.update(
|
||||
transition: .immediate,
|
||||
component: AnyComponent(PlainButtonComponent(content: AnyComponent(Text(text: component.strings.SuggestBirthdate_Accept_HideYear, font: Font.regular(17.0), color: component.theme.list.itemAccentColor)), action: { [weak self] in
|
||||
guard let self, let component = self.component else {
|
||||
return
|
||||
}
|
||||
component.updateValue(TelegramBirthday(day: component.value.day, month: component.value.month, year: nil))
|
||||
component.requestHideYear(.spring(duration: 0.4).withUserData(BirthdayPickerComponent.TransitionHint(animate: true)))
|
||||
}, animateScale: false)),
|
||||
environment: {},
|
||||
containerSize: CGSize(width: availableSize.width - sideInset * 2.0, height: 1000.0)
|
||||
)
|
||||
if let hideYearView = self.hideYear.view {
|
||||
if hideYearView.superview == nil {
|
||||
self.addSubview(hideYearView)
|
||||
}
|
||||
transition.setFrame(view: hideYearView, frame: CGRect(origin: CGPoint(x: floor((availableSize.width - hideYearSize.width) * 0.5), y: contentHeight), size: hideYearSize))
|
||||
}
|
||||
contentHeight += hideYearSize.height
|
||||
contentHeight += 20.0
|
||||
} else if let hideYearView = self.hideYear.view {
|
||||
transition.setAlpha(view: hideYearView, alpha: 0.0, completion: { _ in
|
||||
hideYearView.removeFromSuperview()
|
||||
})
|
||||
}
|
||||
case .suggest:
|
||||
break
|
||||
}
|
||||
contentHeight += mainTextSize.height
|
||||
|
||||
contentHeight += 12.0
|
||||
|
||||
let contentSize = CGSize(width: availableSize.width, height: contentHeight)
|
||||
|
||||
return contentSize
|
||||
|
||||
return CGSize(width: availableSize.width, height: contentHeight)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -12,26 +12,38 @@ import TelegramCore
|
|||
private final class BirthdayPickerSheetContentComponent: Component {
|
||||
typealias EnvironmentType = ViewControllerComponentContainer.Environment
|
||||
|
||||
let context: AccountContext
|
||||
let mode: BirthdayPickerScreen.Mode
|
||||
let settings: Signal<AccountPrivacySettings?, NoError>
|
||||
let canHideYear: Bool
|
||||
let openSettings: () -> Void
|
||||
let dismiss: () -> Void
|
||||
let action: (TelegramBirthday) -> Void
|
||||
let requestHideYear: (ComponentTransition) -> Void
|
||||
|
||||
init(
|
||||
context: AccountContext,
|
||||
mode: BirthdayPickerScreen.Mode,
|
||||
settings: Signal<AccountPrivacySettings?, NoError>,
|
||||
canHideYear: Bool,
|
||||
openSettings: @escaping () -> Void,
|
||||
dismiss: @escaping () -> Void,
|
||||
action: @escaping (TelegramBirthday) -> Void
|
||||
action: @escaping (TelegramBirthday) -> Void,
|
||||
requestHideYear: @escaping (ComponentTransition) -> Void
|
||||
) {
|
||||
self.context = context
|
||||
self.mode = mode
|
||||
self.settings = settings
|
||||
self.canHideYear = canHideYear
|
||||
self.openSettings = openSettings
|
||||
self.dismiss = dismiss
|
||||
self.action = action
|
||||
self.requestHideYear = requestHideYear
|
||||
}
|
||||
|
||||
static func ==(lhs: BirthdayPickerSheetContentComponent, rhs: BirthdayPickerSheetContentComponent) -> Bool {
|
||||
if lhs !== rhs {
|
||||
return true
|
||||
if lhs.canHideYear != rhs.canHideYear {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
|
@ -44,6 +56,7 @@ private final class BirthdayPickerSheetContentComponent: Component {
|
|||
private var birthday = TelegramBirthday(day: 1, month: 1, year: nil)
|
||||
|
||||
private var component: BirthdayPickerSheetContentComponent?
|
||||
private var state: EmptyComponentState?
|
||||
|
||||
override init(frame: CGRect) {
|
||||
super.init(frame: frame)
|
||||
|
|
@ -52,10 +65,17 @@ private final class BirthdayPickerSheetContentComponent: Component {
|
|||
required init?(coder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
|
||||
func update(component: BirthdayPickerSheetContentComponent, availableSize: CGSize, state: EmptyComponentState, environment: Environment<EnvironmentType>, transition: ComponentTransition) -> CGSize {
|
||||
self.component = component
|
||||
if self.component == nil {
|
||||
if case let .acceptSuggestion(birthday) = component.mode {
|
||||
self.birthday = birthday
|
||||
}
|
||||
}
|
||||
|
||||
self.component = component
|
||||
self.state = state
|
||||
|
||||
let environment = environment[EnvironmentType.self].value
|
||||
|
||||
let sideInset: CGFloat = 16.0
|
||||
|
|
@ -66,17 +86,21 @@ private final class BirthdayPickerSheetContentComponent: Component {
|
|||
let contentSize = self.content.update(
|
||||
transition: transition,
|
||||
component: AnyComponent(BirthdayPickerContentComponent(
|
||||
context: component.context,
|
||||
mode: component.mode,
|
||||
theme: environment.theme,
|
||||
strings: environment.strings,
|
||||
settings: component.settings,
|
||||
value: self.birthday,
|
||||
canHideYear: component.canHideYear,
|
||||
updateValue: { [weak self] value in
|
||||
if let self {
|
||||
self.birthday = value
|
||||
}
|
||||
},
|
||||
dismiss: component.dismiss,
|
||||
openSettings: component.openSettings
|
||||
openSettings: component.openSettings,
|
||||
requestHideYear: component.requestHideYear
|
||||
)),
|
||||
environment: {},
|
||||
containerSize: CGSize(width: availableSize.width - sideInset * 2.0, height: availableSize.height)
|
||||
|
|
@ -111,6 +135,16 @@ private final class BirthdayPickerSheetContentComponent: Component {
|
|||
transition.setFrame(view: cancelView, frame: cancelFrame)
|
||||
}
|
||||
|
||||
let buttonTitle: String
|
||||
switch component.mode {
|
||||
case .generic:
|
||||
buttonTitle = environment.strings.Birthday_Save
|
||||
case .suggest:
|
||||
buttonTitle = environment.strings.SuggestBirthdate_Suggest_Action
|
||||
case .acceptSuggestion:
|
||||
buttonTitle = environment.strings.SuggestBirthdate_Accept_Action
|
||||
}
|
||||
|
||||
let buttonSize = self.button.update(
|
||||
transition: transition,
|
||||
component: AnyComponent(ButtonComponent(
|
||||
|
|
@ -120,7 +154,7 @@ private final class BirthdayPickerSheetContentComponent: Component {
|
|||
pressedColor: environment.theme.list.itemCheckColors.fillColor.withMultipliedAlpha(0.8)
|
||||
),
|
||||
content: AnyComponentWithIdentity(id: AnyHashable(0 as Int), component: AnyComponent(
|
||||
Text(text: environment.strings.Birthday_Save, font: Font.semibold(17.0), color: environment.theme.list.itemCheckColors.foregroundColor)
|
||||
Text(text: buttonTitle, font: Font.semibold(17.0), color: environment.theme.list.itemCheckColors.foregroundColor)
|
||||
)),
|
||||
isEnabled: true,
|
||||
displaysProgress: false,
|
||||
|
|
@ -166,17 +200,20 @@ private final class BirthdayPickerScreenComponent: Component {
|
|||
typealias EnvironmentType = ViewControllerComponentContainer.Environment
|
||||
|
||||
let context: AccountContext
|
||||
let mode: BirthdayPickerScreen.Mode
|
||||
let settings: Signal<AccountPrivacySettings?, NoError>
|
||||
let openSettings: (() -> Void)?
|
||||
let completion: ((TelegramBirthday) -> Void)?
|
||||
|
||||
init(
|
||||
context: AccountContext,
|
||||
mode: BirthdayPickerScreen.Mode,
|
||||
settings: Signal<AccountPrivacySettings?, NoError>,
|
||||
openSettings: (() -> Void)?,
|
||||
completion: ((TelegramBirthday) -> Void)?
|
||||
) {
|
||||
self.context = context
|
||||
self.mode = mode
|
||||
self.settings = settings
|
||||
self.openSettings = openSettings
|
||||
self.completion = completion
|
||||
|
|
@ -193,6 +230,8 @@ private final class BirthdayPickerScreenComponent: Component {
|
|||
private let sheet = ComponentView<(ViewControllerComponentContainer.Environment, SheetComponentEnvironment)>()
|
||||
private let sheetAnimateOut = ActionSlot<Action<Void>>()
|
||||
|
||||
private var canHideYear = false
|
||||
|
||||
private var component: BirthdayPickerScreenComponent?
|
||||
private var environment: EnvironmentType?
|
||||
|
||||
|
|
@ -206,6 +245,11 @@ private final class BirthdayPickerScreenComponent: Component {
|
|||
|
||||
private var didAppear = false
|
||||
func update(component: BirthdayPickerScreenComponent, availableSize: CGSize, state: EmptyComponentState, environment: Environment<ViewControllerComponentContainer.Environment>, transition: ComponentTransition) -> CGSize {
|
||||
if self.component == nil {
|
||||
if case let .acceptSuggestion(birthday) = component.mode, let _ = birthday.year {
|
||||
self.canHideYear = true
|
||||
}
|
||||
}
|
||||
self.component = component
|
||||
|
||||
let environment = environment[ViewControllerComponentContainer.Environment.self].value
|
||||
|
|
@ -235,7 +279,10 @@ private final class BirthdayPickerScreenComponent: Component {
|
|||
transition: transition,
|
||||
component: AnyComponent(SheetComponent(
|
||||
content: AnyComponent(BirthdayPickerSheetContentComponent(
|
||||
context: component.context,
|
||||
mode: component.mode,
|
||||
settings: component.settings,
|
||||
canHideYear: self.canHideYear,
|
||||
openSettings: { [weak self] in
|
||||
guard let self, let component = self.component else {
|
||||
return
|
||||
|
|
@ -251,7 +298,8 @@ private final class BirthdayPickerScreenComponent: Component {
|
|||
controller.dismiss(completion: nil)
|
||||
}
|
||||
})
|
||||
}, action: { [weak self] value in
|
||||
},
|
||||
action: { [weak self] value in
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
|
|
@ -264,9 +312,17 @@ private final class BirthdayPickerScreenComponent: Component {
|
|||
}
|
||||
self.component?.completion?(value)
|
||||
})
|
||||
},
|
||||
requestHideYear: { [weak self] transition in
|
||||
guard let self, let controller = self.environment?.controller() as? BirthdayPickerScreen else {
|
||||
return
|
||||
}
|
||||
self.canHideYear = false
|
||||
controller.requestLayout(forceUpdate: true, transition: transition)
|
||||
}
|
||||
)),
|
||||
backgroundColor: .color(environment.theme.list.plainBackgroundColor),
|
||||
followContentSizeChanges: true,
|
||||
isScrollEnabled: false,
|
||||
animateOut: self.sheetAnimateOut
|
||||
)),
|
||||
|
|
@ -297,9 +353,15 @@ private final class BirthdayPickerScreenComponent: Component {
|
|||
}
|
||||
|
||||
public class BirthdayPickerScreen: ViewControllerComponentContainer {
|
||||
public init(context: AccountContext, settings: Signal<AccountPrivacySettings?, NoError>, openSettings: (() -> Void)?, completion: ((TelegramBirthday) -> Void)? = nil) {
|
||||
public enum Mode: Equatable {
|
||||
case generic
|
||||
case suggest(EnginePeer.Id)
|
||||
case acceptSuggestion(TelegramBirthday)
|
||||
}
|
||||
public init(context: AccountContext, mode: Mode = .generic, settings: Signal<AccountPrivacySettings?, NoError>, openSettings: (() -> Void)?, completion: ((TelegramBirthday) -> Void)? = nil) {
|
||||
super.init(context: context, component: BirthdayPickerScreenComponent(
|
||||
context: context,
|
||||
mode: mode,
|
||||
settings: settings,
|
||||
openSettings: openSettings,
|
||||
completion: completion
|
||||
|
|
|
|||
|
|
@ -2905,7 +2905,7 @@ public final class StoryItemSetContainerComponent: Component {
|
|||
}
|
||||
component.presentInGlobalOverlay(c, nil)
|
||||
},
|
||||
sendMessageAction: { [weak self] in
|
||||
sendMessageAction: { [weak self] _ in
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "ic_call_camera.pdf",
|
||||
"filename" : "videocall.pdf",
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
|
|
|
|||
Binary file not shown.
BIN
submodules/TelegramUI/Images.xcassets/Call/CallCameraButton.imageset/videocall.pdf
vendored
Normal file
BIN
submodules/TelegramUI/Images.xcassets/Call/CallCameraButton.imageset/videocall.pdf
vendored
Normal file
Binary file not shown.
Binary file not shown.
|
Before Width: | Height: | Size: 535 B |
Binary file not shown.
|
Before Width: | Height: | Size: 805 B |
|
|
@ -1,22 +1,12 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"filename" : "CallQuickMessageIcon@2x.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"filename" : "CallQuickMessageIcon@3x.png",
|
||||
"scale" : "3x"
|
||||
"filename" : "comment.pdf",
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
BIN
submodules/TelegramUI/Images.xcassets/Call/CallMessageButton.imageset/comment.pdf
vendored
Normal file
BIN
submodules/TelegramUI/Images.xcassets/Call/CallMessageButton.imageset/comment.pdf
vendored
Normal file
Binary file not shown.
|
|
@ -868,7 +868,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
|||
|
||||
var openMessageByAction = false
|
||||
var isLocation = false
|
||||
|
||||
|
||||
for media in message.media {
|
||||
if media is TelegramMediaMap {
|
||||
if !displayVoiceMessageDiscardAlert() {
|
||||
|
|
@ -1227,6 +1227,38 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
|||
let controller = self.context.sharedContext.makeStarsGiftScreen(context: self.context, message: EngineMessage(message))
|
||||
self.push(controller)
|
||||
return true
|
||||
case let .suggestedBirthday(birthday):
|
||||
self.chatDisplayNode.dismissInput()
|
||||
guard message.author?.id != self.context.account.peerId else {
|
||||
return true
|
||||
}
|
||||
let settingsPromise: Promise<AccountPrivacySettings?>
|
||||
if let rootController = self.context.sharedContext.mainWindow?.viewController as? TelegramRootControllerInterface, let current = rootController.getPrivacySettings() {
|
||||
settingsPromise = current
|
||||
} else {
|
||||
settingsPromise = Promise()
|
||||
settingsPromise.set(.single(nil) |> then(self.context.engine.privacy.requestAccountPrivacySettings() |> map(Optional.init)))
|
||||
}
|
||||
|
||||
let controller = self.context.sharedContext.makeBirthdayAcceptSuggestionScreen(context: self.context, birthday: birthday, settings: settingsPromise, openSettings: { [weak self] in
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
self.context.sharedContext.makeBirthdayPrivacyController(context: self.context, settings: settingsPromise, openedFromBirthdayScreen: true, present: { [weak self] c in
|
||||
self?.push(c)
|
||||
})
|
||||
}, completion: { [weak self] value in
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
let _ = self.context.engine.accountData.updateBirthday(birthday: value).startStandalone()
|
||||
|
||||
self.present(UndoOverlayController(presentationData: self.presentationData, content: .actionSucceeded(title: nil, text: self.presentationData.strings.SuggestBirthdate_Accept_Added, cancel: nil, destructive: false), elevatedLayout: false, action: { _ in
|
||||
return true
|
||||
}), in: .current)
|
||||
})
|
||||
self.push(controller)
|
||||
return true
|
||||
case let .suggestedProfilePhoto(image):
|
||||
self.chatDisplayNode.dismissInput()
|
||||
if let image = image {
|
||||
|
|
|
|||
|
|
@ -3932,6 +3932,36 @@ public final class SharedAccountContextImpl: SharedAccountContext {
|
|||
public func makeForumSettingsScreen(context: AccountContext, peerId: EnginePeer.Id) -> ViewController {
|
||||
return ForumSettingsScreen(context: context, peerId: peerId)
|
||||
}
|
||||
|
||||
public func makeBirthdayPickerScreen(context: AccountContext, settings: Promise<AccountPrivacySettings?>, openSettings: @escaping (() -> Void), completion: @escaping (TelegramBirthday) -> Void) -> ViewController {
|
||||
return BirthdayPickerScreen(
|
||||
context: context,
|
||||
mode: .generic,
|
||||
settings: settings.get(),
|
||||
openSettings: openSettings,
|
||||
completion: completion
|
||||
)
|
||||
}
|
||||
|
||||
public func makeBirthdaySuggestionScreen(context: AccountContext, peerId: EnginePeer.Id, completion: @escaping (TelegramBirthday) -> Void) -> ViewController {
|
||||
return BirthdayPickerScreen(
|
||||
context: context,
|
||||
mode: .suggest(peerId),
|
||||
settings: .single(nil),
|
||||
openSettings: nil,
|
||||
completion: completion
|
||||
)
|
||||
}
|
||||
|
||||
public func makeBirthdayAcceptSuggestionScreen(context: AccountContext, birthday: TelegramBirthday, settings: Promise<AccountPrivacySettings?>, openSettings: @escaping () -> Void, completion: @escaping (TelegramBirthday) -> Void) -> ViewController {
|
||||
return BirthdayPickerScreen(
|
||||
context: context,
|
||||
mode: .acceptSuggestion(birthday),
|
||||
settings: settings.get(),
|
||||
openSettings: openSettings,
|
||||
completion: completion
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private func peerInfoControllerImpl(context: AccountContext, updatedPresentationData: (PresentationData, Signal<PresentationData, NoError>)?, peer: Peer, mode: PeerInfoControllerMode, avatarInitiallyExpanded: Bool, isOpenedFromChat: Bool, requestsContext: PeerInvitationImportersContext? = nil) -> ViewController? {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue