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_1" = "You have **%@** free voice transcription left this month.";
"Conversation.FreeTranscriptionLimitTooltip_any" = "You have **%@** free voice transcriptions 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_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 giftcodes."; "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.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.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"; "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: case .stories:
buttonText = strings.Common_OK buttonText = strings.Common_OK
buttonAnimationName = "premium_unlock" buttonAnimationName = "premium_unlock"
case .voiceToText:
buttonText = strings.Premium_VoiceToText_Proceed
default: default:
buttonText = strings.Common_OK buttonText = strings.Common_OK
} }

View File

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

View File

@ -25,7 +25,7 @@ func presentCustomWallpaperPicker(context: AccountContext, present: @escaping (V
controller.selectionBlock = { [weak legacyController] asset, _ in controller.selectionBlock = { [weak legacyController] asset, _ in
if let asset = asset { if let asset = asset {
let controller = WallpaperGalleryController(context: context, source: .asset(asset.backingAsset)) 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 { 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 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 { if let legacyController = legacyController, let controller = controller {
@ -200,7 +200,7 @@ func uploadCustomWallpaper(context: AccountContext, wallpaper: WallpaperGalleryE
}).start() }).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> var imageSignal: Signal<UIImage, NoError>
switch wallpaper { switch wallpaper {
case let .wallpaper(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 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) 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) { Queue.mainQueue().after(0.05) {
completion() completion()

View File

@ -307,8 +307,8 @@ final class ThemeAccentColorControllerNode: ASDisplayNode, UIScrollViewDelegate
let doneButtonType: WallpaperGalleryToolbarDoneButtonType let doneButtonType: WallpaperGalleryToolbarDoneButtonType
if case .edit(_, _, _, _, _, true, _) = self.mode { if case .edit(_, _, _, _, _, true, _) = self.mode {
doneButtonType = .proceed doneButtonType = .proceed
} else if case .peer = resultMode { } else if case let .peer(peer) = resultMode {
doneButtonType = .setPeer doneButtonType = .setPeer(peer.compactDisplayTitle, context.isPremium)
} else { } else {
doneButtonType = .set 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 let strongSelf = self {
if strongSelf.state.displayPatternPanel { if strongSelf.state.displayPatternPanel {
strongSelf.updateState({ current in strongSelf.updateState({ current in
@ -774,8 +774,8 @@ final class ThemeAccentColorControllerNode: ASDisplayNode, UIScrollViewDelegate
} else { } else {
if case .edit(_, _, _, _, _, true, _) = self.mode { if case .edit(_, _, _, _, _, true, _) = self.mode {
doneButtonType = .proceed doneButtonType = .proceed
} else if case .peer = self.resultMode { } else if case let .peer(peer) = self.resultMode {
doneButtonType = .setPeer doneButtonType = .setPeer(peer.compactDisplayTitle, self.context.isPremium)
} else { } else {
doneButtonType = .set doneButtonType = .set
} }
@ -1179,9 +1179,12 @@ final class ThemeAccentColorControllerNode: ASDisplayNode, UIScrollViewDelegate
} }
var toolbarBottomInset = layout.intrinsicInsets.bottom var toolbarBottomInset = layout.intrinsicInsets.bottom
if case .background = mode, toolbarBottomInset.isZero { if case .background = self.mode, toolbarBottomInset.isZero {
toolbarBottomInset = 16.0 toolbarBottomInset = 16.0
} }
if case .peer = self.resultMode {
toolbarBottomInset += 58.0
}
let toolbarHeight = 49.0 + toolbarBottomInset 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))) 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) 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.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 { 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) let _ = (strongSelf.context.engine.themes.setChatWallpaper(peerId: peer.id, wallpaper: wallpaperValue)
|> deliverOnMainQueue).start(completed: { |> 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 self.displayNode = ThemeGridControllerNode(context: self.context, presentationData: self.presentationData, presentPreviewController: { [weak self] source in
if let strongSelf = self { if let strongSelf = self {
let controller = WallpaperGalleryController(context: strongSelf.context, source: source) 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 { if let strongSelf = self {
uploadCustomWallpaper(context: strongSelf.context, wallpaper: wallpaper, mode: options, editedImage: editedImage, cropRect: cropRect, brightness: brightness, completion: { [weak self, weak controller] in uploadCustomWallpaper(context: strongSelf.context, wallpaper: wallpaper, mode: options, editedImage: editedImage, cropRect: cropRect, brightness: brightness, completion: { [weak self, weak controller] in
if let strongSelf = self { if let strongSelf = self {
@ -160,7 +160,7 @@ public final class ThemeGridController: ViewController {
return return
} }
let controller = WallpaperGalleryController(context: strongSelf.context, source: .asset(asset)) 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 { if let strongSelf = self {
uploadCustomWallpaper(context: strongSelf.context, wallpaper: wallpaper, mode: options, editedImage: editedImage, cropRect: cropRect, brightness: brightness, completion: { uploadCustomWallpaper(context: strongSelf.context, wallpaper: wallpaper, mode: options, editedImage: editedImage, cropRect: cropRect, brightness: brightness, completion: {
dismissControllers() dismissControllers()

View File

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

View File

@ -192,7 +192,7 @@ public class WallpaperGalleryController: ViewController {
private let context: AccountContext private let context: AccountContext
private let source: WallpaperListSource private let source: WallpaperListSource
private let mode: Mode 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? private var interaction: WallpaperGalleryInteraction?
@ -497,8 +497,8 @@ public class WallpaperGalleryController: ViewController {
default: default:
break break
} }
if case .peer = self.mode { if case let .peer(peer, _) = self.mode {
doneButtonType = .setPeer doneButtonType = .setPeer(peer.compactDisplayTitle, self.context.isPremium)
} }
let toolbarNode = WallpaperGalleryToolbarNode(theme: presentationData.theme, strings: presentationData.strings, doneButtonType: doneButtonType) let toolbarNode = WallpaperGalleryToolbarNode(theme: presentationData.theme, strings: presentationData.strings, doneButtonType: doneButtonType)
@ -515,8 +515,23 @@ public class WallpaperGalleryController: ViewController {
self?.dismiss(forceAway: true) self?.dismiss(forceAway: true)
} }
var dismissed = false var dismissed = false
toolbarNode.done = { [weak self] in toolbarNode.done = { [weak self] forBoth in
if let strongSelf = self, !dismissed { 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 let centralItemNode = strongSelf.galleryNode.pager.centralItemNode() as? WallpaperGalleryItemNode {
if centralItemNode.cropNode.scrollNode.view.isDecelerating { if centralItemNode.cropNode.scrollNode.view.isDecelerating {
return return
@ -554,12 +569,12 @@ public class WallpaperGalleryController: ViewController {
|> filter({ $0.complete }) |> filter({ $0.complete })
|> take(1) |> take(1)
|> deliverOnMainQueue).start(next: { _ in |> deliverOnMainQueue).start(next: { _ in
apply?(entry, options, nil, nil, centralItemNode.brightness) apply?(entry, options, nil, nil, centralItemNode.brightness, forBoth)
}) })
} }
} }
} else { } else {
apply?(entry, options, centralItemNode.editedFullSizeImage, centralItemNode.editedCropRect, centralItemNode.brightness) apply?(entry, options, centralItemNode.editedFullSizeImage, centralItemNode.editedCropRect, centralItemNode.brightness, forBoth)
} }
return return
} }
@ -717,7 +732,7 @@ public class WallpaperGalleryController: ViewController {
break 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.galleryNode.containerLayoutUpdated(pagerLayout, navigationBarHeight: self.navigationLayout(layout: layout).navigationFrame.maxY, transition: transition)
self.overlayNode?.frame = self.galleryNode.bounds 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))) 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) 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) self.toolbarNode?.setDoneIsSolid(self.patternPanelEnabled || self.colorsPanelEnabled, transition: transition)
bottomInset += 66.0 bottomInset += toolbarHeight
self.validLayout = (layout, bottomInset) self.validLayout = (layout, bottomInset)
if !hadLayout { if !hadLayout {

View File

@ -1329,7 +1329,10 @@ final class WallpaperGalleryItemNode: GalleryItemNode {
let buttonSpacing: CGFloat = 18.0 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 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) 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) self.nativeNode.updateBubbleTheme(bubbleTheme: self.presentationData.theme, bubbleCorners: self.presentationData.chatBubbleCorners)
var bottomInset: CGFloat = 132.0 var bottomInset: CGFloat = 132.0
if let mode = self.mode, case .peer = mode {
bottomInset += 58.0
}
var items: [ListViewItem] = [] var items: [ListViewItem] = []
let peerId = PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(1)) let peerId = PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(1))

View File

@ -3,6 +3,7 @@ import UIKit
import AsyncDisplayKit import AsyncDisplayKit
import Display import Display
import TelegramPresentationData import TelegramPresentationData
import ManagedAnimationNode
enum WallpaperGalleryToolbarCancelButtonType { enum WallpaperGalleryToolbarCancelButtonType {
case cancel case cancel
@ -11,7 +12,7 @@ enum WallpaperGalleryToolbarCancelButtonType {
enum WallpaperGalleryToolbarDoneButtonType { enum WallpaperGalleryToolbarDoneButtonType {
case set case set
case setPeer case setPeer(String, Bool)
case proceed case proceed
case apply case apply
case none case none
@ -22,7 +23,7 @@ protocol WallpaperGalleryToolbar: ASDisplayNode {
var doneButtonType: WallpaperGalleryToolbarDoneButtonType { get set } var doneButtonType: WallpaperGalleryToolbarDoneButtonType { get set }
var cancel: (() -> Void)? { get set } var cancel: (() -> Void)? { get set }
var done: (() -> Void)? { get set } var done: ((Bool) -> Void)? { get set }
func updateThemeAndStrings(theme: PresentationTheme, strings: PresentationStrings) func updateThemeAndStrings(theme: PresentationTheme, strings: PresentationStrings)
@ -30,53 +31,24 @@ protocol WallpaperGalleryToolbar: ASDisplayNode {
} }
final class WallpaperGalleryToolbarNode: ASDisplayNode, WallpaperGalleryToolbar { final class WallpaperGalleryToolbarNode: ASDisplayNode, WallpaperGalleryToolbar {
private var theme: PresentationTheme class ButtonNode: ASDisplayNode {
private let strings: PresentationStrings
var cancelButtonType: WallpaperGalleryToolbarCancelButtonType {
didSet {
self.updateThemeAndStrings(theme: self.theme, strings: self.strings)
}
}
var doneButtonType: WallpaperGalleryToolbarDoneButtonType {
didSet {
self.updateThemeAndStrings(theme: self.theme, strings: self.strings)
}
}
var dark: Bool {
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)
}
}
}
private let doneButton = HighlightTrackingButtonNode() private let doneButton = HighlightTrackingButtonNode()
private var doneButtonBackgroundNode: ASDisplayNode private var doneButtonBackgroundNode: ASDisplayNode
private let doneButtonTitleNode: ImmediateTextNode private let doneButtonTitleNode: ImmediateTextNode
private let doneButtonSolidBackgroundNode: ASDisplayNode private let doneButtonSolidBackgroundNode: ASDisplayNode
private let doneButtonSolidTitleNode: ImmediateTextNode private let doneButtonSolidTitleNode: ImmediateTextNode
var cancel: (() -> Void)? private let animationNode: SimpleAnimationNode
var done: (() -> Void)?
init(theme: PresentationTheme, strings: PresentationStrings, cancelButtonType: WallpaperGalleryToolbarCancelButtonType = .cancel, doneButtonType: WallpaperGalleryToolbarDoneButtonType = .set) { var action: () -> Void = {}
self.theme = theme
self.strings = strings
self.cancelButtonType = cancelButtonType
self.doneButtonType = doneButtonType
self.dark = false
var isLocked: Bool = false {
didSet {
self.animationNode.isHidden = !self.isLocked
}
}
override init() {
self.doneButtonBackgroundNode = WallpaperLightButtonBackgroundNode() self.doneButtonBackgroundNode = WallpaperLightButtonBackgroundNode()
self.doneButtonBackgroundNode.cornerRadius = 14.0 self.doneButtonBackgroundNode.cornerRadius = 14.0
@ -98,6 +70,10 @@ final class WallpaperGalleryToolbarNode: ASDisplayNode, WallpaperGalleryToolbar
self.doneButtonSolidTitleNode.displaysAsynchronously = false self.doneButtonSolidTitleNode.displaysAsynchronously = false
self.doneButtonSolidTitleNode.isUserInteractionEnabled = 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() super.init()
self.doneButton.isExclusiveTouch = true self.doneButton.isExclusiveTouch = true
@ -108,9 +84,9 @@ final class WallpaperGalleryToolbarNode: ASDisplayNode, WallpaperGalleryToolbar
self.addSubnode(self.doneButtonSolidBackgroundNode) self.addSubnode(self.doneButtonSolidBackgroundNode)
self.addSubnode(self.doneButtonSolidTitleNode) self.addSubnode(self.doneButtonSolidTitleNode)
self.addSubnode(self.doneButton) self.addSubnode(self.animationNode)
self.updateThemeAndStrings(theme: theme, strings: strings) self.addSubnode(self.doneButton)
self.doneButton.highligthedChanged = { [weak self] highlighted in self.doneButton.highligthedChanged = { [weak self] highlighted in
if let strongSelf = self { if let strongSelf = self {
@ -142,16 +118,16 @@ final class WallpaperGalleryToolbarNode: ASDisplayNode, WallpaperGalleryToolbar
} }
} }
self.doneButton.addTarget(self, action: #selector(self.donePressed), forControlEvents: .touchUpInside) self.doneButton.addTarget(self, action: #selector(self.pressed), forControlEvents: .touchUpInside)
} }
func setDoneEnabled(_ enabled: Bool) { func setEnabled(_ enabled: Bool) {
self.doneButton.alpha = enabled ? 1.0 : 0.4 self.doneButton.alpha = enabled ? 1.0 : 0.4
self.doneButton.isUserInteractionEnabled = enabled self.doneButton.isUserInteractionEnabled = enabled
} }
private var isSolid = false private var isSolid = false
func setDoneIsSolid(_ isSolid: Bool, transition: ContainedViewLayoutTransition) { func setIsSolid(_ isSolid: Bool, transition: ContainedViewLayoutTransition) {
guard self.isSolid != isSolid else { guard self.isSolid != isSolid else {
return return
} }
@ -163,57 +139,176 @@ final class WallpaperGalleryToolbarNode: ASDisplayNode, WallpaperGalleryToolbar
transition.updateAlpha(node: self.doneButtonSolidTitleNode, alpha: isSolid ? 1.0 : 0.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
var cancelButtonType: WallpaperGalleryToolbarCancelButtonType {
didSet {
self.updateThemeAndStrings(theme: self.theme, strings: self.strings)
}
}
var doneButtonType: WallpaperGalleryToolbarDoneButtonType {
didSet {
self.updateThemeAndStrings(theme: self.theme, strings: self.strings)
}
}
var dark: Bool = false {
didSet {
self.applyButton.dark = self.dark
self.applyForBothButton.dark = self.dark
}
}
private let applyButton = ButtonNode()
private let applyForBothButton = ButtonNode()
var cancel: (() -> 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
super.init()
self.addSubnode(self.applyButton)
if case .setPeer = doneButtonType {
self.addSubnode(self.applyForBothButton)
}
self.updateThemeAndStrings(theme: theme, strings: strings)
self.applyButton.action = { [weak self] in
if let self {
self.done?(false)
}
}
self.applyForBothButton.action = { [weak self] in
if let self {
self.done?(true)
}
}
}
func setDoneEnabled(_ enabled: Bool) {
self.applyButton.setEnabled(enabled)
self.applyForBothButton.setEnabled(enabled)
}
private var isSolid = false
func setDoneIsSolid(_ isSolid: Bool, transition: ContainedViewLayoutTransition) {
guard self.isSolid != isSolid else {
return
}
self.isSolid = isSolid
self.applyButton.setIsSolid(isSolid, transition: transition)
self.applyForBothButton.setIsSolid(isSolid, transition: transition)
}
func updateThemeAndStrings(theme: PresentationTheme, strings: PresentationStrings) { func updateThemeAndStrings(theme: PresentationTheme, strings: PresentationStrings) {
self.theme = theme self.theme = theme
let doneTitle: String let applyTitle: String
var applyForBothTitle: String? = nil
var applyForBothLocked = false
switch self.doneButtonType { switch self.doneButtonType {
case .set: case .set:
doneTitle = strings.Wallpaper_ApplyForAll applyTitle = strings.Wallpaper_ApplyForAll
case .setPeer: case let .setPeer(name, isPremium):
doneTitle = strings.Wallpaper_ApplyForChat applyTitle = strings.Wallpaper_ApplyForMe
applyForBothTitle = strings.Wallpaper_ApplyForBoth(name).string
applyForBothLocked = !isPremium
case .proceed: case .proceed:
doneTitle = strings.Theme_Colors_Proceed applyTitle = strings.Theme_Colors_Proceed
case .apply: case .apply:
doneTitle = strings.WallpaperPreview_PatternPaternApply applyTitle = strings.WallpaperPreview_PatternPaternApply
case .none: case .none:
doneTitle = "" applyTitle = ""
self.doneButton.isUserInteractionEnabled = false 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.applyButton.updateTitle(applyTitle, theme: theme)
self.doneButtonSolidTitleNode.attributedText = NSAttributedString(string: doneTitle, font: Font.semibold(17.0), textColor: theme.list.itemCheckColors.foregroundColor) self.applyForBothButton.updateTitle(applyForBothTitle ?? "", theme: theme)
self.applyForBothButton.isLocked = applyForBothLocked
} }
func updateLayout(size: CGSize, layout: ContainerViewLayout, transition: ContainedViewLayoutTransition) { func updateLayout(size: CGSize, layout: ContainerViewLayout, transition: ContainedViewLayoutTransition) {
let inset: CGFloat = 16.0 let inset: CGFloat = 16.0
let buttonHeight: CGFloat = 50.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)) let spacing: CGFloat = 8.0
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 doneTitleSize = self.doneButtonTitleNode.updateLayout(doneFrame.size) let applyFrame = CGRect(origin: CGPoint(x: inset, y: 2.0), size: CGSize(width: size.width - inset * 2.0, height: buttonHeight))
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 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.applyButton.frame = applyFrame
self.doneButtonSolidTitleNode.frame = self.doneButtonTitleNode.frame self.applyButton.updateSize(applyFrame.size)
self.applyForBothButton.frame = applyForBothFrame
self.applyForBothButton.updateSize(applyForBothFrame.size)
} }
@objc func cancelPressed() { @objc func cancelPressed() {
self.cancel?() self.cancel?()
} }
@objc func donePressed() {
self.done?()
}
} }
final class WallpaperGalleryOldToolbarNode: ASDisplayNode, WallpaperGalleryToolbar { final class WallpaperGalleryOldToolbarNode: ASDisplayNode, WallpaperGalleryToolbar {
@ -240,7 +335,7 @@ final class WallpaperGalleryOldToolbarNode: ASDisplayNode, WallpaperGalleryToolb
private let topSeparatorNode = ASDisplayNode() private let topSeparatorNode = ASDisplayNode()
var cancel: (() -> Void)? var cancel: (() -> Void)?
var done: (() -> Void)? var done: ((Bool) -> Void)?
init(theme: PresentationTheme, strings: PresentationStrings, cancelButtonType: WallpaperGalleryToolbarCancelButtonType = .cancel, doneButtonType: WallpaperGalleryToolbarDoneButtonType = .set) { init(theme: PresentationTheme, strings: PresentationStrings, cancelButtonType: WallpaperGalleryToolbarCancelButtonType = .cancel, doneButtonType: WallpaperGalleryToolbarDoneButtonType = .set) {
self.theme = theme self.theme = theme
@ -343,6 +438,6 @@ final class WallpaperGalleryOldToolbarNode: ASDisplayNode, WallpaperGalleryToolb
} }
@objc func donePressed() { @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[-758129906] = { return Api.MessageAction.parse_messageActionGiftCode($0) }
dict[-935499028] = { return Api.MessageAction.parse_messageActionGiftPremium($0) } dict[-935499028] = { return Api.MessageAction.parse_messageActionGiftPremium($0) }
dict[858499565] = { return Api.MessageAction.parse_messageActionGiveawayLaunch($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[2047704898] = { return Api.MessageAction.parse_messageActionGroupCall($0) }
dict[-1281329567] = { return Api.MessageAction.parse_messageActionGroupCallScheduled($0) } dict[-1281329567] = { return Api.MessageAction.parse_messageActionGroupCallScheduled($0) }
dict[-1615153660] = { return Api.MessageAction.parse_messageActionHistoryClear($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[-648257196] = { return Api.MessageAction.parse_messageActionSecureValuesSent($0) }
dict[455635795] = { return Api.MessageAction.parse_messageActionSecureValuesSentMe($0) } dict[455635795] = { return Api.MessageAction.parse_messageActionSecureValuesSentMe($0) }
dict[-1434950843] = { return Api.MessageAction.parse_messageActionSetChatTheme($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[1007897979] = { return Api.MessageAction.parse_messageActionSetMessagesTTL($0) }
dict[-1065845395] = { return Api.MessageAction.parse_messageActionSetSameChatWallPaper($0) }
dict[1474192222] = { return Api.MessageAction.parse_messageActionSuggestProfilePhoto($0) } dict[1474192222] = { return Api.MessageAction.parse_messageActionSuggestProfilePhoto($0) }
dict[228168278] = { return Api.MessageAction.parse_messageActionTopicCreate($0) } dict[228168278] = { return Api.MessageAction.parse_messageActionTopicCreate($0) }
dict[-1064024032] = { return Api.MessageAction.parse_messageActionTopicEdit($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[2061444128] = { return Api.PollResults.parse_pollResults($0) }
dict[1558266229] = { return Api.PopularContact.parse_popularContact($0) } dict[1558266229] = { return Api.PopularContact.parse_popularContact($0) }
dict[512535275] = { return Api.PostAddress.parse_postAddress($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[629052971] = { return Api.PremiumGiftCodeOption.parse_premiumGiftCodeOption($0) }
dict[1958953753] = { return Api.PremiumGiftOption.parse_premiumGiftOption($0) } dict[1958953753] = { return Api.PremiumGiftOption.parse_premiumGiftOption($0) }
dict[1596792306] = { return Api.PremiumSubscriptionOption.parse_premiumSubscriptionOption($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[-1147422299] = { return Api.Update.parse_updatePeerHistoryTTL($0) }
dict[-1263546448] = { return Api.Update.parse_updatePeerLocated($0) } dict[-1263546448] = { return Api.Update.parse_updatePeerLocated($0) }
dict[1786671974] = { return Api.Update.parse_updatePeerSettings($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[1885586395] = { return Api.Update.parse_updatePendingJoinRequests($0) }
dict[-1425052898] = { return Api.Update.parse_updatePhoneCall($0) } dict[-1425052898] = { return Api.Update.parse_updatePhoneCall($0) }
dict[643940105] = { return Api.Update.parse_updatePhoneCallSignalingData($0) } dict[643940105] = { return Api.Update.parse_updatePhoneCallSignalingData($0) }
@ -1682,8 +1681,6 @@ public extension Api {
_1.serialize(buffer, boxed) _1.serialize(buffer, boxed)
case let _1 as Api.PostAddress: case let _1 as Api.PostAddress:
_1.serialize(buffer, boxed) _1.serialize(buffer, boxed)
case let _1 as Api.PremiumGiftCodeBotOption:
_1.serialize(buffer, boxed)
case let _1 as Api.PremiumGiftCodeOption: case let _1 as Api.PremiumGiftCodeOption:
_1.serialize(buffer, boxed) _1.serialize(buffer, boxed)
case let _1 as Api.PremiumGiftOption: 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 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 messageActionGiftPremium(flags: Int32, currency: String, amount: Int64, months: Int32, cryptoCurrency: String?, cryptoAmount: Int64?)
case messageActionGiveawayLaunch case messageActionGiveawayLaunch
case messageActionGiveawayResults(winnersCount: Int32) case messageActionGiveawayResults(winnersCount: Int32, unclaimedCount: Int32)
case messageActionGroupCall(flags: Int32, call: Api.InputGroupCall, duration: Int32?) case messageActionGroupCall(flags: Int32, call: Api.InputGroupCall, duration: Int32?)
case messageActionGroupCallScheduled(call: Api.InputGroupCall, scheduleDate: Int32) case messageActionGroupCallScheduled(call: Api.InputGroupCall, scheduleDate: Int32)
case messageActionHistoryClear case messageActionHistoryClear
@ -626,9 +626,8 @@ public extension Api {
case messageActionSecureValuesSent(types: [Api.SecureValueType]) case messageActionSecureValuesSent(types: [Api.SecureValueType])
case messageActionSecureValuesSentMe(values: [Api.SecureValue], credentials: Api.SecureCredentialsEncrypted) case messageActionSecureValuesSentMe(values: [Api.SecureValue], credentials: Api.SecureCredentialsEncrypted)
case messageActionSetChatTheme(emoticon: String) 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 messageActionSetMessagesTTL(flags: Int32, period: Int32, autoSettingFrom: Int64?)
case messageActionSetSameChatWallPaper(wallpaper: Api.WallPaper)
case messageActionSuggestProfilePhoto(photo: Api.Photo) case messageActionSuggestProfilePhoto(photo: Api.Photo)
case messageActionTopicCreate(flags: Int32, title: String, iconColor: Int32, iconEmojiId: Int64?) case messageActionTopicCreate(flags: Int32, title: String, iconColor: Int32, iconEmojiId: Int64?)
case messageActionTopicEdit(flags: Int32, title: String?, iconEmojiId: Int64?, closed: Api.Bool?, hidden: Api.Bool?) case messageActionTopicEdit(flags: Int32, title: String?, iconEmojiId: Int64?, closed: Api.Bool?, hidden: Api.Bool?)
@ -780,11 +779,12 @@ public extension Api {
} }
break break
case .messageActionGiveawayResults(let winnersCount): case .messageActionGiveawayResults(let winnersCount, let unclaimedCount):
if boxed { if boxed {
buffer.appendInt32(1927497572) buffer.appendInt32(715107781)
} }
serializeInt32(winnersCount, buffer: buffer, boxed: false) serializeInt32(winnersCount, buffer: buffer, boxed: false)
serializeInt32(unclaimedCount, buffer: buffer, boxed: false)
break break
case .messageActionGroupCall(let flags, let call, let duration): case .messageActionGroupCall(let flags, let call, let duration):
if boxed { if boxed {
@ -894,10 +894,11 @@ public extension Api {
} }
serializeString(emoticon, buffer: buffer, boxed: false) serializeString(emoticon, buffer: buffer, boxed: false)
break break
case .messageActionSetChatWallPaper(let wallpaper): case .messageActionSetChatWallPaper(let flags, let wallpaper):
if boxed { if boxed {
buffer.appendInt32(-1136350937) buffer.appendInt32(1348510708)
} }
serializeInt32(flags, buffer: buffer, boxed: false)
wallpaper.serialize(buffer, true) wallpaper.serialize(buffer, true)
break break
case .messageActionSetMessagesTTL(let flags, let period, let autoSettingFrom): case .messageActionSetMessagesTTL(let flags, let period, let autoSettingFrom):
@ -908,12 +909,6 @@ public extension Api {
serializeInt32(period, buffer: buffer, boxed: false) serializeInt32(period, buffer: buffer, boxed: false)
if Int(flags) & Int(1 << 0) != 0 {serializeInt64(autoSettingFrom!, buffer: buffer, boxed: false)} if Int(flags) & Int(1 << 0) != 0 {serializeInt64(autoSettingFrom!, buffer: buffer, boxed: false)}
break break
case .messageActionSetSameChatWallPaper(let wallpaper):
if boxed {
buffer.appendInt32(-1065845395)
}
wallpaper.serialize(buffer, true)
break
case .messageActionSuggestProfilePhoto(let photo): case .messageActionSuggestProfilePhoto(let photo):
if boxed { if boxed {
buffer.appendInt32(1474192222) 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)]) 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: case .messageActionGiveawayLaunch:
return ("messageActionGiveawayLaunch", []) return ("messageActionGiveawayLaunch", [])
case .messageActionGiveawayResults(let winnersCount): case .messageActionGiveawayResults(let winnersCount, let unclaimedCount):
return ("messageActionGiveawayResults", [("winnersCount", winnersCount as Any)]) return ("messageActionGiveawayResults", [("winnersCount", winnersCount as Any), ("unclaimedCount", unclaimedCount as Any)])
case .messageActionGroupCall(let flags, let call, let duration): case .messageActionGroupCall(let flags, let call, let duration):
return ("messageActionGroupCall", [("flags", flags as Any), ("call", call as Any), ("duration", duration as Any)]) return ("messageActionGroupCall", [("flags", flags as Any), ("call", call as Any), ("duration", duration as Any)])
case .messageActionGroupCallScheduled(let call, let scheduleDate): case .messageActionGroupCallScheduled(let call, let scheduleDate):
@ -1025,12 +1020,10 @@ public extension Api {
return ("messageActionSecureValuesSentMe", [("values", values as Any), ("credentials", credentials as Any)]) return ("messageActionSecureValuesSentMe", [("values", values as Any), ("credentials", credentials as Any)])
case .messageActionSetChatTheme(let emoticon): case .messageActionSetChatTheme(let emoticon):
return ("messageActionSetChatTheme", [("emoticon", emoticon as Any)]) return ("messageActionSetChatTheme", [("emoticon", emoticon as Any)])
case .messageActionSetChatWallPaper(let wallpaper): case .messageActionSetChatWallPaper(let flags, let wallpaper):
return ("messageActionSetChatWallPaper", [("wallpaper", wallpaper as Any)]) return ("messageActionSetChatWallPaper", [("flags", flags as Any), ("wallpaper", wallpaper as Any)])
case .messageActionSetMessagesTTL(let flags, let period, let autoSettingFrom): case .messageActionSetMessagesTTL(let flags, let period, let autoSettingFrom):
return ("messageActionSetMessagesTTL", [("flags", flags as Any), ("period", period as Any), ("autoSettingFrom", autoSettingFrom as Any)]) 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): case .messageActionSuggestProfilePhoto(let photo):
return ("messageActionSuggestProfilePhoto", [("photo", photo as Any)]) return ("messageActionSuggestProfilePhoto", [("photo", photo as Any)])
case .messageActionTopicCreate(let flags, let title, let iconColor, let iconEmojiId): 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? { public static func parse_messageActionGiveawayResults(_ reader: BufferReader) -> MessageAction? {
var _1: Int32? var _1: Int32?
_1 = reader.readInt32() _1 = reader.readInt32()
var _2: Int32?
_2 = reader.readInt32()
let _c1 = _1 != nil let _c1 = _1 != nil
if _c1 { let _c2 = _2 != nil
return Api.MessageAction.messageActionGiveawayResults(winnersCount: _1!) if _c1 && _c2 {
return Api.MessageAction.messageActionGiveawayResults(winnersCount: _1!, unclaimedCount: _2!)
} }
else { else {
return nil return nil
@ -1490,13 +1486,16 @@ public extension Api {
} }
} }
public static func parse_messageActionSetChatWallPaper(_ reader: BufferReader) -> MessageAction? { 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() { 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 let _c1 = _1 != nil
if _c1 { let _c2 = _2 != nil
return Api.MessageAction.messageActionSetChatWallPaper(wallpaper: _1!) if _c1 && _c2 {
return Api.MessageAction.messageActionSetChatWallPaper(flags: _1!, wallpaper: _2!)
} }
else { else {
return nil return nil
@ -1519,19 +1518,6 @@ public extension Api {
return nil 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? { public static func parse_messageActionSuggestProfilePhoto(_ reader: BufferReader) -> MessageAction? {
var _1: Api.Photo? var _1: Api.Photo?
if let signature = reader.readInt32() { 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 { public extension Api {
enum PremiumGiftCodeOption: TypeConstructorDescription { enum PremiumGiftCodeOption: TypeConstructorDescription {
case premiumGiftCodeOption(flags: Int32, users: Int32, months: Int32, storeProduct: String?, storeQuantity: Int32?, currency: String, amount: Int64) 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 { public extension Api {
enum Reaction: TypeConstructorDescription { enum Reaction: TypeConstructorDescription {
case reactionCustomEmoji(documentId: Int64) 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 UpdateStoryStealthMode(data: Api.StoriesStealthMode)
case UpdateStorySentReaction(peerId: PeerId, id: Int32, reaction: Api.Reaction) case UpdateStorySentReaction(peerId: PeerId, id: Int32, reaction: Api.Reaction)
case UpdateNewAuthorization(isUnconfirmed: Bool, hash: Int64, date: Int32, device: String, location: String) case UpdateNewAuthorization(isUnconfirmed: Bool, hash: Int64, date: Int32, device: String, location: String)
case UpdateWallpaper(peerId: PeerId, wallpaper: TelegramWallpaper?)
} }
struct HoleFromPreviousState { struct HoleFromPreviousState {
@ -522,6 +523,10 @@ struct AccountMutableState {
self.addOperation(.UpdateTheme(theme)) self.addOperation(.UpdateTheme(theme))
} }
mutating func updateWallpaper(peerId: PeerId, wallpaper: TelegramWallpaper?) {
self.addOperation(.UpdateWallpaper(peerId: peerId, wallpaper: wallpaper))
}
mutating func mergeUsers(_ users: [Api.User]) { mutating func mergeUsers(_ users: [Api.User]) {
self.addOperation(.MergeApiUsers(users)) self.addOperation(.MergeApiUsers(users))
@ -660,7 +665,7 @@ struct AccountMutableState {
mutating func addOperation(_ operation: AccountStateMutationOperation) { mutating func addOperation(_ operation: AccountStateMutationOperation) {
switch operation { 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 break
case let .AddMessages(messages, location): case let .AddMessages(messages, location):
for message in messages { for message in messages {

View File

@ -217,7 +217,7 @@ func apiMessagePeerIds(_ message: Api.Message) -> [PeerId] {
} }
switch action { 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 break
case let .messageActionChannelMigrateFrom(_, chatId): case let .messageActionChannelMigrateFrom(_, chatId):
result.append(PeerId(namespace: Namespaces.Peer.CloudGroup, id: PeerId.Id._internalFromInt64Value(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))) return TelegramMediaAction(action: .suggestedProfilePhoto(image: telegramMediaImageFromApiPhoto(photo)))
case let .messageActionRequestedPeer(buttonId, peer): case let .messageActionRequestedPeer(buttonId, peer):
return TelegramMediaAction(action: .requestedPeer(buttonId: buttonId, peerId: peer.peerId)) return TelegramMediaAction(action: .requestedPeer(buttonId: buttonId, peerId: peer.peerId))
case let .messageActionSetChatWallPaper(wallpaper): case let .messageActionSetChatWallPaper(flags, wallpaper):
return TelegramMediaAction(action: .setChatWallpaper(wallpaper: TelegramWallpaper(apiWallpaper: wallpaper))) if (flags & (1 << 0)) != 0 {
case let .messageActionSetSameChatWallPaper(wallpaper):
return TelegramMediaAction(action: .setSameChatWallpaper(wallpaper: TelegramWallpaper(apiWallpaper: wallpaper))) 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): 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)) return TelegramMediaAction(action: .giftCode(slug: slug, fromGiveaway: (flags & (1 << 0)) != 0, isUnclaimed: (flags & (1 << 2)) != 0, boostPeerId: boostPeer?.peerId, months: months))
case .messageActionGiveawayLaunch: case .messageActionGiveawayLaunch:
return TelegramMediaAction(action: .giveawayLaunched) return TelegramMediaAction(action: .giveawayLaunched)
case let .messageActionGiveawayResults(winners): case let .messageActionGiveawayResults(winners, unclaimed):
return TelegramMediaAction(action: .giveawayResults(winners: winners)) return TelegramMediaAction(action: .giveawayResults(winners: winners, unclaimed: unclaimed))
} }
} }

View File

@ -15,7 +15,7 @@ public final class PeerMediaUploadingItem: Equatable {
} }
public enum Content: Equatable { public enum Content: Equatable {
case wallpaper(TelegramWallpaper) case wallpaper(wallpaper: TelegramWallpaper, forBoth: Bool)
} }
public let content: Content 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> { private func uploadPeerMedia(postbox: Postbox, network: Network, stateManager: AccountStateManager, peerId: EnginePeer.Id, content: PeerMediaUploadingItem.Content) -> Signal<PeerMediaUploadingItem.ProgressValue, PeerMediaUploadingItem.Error> {
switch content { 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 { 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) return _internal_uploadWallpaper(postbox: postbox, network: network, resource: resource, settings: settings, forChat: true)
|> mapError { error -> PeerMediaUploadingItem.Error in |> 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) 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 |> mapError { error -> PeerMediaUploadingItem.Error in
switch error { switch error {
case .generic: case .generic:
@ -85,7 +85,7 @@ private func uploadPeerMedia(postbox: Postbox, network: Network, stateManager: A
} }
} else { } 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 |> mapError { error -> PeerMediaUploadingItem.Error in
switch error { switch error {
case .generic: case .generic:
@ -124,8 +124,8 @@ private func generatePeerMediaMessage(network: Network, accountPeerId: EnginePee
var media: [Media] = [] var media: [Media] = []
switch content { switch content {
case let .wallpaper(wallpaper): case let .wallpaper(wallpaper, forBoth):
media.append(TelegramMediaAction(action: .setChatWallpaper(wallpaper: wallpaper))) 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) 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): case let .updateNewAuthorization(flags, hash, date, device, location):
let isUnconfirmed = (flags & (1 << 0)) != 0 let isUnconfirmed = (flags & (1 << 0)) != 0
updatedState.updateNewAuthorization(isUnconfirmed: isUnconfirmed, hash: hash, date: date ?? 0, device: device ?? "", location: location ?? "") 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: default:
break break
} }
@ -3229,7 +3231,7 @@ private func optimizedOperations(_ operations: [AccountStateMutationOperation])
var currentAddScheduledMessages: OptimizeAddMessagesState? var currentAddScheduledMessages: OptimizeAddMessagesState?
for operation in operations { for operation in operations {
switch operation { 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 { if let currentAddMessages = currentAddMessages, !currentAddMessages.messages.isEmpty {
result.append(.AddMessages(currentAddMessages.messages, currentAddMessages.location)) result.append(.AddMessages(currentAddMessages.messages, currentAddMessages.location))
} }
@ -3342,6 +3344,7 @@ func replayFinalState(
var langPackDifferences: [String: [Api.LangPackDifference]] = [:] var langPackDifferences: [String: [Api.LangPackDifference]] = [:]
var pollLangPacks = Set<String>() var pollLangPacks = Set<String>()
var updatedThemes: [Int64: TelegramTheme] = [:] var updatedThemes: [Int64: TelegramTheme] = [:]
var updatedWallpapers: [PeerId: TelegramWallpaper] = [:]
var delayNotificatonsUntil: Int32? var delayNotificatonsUntil: Int32?
var peerActivityTimestamps: [PeerId: Int32] = [:] var peerActivityTimestamps: [PeerId: Int32] = [:]
var syncChatListFilters = false var syncChatListFilters = false
@ -3645,7 +3648,7 @@ func replayFinalState(
for (space, _) in holesAtHistoryStart { for (space, _) in holesAtHistoryStart {
transaction.removeHole(peerId: chatPeerId, threadId: nil, namespace: Namespaces.Message.Cloud, space: space, range: 1 ... id.id) transaction.removeHole(peerId: chatPeerId, threadId: nil, namespace: Namespaces.Message.Cloud, space: space, range: 1 ... id.id)
} }
case let .setChatWallpaper(wallpaper), let .setSameChatWallpaper(wallpaper): case let .setChatWallpaper(wallpaper, _):
if message.authorId == accountPeerId { if message.authorId == accountPeerId {
transaction.updatePeerCachedData(peerIds: [message.id.peerId], update: { peerId, current in transaction.updatePeerCachedData(peerIds: [message.id.peerId], update: { peerId, current in
var current = current var current = current
@ -4378,6 +4381,8 @@ func replayFinalState(
updatedPeersNearby = peersNearby updatedPeersNearby = peersNearby
case let .UpdateTheme(theme): case let .UpdateTheme(theme):
updatedThemes[theme.id] = theme updatedThemes[theme.id] = theme
case let .UpdateWallpaper(peerId, wallpaper):
updatedWallpapers[peerId] = wallpaper
case .SyncChatListFilters: case .SyncChatListFilters:
syncChatListFilters = true syncChatListFilters = true
case let .UpdateChatListFilterOrder(order): case let .UpdateChatListFilterOrder(order):
@ -5140,6 +5145,20 @@ func replayFinalState(
}.start() }.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) addedIncomingMessageIds.append(contentsOf: addedSecretMessageIds)
for (uniqueId, messageIdValue) in finalState.state.updatedOutgoingUniqueMessageIds { for (uniqueId, messageIdValue) in finalState.state.updatedOutgoingUniqueMessageIds {

View File

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

View File

@ -123,7 +123,7 @@ public enum SetChatWallpaperError {
case flood 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) return postbox.loadedPeerWithId(peerId)
|> castError(SetChatWallpaperError.self) |> castError(SetChatWallpaperError.self)
|> mapToSignal { peer in |> mapToSignal { peer in
@ -148,6 +148,9 @@ func _internal_setChatWallpaper(postbox: Postbox, network: Network, stateManager
inputWallpaper = inputWallpaperAndInputSettings.0 inputWallpaper = inputWallpaperAndInputSettings.0
inputSettings = inputWallpaperAndInputSettings.1 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) return network.request(Api.functions.messages.setChatWallPaper(flags: flags, peer: inputPeer, wallpaper: inputWallpaper, settings: inputSettings, id: nil), automaticFloodWait: false)
|> mapError { error -> SetChatWallpaperError in |> mapError { error -> SetChatWallpaperError in
if error.errorDescription.hasPrefix("FLOOD_WAIT") { if error.errorDescription.hasPrefix("FLOOD_WAIT") {
@ -168,6 +171,29 @@ func _internal_setChatWallpaper(postbox: Postbox, network: Network, stateManager
} }
} }
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 { public enum SetExistingChatWallpaperError {
case generic case generic
} }
@ -175,7 +201,7 @@ public enum SetExistingChatWallpaperError {
func _internal_setExistingChatWallpaper(account: Account, messageId: MessageId, settings: WallpaperSettings?) -> Signal<Void, SetExistingChatWallpaperError> { func _internal_setExistingChatWallpaper(account: Account, messageId: MessageId, settings: WallpaperSettings?) -> Signal<Void, SetExistingChatWallpaperError> {
return account.postbox.transaction { transaction -> Peer? in return account.postbox.transaction { transaction -> Peer? in
if let peer = transaction.getPeer(messageId.peerId), let message = transaction.getMessage(messageId) { 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 var wallpaper = wallpaper
if let settings = settings { if let settings = settings {
wallpaper = wallpaper.withUpdatedSettings(settings) wallpaper = wallpaper.withUpdatedSettings(settings)

View File

@ -18,12 +18,16 @@ public extension TelegramEngine {
} }
public func setChatWallpaper(peerId: PeerId, wallpaper: TelegramWallpaper?) -> Signal<Never, SetChatWallpaperError> { 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 |> ignoreValues
} }
public func setExistingChatWallpaper(messageId: MessageId, settings: WallpaperSettings?) -> Signal<Void, SetExistingChatWallpaperError> { public func setExistingChatWallpaper(messageId: MessageId, settings: WallpaperSettings?) -> Signal<Void, SetExistingChatWallpaperError> {
return _internal_setExistingChatWallpaper(account: self.account, messageId: messageId, settings: settings) 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 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) ?? "" 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)])) 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 { if message.author?.id == accountPeerId {
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) attributedString = NSAttributedString(string: strings.Notification_YouChangedWallpaper, font: titleFont, textColor: primaryTextColor)
}
} else { } else {
let resultTitleString = strings.Notification_ChangedWallpaper(compactAuthorName) let resultTitleString = strings.Notification_ChangedWallpaper(compactAuthorName)
attributedString = addAttributesToStringWithRanges(resultTitleString._tuple, body: bodyAttributes, argumentAttributes: [0: boldAttributes]) 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]) attributedString = addAttributesToStringWithRanges(resultTitleString._tuple, body: bodyAttributes, argumentAttributes: [0: boldAttributes])
case .joinedChannel: case .joinedChannel:
attributedString = NSAttributedString(string: strings.Notification_ChannelJoinedByYou, font: titleBoldFont, textColor: primaryTextColor) attributedString = NSAttributedString(string: strings.Notification_ChannelJoinedByYou, font: titleBoldFont, textColor: primaryTextColor)
case let .giveawayResults(winners): case let .giveawayResults(winners, unclaimed):
attributedString = NSAttributedString(string: strings.Notification_GiveawayResults(winners), font: titleFont, textColor: primaryTextColor) 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: case .unknown:
attributedString = nil attributedString = nil
} }

View File

@ -318,6 +318,14 @@ public class ChatMessageJoinedChannelBubbleContentNode: ChatMessageBubbleContent
theme: item.presentationData.theme.theme, theme: item.presentationData.theme.theme,
peers: recommendedChannels, peers: recommendedChannels,
action: { peer in 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) 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 { private final class ChannelItemComponent: Component {
let context: AccountContext 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)) text: .plain(NSAttributedString(string: component.subtitle, font: Font.regular(10.0), textColor: component.theme.chat.message.incoming.secondaryTextColor))
)), )),
environment: {}, 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) let avatarSize = CGSize(width: 60.0, height: 60.0)
@ -694,7 +702,7 @@ final class ChannelListPanelComponent: Component {
} }
func itemFrame(for index: Int) -> CGRect { 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 self.component = component
let itemLayout = ItemLayout( let itemLayout = ItemLayout(
containerInsets: .zero, containerInsets: UIEdgeInsets(top: 0.0, left: 4.0, bottom: 0.0, right: 4.0),
containerHeight: availableSize.height, containerHeight: availableSize.height,
itemWidth: itemSize.width, itemWidth: itemSize.width,
itemCount: component.peers.channels.count itemCount: component.peers.channels.count

View File

@ -182,8 +182,22 @@ public class ChatMessageWallpaperBubbleContentNode: ChatMessageBubbleContentNode
guard let item = self.item else { guard let item = self.item else {
return return
} }
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)) let _ = item.controllerInteraction.openMessage(item.message, OpenMessageParams(mode: .default))
} }
}
private func updateProgress(_ progress: Float?) { private func updateProgress(_ progress: Float?) {
guard let item = self.item else { guard let item = self.item else {
@ -225,12 +239,14 @@ public class ChatMessageWallpaperBubbleContentNode: ChatMessageBubbleContentNode
let primaryTextColor = serviceMessageColorComponents(theme: item.presentationData.theme.theme, wallpaper: item.presentationData.theme.wallpaper).primaryText let primaryTextColor = serviceMessageColorComponents(theme: item.presentationData.theme.theme, wallpaper: item.presentationData.theme.wallpaper).primaryText
var wallpaper: TelegramWallpaper? 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 wallpaper = wallpaperValue
forBoth = forBothValue
} }
var mediaUpdated = true 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 mediaUpdated = wallpaper != currentWallpaper
} }
@ -248,9 +264,13 @@ public class ChatMessageWallpaperBubbleContentNode: ChatMessageBubbleContentNode
if item.message.id.namespace == Namespaces.Message.Local { if item.message.id.namespace == Namespaces.Message.Local {
text = item.presentationData.strings.Notification_YouChangingWallpaper text = item.presentationData.strings.Notification_YouChangingWallpaper
displayTrailingAnimatedDots = true displayTrailingAnimatedDots = true
} else {
if forBoth {
text = item.presentationData.strings.Notification_YouChangedWallpaperBoth(peerName).string
} else { } else {
text = item.presentationData.strings.Notification_YouChangedWallpaper text = item.presentationData.strings.Notification_YouChangedWallpaper
} }
}
} else { } else {
text = item.presentationData.strings.Notification_ChangedWallpaper(peerName).string 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 (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 var textHeight = subtitleLayout.size.height
if displayTrailingAnimatedDots { if displayTrailingAnimatedDots {
@ -463,6 +490,8 @@ public class ChatMessageWallpaperBubbleContentNode: ChatMessageBubbleContentNode
override public func tapActionAtPoint(_ point: CGPoint, gesture: TapLongTapOrDoubleTapGesture, isEstimating: Bool) -> ChatMessageBubbleContentTapAction { override public func tapActionAtPoint(_ point: CGPoint, gesture: TapLongTapOrDoubleTapGesture, isEstimating: Bool) -> ChatMessageBubbleContentTapAction {
if self.statusOverlayNode.alpha > 0.0 { if self.statusOverlayNode.alpha > 0.0 {
return ChatMessageBubbleContentTapAction(content: .none) return ChatMessageBubbleContentTapAction(content: .none)
} else if self.buttonNode.frame.contains(point) {
return ChatMessageBubbleContentTapAction(content: .ignore)
} else if self.mediaBackgroundNode.frame.contains(point) { } else if self.mediaBackgroundNode.frame.contains(point) {
return ChatMessageBubbleContentTapAction(content: .openMessage) return ChatMessageBubbleContentTapAction(content: .openMessage)
} else { } else {

View File

@ -908,7 +908,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
case .setChatTheme: case .setChatTheme:
strongSelf.presentThemeSelection() strongSelf.presentThemeSelection()
return true return true
case let .setChatWallpaper(wallpaper): case let .setChatWallpaper(wallpaper, _):
guard message.effectivelyIncoming(strongSelf.context.account.peerId), let peer = strongSelf.presentationInterfaceState.renderedPeer?.peer else { guard message.effectivelyIncoming(strongSelf.context.account.peerId), let peer = strongSelf.presentationInterfaceState.renderedPeer?.peer else {
strongSelf.presentThemeSelection() strongSelf.presentThemeSelection()
return true 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)) 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? var settings: WallpaperSettings?
if case let .wallpaper(wallpaper, _) = entry { if case let .wallpaper(wallpaper, _) = entry {
let baseSettings = wallpaper.settings let baseSettings = wallpaper.settings
@ -6536,7 +6536,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
if let peerId = self.chatLocation.peerId { if let peerId = self.chatLocation.peerId {
uploadingChatWallpaper = self.context.account.pendingPeerMediaUploadManager.uploadingPeerMedia uploadingChatWallpaper = self.context.account.pendingPeerMediaUploadManager.uploadingPeerMedia
|> map { uploadingPeerMedia -> TelegramWallpaper? in |> 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 return wallpaper
} else { } else {
return nil 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)) let controller = WallpaperGalleryController(context: strongSelf.context, source: .asset(asset), mode: .peer(EnginePeer(peer), false))
controller.navigationPresentation = .modal 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 { 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, { Queue.mainQueue().after(0.3, {
dismissControllers() dismissControllers()
}) })