Wallpaper improvements

This commit is contained in:
Ilya Laktyushin 2023-11-10 16:35:25 +04:00
parent 14d6be6473
commit 81b392d30c
41 changed files with 25254 additions and 25043 deletions

View File

@ -10468,10 +10468,26 @@ Sorry for the inconvenience.";
"Conversation.FreeTranscriptionLimitTooltip_1" = "You have **%@** free voice transcription left this month.";
"Conversation.FreeTranscriptionLimitTooltip_any" = "You have **%@** free voice transcriptions left this month.";
"Notification.GiveawayResults_1" = "%@ winner of the giveaway was randomly selected by Telegram and received private message with giftcode.";
"Notification.GiveawayResults_any" = "%@ winners of the giveaway were randomly selected by Telegram and received private messages with giftcodes.";
"Notification.GiveawayResults_1" = "**%@** winner of the giveaway was randomly selected by Telegram and received a private message with gift code.";
"Notification.GiveawayResults_any" = "**%@** winners of the giveaway were randomly selected by Telegram and received private messages with gift codes.";
"Notification.GiveawayResultsNoWinners_1" = "Due to the giveaway terms, no winners could be selected by Telegram, a gift code was forwarded to channel administrators.";
"Notification.GiveawayResultsNoWinners_any" = "Due to the giveaway terms, no winners could be selected by Telegram, all %@ gift codes were forwarded to channel administrators.";
"Notification.GiveawayResultsMixedWinners_1" = "**%@** winner of the giveaway was randomly selected by Telegram and received a private message with gift code.";
"Notification.GiveawayResultsMixedWinners_any" = "Due to the giveaway terms, no winners could be selected by Telegram, all %@ gift codes were forwarded to channel administrators.";
"Notification.GiveawayResultsMixedUnclaimed_1" = "%@ undistributed gift code was forwarded to channel administrators";
"Notification.GiveawayResultsMixedUnclaimed_any" = "%@ undistributed gift codes were forwarded to channel administrators";
"Chat.Giveaway.DeleteConfirmation.Title" = "Do you want to delete the Giveaway Announcement?";
"Chat.Giveaway.DeleteConfirmation.Text" = "Deleting this message won't cancel the giveaway - the winners will still be selected on **%@**.\n\nOnce deleted, the Giveaway Announcement cannot be recovered.";
"Chat.SimilarChannels" = "Similar Channels";
"Wallpaper.ApplyForMe" = "Apply for Me";
"Wallpaper.ApplyForBoth" = "Apply for Me and %@";
"Premium.VoiceToText.Proceed" = "About Telegram Premium";
"Premium.Wallpaper.Proceed" = "About Telegram Premium";
"Notification.YouChangedWallpaperBoth" = "You set a new wallpaper for %@ and you.";

View File

@ -1042,6 +1042,8 @@ private final class DemoSheetContent: CombinedComponent {
case .stories:
buttonText = strings.Common_OK
buttonAnimationName = "premium_unlock"
case .voiceToText:
buttonText = strings.Premium_VoiceToText_Proceed
default:
buttonText = strings.Common_OK
}

View File

@ -115,6 +115,7 @@ swift_library(
"//submodules/AttachmentUI:AttachmentUI",
"//submodules/TelegramUI/Components/PeerInfo/PeerInfoStoryGridScreen",
"//submodules/TelegramUI/Components/Settings/PeerNameColorScreen",
"//submodules/ManagedAnimationNode:ManagedAnimationNode",
],
visibility = [
"//visibility:public",

View File

@ -25,7 +25,7 @@ func presentCustomWallpaperPicker(context: AccountContext, present: @escaping (V
controller.selectionBlock = { [weak legacyController] asset, _ in
if let asset = asset {
let controller = WallpaperGalleryController(context: context, source: .asset(asset.backingAsset))
controller.apply = { [weak legacyController, weak controller] wallpaper, mode, editedImage, cropRect, brightness in
controller.apply = { [weak legacyController, weak controller] wallpaper, mode, editedImage, cropRect, brightness, _ in
if let legacyController = legacyController, let controller = controller {
uploadCustomWallpaper(context: context, wallpaper: wallpaper, mode: mode, editedImage: nil, cropRect: cropRect, brightness: brightness, completion: { [weak legacyController, weak controller] in
if let legacyController = legacyController, let controller = controller {
@ -200,7 +200,7 @@ func uploadCustomWallpaper(context: AccountContext, wallpaper: WallpaperGalleryE
}).start()
}
public func uploadCustomPeerWallpaper(context: AccountContext, wallpaper: WallpaperGalleryEntry, mode: WallpaperPresentationOptions, editedImage: UIImage?, cropRect: CGRect?, brightness: CGFloat?, peerId: PeerId, completion: @escaping () -> Void) {
public func uploadCustomPeerWallpaper(context: AccountContext, wallpaper: WallpaperGalleryEntry, mode: WallpaperPresentationOptions, editedImage: UIImage?, cropRect: CGRect?, brightness: CGFloat?, peerId: PeerId, forBoth: Bool, completion: @escaping () -> Void) {
var imageSignal: Signal<UIImage, NoError>
switch wallpaper {
case let .wallpaper(wallpaper, _):
@ -308,7 +308,7 @@ public func uploadCustomPeerWallpaper(context: AccountContext, wallpaper: Wallpa
let settings = WallpaperSettings(blur: mode.contains(.blur), motion: mode.contains(.motion), colors: [], intensity: intensity)
let temporaryWallpaper: TelegramWallpaper = .image([TelegramMediaImageRepresentation(dimensions: PixelDimensions(thumbnailDimensions), resource: thumbnailResource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false, isPersonal: false), TelegramMediaImageRepresentation(dimensions: PixelDimensions(croppedImage.size), resource: resource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false, isPersonal: false)], settings)
context.account.pendingPeerMediaUploadManager.add(peerId: peerId, content: .wallpaper(temporaryWallpaper))
context.account.pendingPeerMediaUploadManager.add(peerId: peerId, content: .wallpaper(wallpaper: temporaryWallpaper, forBoth: forBoth))
Queue.mainQueue().after(0.05) {
completion()

View File

@ -307,8 +307,8 @@ final class ThemeAccentColorControllerNode: ASDisplayNode, UIScrollViewDelegate
let doneButtonType: WallpaperGalleryToolbarDoneButtonType
if case .edit(_, _, _, _, _, true, _) = self.mode {
doneButtonType = .proceed
} else if case .peer = resultMode {
doneButtonType = .setPeer
} else if case let .peer(peer) = resultMode {
doneButtonType = .setPeer(peer.compactDisplayTitle, context.isPremium)
} else {
doneButtonType = .set
}
@ -437,7 +437,7 @@ final class ThemeAccentColorControllerNode: ASDisplayNode, UIScrollViewDelegate
}
}
self.toolbarNode.done = { [weak self] in
self.toolbarNode.done = { [weak self] _ in
if let strongSelf = self {
if strongSelf.state.displayPatternPanel {
strongSelf.updateState({ current in
@ -774,8 +774,8 @@ final class ThemeAccentColorControllerNode: ASDisplayNode, UIScrollViewDelegate
} else {
if case .edit(_, _, _, _, _, true, _) = self.mode {
doneButtonType = .proceed
} else if case .peer = self.resultMode {
doneButtonType = .setPeer
} else if case let .peer(peer) = self.resultMode {
doneButtonType = .setPeer(peer.compactDisplayTitle, self.context.isPremium)
} else {
doneButtonType = .set
}
@ -1179,9 +1179,12 @@ final class ThemeAccentColorControllerNode: ASDisplayNode, UIScrollViewDelegate
}
var toolbarBottomInset = layout.intrinsicInsets.bottom
if case .background = mode, toolbarBottomInset.isZero {
if case .background = self.mode, toolbarBottomInset.isZero {
toolbarBottomInset = 16.0
}
if case .peer = self.resultMode {
toolbarBottomInset += 58.0
}
let toolbarHeight = 49.0 + toolbarBottomInset
transition.updateFrame(node: self.toolbarNode, frame: CGRect(origin: CGPoint(x: 0.0, y: layout.size.height - toolbarHeight), size: CGSize(width: layout.size.width, height: toolbarHeight)))
self.toolbarNode.updateLayout(size: CGSize(width: layout.size.width, height: 49.0), layout: layout, transition: transition)

View File

@ -157,7 +157,7 @@ final class ThemeColorsGridControllerNode: ASDisplayNode {
}
controller.navigationPresentation = .modal
controller.apply = { [weak self] wallpaper, _, _, _, _ in
controller.apply = { [weak self] wallpaper, _, _, _, _, _ in
if let strongSelf = self, let mode = strongSelf.controller?.mode, case let .peer(peer) = mode, case let .wallpaper(wallpaperValue, _) = wallpaper {
let _ = (strongSelf.context.engine.themes.setChatWallpaper(peerId: peer.id, wallpaper: wallpaperValue)
|> deliverOnMainQueue).start(completed: {

View File

@ -120,7 +120,7 @@ public final class ThemeGridController: ViewController {
self.displayNode = ThemeGridControllerNode(context: self.context, presentationData: self.presentationData, presentPreviewController: { [weak self] source in
if let strongSelf = self {
let controller = WallpaperGalleryController(context: strongSelf.context, source: source)
controller.apply = { [weak self, weak controller] wallpaper, options, editedImage, cropRect, brightness in
controller.apply = { [weak self, weak controller] wallpaper, options, editedImage, cropRect, brightness, _ in
if let strongSelf = self {
uploadCustomWallpaper(context: strongSelf.context, wallpaper: wallpaper, mode: options, editedImage: editedImage, cropRect: cropRect, brightness: brightness, completion: { [weak self, weak controller] in
if let strongSelf = self {
@ -160,7 +160,7 @@ public final class ThemeGridController: ViewController {
return
}
let controller = WallpaperGalleryController(context: strongSelf.context, source: .asset(asset))
controller.apply = { [weak self] wallpaper, options, editedImage, cropRect, brightness in
controller.apply = { [weak self] wallpaper, options, editedImage, cropRect, brightness, _ in
if let strongSelf = self {
uploadCustomWallpaper(context: strongSelf.context, wallpaper: wallpaper, mode: options, editedImage: editedImage, cropRect: cropRect, brightness: brightness, completion: {
dismissControllers()

View File

@ -183,7 +183,7 @@ final class ThemePreviewControllerNode: ASDisplayNode, UIScrollViewDelegate {
self.toolbarNode.cancel = {
dismiss()
}
self.toolbarNode.done = { [weak self] in
self.toolbarNode.done = { [weak self] _ in
if let strongSelf = self {
if !strongSelf.dismissed {
strongSelf.dismissed = true

View File

@ -192,7 +192,7 @@ public class WallpaperGalleryController: ViewController {
private let context: AccountContext
private let source: WallpaperListSource
private let mode: Mode
public var apply: ((WallpaperGalleryEntry, WallpaperPresentationOptions, UIImage?, CGRect?, CGFloat?) -> Void)?
public var apply: ((WallpaperGalleryEntry, WallpaperPresentationOptions, UIImage?, CGRect?, CGFloat?, Bool) -> Void)?
private var interaction: WallpaperGalleryInteraction?
@ -497,8 +497,8 @@ public class WallpaperGalleryController: ViewController {
default:
break
}
if case .peer = self.mode {
doneButtonType = .setPeer
if case let .peer(peer, _) = self.mode {
doneButtonType = .setPeer(peer.compactDisplayTitle, self.context.isPremium)
}
let toolbarNode = WallpaperGalleryToolbarNode(theme: presentationData.theme, strings: presentationData.strings, doneButtonType: doneButtonType)
@ -515,8 +515,23 @@ public class WallpaperGalleryController: ViewController {
self?.dismiss(forceAway: true)
}
var dismissed = false
toolbarNode.done = { [weak self] in
toolbarNode.done = { [weak self] forBoth in
if let strongSelf = self, !dismissed {
if forBoth && !strongSelf.context.isPremium {
let context = strongSelf.context
var replaceImpl: ((ViewController) -> Void)?
let controller = context.sharedContext.makePremiumDemoController(context: context, subject: .voiceToText, action: {
let controller = context.sharedContext.makePremiumIntroController(context: context, source: .settings, forceDark: false, dismissed: nil)
replaceImpl?(controller)
})
replaceImpl = { [weak controller] c in
controller?.replace(with: c)
}
strongSelf.push(controller)
return
}
if let centralItemNode = strongSelf.galleryNode.pager.centralItemNode() as? WallpaperGalleryItemNode {
if centralItemNode.cropNode.scrollNode.view.isDecelerating {
return
@ -554,12 +569,12 @@ public class WallpaperGalleryController: ViewController {
|> filter({ $0.complete })
|> take(1)
|> deliverOnMainQueue).start(next: { _ in
apply?(entry, options, nil, nil, centralItemNode.brightness)
apply?(entry, options, nil, nil, centralItemNode.brightness, forBoth)
})
}
}
} else {
apply?(entry, options, centralItemNode.editedFullSizeImage, centralItemNode.editedCropRect, centralItemNode.brightness)
apply?(entry, options, centralItemNode.editedFullSizeImage, centralItemNode.editedCropRect, centralItemNode.brightness, forBoth)
}
return
}
@ -717,7 +732,7 @@ public class WallpaperGalleryController: ViewController {
break
}
strongSelf.apply?(entry, options, nil, centralItemNode.cropRect, centralItemNode.brightness)
strongSelf.apply?(entry, options, nil, centralItemNode.cropRect, centralItemNode.brightness, forBoth)
}
}
}
@ -953,7 +968,10 @@ public class WallpaperGalleryController: ViewController {
self.galleryNode.containerLayoutUpdated(pagerLayout, navigationBarHeight: self.navigationLayout(layout: layout).navigationFrame.maxY, transition: transition)
self.overlayNode?.frame = self.galleryNode.bounds
let toolbarHeight: CGFloat = 66.0
var toolbarHeight: CGFloat = 66.0
if case .peer = self.mode {
toolbarHeight += 58.0
}
transition.updateFrame(node: self.toolbarNode!, frame: CGRect(origin: CGPoint(x: 0.0, y: layout.size.height - toolbarHeight - layout.intrinsicInsets.bottom), size: CGSize(width: layout.size.width, height: toolbarHeight + layout.intrinsicInsets.bottom)))
self.toolbarNode!.updateLayout(size: CGSize(width: layout.size.width, height: toolbarHeight), layout: layout, transition: transition)
@ -1051,7 +1069,7 @@ public class WallpaperGalleryController: ViewController {
self.toolbarNode?.setDoneIsSolid(self.patternPanelEnabled || self.colorsPanelEnabled, transition: transition)
bottomInset += 66.0
bottomInset += toolbarHeight
self.validLayout = (layout, bottomInset)
if !hadLayout {

View File

@ -1329,7 +1329,10 @@ final class WallpaperGalleryItemNode: GalleryItemNode {
let buttonSpacing: CGFloat = 18.0
let toolbarHeight: CGFloat = 66.0
var toolbarHeight: CGFloat = 66.0
if let mode = self.mode, case .peer = mode {
toolbarHeight += 58.0
}
let leftButtonFrame = CGRect(origin: CGPoint(x: floor(layout.size.width / 2.0 - buttonSize.width - buttonSpacing) + offset.x, y: layout.size.height - toolbarHeight - layout.intrinsicInsets.bottom - 54.0 + offset.y + additionalYOffset), size: buttonSize)
let centerButtonFrame = CGRect(origin: CGPoint(x: floor((layout.size.width - buttonSize.width) / 2.0) + offset.x, y: layout.size.height - toolbarHeight - layout.intrinsicInsets.bottom - 54.0 + offset.y + additionalYOffset), size: buttonSize)
@ -1479,6 +1482,9 @@ final class WallpaperGalleryItemNode: GalleryItemNode {
self.nativeNode.updateBubbleTheme(bubbleTheme: self.presentationData.theme, bubbleCorners: self.presentationData.chatBubbleCorners)
var bottomInset: CGFloat = 132.0
if let mode = self.mode, case .peer = mode {
bottomInset += 58.0
}
var items: [ListViewItem] = []
let peerId = PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(1))

View File

@ -3,6 +3,7 @@ import UIKit
import AsyncDisplayKit
import Display
import TelegramPresentationData
import ManagedAnimationNode
enum WallpaperGalleryToolbarCancelButtonType {
case cancel
@ -11,7 +12,7 @@ enum WallpaperGalleryToolbarCancelButtonType {
enum WallpaperGalleryToolbarDoneButtonType {
case set
case setPeer
case setPeer(String, Bool)
case proceed
case apply
case none
@ -22,7 +23,7 @@ protocol WallpaperGalleryToolbar: ASDisplayNode {
var doneButtonType: WallpaperGalleryToolbarDoneButtonType { get set }
var cancel: (() -> Void)? { get set }
var done: (() -> Void)? { get set }
var done: ((Bool) -> Void)? { get set }
func updateThemeAndStrings(theme: PresentationTheme, strings: PresentationStrings)
@ -30,6 +31,169 @@ protocol WallpaperGalleryToolbar: ASDisplayNode {
}
final class WallpaperGalleryToolbarNode: ASDisplayNode, WallpaperGalleryToolbar {
class ButtonNode: ASDisplayNode {
private let doneButton = HighlightTrackingButtonNode()
private var doneButtonBackgroundNode: ASDisplayNode
private let doneButtonTitleNode: ImmediateTextNode
private let doneButtonSolidBackgroundNode: ASDisplayNode
private let doneButtonSolidTitleNode: ImmediateTextNode
private let animationNode: SimpleAnimationNode
var action: () -> Void = {}
var isLocked: Bool = false {
didSet {
self.animationNode.isHidden = !self.isLocked
}
}
override init() {
self.doneButtonBackgroundNode = WallpaperLightButtonBackgroundNode()
self.doneButtonBackgroundNode.cornerRadius = 14.0
self.doneButtonTitleNode = ImmediateTextNode()
self.doneButtonTitleNode.displaysAsynchronously = false
self.doneButtonTitleNode.isUserInteractionEnabled = false
self.doneButtonSolidBackgroundNode = ASDisplayNode()
self.doneButtonSolidBackgroundNode.alpha = 0.0
self.doneButtonSolidBackgroundNode.clipsToBounds = true
self.doneButtonSolidBackgroundNode.layer.cornerRadius = 14.0
if #available(iOS 13.0, *) {
self.doneButtonSolidBackgroundNode.layer.cornerCurve = .continuous
}
self.doneButtonSolidBackgroundNode.isUserInteractionEnabled = false
self.doneButtonSolidTitleNode = ImmediateTextNode()
self.doneButtonSolidTitleNode.alpha = 0.0
self.doneButtonSolidTitleNode.displaysAsynchronously = false
self.doneButtonSolidTitleNode.isUserInteractionEnabled = false
self.animationNode = SimpleAnimationNode(animationName: "premium_unlock", size: CGSize(width: 30.0, height: 30.0))
self.animationNode.customColor = .white
self.animationNode.isHidden = true
super.init()
self.doneButton.isExclusiveTouch = true
self.addSubnode(self.doneButtonBackgroundNode)
self.addSubnode(self.doneButtonTitleNode)
self.addSubnode(self.doneButtonSolidBackgroundNode)
self.addSubnode(self.doneButtonSolidTitleNode)
self.addSubnode(self.animationNode)
self.addSubnode(self.doneButton)
self.doneButton.highligthedChanged = { [weak self] highlighted in
if let strongSelf = self {
if highlighted {
if strongSelf.isSolid {
strongSelf.doneButtonSolidBackgroundNode.layer.removeAnimation(forKey: "opacity")
strongSelf.doneButtonSolidBackgroundNode.alpha = 0.55
strongSelf.doneButtonSolidTitleNode.layer.removeAnimation(forKey: "opacity")
strongSelf.doneButtonSolidTitleNode.alpha = 0.55
} else {
strongSelf.doneButtonBackgroundNode.layer.removeAnimation(forKey: "opacity")
strongSelf.doneButtonBackgroundNode.alpha = 0.55
strongSelf.doneButtonTitleNode.layer.removeAnimation(forKey: "opacity")
strongSelf.doneButtonTitleNode.alpha = 0.55
}
} else {
if strongSelf.isSolid {
strongSelf.doneButtonSolidBackgroundNode.alpha = 1.0
strongSelf.doneButtonSolidBackgroundNode.layer.animateAlpha(from: 0.55, to: 1.0, duration: 0.2)
strongSelf.doneButtonSolidTitleNode.alpha = 1.0
strongSelf.doneButtonSolidTitleNode.layer.animateAlpha(from: 0.55, to: 1.0, duration: 0.2)
} else {
strongSelf.doneButtonBackgroundNode.alpha = 1.0
strongSelf.doneButtonBackgroundNode.layer.animateAlpha(from: 0.55, to: 1.0, duration: 0.2)
strongSelf.doneButtonTitleNode.alpha = 1.0
strongSelf.doneButtonTitleNode.layer.animateAlpha(from: 0.55, to: 1.0, duration: 0.2)
}
}
}
}
self.doneButton.addTarget(self, action: #selector(self.pressed), forControlEvents: .touchUpInside)
}
func setEnabled(_ enabled: Bool) {
self.doneButton.alpha = enabled ? 1.0 : 0.4
self.doneButton.isUserInteractionEnabled = enabled
}
private var isSolid = false
func setIsSolid(_ isSolid: Bool, transition: ContainedViewLayoutTransition) {
guard self.isSolid != isSolid else {
return
}
self.isSolid = isSolid
transition.updateAlpha(node: self.doneButtonBackgroundNode, alpha: isSolid ? 0.0 : 1.0)
transition.updateAlpha(node: self.doneButtonSolidBackgroundNode, alpha: isSolid ? 1.0 : 0.0)
transition.updateAlpha(node: self.doneButtonTitleNode, alpha: isSolid ? 0.0 : 1.0)
transition.updateAlpha(node: self.doneButtonSolidTitleNode, alpha: isSolid ? 1.0 : 0.0)
}
func updateTitle(_ title: String, theme: PresentationTheme) {
self.doneButtonTitleNode.attributedText = NSAttributedString(string: title, font: Font.semibold(17.0), textColor: .white)
self.doneButtonSolidBackgroundNode.backgroundColor = theme.list.itemCheckColors.fillColor
self.doneButtonSolidTitleNode.attributedText = NSAttributedString(string: title, font: Font.semibold(17.0), textColor: theme.list.itemCheckColors.foregroundColor)
}
func updateSize(_ size: CGSize) {
let bounds = CGRect(origin: .zero, size: size)
self.doneButtonBackgroundNode.frame = bounds
if let backgroundNode = self.doneButtonBackgroundNode as? WallpaperOptionBackgroundNode {
backgroundNode.updateLayout(size: size)
} else if let backgroundNode = self.doneButtonBackgroundNode as? WallpaperLightButtonBackgroundNode {
backgroundNode.updateLayout(size: size)
}
self.doneButtonSolidBackgroundNode.frame = bounds
let iconSize = CGSize(width: 30.0, height: 30.0)
let doneTitleSize = self.doneButtonTitleNode.updateLayout(size)
var totalWidth = doneTitleSize.width
if self.isLocked {
totalWidth += iconSize.width + 1.0
}
let titleOriginX = floorToScreenPixels((bounds.width - totalWidth) / 2.0)
self.animationNode.frame = CGRect(origin: CGPoint(x: titleOriginX, y: floorToScreenPixels((bounds.height - iconSize.height) / 2.0)), size: iconSize)
self.doneButtonTitleNode.frame = CGRect(origin: CGPoint(x: titleOriginX + totalWidth - doneTitleSize.width, y: floorToScreenPixels((bounds.height - doneTitleSize.height) / 2.0)), size: doneTitleSize).offsetBy(dx: bounds.minX, dy: bounds.minY)
let _ = self.doneButtonSolidTitleNode.updateLayout(size)
self.doneButtonSolidTitleNode.frame = self.doneButtonTitleNode.frame
self.doneButton.frame = bounds
}
var dark: Bool = false {
didSet {
if self.dark != oldValue {
self.doneButtonBackgroundNode.removeFromSupernode()
if self.dark {
self.doneButtonBackgroundNode = WallpaperOptionBackgroundNode(enableSaturation: true)
} else {
self.doneButtonBackgroundNode = WallpaperLightButtonBackgroundNode()
}
self.doneButtonBackgroundNode.cornerRadius = 14.0
self.insertSubnode(self.doneButtonBackgroundNode, at: 0)
}
}
}
@objc func pressed() {
self.action()
}
}
private var theme: PresentationTheme
private let strings: PresentationStrings
@ -44,110 +208,49 @@ final class WallpaperGalleryToolbarNode: ASDisplayNode, WallpaperGalleryToolbar
}
}
var dark: Bool {
var dark: Bool = false {
didSet {
if self.dark != oldValue {
self.doneButtonBackgroundNode.removeFromSupernode()
if self.dark {
self.doneButtonBackgroundNode = WallpaperOptionBackgroundNode(enableSaturation: true)
} else {
self.doneButtonBackgroundNode = WallpaperLightButtonBackgroundNode()
}
self.doneButtonBackgroundNode.cornerRadius = 14.0
self.insertSubnode(self.doneButtonBackgroundNode, at: 0)
}
self.applyButton.dark = self.dark
self.applyForBothButton.dark = self.dark
}
}
private let doneButton = HighlightTrackingButtonNode()
private var doneButtonBackgroundNode: ASDisplayNode
private let doneButtonTitleNode: ImmediateTextNode
private let doneButtonSolidBackgroundNode: ASDisplayNode
private let doneButtonSolidTitleNode: ImmediateTextNode
private let applyButton = ButtonNode()
private let applyForBothButton = ButtonNode()
var cancel: (() -> Void)?
var done: (() -> Void)?
var done: ((Bool) -> Void)?
init(theme: PresentationTheme, strings: PresentationStrings, cancelButtonType: WallpaperGalleryToolbarCancelButtonType = .cancel, doneButtonType: WallpaperGalleryToolbarDoneButtonType = .set) {
self.theme = theme
self.strings = strings
self.cancelButtonType = cancelButtonType
self.doneButtonType = doneButtonType
self.dark = false
self.doneButtonBackgroundNode = WallpaperLightButtonBackgroundNode()
self.doneButtonBackgroundNode.cornerRadius = 14.0
self.doneButtonTitleNode = ImmediateTextNode()
self.doneButtonTitleNode.displaysAsynchronously = false
self.doneButtonTitleNode.isUserInteractionEnabled = false
self.doneButtonSolidBackgroundNode = ASDisplayNode()
self.doneButtonSolidBackgroundNode.alpha = 0.0
self.doneButtonSolidBackgroundNode.clipsToBounds = true
self.doneButtonSolidBackgroundNode.layer.cornerRadius = 14.0
if #available(iOS 13.0, *) {
self.doneButtonSolidBackgroundNode.layer.cornerCurve = .continuous
}
self.doneButtonSolidBackgroundNode.isUserInteractionEnabled = false
self.doneButtonSolidTitleNode = ImmediateTextNode()
self.doneButtonSolidTitleNode.alpha = 0.0
self.doneButtonSolidTitleNode.displaysAsynchronously = false
self.doneButtonSolidTitleNode.isUserInteractionEnabled = false
super.init()
self.doneButton.isExclusiveTouch = true
self.addSubnode(self.doneButtonBackgroundNode)
self.addSubnode(self.doneButtonTitleNode)
self.addSubnode(self.doneButtonSolidBackgroundNode)
self.addSubnode(self.doneButtonSolidTitleNode)
self.addSubnode(self.doneButton)
self.addSubnode(self.applyButton)
if case .setPeer = doneButtonType {
self.addSubnode(self.applyForBothButton)
}
self.updateThemeAndStrings(theme: theme, strings: strings)
self.doneButton.highligthedChanged = { [weak self] highlighted in
if let strongSelf = self {
if highlighted {
if strongSelf.isSolid {
strongSelf.doneButtonSolidBackgroundNode.layer.removeAnimation(forKey: "opacity")
strongSelf.doneButtonSolidBackgroundNode.alpha = 0.55
strongSelf.doneButtonSolidTitleNode.layer.removeAnimation(forKey: "opacity")
strongSelf.doneButtonSolidTitleNode.alpha = 0.55
} else {
strongSelf.doneButtonBackgroundNode.layer.removeAnimation(forKey: "opacity")
strongSelf.doneButtonBackgroundNode.alpha = 0.55
strongSelf.doneButtonTitleNode.layer.removeAnimation(forKey: "opacity")
strongSelf.doneButtonTitleNode.alpha = 0.55
}
} else {
if strongSelf.isSolid {
strongSelf.doneButtonSolidBackgroundNode.alpha = 1.0
strongSelf.doneButtonSolidBackgroundNode.layer.animateAlpha(from: 0.55, to: 1.0, duration: 0.2)
strongSelf.doneButtonSolidTitleNode.alpha = 1.0
strongSelf.doneButtonSolidTitleNode.layer.animateAlpha(from: 0.55, to: 1.0, duration: 0.2)
} else {
strongSelf.doneButtonBackgroundNode.alpha = 1.0
strongSelf.doneButtonBackgroundNode.layer.animateAlpha(from: 0.55, to: 1.0, duration: 0.2)
strongSelf.doneButtonTitleNode.alpha = 1.0
strongSelf.doneButtonTitleNode.layer.animateAlpha(from: 0.55, to: 1.0, duration: 0.2)
}
}
self.applyButton.action = { [weak self] in
if let self {
self.done?(false)
}
}
self.applyForBothButton.action = { [weak self] in
if let self {
self.done?(true)
}
}
self.doneButton.addTarget(self, action: #selector(self.donePressed), forControlEvents: .touchUpInside)
}
func setDoneEnabled(_ enabled: Bool) {
self.doneButton.alpha = enabled ? 1.0 : 0.4
self.doneButton.isUserInteractionEnabled = enabled
self.applyButton.setEnabled(enabled)
self.applyForBothButton.setEnabled(enabled)
}
private var isSolid = false
@ -155,65 +258,57 @@ final class WallpaperGalleryToolbarNode: ASDisplayNode, WallpaperGalleryToolbar
guard self.isSolid != isSolid else {
return
}
self.isSolid = isSolid
transition.updateAlpha(node: self.doneButtonBackgroundNode, alpha: isSolid ? 0.0 : 1.0)
transition.updateAlpha(node: self.doneButtonSolidBackgroundNode, alpha: isSolid ? 1.0 : 0.0)
transition.updateAlpha(node: self.doneButtonTitleNode, alpha: isSolid ? 0.0 : 1.0)
transition.updateAlpha(node: self.doneButtonSolidTitleNode, alpha: isSolid ? 1.0 : 0.0)
self.isSolid = isSolid
self.applyButton.setIsSolid(isSolid, transition: transition)
self.applyForBothButton.setIsSolid(isSolid, transition: transition)
}
func updateThemeAndStrings(theme: PresentationTheme, strings: PresentationStrings) {
self.theme = theme
let doneTitle: String
let applyTitle: String
var applyForBothTitle: String? = nil
var applyForBothLocked = false
switch self.doneButtonType {
case .set:
doneTitle = strings.Wallpaper_ApplyForAll
case .setPeer:
doneTitle = strings.Wallpaper_ApplyForChat
case .proceed:
doneTitle = strings.Theme_Colors_Proceed
case .apply:
doneTitle = strings.WallpaperPreview_PatternPaternApply
case .none:
doneTitle = ""
self.doneButton.isUserInteractionEnabled = false
case .set:
applyTitle = strings.Wallpaper_ApplyForAll
case let .setPeer(name, isPremium):
applyTitle = strings.Wallpaper_ApplyForMe
applyForBothTitle = strings.Wallpaper_ApplyForBoth(name).string
applyForBothLocked = !isPremium
case .proceed:
applyTitle = strings.Theme_Colors_Proceed
case .apply:
applyTitle = strings.WallpaperPreview_PatternPaternApply
case .none:
applyTitle = ""
self.applyButton.isUserInteractionEnabled = false
}
self.doneButtonTitleNode.attributedText = NSAttributedString(string: doneTitle, font: Font.semibold(17.0), textColor: .white)
self.doneButtonSolidBackgroundNode.backgroundColor = theme.list.itemCheckColors.fillColor
self.doneButtonSolidTitleNode.attributedText = NSAttributedString(string: doneTitle, font: Font.semibold(17.0), textColor: theme.list.itemCheckColors.foregroundColor)
self.applyButton.updateTitle(applyTitle, theme: theme)
self.applyForBothButton.updateTitle(applyForBothTitle ?? "", theme: theme)
self.applyForBothButton.isLocked = applyForBothLocked
}
func updateLayout(size: CGSize, layout: ContainerViewLayout, transition: ContainedViewLayoutTransition) {
let inset: CGFloat = 16.0
let buttonHeight: CGFloat = 50.0
let doneFrame = CGRect(origin: CGPoint(x: inset, y: 2.0), size: CGSize(width: size.width - inset * 2.0, height: buttonHeight))
self.doneButton.frame = doneFrame
self.doneButtonBackgroundNode.frame = doneFrame
if let backgroundNode = self.doneButtonBackgroundNode as? WallpaperOptionBackgroundNode {
backgroundNode.updateLayout(size: doneFrame.size)
} else if let backgroundNode = self.doneButtonBackgroundNode as? WallpaperLightButtonBackgroundNode {
backgroundNode.updateLayout(size: doneFrame.size)
}
self.doneButtonSolidBackgroundNode.frame = doneFrame
let spacing: CGFloat = 8.0
let doneTitleSize = self.doneButtonTitleNode.updateLayout(doneFrame.size)
self.doneButtonTitleNode.frame = CGRect(origin: CGPoint(x: floorToScreenPixels((doneFrame.width - doneTitleSize.width) / 2.0), y: floorToScreenPixels((doneFrame.height - doneTitleSize.height) / 2.0)), size: doneTitleSize).offsetBy(dx: doneFrame.minX, dy: doneFrame.minY)
let applyFrame = CGRect(origin: CGPoint(x: inset, y: 2.0), size: CGSize(width: size.width - inset * 2.0, height: buttonHeight))
let applyForBothFrame = CGRect(origin: CGPoint(x: inset, y: applyFrame.maxY + spacing), size: CGSize(width: size.width - inset * 2.0, height: buttonHeight))
let _ = self.doneButtonSolidTitleNode.updateLayout(doneFrame.size)
self.doneButtonSolidTitleNode.frame = self.doneButtonTitleNode.frame
self.applyButton.frame = applyFrame
self.applyButton.updateSize(applyFrame.size)
self.applyForBothButton.frame = applyForBothFrame
self.applyForBothButton.updateSize(applyForBothFrame.size)
}
@objc func cancelPressed() {
self.cancel?()
}
@objc func donePressed() {
self.done?()
}
}
final class WallpaperGalleryOldToolbarNode: ASDisplayNode, WallpaperGalleryToolbar {
@ -240,7 +335,7 @@ final class WallpaperGalleryOldToolbarNode: ASDisplayNode, WallpaperGalleryToolb
private let topSeparatorNode = ASDisplayNode()
var cancel: (() -> Void)?
var done: (() -> Void)?
var done: ((Bool) -> Void)?
init(theme: PresentationTheme, strings: PresentationStrings, cancelButtonType: WallpaperGalleryToolbarCancelButtonType = .cancel, doneButtonType: WallpaperGalleryToolbarDoneButtonType = .set) {
self.theme = theme
@ -343,6 +438,6 @@ final class WallpaperGalleryOldToolbarNode: ASDisplayNode, WallpaperGalleryToolb
}
@objc func donePressed() {
self.done?()
self.done?(false)
}
}

View File

@ -490,7 +490,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
dict[-758129906] = { return Api.MessageAction.parse_messageActionGiftCode($0) }
dict[-935499028] = { return Api.MessageAction.parse_messageActionGiftPremium($0) }
dict[858499565] = { return Api.MessageAction.parse_messageActionGiveawayLaunch($0) }
dict[1927497572] = { return Api.MessageAction.parse_messageActionGiveawayResults($0) }
dict[715107781] = { return Api.MessageAction.parse_messageActionGiveawayResults($0) }
dict[2047704898] = { return Api.MessageAction.parse_messageActionGroupCall($0) }
dict[-1281329567] = { return Api.MessageAction.parse_messageActionGroupCallScheduled($0) }
dict[-1615153660] = { return Api.MessageAction.parse_messageActionHistoryClear($0) }
@ -504,9 +504,8 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
dict[-648257196] = { return Api.MessageAction.parse_messageActionSecureValuesSent($0) }
dict[455635795] = { return Api.MessageAction.parse_messageActionSecureValuesSentMe($0) }
dict[-1434950843] = { return Api.MessageAction.parse_messageActionSetChatTheme($0) }
dict[-1136350937] = { return Api.MessageAction.parse_messageActionSetChatWallPaper($0) }
dict[1348510708] = { return Api.MessageAction.parse_messageActionSetChatWallPaper($0) }
dict[1007897979] = { return Api.MessageAction.parse_messageActionSetMessagesTTL($0) }
dict[-1065845395] = { return Api.MessageAction.parse_messageActionSetSameChatWallPaper($0) }
dict[1474192222] = { return Api.MessageAction.parse_messageActionSuggestProfilePhoto($0) }
dict[228168278] = { return Api.MessageAction.parse_messageActionTopicCreate($0) }
dict[-1064024032] = { return Api.MessageAction.parse_messageActionTopicEdit($0) }
@ -670,7 +669,6 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
dict[2061444128] = { return Api.PollResults.parse_pollResults($0) }
dict[1558266229] = { return Api.PopularContact.parse_popularContact($0) }
dict[512535275] = { return Api.PostAddress.parse_postAddress($0) }
dict[207307878] = { return Api.PremiumGiftCodeBotOption.parse_premiumGiftCodeBotOption($0) }
dict[629052971] = { return Api.PremiumGiftCodeOption.parse_premiumGiftCodeOption($0) }
dict[1958953753] = { return Api.PremiumGiftOption.parse_premiumGiftOption($0) }
dict[1596792306] = { return Api.PremiumSubscriptionOption.parse_premiumSubscriptionOption($0) }
@ -916,6 +914,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
dict[-1147422299] = { return Api.Update.parse_updatePeerHistoryTTL($0) }
dict[-1263546448] = { return Api.Update.parse_updatePeerLocated($0) }
dict[1786671974] = { return Api.Update.parse_updatePeerSettings($0) }
dict[-1371598819] = { return Api.Update.parse_updatePeerWallpaper($0) }
dict[1885586395] = { return Api.Update.parse_updatePendingJoinRequests($0) }
dict[-1425052898] = { return Api.Update.parse_updatePhoneCall($0) }
dict[643940105] = { return Api.Update.parse_updatePhoneCallSignalingData($0) }
@ -1682,8 +1681,6 @@ public extension Api {
_1.serialize(buffer, boxed)
case let _1 as Api.PostAddress:
_1.serialize(buffer, boxed)
case let _1 as Api.PremiumGiftCodeBotOption:
_1.serialize(buffer, boxed)
case let _1 as Api.PremiumGiftCodeOption:
_1.serialize(buffer, boxed)
case let _1 as Api.PremiumGiftOption:

View File

@ -612,7 +612,7 @@ public extension Api {
case messageActionGiftCode(flags: Int32, boostPeer: Api.Peer?, months: Int32, slug: String)
case messageActionGiftPremium(flags: Int32, currency: String, amount: Int64, months: Int32, cryptoCurrency: String?, cryptoAmount: Int64?)
case messageActionGiveawayLaunch
case messageActionGiveawayResults(winnersCount: Int32)
case messageActionGiveawayResults(winnersCount: Int32, unclaimedCount: Int32)
case messageActionGroupCall(flags: Int32, call: Api.InputGroupCall, duration: Int32?)
case messageActionGroupCallScheduled(call: Api.InputGroupCall, scheduleDate: Int32)
case messageActionHistoryClear
@ -626,9 +626,8 @@ public extension Api {
case messageActionSecureValuesSent(types: [Api.SecureValueType])
case messageActionSecureValuesSentMe(values: [Api.SecureValue], credentials: Api.SecureCredentialsEncrypted)
case messageActionSetChatTheme(emoticon: String)
case messageActionSetChatWallPaper(wallpaper: Api.WallPaper)
case messageActionSetChatWallPaper(flags: Int32, wallpaper: Api.WallPaper)
case messageActionSetMessagesTTL(flags: Int32, period: Int32, autoSettingFrom: Int64?)
case messageActionSetSameChatWallPaper(wallpaper: Api.WallPaper)
case messageActionSuggestProfilePhoto(photo: Api.Photo)
case messageActionTopicCreate(flags: Int32, title: String, iconColor: Int32, iconEmojiId: Int64?)
case messageActionTopicEdit(flags: Int32, title: String?, iconEmojiId: Int64?, closed: Api.Bool?, hidden: Api.Bool?)
@ -780,11 +779,12 @@ public extension Api {
}
break
case .messageActionGiveawayResults(let winnersCount):
case .messageActionGiveawayResults(let winnersCount, let unclaimedCount):
if boxed {
buffer.appendInt32(1927497572)
buffer.appendInt32(715107781)
}
serializeInt32(winnersCount, buffer: buffer, boxed: false)
serializeInt32(unclaimedCount, buffer: buffer, boxed: false)
break
case .messageActionGroupCall(let flags, let call, let duration):
if boxed {
@ -894,10 +894,11 @@ public extension Api {
}
serializeString(emoticon, buffer: buffer, boxed: false)
break
case .messageActionSetChatWallPaper(let wallpaper):
case .messageActionSetChatWallPaper(let flags, let wallpaper):
if boxed {
buffer.appendInt32(-1136350937)
buffer.appendInt32(1348510708)
}
serializeInt32(flags, buffer: buffer, boxed: false)
wallpaper.serialize(buffer, true)
break
case .messageActionSetMessagesTTL(let flags, let period, let autoSettingFrom):
@ -908,12 +909,6 @@ public extension Api {
serializeInt32(period, buffer: buffer, boxed: false)
if Int(flags) & Int(1 << 0) != 0 {serializeInt64(autoSettingFrom!, buffer: buffer, boxed: false)}
break
case .messageActionSetSameChatWallPaper(let wallpaper):
if boxed {
buffer.appendInt32(-1065845395)
}
wallpaper.serialize(buffer, true)
break
case .messageActionSuggestProfilePhoto(let photo):
if boxed {
buffer.appendInt32(1474192222)
@ -997,8 +992,8 @@ public extension Api {
return ("messageActionGiftPremium", [("flags", flags as Any), ("currency", currency as Any), ("amount", amount as Any), ("months", months as Any), ("cryptoCurrency", cryptoCurrency as Any), ("cryptoAmount", cryptoAmount as Any)])
case .messageActionGiveawayLaunch:
return ("messageActionGiveawayLaunch", [])
case .messageActionGiveawayResults(let winnersCount):
return ("messageActionGiveawayResults", [("winnersCount", winnersCount as Any)])
case .messageActionGiveawayResults(let winnersCount, let unclaimedCount):
return ("messageActionGiveawayResults", [("winnersCount", winnersCount as Any), ("unclaimedCount", unclaimedCount as Any)])
case .messageActionGroupCall(let flags, let call, let duration):
return ("messageActionGroupCall", [("flags", flags as Any), ("call", call as Any), ("duration", duration as Any)])
case .messageActionGroupCallScheduled(let call, let scheduleDate):
@ -1025,12 +1020,10 @@ public extension Api {
return ("messageActionSecureValuesSentMe", [("values", values as Any), ("credentials", credentials as Any)])
case .messageActionSetChatTheme(let emoticon):
return ("messageActionSetChatTheme", [("emoticon", emoticon as Any)])
case .messageActionSetChatWallPaper(let wallpaper):
return ("messageActionSetChatWallPaper", [("wallpaper", wallpaper as Any)])
case .messageActionSetChatWallPaper(let flags, let wallpaper):
return ("messageActionSetChatWallPaper", [("flags", flags as Any), ("wallpaper", wallpaper as Any)])
case .messageActionSetMessagesTTL(let flags, let period, let autoSettingFrom):
return ("messageActionSetMessagesTTL", [("flags", flags as Any), ("period", period as Any), ("autoSettingFrom", autoSettingFrom as Any)])
case .messageActionSetSameChatWallPaper(let wallpaper):
return ("messageActionSetSameChatWallPaper", [("wallpaper", wallpaper as Any)])
case .messageActionSuggestProfilePhoto(let photo):
return ("messageActionSuggestProfilePhoto", [("photo", photo as Any)])
case .messageActionTopicCreate(let flags, let title, let iconColor, let iconEmojiId):
@ -1286,9 +1279,12 @@ public extension Api {
public static func parse_messageActionGiveawayResults(_ reader: BufferReader) -> MessageAction? {
var _1: Int32?
_1 = reader.readInt32()
var _2: Int32?
_2 = reader.readInt32()
let _c1 = _1 != nil
if _c1 {
return Api.MessageAction.messageActionGiveawayResults(winnersCount: _1!)
let _c2 = _2 != nil
if _c1 && _c2 {
return Api.MessageAction.messageActionGiveawayResults(winnersCount: _1!, unclaimedCount: _2!)
}
else {
return nil
@ -1490,13 +1486,16 @@ public extension Api {
}
}
public static func parse_messageActionSetChatWallPaper(_ reader: BufferReader) -> MessageAction? {
var _1: Api.WallPaper?
var _1: Int32?
_1 = reader.readInt32()
var _2: Api.WallPaper?
if let signature = reader.readInt32() {
_1 = Api.parse(reader, signature: signature) as? Api.WallPaper
_2 = Api.parse(reader, signature: signature) as? Api.WallPaper
}
let _c1 = _1 != nil
if _c1 {
return Api.MessageAction.messageActionSetChatWallPaper(wallpaper: _1!)
let _c2 = _2 != nil
if _c1 && _c2 {
return Api.MessageAction.messageActionSetChatWallPaper(flags: _1!, wallpaper: _2!)
}
else {
return nil
@ -1519,19 +1518,6 @@ public extension Api {
return nil
}
}
public static func parse_messageActionSetSameChatWallPaper(_ reader: BufferReader) -> MessageAction? {
var _1: Api.WallPaper?
if let signature = reader.readInt32() {
_1 = Api.parse(reader, signature: signature) as? Api.WallPaper
}
let _c1 = _1 != nil
if _c1 {
return Api.MessageAction.messageActionSetSameChatWallPaper(wallpaper: _1!)
}
else {
return nil
}
}
public static func parse_messageActionSuggestProfilePhoto(_ reader: BufferReader) -> MessageAction? {
var _1: Api.Photo?
if let signature = reader.readInt32() {

View File

@ -750,62 +750,6 @@ public extension Api {
}
}
public extension Api {
enum PremiumGiftCodeBotOption: TypeConstructorDescription {
case premiumGiftCodeBotOption(flags: Int32, users: Int32, months: Int32, botUrl: String, currency: String, amount: Int64)
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
switch self {
case .premiumGiftCodeBotOption(let flags, let users, let months, let botUrl, let currency, let amount):
if boxed {
buffer.appendInt32(207307878)
}
serializeInt32(flags, buffer: buffer, boxed: false)
serializeInt32(users, buffer: buffer, boxed: false)
serializeInt32(months, buffer: buffer, boxed: false)
serializeString(botUrl, buffer: buffer, boxed: false)
serializeString(currency, buffer: buffer, boxed: false)
serializeInt64(amount, buffer: buffer, boxed: false)
break
}
}
public func descriptionFields() -> (String, [(String, Any)]) {
switch self {
case .premiumGiftCodeBotOption(let flags, let users, let months, let botUrl, let currency, let amount):
return ("premiumGiftCodeBotOption", [("flags", flags as Any), ("users", users as Any), ("months", months as Any), ("botUrl", botUrl as Any), ("currency", currency as Any), ("amount", amount as Any)])
}
}
public static func parse_premiumGiftCodeBotOption(_ reader: BufferReader) -> PremiumGiftCodeBotOption? {
var _1: Int32?
_1 = reader.readInt32()
var _2: Int32?
_2 = reader.readInt32()
var _3: Int32?
_3 = reader.readInt32()
var _4: String?
_4 = parseString(reader)
var _5: String?
_5 = parseString(reader)
var _6: Int64?
_6 = reader.readInt64()
let _c1 = _1 != nil
let _c2 = _2 != nil
let _c3 = _3 != nil
let _c4 = _4 != nil
let _c5 = _5 != nil
let _c6 = _6 != nil
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 {
return Api.PremiumGiftCodeBotOption.premiumGiftCodeBotOption(flags: _1!, users: _2!, months: _3!, botUrl: _4!, currency: _5!, amount: _6!)
}
else {
return nil
}
}
}
}
public extension Api {
enum PremiumGiftCodeOption: TypeConstructorDescription {
case premiumGiftCodeOption(flags: Int32, users: Int32, months: Int32, storeProduct: String?, storeQuantity: Int32?, currency: String, amount: Int64)
@ -1166,3 +1110,183 @@ public extension Api {
}
}
public extension Api {
enum PrivacyRule: TypeConstructorDescription {
case privacyValueAllowAll
case privacyValueAllowChatParticipants(chats: [Int64])
case privacyValueAllowCloseFriends
case privacyValueAllowContacts
case privacyValueAllowUsers(users: [Int64])
case privacyValueDisallowAll
case privacyValueDisallowChatParticipants(chats: [Int64])
case privacyValueDisallowContacts
case privacyValueDisallowUsers(users: [Int64])
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
switch self {
case .privacyValueAllowAll:
if boxed {
buffer.appendInt32(1698855810)
}
break
case .privacyValueAllowChatParticipants(let chats):
if boxed {
buffer.appendInt32(1796427406)
}
buffer.appendInt32(481674261)
buffer.appendInt32(Int32(chats.count))
for item in chats {
serializeInt64(item, buffer: buffer, boxed: false)
}
break
case .privacyValueAllowCloseFriends:
if boxed {
buffer.appendInt32(-135735141)
}
break
case .privacyValueAllowContacts:
if boxed {
buffer.appendInt32(-123988)
}
break
case .privacyValueAllowUsers(let users):
if boxed {
buffer.appendInt32(-1198497870)
}
buffer.appendInt32(481674261)
buffer.appendInt32(Int32(users.count))
for item in users {
serializeInt64(item, buffer: buffer, boxed: false)
}
break
case .privacyValueDisallowAll:
if boxed {
buffer.appendInt32(-1955338397)
}
break
case .privacyValueDisallowChatParticipants(let chats):
if boxed {
buffer.appendInt32(1103656293)
}
buffer.appendInt32(481674261)
buffer.appendInt32(Int32(chats.count))
for item in chats {
serializeInt64(item, buffer: buffer, boxed: false)
}
break
case .privacyValueDisallowContacts:
if boxed {
buffer.appendInt32(-125240806)
}
break
case .privacyValueDisallowUsers(let users):
if boxed {
buffer.appendInt32(-463335103)
}
buffer.appendInt32(481674261)
buffer.appendInt32(Int32(users.count))
for item in users {
serializeInt64(item, buffer: buffer, boxed: false)
}
break
}
}
public func descriptionFields() -> (String, [(String, Any)]) {
switch self {
case .privacyValueAllowAll:
return ("privacyValueAllowAll", [])
case .privacyValueAllowChatParticipants(let chats):
return ("privacyValueAllowChatParticipants", [("chats", chats as Any)])
case .privacyValueAllowCloseFriends:
return ("privacyValueAllowCloseFriends", [])
case .privacyValueAllowContacts:
return ("privacyValueAllowContacts", [])
case .privacyValueAllowUsers(let users):
return ("privacyValueAllowUsers", [("users", users as Any)])
case .privacyValueDisallowAll:
return ("privacyValueDisallowAll", [])
case .privacyValueDisallowChatParticipants(let chats):
return ("privacyValueDisallowChatParticipants", [("chats", chats as Any)])
case .privacyValueDisallowContacts:
return ("privacyValueDisallowContacts", [])
case .privacyValueDisallowUsers(let users):
return ("privacyValueDisallowUsers", [("users", users as Any)])
}
}
public static func parse_privacyValueAllowAll(_ reader: BufferReader) -> PrivacyRule? {
return Api.PrivacyRule.privacyValueAllowAll
}
public static func parse_privacyValueAllowChatParticipants(_ reader: BufferReader) -> PrivacyRule? {
var _1: [Int64]?
if let _ = reader.readInt32() {
_1 = Api.parseVector(reader, elementSignature: 570911930, elementType: Int64.self)
}
let _c1 = _1 != nil
if _c1 {
return Api.PrivacyRule.privacyValueAllowChatParticipants(chats: _1!)
}
else {
return nil
}
}
public static func parse_privacyValueAllowCloseFriends(_ reader: BufferReader) -> PrivacyRule? {
return Api.PrivacyRule.privacyValueAllowCloseFriends
}
public static func parse_privacyValueAllowContacts(_ reader: BufferReader) -> PrivacyRule? {
return Api.PrivacyRule.privacyValueAllowContacts
}
public static func parse_privacyValueAllowUsers(_ reader: BufferReader) -> PrivacyRule? {
var _1: [Int64]?
if let _ = reader.readInt32() {
_1 = Api.parseVector(reader, elementSignature: 570911930, elementType: Int64.self)
}
let _c1 = _1 != nil
if _c1 {
return Api.PrivacyRule.privacyValueAllowUsers(users: _1!)
}
else {
return nil
}
}
public static func parse_privacyValueDisallowAll(_ reader: BufferReader) -> PrivacyRule? {
return Api.PrivacyRule.privacyValueDisallowAll
}
public static func parse_privacyValueDisallowChatParticipants(_ reader: BufferReader) -> PrivacyRule? {
var _1: [Int64]?
if let _ = reader.readInt32() {
_1 = Api.parseVector(reader, elementSignature: 570911930, elementType: Int64.self)
}
let _c1 = _1 != nil
if _c1 {
return Api.PrivacyRule.privacyValueDisallowChatParticipants(chats: _1!)
}
else {
return nil
}
}
public static func parse_privacyValueDisallowContacts(_ reader: BufferReader) -> PrivacyRule? {
return Api.PrivacyRule.privacyValueDisallowContacts
}
public static func parse_privacyValueDisallowUsers(_ reader: BufferReader) -> PrivacyRule? {
var _1: [Int64]?
if let _ = reader.readInt32() {
_1 = Api.parseVector(reader, elementSignature: 570911930, elementType: Int64.self)
}
let _c1 = _1 != nil
if _c1 {
return Api.PrivacyRule.privacyValueDisallowUsers(users: _1!)
}
else {
return nil
}
}
}
}

View File

@ -1,183 +1,3 @@
public extension Api {
enum PrivacyRule: TypeConstructorDescription {
case privacyValueAllowAll
case privacyValueAllowChatParticipants(chats: [Int64])
case privacyValueAllowCloseFriends
case privacyValueAllowContacts
case privacyValueAllowUsers(users: [Int64])
case privacyValueDisallowAll
case privacyValueDisallowChatParticipants(chats: [Int64])
case privacyValueDisallowContacts
case privacyValueDisallowUsers(users: [Int64])
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
switch self {
case .privacyValueAllowAll:
if boxed {
buffer.appendInt32(1698855810)
}
break
case .privacyValueAllowChatParticipants(let chats):
if boxed {
buffer.appendInt32(1796427406)
}
buffer.appendInt32(481674261)
buffer.appendInt32(Int32(chats.count))
for item in chats {
serializeInt64(item, buffer: buffer, boxed: false)
}
break
case .privacyValueAllowCloseFriends:
if boxed {
buffer.appendInt32(-135735141)
}
break
case .privacyValueAllowContacts:
if boxed {
buffer.appendInt32(-123988)
}
break
case .privacyValueAllowUsers(let users):
if boxed {
buffer.appendInt32(-1198497870)
}
buffer.appendInt32(481674261)
buffer.appendInt32(Int32(users.count))
for item in users {
serializeInt64(item, buffer: buffer, boxed: false)
}
break
case .privacyValueDisallowAll:
if boxed {
buffer.appendInt32(-1955338397)
}
break
case .privacyValueDisallowChatParticipants(let chats):
if boxed {
buffer.appendInt32(1103656293)
}
buffer.appendInt32(481674261)
buffer.appendInt32(Int32(chats.count))
for item in chats {
serializeInt64(item, buffer: buffer, boxed: false)
}
break
case .privacyValueDisallowContacts:
if boxed {
buffer.appendInt32(-125240806)
}
break
case .privacyValueDisallowUsers(let users):
if boxed {
buffer.appendInt32(-463335103)
}
buffer.appendInt32(481674261)
buffer.appendInt32(Int32(users.count))
for item in users {
serializeInt64(item, buffer: buffer, boxed: false)
}
break
}
}
public func descriptionFields() -> (String, [(String, Any)]) {
switch self {
case .privacyValueAllowAll:
return ("privacyValueAllowAll", [])
case .privacyValueAllowChatParticipants(let chats):
return ("privacyValueAllowChatParticipants", [("chats", chats as Any)])
case .privacyValueAllowCloseFriends:
return ("privacyValueAllowCloseFriends", [])
case .privacyValueAllowContacts:
return ("privacyValueAllowContacts", [])
case .privacyValueAllowUsers(let users):
return ("privacyValueAllowUsers", [("users", users as Any)])
case .privacyValueDisallowAll:
return ("privacyValueDisallowAll", [])
case .privacyValueDisallowChatParticipants(let chats):
return ("privacyValueDisallowChatParticipants", [("chats", chats as Any)])
case .privacyValueDisallowContacts:
return ("privacyValueDisallowContacts", [])
case .privacyValueDisallowUsers(let users):
return ("privacyValueDisallowUsers", [("users", users as Any)])
}
}
public static func parse_privacyValueAllowAll(_ reader: BufferReader) -> PrivacyRule? {
return Api.PrivacyRule.privacyValueAllowAll
}
public static func parse_privacyValueAllowChatParticipants(_ reader: BufferReader) -> PrivacyRule? {
var _1: [Int64]?
if let _ = reader.readInt32() {
_1 = Api.parseVector(reader, elementSignature: 570911930, elementType: Int64.self)
}
let _c1 = _1 != nil
if _c1 {
return Api.PrivacyRule.privacyValueAllowChatParticipants(chats: _1!)
}
else {
return nil
}
}
public static func parse_privacyValueAllowCloseFriends(_ reader: BufferReader) -> PrivacyRule? {
return Api.PrivacyRule.privacyValueAllowCloseFriends
}
public static func parse_privacyValueAllowContacts(_ reader: BufferReader) -> PrivacyRule? {
return Api.PrivacyRule.privacyValueAllowContacts
}
public static func parse_privacyValueAllowUsers(_ reader: BufferReader) -> PrivacyRule? {
var _1: [Int64]?
if let _ = reader.readInt32() {
_1 = Api.parseVector(reader, elementSignature: 570911930, elementType: Int64.self)
}
let _c1 = _1 != nil
if _c1 {
return Api.PrivacyRule.privacyValueAllowUsers(users: _1!)
}
else {
return nil
}
}
public static func parse_privacyValueDisallowAll(_ reader: BufferReader) -> PrivacyRule? {
return Api.PrivacyRule.privacyValueDisallowAll
}
public static func parse_privacyValueDisallowChatParticipants(_ reader: BufferReader) -> PrivacyRule? {
var _1: [Int64]?
if let _ = reader.readInt32() {
_1 = Api.parseVector(reader, elementSignature: 570911930, elementType: Int64.self)
}
let _c1 = _1 != nil
if _c1 {
return Api.PrivacyRule.privacyValueDisallowChatParticipants(chats: _1!)
}
else {
return nil
}
}
public static func parse_privacyValueDisallowContacts(_ reader: BufferReader) -> PrivacyRule? {
return Api.PrivacyRule.privacyValueDisallowContacts
}
public static func parse_privacyValueDisallowUsers(_ reader: BufferReader) -> PrivacyRule? {
var _1: [Int64]?
if let _ = reader.readInt32() {
_1 = Api.parseVector(reader, elementSignature: 570911930, elementType: Int64.self)
}
let _c1 = _1 != nil
if _c1 {
return Api.PrivacyRule.privacyValueDisallowUsers(users: _1!)
}
else {
return nil
}
}
}
}
public extension Api {
enum Reaction: TypeConstructorDescription {
case reactionCustomEmoji(documentId: Int64)
@ -768,3 +588,563 @@ public extension Api {
}
}
public extension Api {
enum RequestPeerType: TypeConstructorDescription {
case requestPeerTypeBroadcast(flags: Int32, hasUsername: Api.Bool?, userAdminRights: Api.ChatAdminRights?, botAdminRights: Api.ChatAdminRights?)
case requestPeerTypeChat(flags: Int32, hasUsername: Api.Bool?, forum: Api.Bool?, userAdminRights: Api.ChatAdminRights?, botAdminRights: Api.ChatAdminRights?)
case requestPeerTypeUser(flags: Int32, bot: Api.Bool?, premium: Api.Bool?)
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
switch self {
case .requestPeerTypeBroadcast(let flags, let hasUsername, let userAdminRights, let botAdminRights):
if boxed {
buffer.appendInt32(865857388)
}
serializeInt32(flags, buffer: buffer, boxed: false)
if Int(flags) & Int(1 << 3) != 0 {hasUsername!.serialize(buffer, true)}
if Int(flags) & Int(1 << 1) != 0 {userAdminRights!.serialize(buffer, true)}
if Int(flags) & Int(1 << 2) != 0 {botAdminRights!.serialize(buffer, true)}
break
case .requestPeerTypeChat(let flags, let hasUsername, let forum, let userAdminRights, let botAdminRights):
if boxed {
buffer.appendInt32(-906990053)
}
serializeInt32(flags, buffer: buffer, boxed: false)
if Int(flags) & Int(1 << 3) != 0 {hasUsername!.serialize(buffer, true)}
if Int(flags) & Int(1 << 4) != 0 {forum!.serialize(buffer, true)}
if Int(flags) & Int(1 << 1) != 0 {userAdminRights!.serialize(buffer, true)}
if Int(flags) & Int(1 << 2) != 0 {botAdminRights!.serialize(buffer, true)}
break
case .requestPeerTypeUser(let flags, let bot, let premium):
if boxed {
buffer.appendInt32(1597737472)
}
serializeInt32(flags, buffer: buffer, boxed: false)
if Int(flags) & Int(1 << 0) != 0 {bot!.serialize(buffer, true)}
if Int(flags) & Int(1 << 1) != 0 {premium!.serialize(buffer, true)}
break
}
}
public func descriptionFields() -> (String, [(String, Any)]) {
switch self {
case .requestPeerTypeBroadcast(let flags, let hasUsername, let userAdminRights, let botAdminRights):
return ("requestPeerTypeBroadcast", [("flags", flags as Any), ("hasUsername", hasUsername as Any), ("userAdminRights", userAdminRights as Any), ("botAdminRights", botAdminRights as Any)])
case .requestPeerTypeChat(let flags, let hasUsername, let forum, let userAdminRights, let botAdminRights):
return ("requestPeerTypeChat", [("flags", flags as Any), ("hasUsername", hasUsername as Any), ("forum", forum as Any), ("userAdminRights", userAdminRights as Any), ("botAdminRights", botAdminRights as Any)])
case .requestPeerTypeUser(let flags, let bot, let premium):
return ("requestPeerTypeUser", [("flags", flags as Any), ("bot", bot as Any), ("premium", premium as Any)])
}
}
public static func parse_requestPeerTypeBroadcast(_ reader: BufferReader) -> RequestPeerType? {
var _1: Int32?
_1 = reader.readInt32()
var _2: Api.Bool?
if Int(_1!) & Int(1 << 3) != 0 {if let signature = reader.readInt32() {
_2 = Api.parse(reader, signature: signature) as? Api.Bool
} }
var _3: Api.ChatAdminRights?
if Int(_1!) & Int(1 << 1) != 0 {if let signature = reader.readInt32() {
_3 = Api.parse(reader, signature: signature) as? Api.ChatAdminRights
} }
var _4: Api.ChatAdminRights?
if Int(_1!) & Int(1 << 2) != 0 {if let signature = reader.readInt32() {
_4 = Api.parse(reader, signature: signature) as? Api.ChatAdminRights
} }
let _c1 = _1 != nil
let _c2 = (Int(_1!) & Int(1 << 3) == 0) || _2 != nil
let _c3 = (Int(_1!) & Int(1 << 1) == 0) || _3 != nil
let _c4 = (Int(_1!) & Int(1 << 2) == 0) || _4 != nil
if _c1 && _c2 && _c3 && _c4 {
return Api.RequestPeerType.requestPeerTypeBroadcast(flags: _1!, hasUsername: _2, userAdminRights: _3, botAdminRights: _4)
}
else {
return nil
}
}
public static func parse_requestPeerTypeChat(_ reader: BufferReader) -> RequestPeerType? {
var _1: Int32?
_1 = reader.readInt32()
var _2: Api.Bool?
if Int(_1!) & Int(1 << 3) != 0 {if let signature = reader.readInt32() {
_2 = Api.parse(reader, signature: signature) as? Api.Bool
} }
var _3: Api.Bool?
if Int(_1!) & Int(1 << 4) != 0 {if let signature = reader.readInt32() {
_3 = Api.parse(reader, signature: signature) as? Api.Bool
} }
var _4: Api.ChatAdminRights?
if Int(_1!) & Int(1 << 1) != 0 {if let signature = reader.readInt32() {
_4 = Api.parse(reader, signature: signature) as? Api.ChatAdminRights
} }
var _5: Api.ChatAdminRights?
if Int(_1!) & Int(1 << 2) != 0 {if let signature = reader.readInt32() {
_5 = Api.parse(reader, signature: signature) as? Api.ChatAdminRights
} }
let _c1 = _1 != nil
let _c2 = (Int(_1!) & Int(1 << 3) == 0) || _2 != nil
let _c3 = (Int(_1!) & Int(1 << 4) == 0) || _3 != nil
let _c4 = (Int(_1!) & Int(1 << 1) == 0) || _4 != nil
let _c5 = (Int(_1!) & Int(1 << 2) == 0) || _5 != nil
if _c1 && _c2 && _c3 && _c4 && _c5 {
return Api.RequestPeerType.requestPeerTypeChat(flags: _1!, hasUsername: _2, forum: _3, userAdminRights: _4, botAdminRights: _5)
}
else {
return nil
}
}
public static func parse_requestPeerTypeUser(_ reader: BufferReader) -> RequestPeerType? {
var _1: Int32?
_1 = reader.readInt32()
var _2: Api.Bool?
if Int(_1!) & Int(1 << 0) != 0 {if let signature = reader.readInt32() {
_2 = Api.parse(reader, signature: signature) as? Api.Bool
} }
var _3: Api.Bool?
if Int(_1!) & Int(1 << 1) != 0 {if let signature = reader.readInt32() {
_3 = Api.parse(reader, signature: signature) as? Api.Bool
} }
let _c1 = _1 != nil
let _c2 = (Int(_1!) & Int(1 << 0) == 0) || _2 != nil
let _c3 = (Int(_1!) & Int(1 << 1) == 0) || _3 != nil
if _c1 && _c2 && _c3 {
return Api.RequestPeerType.requestPeerTypeUser(flags: _1!, bot: _2, premium: _3)
}
else {
return nil
}
}
}
}
public extension Api {
enum RestrictionReason: TypeConstructorDescription {
case restrictionReason(platform: String, reason: String, text: String)
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
switch self {
case .restrictionReason(let platform, let reason, let text):
if boxed {
buffer.appendInt32(-797791052)
}
serializeString(platform, buffer: buffer, boxed: false)
serializeString(reason, buffer: buffer, boxed: false)
serializeString(text, buffer: buffer, boxed: false)
break
}
}
public func descriptionFields() -> (String, [(String, Any)]) {
switch self {
case .restrictionReason(let platform, let reason, let text):
return ("restrictionReason", [("platform", platform as Any), ("reason", reason as Any), ("text", text as Any)])
}
}
public static func parse_restrictionReason(_ reader: BufferReader) -> RestrictionReason? {
var _1: String?
_1 = parseString(reader)
var _2: String?
_2 = parseString(reader)
var _3: String?
_3 = parseString(reader)
let _c1 = _1 != nil
let _c2 = _2 != nil
let _c3 = _3 != nil
if _c1 && _c2 && _c3 {
return Api.RestrictionReason.restrictionReason(platform: _1!, reason: _2!, text: _3!)
}
else {
return nil
}
}
}
}
public extension Api {
indirect enum RichText: TypeConstructorDescription {
case textAnchor(text: Api.RichText, name: String)
case textBold(text: Api.RichText)
case textConcat(texts: [Api.RichText])
case textEmail(text: Api.RichText, email: String)
case textEmpty
case textFixed(text: Api.RichText)
case textImage(documentId: Int64, w: Int32, h: Int32)
case textItalic(text: Api.RichText)
case textMarked(text: Api.RichText)
case textPhone(text: Api.RichText, phone: String)
case textPlain(text: String)
case textStrike(text: Api.RichText)
case textSubscript(text: Api.RichText)
case textSuperscript(text: Api.RichText)
case textUnderline(text: Api.RichText)
case textUrl(text: Api.RichText, url: String, webpageId: Int64)
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
switch self {
case .textAnchor(let text, let name):
if boxed {
buffer.appendInt32(894777186)
}
text.serialize(buffer, true)
serializeString(name, buffer: buffer, boxed: false)
break
case .textBold(let text):
if boxed {
buffer.appendInt32(1730456516)
}
text.serialize(buffer, true)
break
case .textConcat(let texts):
if boxed {
buffer.appendInt32(2120376535)
}
buffer.appendInt32(481674261)
buffer.appendInt32(Int32(texts.count))
for item in texts {
item.serialize(buffer, true)
}
break
case .textEmail(let text, let email):
if boxed {
buffer.appendInt32(-564523562)
}
text.serialize(buffer, true)
serializeString(email, buffer: buffer, boxed: false)
break
case .textEmpty:
if boxed {
buffer.appendInt32(-599948721)
}
break
case .textFixed(let text):
if boxed {
buffer.appendInt32(1816074681)
}
text.serialize(buffer, true)
break
case .textImage(let documentId, let w, let h):
if boxed {
buffer.appendInt32(136105807)
}
serializeInt64(documentId, buffer: buffer, boxed: false)
serializeInt32(w, buffer: buffer, boxed: false)
serializeInt32(h, buffer: buffer, boxed: false)
break
case .textItalic(let text):
if boxed {
buffer.appendInt32(-653089380)
}
text.serialize(buffer, true)
break
case .textMarked(let text):
if boxed {
buffer.appendInt32(55281185)
}
text.serialize(buffer, true)
break
case .textPhone(let text, let phone):
if boxed {
buffer.appendInt32(483104362)
}
text.serialize(buffer, true)
serializeString(phone, buffer: buffer, boxed: false)
break
case .textPlain(let text):
if boxed {
buffer.appendInt32(1950782688)
}
serializeString(text, buffer: buffer, boxed: false)
break
case .textStrike(let text):
if boxed {
buffer.appendInt32(-1678197867)
}
text.serialize(buffer, true)
break
case .textSubscript(let text):
if boxed {
buffer.appendInt32(-311786236)
}
text.serialize(buffer, true)
break
case .textSuperscript(let text):
if boxed {
buffer.appendInt32(-939827711)
}
text.serialize(buffer, true)
break
case .textUnderline(let text):
if boxed {
buffer.appendInt32(-1054465340)
}
text.serialize(buffer, true)
break
case .textUrl(let text, let url, let webpageId):
if boxed {
buffer.appendInt32(1009288385)
}
text.serialize(buffer, true)
serializeString(url, buffer: buffer, boxed: false)
serializeInt64(webpageId, buffer: buffer, boxed: false)
break
}
}
public func descriptionFields() -> (String, [(String, Any)]) {
switch self {
case .textAnchor(let text, let name):
return ("textAnchor", [("text", text as Any), ("name", name as Any)])
case .textBold(let text):
return ("textBold", [("text", text as Any)])
case .textConcat(let texts):
return ("textConcat", [("texts", texts as Any)])
case .textEmail(let text, let email):
return ("textEmail", [("text", text as Any), ("email", email as Any)])
case .textEmpty:
return ("textEmpty", [])
case .textFixed(let text):
return ("textFixed", [("text", text as Any)])
case .textImage(let documentId, let w, let h):
return ("textImage", [("documentId", documentId as Any), ("w", w as Any), ("h", h as Any)])
case .textItalic(let text):
return ("textItalic", [("text", text as Any)])
case .textMarked(let text):
return ("textMarked", [("text", text as Any)])
case .textPhone(let text, let phone):
return ("textPhone", [("text", text as Any), ("phone", phone as Any)])
case .textPlain(let text):
return ("textPlain", [("text", text as Any)])
case .textStrike(let text):
return ("textStrike", [("text", text as Any)])
case .textSubscript(let text):
return ("textSubscript", [("text", text as Any)])
case .textSuperscript(let text):
return ("textSuperscript", [("text", text as Any)])
case .textUnderline(let text):
return ("textUnderline", [("text", text as Any)])
case .textUrl(let text, let url, let webpageId):
return ("textUrl", [("text", text as Any), ("url", url as Any), ("webpageId", webpageId as Any)])
}
}
public static func parse_textAnchor(_ reader: BufferReader) -> RichText? {
var _1: Api.RichText?
if let signature = reader.readInt32() {
_1 = Api.parse(reader, signature: signature) as? Api.RichText
}
var _2: String?
_2 = parseString(reader)
let _c1 = _1 != nil
let _c2 = _2 != nil
if _c1 && _c2 {
return Api.RichText.textAnchor(text: _1!, name: _2!)
}
else {
return nil
}
}
public static func parse_textBold(_ reader: BufferReader) -> RichText? {
var _1: Api.RichText?
if let signature = reader.readInt32() {
_1 = Api.parse(reader, signature: signature) as? Api.RichText
}
let _c1 = _1 != nil
if _c1 {
return Api.RichText.textBold(text: _1!)
}
else {
return nil
}
}
public static func parse_textConcat(_ reader: BufferReader) -> RichText? {
var _1: [Api.RichText]?
if let _ = reader.readInt32() {
_1 = Api.parseVector(reader, elementSignature: 0, elementType: Api.RichText.self)
}
let _c1 = _1 != nil
if _c1 {
return Api.RichText.textConcat(texts: _1!)
}
else {
return nil
}
}
public static func parse_textEmail(_ reader: BufferReader) -> RichText? {
var _1: Api.RichText?
if let signature = reader.readInt32() {
_1 = Api.parse(reader, signature: signature) as? Api.RichText
}
var _2: String?
_2 = parseString(reader)
let _c1 = _1 != nil
let _c2 = _2 != nil
if _c1 && _c2 {
return Api.RichText.textEmail(text: _1!, email: _2!)
}
else {
return nil
}
}
public static func parse_textEmpty(_ reader: BufferReader) -> RichText? {
return Api.RichText.textEmpty
}
public static func parse_textFixed(_ reader: BufferReader) -> RichText? {
var _1: Api.RichText?
if let signature = reader.readInt32() {
_1 = Api.parse(reader, signature: signature) as? Api.RichText
}
let _c1 = _1 != nil
if _c1 {
return Api.RichText.textFixed(text: _1!)
}
else {
return nil
}
}
public static func parse_textImage(_ reader: BufferReader) -> RichText? {
var _1: Int64?
_1 = reader.readInt64()
var _2: Int32?
_2 = reader.readInt32()
var _3: Int32?
_3 = reader.readInt32()
let _c1 = _1 != nil
let _c2 = _2 != nil
let _c3 = _3 != nil
if _c1 && _c2 && _c3 {
return Api.RichText.textImage(documentId: _1!, w: _2!, h: _3!)
}
else {
return nil
}
}
public static func parse_textItalic(_ reader: BufferReader) -> RichText? {
var _1: Api.RichText?
if let signature = reader.readInt32() {
_1 = Api.parse(reader, signature: signature) as? Api.RichText
}
let _c1 = _1 != nil
if _c1 {
return Api.RichText.textItalic(text: _1!)
}
else {
return nil
}
}
public static func parse_textMarked(_ reader: BufferReader) -> RichText? {
var _1: Api.RichText?
if let signature = reader.readInt32() {
_1 = Api.parse(reader, signature: signature) as? Api.RichText
}
let _c1 = _1 != nil
if _c1 {
return Api.RichText.textMarked(text: _1!)
}
else {
return nil
}
}
public static func parse_textPhone(_ reader: BufferReader) -> RichText? {
var _1: Api.RichText?
if let signature = reader.readInt32() {
_1 = Api.parse(reader, signature: signature) as? Api.RichText
}
var _2: String?
_2 = parseString(reader)
let _c1 = _1 != nil
let _c2 = _2 != nil
if _c1 && _c2 {
return Api.RichText.textPhone(text: _1!, phone: _2!)
}
else {
return nil
}
}
public static func parse_textPlain(_ reader: BufferReader) -> RichText? {
var _1: String?
_1 = parseString(reader)
let _c1 = _1 != nil
if _c1 {
return Api.RichText.textPlain(text: _1!)
}
else {
return nil
}
}
public static func parse_textStrike(_ reader: BufferReader) -> RichText? {
var _1: Api.RichText?
if let signature = reader.readInt32() {
_1 = Api.parse(reader, signature: signature) as? Api.RichText
}
let _c1 = _1 != nil
if _c1 {
return Api.RichText.textStrike(text: _1!)
}
else {
return nil
}
}
public static func parse_textSubscript(_ reader: BufferReader) -> RichText? {
var _1: Api.RichText?
if let signature = reader.readInt32() {
_1 = Api.parse(reader, signature: signature) as? Api.RichText
}
let _c1 = _1 != nil
if _c1 {
return Api.RichText.textSubscript(text: _1!)
}
else {
return nil
}
}
public static func parse_textSuperscript(_ reader: BufferReader) -> RichText? {
var _1: Api.RichText?
if let signature = reader.readInt32() {
_1 = Api.parse(reader, signature: signature) as? Api.RichText
}
let _c1 = _1 != nil
if _c1 {
return Api.RichText.textSuperscript(text: _1!)
}
else {
return nil
}
}
public static func parse_textUnderline(_ reader: BufferReader) -> RichText? {
var _1: Api.RichText?
if let signature = reader.readInt32() {
_1 = Api.parse(reader, signature: signature) as? Api.RichText
}
let _c1 = _1 != nil
if _c1 {
return Api.RichText.textUnderline(text: _1!)
}
else {
return nil
}
}
public static func parse_textUrl(_ reader: BufferReader) -> RichText? {
var _1: Api.RichText?
if let signature = reader.readInt32() {
_1 = Api.parse(reader, signature: signature) as? Api.RichText
}
var _2: String?
_2 = parseString(reader)
var _3: Int64?
_3 = reader.readInt64()
let _c1 = _1 != nil
let _c2 = _2 != nil
let _c3 = _3 != nil
if _c1 && _c2 && _c3 {
return Api.RichText.textUrl(text: _1!, url: _2!, webpageId: _3!)
}
else {
return nil
}
}
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -125,6 +125,7 @@ enum AccountStateMutationOperation {
case UpdateStoryStealthMode(data: Api.StoriesStealthMode)
case UpdateStorySentReaction(peerId: PeerId, id: Int32, reaction: Api.Reaction)
case UpdateNewAuthorization(isUnconfirmed: Bool, hash: Int64, date: Int32, device: String, location: String)
case UpdateWallpaper(peerId: PeerId, wallpaper: TelegramWallpaper?)
}
struct HoleFromPreviousState {
@ -522,6 +523,10 @@ struct AccountMutableState {
self.addOperation(.UpdateTheme(theme))
}
mutating func updateWallpaper(peerId: PeerId, wallpaper: TelegramWallpaper?) {
self.addOperation(.UpdateWallpaper(peerId: peerId, wallpaper: wallpaper))
}
mutating func mergeUsers(_ users: [Api.User]) {
self.addOperation(.MergeApiUsers(users))
@ -660,7 +665,7 @@ struct AccountMutableState {
mutating func addOperation(_ operation: AccountStateMutationOperation) {
switch operation {
case .DeleteMessages, .DeleteMessagesWithGlobalIds, .EditMessage, .UpdateMessagePoll, .UpdateMessageReactions, .UpdateMedia, .ReadOutbox, .ReadGroupFeedInbox, .MergePeerPresences, .UpdateSecretChat, .AddSecretMessages, .ReadSecretOutbox, .AddPeerInputActivity, .UpdateCachedPeerData, .UpdatePinnedItemIds, .UpdatePinnedTopic, .UpdatePinnedTopicOrder, .ReadMessageContents, .UpdateMessageImpressionCount, .UpdateMessageForwardsCount, .UpdateInstalledStickerPacks, .UpdateRecentGifs, .UpdateChatInputState, .UpdateCall, .AddCallSignalingData, .UpdateLangPack, .UpdateMinAvailableMessage, .UpdatePeerChatUnreadMark, .UpdateIsContact, .UpdatePeerChatInclusion, .UpdatePeersNearby, .UpdateTheme, .SyncChatListFilters, .UpdateChatListFilterOrder, .UpdateChatListFilter, .UpdateReadThread, .UpdateGroupCallParticipants, .UpdateGroupCall, .UpdateMessagesPinned, .UpdateAutoremoveTimeout, .UpdateAttachMenuBots, .UpdateAudioTranscription, .UpdateConfig, .UpdateExtendedMedia, .ResetForumTopic, .UpdateStory, .UpdateReadStories, .UpdateStoryStealthMode, .UpdateStorySentReaction, .UpdateNewAuthorization:
case .DeleteMessages, .DeleteMessagesWithGlobalIds, .EditMessage, .UpdateMessagePoll, .UpdateMessageReactions, .UpdateMedia, .ReadOutbox, .ReadGroupFeedInbox, .MergePeerPresences, .UpdateSecretChat, .AddSecretMessages, .ReadSecretOutbox, .AddPeerInputActivity, .UpdateCachedPeerData, .UpdatePinnedItemIds, .UpdatePinnedTopic, .UpdatePinnedTopicOrder, .ReadMessageContents, .UpdateMessageImpressionCount, .UpdateMessageForwardsCount, .UpdateInstalledStickerPacks, .UpdateRecentGifs, .UpdateChatInputState, .UpdateCall, .AddCallSignalingData, .UpdateLangPack, .UpdateMinAvailableMessage, .UpdatePeerChatUnreadMark, .UpdateIsContact, .UpdatePeerChatInclusion, .UpdatePeersNearby, .UpdateTheme, .UpdateWallpaper, .SyncChatListFilters, .UpdateChatListFilterOrder, .UpdateChatListFilter, .UpdateReadThread, .UpdateGroupCallParticipants, .UpdateGroupCall, .UpdateMessagesPinned, .UpdateAutoremoveTimeout, .UpdateAttachMenuBots, .UpdateAudioTranscription, .UpdateConfig, .UpdateExtendedMedia, .ResetForumTopic, .UpdateStory, .UpdateReadStories, .UpdateStoryStealthMode, .UpdateStorySentReaction, .UpdateNewAuthorization:
break
case let .AddMessages(messages, location):
for message in messages {

View File

@ -217,7 +217,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, .messageActionTopicCreate, .messageActionTopicEdit, .messageActionSuggestProfilePhoto, .messageActionSetChatWallPaper, .messageActionSetSameChatWallPaper, .messageActionGiveawayLaunch, .messageActionGiveawayResults:
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, .messageActionTopicCreate, .messageActionTopicEdit, .messageActionSuggestProfilePhoto, .messageActionSetChatWallPaper, .messageActionGiveawayLaunch, .messageActionGiveawayResults:
break
case let .messageActionChannelMigrateFrom(_, chatId):
result.append(PeerId(namespace: Namespaces.Peer.CloudGroup, id: PeerId.Id._internalFromInt64Value(chatId)))

View File

@ -123,16 +123,18 @@ func telegramMediaActionFromApiAction(_ action: Api.MessageAction) -> TelegramMe
return TelegramMediaAction(action: .suggestedProfilePhoto(image: telegramMediaImageFromApiPhoto(photo)))
case let .messageActionRequestedPeer(buttonId, peer):
return TelegramMediaAction(action: .requestedPeer(buttonId: buttonId, peerId: peer.peerId))
case let .messageActionSetChatWallPaper(wallpaper):
return TelegramMediaAction(action: .setChatWallpaper(wallpaper: TelegramWallpaper(apiWallpaper: wallpaper)))
case let .messageActionSetSameChatWallPaper(wallpaper):
return TelegramMediaAction(action: .setSameChatWallpaper(wallpaper: TelegramWallpaper(apiWallpaper: wallpaper)))
case let .messageActionSetChatWallPaper(flags, wallpaper):
if (flags & (1 << 0)) != 0 {
return TelegramMediaAction(action: .setSameChatWallpaper(wallpaper: TelegramWallpaper(apiWallpaper: wallpaper)))
} else {
return TelegramMediaAction(action: .setChatWallpaper(wallpaper: TelegramWallpaper(apiWallpaper: wallpaper), forBoth: (flags & (1 << 1)) != 0))
}
case let .messageActionGiftCode(flags, boostPeer, months, slug):
return TelegramMediaAction(action: .giftCode(slug: slug, fromGiveaway: (flags & (1 << 0)) != 0, isUnclaimed: (flags & (1 << 2)) != 0, boostPeerId: boostPeer?.peerId, months: months))
case .messageActionGiveawayLaunch:
return TelegramMediaAction(action: .giveawayLaunched)
case let .messageActionGiveawayResults(winners):
return TelegramMediaAction(action: .giveawayResults(winners: winners))
case let .messageActionGiveawayResults(winners, unclaimed):
return TelegramMediaAction(action: .giveawayResults(winners: winners, unclaimed: unclaimed))
}
}

View File

@ -15,7 +15,7 @@ public final class PeerMediaUploadingItem: Equatable {
}
public enum Content: Equatable {
case wallpaper(TelegramWallpaper)
case wallpaper(wallpaper: TelegramWallpaper, forBoth: Bool)
}
public let content: Content
@ -52,7 +52,7 @@ public final class PeerMediaUploadingItem: Equatable {
private func uploadPeerMedia(postbox: Postbox, network: Network, stateManager: AccountStateManager, peerId: EnginePeer.Id, content: PeerMediaUploadingItem.Content) -> Signal<PeerMediaUploadingItem.ProgressValue, PeerMediaUploadingItem.Error> {
switch content {
case let .wallpaper(wallpaper):
case let .wallpaper(wallpaper, forBoth):
if case let .image(representations, settings) = wallpaper, let resource = representations.last?.resource as? LocalFileMediaResource {
return _internal_uploadWallpaper(postbox: postbox, network: network, resource: resource, settings: settings, forChat: true)
|> mapError { error -> PeerMediaUploadingItem.Error in
@ -69,7 +69,7 @@ private func uploadPeerMedia(postbox: Postbox, network: Network, stateManager: A
postbox.mediaBox.copyResourceData(from: resource.id, to: representation.resource.id, synchronous: true)
}
}
return _internal_setChatWallpaper(postbox: postbox, network: network, stateManager: stateManager, peerId: peerId, wallpaper: result, applyUpdates: false)
return _internal_setChatWallpaper(postbox: postbox, network: network, stateManager: stateManager, peerId: peerId, wallpaper: result, forBoth: forBoth, applyUpdates: false)
|> mapError { error -> PeerMediaUploadingItem.Error in
switch error {
case .generic:
@ -85,7 +85,7 @@ private func uploadPeerMedia(postbox: Postbox, network: Network, stateManager: A
}
} else {
return _internal_setChatWallpaper(postbox: postbox, network: network, stateManager: stateManager, peerId: peerId, wallpaper: wallpaper, applyUpdates: false)
return _internal_setChatWallpaper(postbox: postbox, network: network, stateManager: stateManager, peerId: peerId, wallpaper: wallpaper, forBoth: forBoth, applyUpdates: false)
|> mapError { error -> PeerMediaUploadingItem.Error in
switch error {
case .generic:
@ -124,8 +124,8 @@ private func generatePeerMediaMessage(network: Network, accountPeerId: EnginePee
var media: [Media] = []
switch content {
case let .wallpaper(wallpaper):
media.append(TelegramMediaAction(action: .setChatWallpaper(wallpaper: wallpaper)))
case let .wallpaper(wallpaper, forBoth):
media.append(TelegramMediaAction(action: .setChatWallpaper(wallpaper: wallpaper, forBoth: forBoth)))
}
return StoreMessage(peerId: peerId, namespace: Namespaces.Message.Local, globallyUniqueId: randomId, groupingKey: nil, threadId: nil, timestamp: timestamp, flags: [], tags: [], globalTags: [], localTags: [], forwardInfo: nil, authorId: accountPeerId, text: "", attributes: attributes, media: media)

View File

@ -1739,6 +1739,8 @@ private func finalStateWithUpdatesAndServerTime(accountPeerId: PeerId, postbox:
case let .updateNewAuthorization(flags, hash, date, device, location):
let isUnconfirmed = (flags & (1 << 0)) != 0
updatedState.updateNewAuthorization(isUnconfirmed: isUnconfirmed, hash: hash, date: date ?? 0, device: device ?? "", location: location ?? "")
case let .updatePeerWallpaper(_, peer, wallpaper):
updatedState.updateWallpaper(peerId: peer.peerId, wallpaper: wallpaper.flatMap { TelegramWallpaper(apiWallpaper: $0) })
default:
break
}
@ -3229,7 +3231,7 @@ private func optimizedOperations(_ operations: [AccountStateMutationOperation])
var currentAddScheduledMessages: OptimizeAddMessagesState?
for operation in operations {
switch operation {
case .DeleteMessages, .DeleteMessagesWithGlobalIds, .EditMessage, .UpdateMessagePoll, .UpdateMessageReactions, .UpdateMedia, .MergeApiChats, .MergeApiUsers, .MergePeerPresences, .UpdatePeer, .ReadInbox, .ReadOutbox, .ReadGroupFeedInbox, .ResetReadState, .ResetIncomingReadState, .UpdatePeerChatUnreadMark, .ResetMessageTagSummary, .UpdateNotificationSettings, .UpdateGlobalNotificationSettings, .UpdateSecretChat, .AddSecretMessages, .ReadSecretOutbox, .AddPeerInputActivity, .UpdateCachedPeerData, .UpdatePinnedItemIds, .UpdatePinnedTopic, .UpdatePinnedTopicOrder, .ReadMessageContents, .UpdateMessageImpressionCount, .UpdateMessageForwardsCount, .UpdateInstalledStickerPacks, .UpdateRecentGifs, .UpdateChatInputState, .UpdateCall, .AddCallSignalingData, .UpdateLangPack, .UpdateMinAvailableMessage, .UpdateIsContact, .UpdatePeerChatInclusion, .UpdatePeersNearby, .UpdateTheme, .SyncChatListFilters, .UpdateChatListFilter, .UpdateChatListFilterOrder, .UpdateReadThread, .UpdateMessagesPinned, .UpdateGroupCallParticipants, .UpdateGroupCall, .UpdateAutoremoveTimeout, .UpdateAttachMenuBots, .UpdateAudioTranscription, .UpdateConfig, .UpdateExtendedMedia, .ResetForumTopic, .UpdateStory, .UpdateReadStories, .UpdateStoryStealthMode, .UpdateStorySentReaction, .UpdateNewAuthorization:
case .DeleteMessages, .DeleteMessagesWithGlobalIds, .EditMessage, .UpdateMessagePoll, .UpdateMessageReactions, .UpdateMedia, .MergeApiChats, .MergeApiUsers, .MergePeerPresences, .UpdatePeer, .ReadInbox, .ReadOutbox, .ReadGroupFeedInbox, .ResetReadState, .ResetIncomingReadState, .UpdatePeerChatUnreadMark, .ResetMessageTagSummary, .UpdateNotificationSettings, .UpdateGlobalNotificationSettings, .UpdateSecretChat, .AddSecretMessages, .ReadSecretOutbox, .AddPeerInputActivity, .UpdateCachedPeerData, .UpdatePinnedItemIds, .UpdatePinnedTopic, .UpdatePinnedTopicOrder, .ReadMessageContents, .UpdateMessageImpressionCount, .UpdateMessageForwardsCount, .UpdateInstalledStickerPacks, .UpdateRecentGifs, .UpdateChatInputState, .UpdateCall, .AddCallSignalingData, .UpdateLangPack, .UpdateMinAvailableMessage, .UpdateIsContact, .UpdatePeerChatInclusion, .UpdatePeersNearby, .UpdateTheme, .SyncChatListFilters, .UpdateChatListFilter, .UpdateChatListFilterOrder, .UpdateReadThread, .UpdateMessagesPinned, .UpdateGroupCallParticipants, .UpdateGroupCall, .UpdateAutoremoveTimeout, .UpdateAttachMenuBots, .UpdateAudioTranscription, .UpdateConfig, .UpdateExtendedMedia, .ResetForumTopic, .UpdateStory, .UpdateReadStories, .UpdateStoryStealthMode, .UpdateStorySentReaction, .UpdateNewAuthorization, .UpdateWallpaper:
if let currentAddMessages = currentAddMessages, !currentAddMessages.messages.isEmpty {
result.append(.AddMessages(currentAddMessages.messages, currentAddMessages.location))
}
@ -3342,6 +3344,7 @@ func replayFinalState(
var langPackDifferences: [String: [Api.LangPackDifference]] = [:]
var pollLangPacks = Set<String>()
var updatedThemes: [Int64: TelegramTheme] = [:]
var updatedWallpapers: [PeerId: TelegramWallpaper] = [:]
var delayNotificatonsUntil: Int32?
var peerActivityTimestamps: [PeerId: Int32] = [:]
var syncChatListFilters = false
@ -3618,34 +3621,34 @@ func replayFinalState(
})
}
switch action.action {
case let .setChatTheme(emoticon):
transaction.updatePeerCachedData(peerIds: [message.id.peerId], update: { peerId, current in
var current = current
if current == nil {
if peerId.namespace == Namespaces.Peer.CloudUser {
current = CachedUserData()
} else if peerId.namespace == Namespaces.Peer.CloudGroup {
current = CachedGroupData()
} else if peerId.namespace == Namespaces.Peer.CloudChannel {
current = CachedChannelData()
}
case let .setChatTheme(emoticon):
transaction.updatePeerCachedData(peerIds: [message.id.peerId], update: { peerId, current in
var current = current
if current == nil {
if peerId.namespace == Namespaces.Peer.CloudUser {
current = CachedUserData()
} else if peerId.namespace == Namespaces.Peer.CloudGroup {
current = CachedGroupData()
} else if peerId.namespace == Namespaces.Peer.CloudChannel {
current = CachedChannelData()
}
if let cachedData = current as? CachedUserData {
return cachedData.withUpdatedThemeEmoticon(!emoticon.isEmpty ? emoticon : nil)
} else if let cachedData = current as? CachedGroupData {
return cachedData.withUpdatedThemeEmoticon(!emoticon.isEmpty ? emoticon : nil)
} else if let cachedData = current as? CachedChannelData {
return cachedData.withUpdatedThemeEmoticon(!emoticon.isEmpty ? emoticon : nil)
} else {
return current
}
})
case .groupCreated, .channelMigratedFromGroup:
let holesAtHistoryStart = transaction.getHole(containing: MessageId(peerId: chatPeerId, namespace: Namespaces.Message.Cloud, id: id.id - 1))
for (space, _) in holesAtHistoryStart {
transaction.removeHole(peerId: chatPeerId, threadId: nil, namespace: Namespaces.Message.Cloud, space: space, range: 1 ... id.id)
}
case let .setChatWallpaper(wallpaper), let .setSameChatWallpaper(wallpaper):
if let cachedData = current as? CachedUserData {
return cachedData.withUpdatedThemeEmoticon(!emoticon.isEmpty ? emoticon : nil)
} else if let cachedData = current as? CachedGroupData {
return cachedData.withUpdatedThemeEmoticon(!emoticon.isEmpty ? emoticon : nil)
} else if let cachedData = current as? CachedChannelData {
return cachedData.withUpdatedThemeEmoticon(!emoticon.isEmpty ? emoticon : nil)
} else {
return current
}
})
case .groupCreated, .channelMigratedFromGroup:
let holesAtHistoryStart = transaction.getHole(containing: MessageId(peerId: chatPeerId, namespace: Namespaces.Message.Cloud, id: id.id - 1))
for (space, _) in holesAtHistoryStart {
transaction.removeHole(peerId: chatPeerId, threadId: nil, namespace: Namespaces.Message.Cloud, space: space, range: 1 ... id.id)
}
case let .setChatWallpaper(wallpaper, _):
if message.authorId == accountPeerId {
transaction.updatePeerCachedData(peerIds: [message.id.peerId], update: { peerId, current in
var current = current
@ -3661,8 +3664,8 @@ func replayFinalState(
}
})
}
default:
break
default:
break
}
}
}
@ -4378,6 +4381,8 @@ func replayFinalState(
updatedPeersNearby = peersNearby
case let .UpdateTheme(theme):
updatedThemes[theme.id] = theme
case let .UpdateWallpaper(peerId, wallpaper):
updatedWallpapers[peerId] = wallpaper
case .SyncChatListFilters:
syncChatListFilters = true
case let .UpdateChatListFilterOrder(order):
@ -5140,6 +5145,20 @@ func replayFinalState(
}.start()
}
if !updatedWallpapers.isEmpty {
for (peerId, wallpaper) in updatedWallpapers {
transaction.updatePeerCachedData(peerIds: Set([peerId]), update: { _, current in
if let current = current as? CachedUserData {
return current.withUpdatedWallpaper(wallpaper)
} else {
var cachedData = CachedUserData()
cachedData = cachedData.withUpdatedWallpaper(wallpaper)
return cachedData
}
})
}
}
addedIncomingMessageIds.append(contentsOf: addedSecretMessageIds)
for (uniqueId, messageIdValue) in finalState.state.updatedOutgoingUniqueMessageIds {

View File

@ -107,12 +107,12 @@ public enum TelegramMediaActionType: PostboxCoding, Equatable {
case suggestedProfilePhoto(image: TelegramMediaImage?)
case attachMenuBotAllowed
case requestedPeer(buttonId: Int32, peerId: PeerId)
case setChatWallpaper(wallpaper: TelegramWallpaper)
case setChatWallpaper(wallpaper: TelegramWallpaper, forBoth: Bool)
case setSameChatWallpaper(wallpaper: TelegramWallpaper)
case giftCode(slug: String, fromGiveaway: Bool, isUnclaimed: Bool, boostPeerId: PeerId?, months: Int32)
case giveawayLaunched
case joinedChannel
case giveawayResults(winners: Int32)
case giveawayResults(winners: Int32, unclaimed: Int32)
public init(decoder: PostboxDecoder) {
let rawValue: Int32 = decoder.decodeInt32ForKey("_rawValue", orElse: 0)
@ -195,7 +195,7 @@ public enum TelegramMediaActionType: PostboxCoding, Equatable {
self = .requestedPeer(buttonId: decoder.decodeInt32ForKey("b", orElse: 0), peerId: PeerId(decoder.decodeInt64ForKey("pi", orElse: 0)))
case 33:
if let wallpaper = decoder.decode(TelegramWallpaperNativeCodable.self, forKey: "wallpaper")?.value {
self = .setChatWallpaper(wallpaper: wallpaper)
self = .setChatWallpaper(wallpaper: wallpaper, forBoth: decoder.decodeBoolForKey("both", orElse: false))
} else {
self = .unknown
}
@ -214,7 +214,7 @@ public enum TelegramMediaActionType: PostboxCoding, Equatable {
case 38:
self = .joinedChannel
case 39:
self = .giveawayResults(winners: decoder.decodeInt32ForKey("winners", orElse: 0))
self = .giveawayResults(winners: decoder.decodeInt32ForKey("winners", orElse: 0), unclaimed: decoder.decodeInt32ForKey("unclaimed", orElse: 0))
default:
self = .unknown
}
@ -376,9 +376,10 @@ public enum TelegramMediaActionType: PostboxCoding, Equatable {
encoder.encodeInt32(32, forKey: "_rawValue")
encoder.encodeInt32(buttonId, forKey: "b")
encoder.encodeInt64(peerId.toInt64(), forKey: "pi")
case let .setChatWallpaper(wallpaper):
case let .setChatWallpaper(wallpaper, forBoth):
encoder.encodeInt32(33, forKey: "_rawValue")
encoder.encode(TelegramWallpaperNativeCodable(wallpaper), forKey: "wallpaper")
encoder.encodeBool(forBoth, forKey: "both")
case let .setSameChatWallpaper(wallpaper):
encoder.encodeInt32(34, forKey: "_rawValue")
encoder.encode(TelegramWallpaperNativeCodable(wallpaper), forKey: "wallpaper")
@ -409,9 +410,10 @@ public enum TelegramMediaActionType: PostboxCoding, Equatable {
encoder.encodeInt32(37, forKey: "_rawValue")
case .joinedChannel:
encoder.encodeInt32(38, forKey: "_rawValue")
case let .giveawayResults(winners):
case let .giveawayResults(winners, unclaimed):
encoder.encodeInt32(39, forKey: "_rawValue")
encoder.encodeInt32(winners, forKey: "winners")
encoder.encodeInt32(unclaimed, forKey: "unclaimed")
}
}

View File

@ -123,7 +123,7 @@ public enum SetChatWallpaperError {
case flood
}
func _internal_setChatWallpaper(postbox: Postbox, network: Network, stateManager: AccountStateManager, peerId: PeerId, wallpaper: TelegramWallpaper?, applyUpdates: Bool = true) -> Signal<Api.Updates, SetChatWallpaperError> {
func _internal_setChatWallpaper(postbox: Postbox, network: Network, stateManager: AccountStateManager, peerId: PeerId, wallpaper: TelegramWallpaper?, forBoth: Bool, applyUpdates: Bool = true) -> Signal<Api.Updates, SetChatWallpaperError> {
return postbox.loadedPeerWithId(peerId)
|> castError(SetChatWallpaperError.self)
|> mapToSignal { peer in
@ -148,6 +148,9 @@ func _internal_setChatWallpaper(postbox: Postbox, network: Network, stateManager
inputWallpaper = inputWallpaperAndInputSettings.0
inputSettings = inputWallpaperAndInputSettings.1
}
if forBoth {
flags |= 1 << 3
}
return network.request(Api.functions.messages.setChatWallPaper(flags: flags, peer: inputPeer, wallpaper: inputWallpaper, settings: inputSettings, id: nil), automaticFloodWait: false)
|> mapError { error -> SetChatWallpaperError in
if error.errorDescription.hasPrefix("FLOOD_WAIT") {
@ -168,14 +171,37 @@ func _internal_setChatWallpaper(postbox: Postbox, network: Network, stateManager
}
}
public enum SetExistingChatWallpaperError {
public enum RevertChatWallpaperError {
case generic
}
func _internal_revertChatWallpaper(account: Account, peerId: EnginePeer.Id) -> Signal<Void, RevertChatWallpaperError> {
return account.postbox.loadedPeerWithId(peerId)
|> castError(RevertChatWallpaperError.self)
|> mapToSignal { peer in
guard let inputPeer = apiInputPeer(peer) else {
return .fail(.generic)
}
let flags: Int32 = 1 << 4
return account.network.request(Api.functions.messages.setChatWallPaper(flags: flags, peer: inputPeer, wallpaper: nil, settings: nil, id: nil), automaticFloodWait: false)
|> `catch` { _ -> Signal<Api.Updates, RevertChatWallpaperError> in
return .fail(.generic)
}
|> mapToSignal { updates -> Signal<Void, RevertChatWallpaperError> in
account.stateManager.addUpdates(updates)
return .complete()
}
}
}
public enum SetExistingChatWallpaperError {
case generic
}
func _internal_setExistingChatWallpaper(account: Account, messageId: MessageId, settings: WallpaperSettings?) -> Signal<Void, SetExistingChatWallpaperError> {
return account.postbox.transaction { transaction -> Peer? in
if let peer = transaction.getPeer(messageId.peerId), let message = transaction.getMessage(messageId) {
if let action = message.media.first(where: { $0 is TelegramMediaAction }) as? TelegramMediaAction, case let .setChatWallpaper(wallpaper) = action.action {
if let action = message.media.first(where: { $0 is TelegramMediaAction }) as? TelegramMediaAction, case let .setChatWallpaper(wallpaper, _) = action.action {
var wallpaper = wallpaper
if let settings = settings {
wallpaper = wallpaper.withUpdatedSettings(settings)

View File

@ -18,12 +18,16 @@ public extension TelegramEngine {
}
public func setChatWallpaper(peerId: PeerId, wallpaper: TelegramWallpaper?) -> Signal<Never, SetChatWallpaperError> {
return _internal_setChatWallpaper(postbox: self.account.postbox, network: self.account.network, stateManager: self.account.stateManager, peerId: peerId, wallpaper: wallpaper)
return _internal_setChatWallpaper(postbox: self.account.postbox, network: self.account.network, stateManager: self.account.stateManager, peerId: peerId, wallpaper: wallpaper, forBoth: false)
|> ignoreValues
}
public func setExistingChatWallpaper(messageId: MessageId, settings: WallpaperSettings?) -> Signal<Void, SetExistingChatWallpaperError> {
return _internal_setExistingChatWallpaper(account: self.account, messageId: messageId, settings: settings)
}
public func revertChatWallpaper(peerId: EnginePeer.Id) -> Signal<Void, RevertChatWallpaperError> {
return _internal_revertChatWallpaper(account: self.account, peerId: peerId)
}
}
}

View File

@ -884,9 +884,15 @@ public func universalServiceMessageString(presentationData: (PresentationTheme,
let botName = message.peers[message.id.peerId].flatMap(EnginePeer.init)?.displayTitle(strings: strings, displayOrder: nameDisplayOrder) ?? ""
let peerName = message.peers[peerId].flatMap(EnginePeer.init)?.displayTitle(strings: strings, displayOrder: nameDisplayOrder) ?? ""
attributedString = addAttributesToStringWithRanges(strings.Notification_RequestedPeer(peerName, botName)._tuple, body: bodyAttributes, argumentAttributes: peerMentionsAttributes(primaryTextColor: primaryTextColor, peerIds: [(0, peerId), (1, message.id.peerId)]))
case .setChatWallpaper:
case let .setChatWallpaper(_, forBoth):
if message.author?.id == accountPeerId {
attributedString = NSAttributedString(string: strings.Notification_YouChangedWallpaper, font: titleFont, textColor: primaryTextColor)
if forBoth {
let peerName = message.peers[message.id.peerId].flatMap(EnginePeer.init)?.compactDisplayTitle ?? ""
let resultTitleString = strings.Notification_YouChangedWallpaperBoth(peerName)
attributedString = addAttributesToStringWithRanges(resultTitleString._tuple, body: bodyAttributes, argumentAttributes: [0: boldAttributes])
} else {
attributedString = NSAttributedString(string: strings.Notification_YouChangedWallpaper, font: titleFont, textColor: primaryTextColor)
}
} else {
let resultTitleString = strings.Notification_ChangedWallpaper(compactAuthorName)
attributedString = addAttributesToStringWithRanges(resultTitleString._tuple, body: bodyAttributes, argumentAttributes: [0: boldAttributes])
@ -905,8 +911,18 @@ public func universalServiceMessageString(presentationData: (PresentationTheme,
attributedString = addAttributesToStringWithRanges(resultTitleString._tuple, body: bodyAttributes, argumentAttributes: [0: boldAttributes])
case .joinedChannel:
attributedString = NSAttributedString(string: strings.Notification_ChannelJoinedByYou, font: titleBoldFont, textColor: primaryTextColor)
case let .giveawayResults(winners):
attributedString = NSAttributedString(string: strings.Notification_GiveawayResults(winners), font: titleFont, textColor: primaryTextColor)
case let .giveawayResults(winners, unclaimed):
if winners == 0 {
attributedString = parseMarkdownIntoAttributedString(strings.Notification_GiveawayResultsNoWinners(unclaimed), attributes: MarkdownAttributes(body: bodyAttributes, bold: boldAttributes, link: bodyAttributes, linkAttribute: { _ in return nil }))
} else if unclaimed > 0 {
let winnersString = parseMarkdownIntoAttributedString(strings.Notification_GiveawayResultsMixedWinners(winners), attributes: MarkdownAttributes(body: bodyAttributes, bold: boldAttributes, link: bodyAttributes, linkAttribute: { _ in return nil }))
let unclaimedString = parseMarkdownIntoAttributedString(strings.Notification_GiveawayResultsMixedUnclaimed(unclaimed), attributes: MarkdownAttributes(body: bodyAttributes, bold: boldAttributes, link: bodyAttributes, linkAttribute: { _ in return nil }))
let combinedString = NSMutableAttributedString(attributedString: winnersString)
combinedString.append(NSAttributedString(string: "\n"))
combinedString.append(unclaimedString)
} else {
attributedString = parseMarkdownIntoAttributedString(strings.Notification_GiveawayResults(winners), attributes: MarkdownAttributes(body: bodyAttributes, bold: boldAttributes, link: bodyAttributes, linkAttribute: { _ in return nil }))
}
case .unknown:
attributedString = nil
}

View File

@ -318,6 +318,14 @@ public class ChatMessageJoinedChannelBubbleContentNode: ChatMessageBubbleContent
theme: item.presentationData.theme.theme,
peers: recommendedChannels,
action: { peer in
var jsonString: String = "{"
jsonString += "\"ref_channel_id\": \"\(item.message.id.peerId.id._internalGetInt64Value())\","
jsonString += "\"open_channel_id\": \"\(peer.id.id._internalGetInt64Value())\""
jsonString += "}"
if let data = jsonString.data(using: .utf8), let json = JSON(data: data) {
addAppLogEvent(postbox: item.context.account.postbox, type: "channels.open_recommended_channel", data: json)
}
item.controllerInteraction.openPeer(peer, .chat(textInputState: nil, subject: nil, peekData: nil), nil, .default)
}
)
@ -488,7 +496,7 @@ private class MessageBackgroundNode: ASDisplayNode {
}
}
private let itemSize = CGSize(width: 94.0, height: 90.0)
private let itemSize = CGSize(width: 84.0, height: 90.0)
private final class ChannelItemComponent: Component {
let context: AccountContext
@ -581,7 +589,7 @@ private final class ChannelItemComponent: Component {
text: .plain(NSAttributedString(string: component.subtitle, font: Font.regular(10.0), textColor: component.theme.chat.message.incoming.secondaryTextColor))
)),
environment: {},
containerSize: CGSize(width: itemSize.width - 12.0, height: 100.0)
containerSize: CGSize(width: itemSize.width - 6.0, height: 100.0)
)
let avatarSize = CGSize(width: 60.0, height: 60.0)
@ -694,7 +702,7 @@ final class ChannelListPanelComponent: Component {
}
func itemFrame(for index: Int) -> CGRect {
return CGRect(origin: CGPoint(x: self.containerInsets.top + CGFloat(index) * self.itemWidth, y: 0.0), size: CGSize(width: self.itemWidth, height: self.containerHeight))
return CGRect(origin: CGPoint(x: self.containerInsets.left + CGFloat(index) * self.itemWidth, y: 0.0), size: CGSize(width: self.itemWidth, height: self.containerHeight))
}
}
@ -820,7 +828,7 @@ final class ChannelListPanelComponent: Component {
self.component = component
let itemLayout = ItemLayout(
containerInsets: .zero,
containerInsets: UIEdgeInsets(top: 0.0, left: 4.0, bottom: 0.0, right: 4.0),
containerHeight: availableSize.height,
itemWidth: itemSize.width,
itemCount: component.peers.channels.count

View File

@ -182,7 +182,21 @@ public class ChatMessageWallpaperBubbleContentNode: ChatMessageBubbleContentNode
guard let item = self.item else {
return
}
let _ = item.controllerInteraction.openMessage(item.message, OpenMessageParams(mode: .default))
var canRemove = false
if item.message.effectivelyIncoming(item.context.account.peerId) {
if let media = item.message.media.first(where: { $0 is TelegramMediaAction }) as? TelegramMediaAction, case let .setChatWallpaper(wallpaper, forBoth) = media.action {
if forBoth, item.presentationData.theme.wallpaper.isBasicallyEqual(to: wallpaper) {
canRemove = true
}
}
}
if canRemove {
let _ = item.context.engine.themes.revertChatWallpaper(peerId: item.message.id.peerId).startStandalone()
} else {
let _ = item.controllerInteraction.openMessage(item.message, OpenMessageParams(mode: .default))
}
}
private func updateProgress(_ progress: Float?) {
@ -225,12 +239,14 @@ public class ChatMessageWallpaperBubbleContentNode: ChatMessageBubbleContentNode
let primaryTextColor = serviceMessageColorComponents(theme: item.presentationData.theme.theme, wallpaper: item.presentationData.theme.wallpaper).primaryText
var wallpaper: TelegramWallpaper?
if let media = item.message.media.first(where: { $0 is TelegramMediaAction }) as? TelegramMediaAction, case let .setChatWallpaper(wallpaperValue) = media.action {
var forBoth = false
if let media = item.message.media.first(where: { $0 is TelegramMediaAction }) as? TelegramMediaAction, case let .setChatWallpaper(wallpaperValue, forBothValue) = media.action {
wallpaper = wallpaperValue
forBoth = forBothValue
}
var mediaUpdated = true
if let wallpaper = wallpaper, let media = currentItem?.message.media.first(where: { $0 is TelegramMediaAction }) as? TelegramMediaAction, case let .setChatWallpaper(currentWallpaper) = media.action {
if let wallpaper = wallpaper, let media = currentItem?.message.media.first(where: { $0 is TelegramMediaAction }) as? TelegramMediaAction, case let .setChatWallpaper(currentWallpaper, _) = media.action {
mediaUpdated = wallpaper != currentWallpaper
}
@ -249,7 +265,11 @@ public class ChatMessageWallpaperBubbleContentNode: ChatMessageBubbleContentNode
text = item.presentationData.strings.Notification_YouChangingWallpaper
displayTrailingAnimatedDots = true
} else {
text = item.presentationData.strings.Notification_YouChangedWallpaper
if forBoth {
text = item.presentationData.strings.Notification_YouChangedWallpaperBoth(peerName).string
} else {
text = item.presentationData.strings.Notification_YouChangedWallpaper
}
}
} else {
text = item.presentationData.strings.Notification_ChangedWallpaper(peerName).string
@ -269,7 +289,14 @@ public class ChatMessageWallpaperBubbleContentNode: ChatMessageBubbleContentNode
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 (buttonTitleLayout, buttonTitleApply) = makeButtonTitleLayout(TextNodeLayoutArguments(attributedString: NSAttributedString(string: item.presentationData.strings.Notification_Wallpaper_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()))
let buttonText: String
if let wallpaper, forBoth && item.presentationData.theme.wallpaper.isBasicallyEqual(to: wallpaper) {
buttonText = "Remove"
} else {
buttonText = item.presentationData.strings.Notification_Wallpaper_View
}
let (buttonTitleLayout, buttonTitleApply) = makeButtonTitleLayout(TextNodeLayoutArguments(attributedString: NSAttributedString(string: buttonText, 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 textHeight = subtitleLayout.size.height
if displayTrailingAnimatedDots {
@ -463,6 +490,8 @@ public class ChatMessageWallpaperBubbleContentNode: ChatMessageBubbleContentNode
override public func tapActionAtPoint(_ point: CGPoint, gesture: TapLongTapOrDoubleTapGesture, isEstimating: Bool) -> ChatMessageBubbleContentTapAction {
if self.statusOverlayNode.alpha > 0.0 {
return ChatMessageBubbleContentTapAction(content: .none)
} else if self.buttonNode.frame.contains(point) {
return ChatMessageBubbleContentTapAction(content: .ignore)
} else if self.mediaBackgroundNode.frame.contains(point) {
return ChatMessageBubbleContentTapAction(content: .openMessage)
} else {

View File

@ -908,7 +908,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
case .setChatTheme:
strongSelf.presentThemeSelection()
return true
case let .setChatWallpaper(wallpaper):
case let .setChatWallpaper(wallpaper, _):
guard message.effectivelyIncoming(strongSelf.context.account.peerId), let peer = strongSelf.presentationInterfaceState.renderedPeer?.peer else {
strongSelf.presentThemeSelection()
return true
@ -928,7 +928,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
}
}
let wallpaperPreviewController = WallpaperGalleryController(context: strongSelf.context, source: .wallpaper(wallpaper, options, [], intensity, nil, nil), mode: .peer(EnginePeer(peer), true))
wallpaperPreviewController.apply = { [weak wallpaperPreviewController] entry, options, _, _, brightness in
wallpaperPreviewController.apply = { [weak wallpaperPreviewController] entry, options, _, _, brightness, _ in
var settings: WallpaperSettings?
if case let .wallpaper(wallpaper, _) = entry {
let baseSettings = wallpaper.settings
@ -6536,7 +6536,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
if let peerId = self.chatLocation.peerId {
uploadingChatWallpaper = self.context.account.pendingPeerMediaUploadManager.uploadingPeerMedia
|> map { uploadingPeerMedia -> TelegramWallpaper? in
if let item = uploadingPeerMedia[peerId], case let .wallpaper(wallpaper) = item.content {
if let item = uploadingPeerMedia[peerId], case let .wallpaper(wallpaper, _) = item.content {
return wallpaper
} else {
return nil
@ -18978,9 +18978,9 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
}
let controller = WallpaperGalleryController(context: strongSelf.context, source: .asset(asset), mode: .peer(EnginePeer(peer), false))
controller.navigationPresentation = .modal
controller.apply = { [weak self] wallpaper, options, editedImage, cropRect, brightness in
controller.apply = { [weak self] wallpaper, options, editedImage, cropRect, brightness, forBoth in
if let strongSelf = self {
uploadCustomPeerWallpaper(context: strongSelf.context, wallpaper: wallpaper, mode: options, editedImage: editedImage, cropRect: cropRect, brightness: brightness, peerId: peerId, completion: {
uploadCustomPeerWallpaper(context: strongSelf.context, wallpaper: wallpaper, mode: options, editedImage: editedImage, cropRect: cropRect, brightness: brightness, peerId: peerId, forBoth: forBoth, completion: {
Queue.mainQueue().after(0.3, {
dismissControllers()
})