mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-10-08 19:10:53 +00:00
[WIP] Stars reactions
This commit is contained in:
parent
83be782893
commit
05372b578c
@ -2171,6 +2171,8 @@ public class ChatListItemNode: ItemListRevealOptionsItemNode {
|
|||||||
messageText = item.presentationData.strings.ChatList_UserReacted(value).string
|
messageText = item.presentationData.strings.ChatList_UserReacted(value).string
|
||||||
case .custom:
|
case .custom:
|
||||||
break
|
break
|
||||||
|
case .stars:
|
||||||
|
break
|
||||||
}
|
}
|
||||||
break loop
|
break loop
|
||||||
}
|
}
|
||||||
|
@ -175,6 +175,10 @@ public final class ReactionIconView: PortalSourceView {
|
|||||||
iconSize = CGSize(width: floor(size.width * 1.25), height: floor(size.height * 1.25))
|
iconSize = CGSize(width: floor(size.width * 1.25), height: floor(size.height * 1.25))
|
||||||
animationLayer.masksToBounds = true
|
animationLayer.masksToBounds = true
|
||||||
animationLayer.cornerRadius = floor(size.width * 0.2)
|
animationLayer.cornerRadius = floor(size.width * 0.2)
|
||||||
|
case .stars:
|
||||||
|
iconSize = CGSize(width: floor(size.width * 2.0), height: floor(size.height * 2.0))
|
||||||
|
animationLayer.masksToBounds = false
|
||||||
|
animationLayer.cornerRadius = 0.0
|
||||||
}
|
}
|
||||||
|
|
||||||
transition.updateFrame(layer: animationLayer, frame: CGRect(origin: CGPoint(x: floor((size.width - iconSize.width) / 2.0), y: floor((size.height - iconSize.height) / 2.0)), size: iconSize))
|
transition.updateFrame(layer: animationLayer, frame: CGRect(origin: CGPoint(x: floor((size.width - iconSize.width) / 2.0), y: floor((size.height - iconSize.height) / 2.0)), size: iconSize))
|
||||||
@ -207,6 +211,8 @@ public final class ReactionIconView: PortalSourceView {
|
|||||||
iconSize = CGSize(width: floor(size.width * 2.0), height: floor(size.height * 2.0))
|
iconSize = CGSize(width: floor(size.width * 2.0), height: floor(size.height * 2.0))
|
||||||
case .custom:
|
case .custom:
|
||||||
iconSize = CGSize(width: floor(size.width * 1.25), height: floor(size.height * 1.25))
|
iconSize = CGSize(width: floor(size.width * 1.25), height: floor(size.height * 1.25))
|
||||||
|
case .stars:
|
||||||
|
iconSize = CGSize(width: floor(size.width * 2.0), height: floor(size.height * 2.0))
|
||||||
}
|
}
|
||||||
|
|
||||||
let animationLayer = InlineStickerItemLayer(
|
let animationLayer = InlineStickerItemLayer(
|
||||||
@ -234,6 +240,9 @@ public final class ReactionIconView: PortalSourceView {
|
|||||||
case .custom:
|
case .custom:
|
||||||
animationLayer.masksToBounds = true
|
animationLayer.masksToBounds = true
|
||||||
animationLayer.cornerRadius = floor(size.width * 0.3)
|
animationLayer.cornerRadius = floor(size.width * 0.3)
|
||||||
|
case .stars:
|
||||||
|
animationLayer.masksToBounds = false
|
||||||
|
animationLayer.cornerRadius = 0.0
|
||||||
}
|
}
|
||||||
|
|
||||||
animationLayer.frame = CGRect(origin: CGPoint(x: floor((size.width - iconSize.width) / 2.0), y: floor((size.height - iconSize.height) / 2.0)), size: iconSize)
|
animationLayer.frame = CGRect(origin: CGPoint(x: floor((size.width - iconSize.width) / 2.0), y: floor((size.height - iconSize.height) / 2.0)), size: iconSize)
|
||||||
@ -766,7 +775,7 @@ public final class ReactionButtonAsyncNode: ContextControllerSourceView {
|
|||||||
|
|
||||||
let backgroundColors: ReactionButtonAsyncNode.ContainerButtonNode.Colors
|
let backgroundColors: ReactionButtonAsyncNode.ContainerButtonNode.Colors
|
||||||
|
|
||||||
if case .custom(MessageReaction.starsReactionId) = spec.component.reaction.value {
|
if case .stars = spec.component.reaction.value {
|
||||||
backgroundColors = ReactionButtonAsyncNode.ContainerButtonNode.Colors(
|
backgroundColors = ReactionButtonAsyncNode.ContainerButtonNode.Colors(
|
||||||
background: spec.component.chosenOrder != nil ? spec.component.colors.selectedStarsBackground : spec.component.colors.deselectedStarsBackground,
|
background: spec.component.chosenOrder != nil ? spec.component.colors.selectedStarsBackground : spec.component.colors.deselectedStarsBackground,
|
||||||
foreground: spec.component.chosenOrder != nil ? spec.component.colors.selectedStarsForeground : spec.component.colors.deselectedStarsForeground,
|
foreground: spec.component.chosenOrder != nil ? spec.component.colors.selectedStarsForeground : spec.component.colors.deselectedStarsForeground,
|
||||||
@ -821,6 +830,8 @@ public final class ReactionButtonAsyncNode: ContextControllerSourceView {
|
|||||||
|
|
||||||
private let iconImageDisposable = MetaDisposable()
|
private let iconImageDisposable = MetaDisposable()
|
||||||
|
|
||||||
|
private var ignoreButtonTap: Bool = false
|
||||||
|
|
||||||
public var activateAfterCompletion: Bool = false {
|
public var activateAfterCompletion: Bool = false {
|
||||||
didSet {
|
didSet {
|
||||||
if self.activateAfterCompletion {
|
if self.activateAfterCompletion {
|
||||||
@ -881,6 +892,20 @@ public final class ReactionButtonAsyncNode: ContextControllerSourceView {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self.contextGesture?.cancelGesturesOnActivation = { [weak self] in
|
||||||
|
guard let self else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
self.buttonNode.isUserInteractionEnabled = false
|
||||||
|
self.buttonNode.cancelTracking(with: nil)
|
||||||
|
DispatchQueue.main.async { [weak self] in
|
||||||
|
guard let self else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
self.buttonNode.isUserInteractionEnabled = true
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
required init?(coder aDecoder: NSCoder) {
|
required init?(coder aDecoder: NSCoder) {
|
||||||
@ -902,6 +927,9 @@ public final class ReactionButtonAsyncNode: ContextControllerSourceView {
|
|||||||
guard let layout = self.layout else {
|
guard let layout = self.layout else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if self.ignoreButtonTap {
|
||||||
|
return
|
||||||
|
}
|
||||||
layout.spec.component.action(self, layout.spec.component.reaction.value, self.containerView)
|
layout.spec.component.action(self, layout.spec.component.reaction.value, self.containerView)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -911,7 +939,7 @@ public final class ReactionButtonAsyncNode: ContextControllerSourceView {
|
|||||||
self.containerView.contentRect = CGRect(origin: CGPoint(), size: layout.size)
|
self.containerView.contentRect = CGRect(origin: CGPoint(), size: layout.size)
|
||||||
animation.animator.updateFrame(layer: self.buttonNode.layer, frame: CGRect(origin: CGPoint(), size: layout.size), completion: nil)
|
animation.animator.updateFrame(layer: self.buttonNode.layer, frame: CGRect(origin: CGPoint(), size: layout.size), completion: nil)
|
||||||
|
|
||||||
if case .custom(MessageReaction.starsReactionId) = layout.spec.component.reaction.value {
|
if case .stars = layout.spec.component.reaction.value {
|
||||||
let starsEffectLayer: StarsButtonEffectLayer
|
let starsEffectLayer: StarsButtonEffectLayer
|
||||||
if let current = self.starsEffectLayer {
|
if let current = self.starsEffectLayer {
|
||||||
starsEffectLayer = current
|
starsEffectLayer = current
|
||||||
@ -1319,7 +1347,7 @@ public final class ReactionButtonsAsyncLayoutContainer {
|
|||||||
})
|
})
|
||||||
|
|
||||||
if let index = reactions.firstIndex(where: {
|
if let index = reactions.firstIndex(where: {
|
||||||
if case .custom(MessageReaction.starsReactionId) = $0.reaction.value {
|
if case .stars = $0.reaction.value {
|
||||||
return true
|
return true
|
||||||
} else {
|
} else {
|
||||||
return false
|
return false
|
||||||
|
@ -164,6 +164,16 @@ public final class ReactionListContextMenuContent: ContextControllerItemsContent
|
|||||||
strongSelf.file = file
|
strongSelf.file = file
|
||||||
strongSelf.updateReactionLayer()
|
strongSelf.updateReactionLayer()
|
||||||
}).strict()
|
}).strict()
|
||||||
|
case .stars:
|
||||||
|
if let availableReactions = availableReactions {
|
||||||
|
for availableReaction in availableReactions.reactions {
|
||||||
|
if availableReaction.value == reaction {
|
||||||
|
self.file = availableReaction.centerAnimation
|
||||||
|
self.updateReactionLayer()
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let iconNode = ASImageNode()
|
let iconNode = ASImageNode()
|
||||||
@ -574,6 +584,17 @@ public final class ReactionListContextMenuContent: ContextControllerItemsContent
|
|||||||
strongSelf.updateReactionLayer()
|
strongSelf.updateReactionLayer()
|
||||||
strongSelf.updateReactionAccentColor(theme: presentationData.theme)
|
strongSelf.updateReactionAccentColor(theme: presentationData.theme)
|
||||||
}).strict()
|
}).strict()
|
||||||
|
case .stars:
|
||||||
|
if let availableReactions = self.availableReactions {
|
||||||
|
for availableReaction in availableReactions.reactions {
|
||||||
|
if availableReaction.value == reaction {
|
||||||
|
self.file = availableReaction.centerAnimation
|
||||||
|
self.updateReactionLayer()
|
||||||
|
self.updateReactionAccentColor(theme: presentationData.theme)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
self.file = nil
|
self.file = nil
|
||||||
@ -598,6 +619,8 @@ public final class ReactionListContextMenuContent: ContextControllerItemsContent
|
|||||||
reactionStringValue = value
|
reactionStringValue = value
|
||||||
case .custom:
|
case .custom:
|
||||||
reactionStringValue = ""
|
reactionStringValue = ""
|
||||||
|
case .stars:
|
||||||
|
reactionStringValue = "Star"
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
reactionStringValue = ""
|
reactionStringValue = ""
|
||||||
|
@ -1329,9 +1329,9 @@ final class ContextControllerNode: ViewControllerTracingNode, ASScrollViewDelega
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func animateOutToReaction(value: MessageReaction.Reaction, targetView: UIView, hideNode: Bool, animateTargetContainer: UIView?, addStandaloneReactionAnimation: ((StandaloneReactionAnimation) -> Void)?, reducedCurve: Bool, completion: @escaping () -> Void) {
|
func animateOutToReaction(value: MessageReaction.Reaction, targetView: UIView, hideNode: Bool, animateTargetContainer: UIView?, addStandaloneReactionAnimation: ((StandaloneReactionAnimation) -> Void)?, reducedCurve: Bool, onHit: (() -> Void)?, completion: @escaping () -> Void) {
|
||||||
if let sourceContainer = self.sourceContainer {
|
if let sourceContainer = self.sourceContainer {
|
||||||
sourceContainer.animateOutToReaction(value: value, targetView: targetView, hideNode: hideNode, animateTargetContainer: animateTargetContainer, addStandaloneReactionAnimation: addStandaloneReactionAnimation, reducedCurve: reducedCurve, completion: completion)
|
sourceContainer.animateOutToReaction(value: value, targetView: targetView, hideNode: hideNode, animateTargetContainer: animateTargetContainer, addStandaloneReactionAnimation: addStandaloneReactionAnimation, reducedCurve: reducedCurve, onHit: onHit, completion: completion)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2604,7 +2604,7 @@ public final class ContextController: ViewController, StandalonePresentableContr
|
|||||||
} else if let args = self.dismissToReactionOnInputClose {
|
} else if let args = self.dismissToReactionOnInputClose {
|
||||||
self.dismissToReactionOnInputClose = nil
|
self.dismissToReactionOnInputClose = nil
|
||||||
DispatchQueue.main.async {
|
DispatchQueue.main.async {
|
||||||
self.dismissWithReactionImpl(value: args.value, targetView: args.targetView, hideNode: args.hideNode, animateTargetContainer: args.animateTargetContainer, addStandaloneReactionAnimation: args.addStandaloneReactionAnimation, reducedCurve: true, completion: args.completion)
|
self.dismissWithReactionImpl(value: args.value, targetView: args.targetView, hideNode: args.hideNode, animateTargetContainer: args.animateTargetContainer, addStandaloneReactionAnimation: args.addStandaloneReactionAnimation, reducedCurve: true, onHit: nil, completion: args.completion)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2706,11 +2706,11 @@ public final class ContextController: ViewController, StandalonePresentableContr
|
|||||||
self.dismissed?()
|
self.dismissed?()
|
||||||
}
|
}
|
||||||
|
|
||||||
public func dismissWithReaction(value: MessageReaction.Reaction, targetView: UIView, hideNode: Bool, animateTargetContainer: UIView?, addStandaloneReactionAnimation: ((StandaloneReactionAnimation) -> Void)?, completion: (() -> Void)?) {
|
public func dismissWithReaction(value: MessageReaction.Reaction, targetView: UIView, hideNode: Bool, animateTargetContainer: UIView?, addStandaloneReactionAnimation: ((StandaloneReactionAnimation) -> Void)?, onHit: (() -> Void)?, completion: (() -> Void)?) {
|
||||||
self.dismissWithReactionImpl(value: value, targetView: targetView, hideNode: hideNode, animateTargetContainer: animateTargetContainer, addStandaloneReactionAnimation: addStandaloneReactionAnimation, reducedCurve: false, completion: completion)
|
self.dismissWithReactionImpl(value: value, targetView: targetView, hideNode: hideNode, animateTargetContainer: animateTargetContainer, addStandaloneReactionAnimation: addStandaloneReactionAnimation, reducedCurve: false, onHit: onHit, completion: completion)
|
||||||
}
|
}
|
||||||
|
|
||||||
private func dismissWithReactionImpl(value: MessageReaction.Reaction, targetView: UIView, hideNode: Bool, animateTargetContainer: UIView?, addStandaloneReactionAnimation: ((StandaloneReactionAnimation) -> Void)?, reducedCurve: Bool, completion: (() -> Void)?) {
|
private func dismissWithReactionImpl(value: MessageReaction.Reaction, targetView: UIView, hideNode: Bool, animateTargetContainer: UIView?, addStandaloneReactionAnimation: ((StandaloneReactionAnimation) -> Void)?, reducedCurve: Bool, onHit: (() -> Void)?, completion: (() -> Void)?) {
|
||||||
if viewTreeContainsFirstResponder(view: self.view) {
|
if viewTreeContainsFirstResponder(view: self.view) {
|
||||||
self.dismissToReactionOnInputClose = (value, targetView, hideNode, animateTargetContainer, addStandaloneReactionAnimation, completion)
|
self.dismissToReactionOnInputClose = (value, targetView, hideNode, animateTargetContainer, addStandaloneReactionAnimation, completion)
|
||||||
self.view.endEditing(true)
|
self.view.endEditing(true)
|
||||||
@ -2719,7 +2719,7 @@ public final class ContextController: ViewController, StandalonePresentableContr
|
|||||||
|
|
||||||
if !self.wasDismissed {
|
if !self.wasDismissed {
|
||||||
self.wasDismissed = true
|
self.wasDismissed = true
|
||||||
self.controllerNode.animateOutToReaction(value: value, targetView: targetView, hideNode: hideNode, animateTargetContainer: animateTargetContainer, addStandaloneReactionAnimation: addStandaloneReactionAnimation, reducedCurve: reducedCurve, completion: { [weak self] in
|
self.controllerNode.animateOutToReaction(value: value, targetView: targetView, hideNode: hideNode, animateTargetContainer: animateTargetContainer, addStandaloneReactionAnimation: addStandaloneReactionAnimation, reducedCurve: reducedCurve, onHit: onHit, completion: { [weak self] in
|
||||||
self?.presentingViewController?.dismiss(animated: false, completion: nil)
|
self?.presentingViewController?.dismiss(animated: false, completion: nil)
|
||||||
completion?()
|
completion?()
|
||||||
})
|
})
|
||||||
|
@ -1668,7 +1668,7 @@ final class ContextControllerExtractedPresentationNode: ASDisplayNode, ContextCo
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func animateOutToReaction(value: MessageReaction.Reaction, targetView: UIView, hideNode: Bool, animateTargetContainer: UIView?, addStandaloneReactionAnimation: ((StandaloneReactionAnimation) -> Void)?, reducedCurve: Bool, completion: @escaping () -> Void) {
|
func animateOutToReaction(value: MessageReaction.Reaction, targetView: UIView, hideNode: Bool, animateTargetContainer: UIView?, addStandaloneReactionAnimation: ((StandaloneReactionAnimation) -> Void)?, reducedCurve: Bool, onHit: (() -> Void)?, completion: @escaping () -> Void) {
|
||||||
guard let reactionContextNode = self.reactionContextNode else {
|
guard let reactionContextNode = self.reactionContextNode else {
|
||||||
self.requestAnimateOut(.default, completion)
|
self.requestAnimateOut(.default, completion)
|
||||||
return
|
return
|
||||||
@ -1697,7 +1697,7 @@ final class ContextControllerExtractedPresentationNode: ASDisplayNode, ContextCo
|
|||||||
intermediateCompletion()
|
intermediateCompletion()
|
||||||
})
|
})
|
||||||
|
|
||||||
reactionContextNode.animateOutToReaction(value: value, targetView: targetView, hideNode: hideNode, animateTargetContainer: animateTargetContainer, addStandaloneReactionAnimation: addStandaloneReactionAnimation, completion: { [weak self] in
|
reactionContextNode.animateOutToReaction(value: value, targetView: targetView, hideNode: hideNode, animateTargetContainer: animateTargetContainer, addStandaloneReactionAnimation: addStandaloneReactionAnimation, onHit: onHit, completion: { [weak self] in
|
||||||
guard let strongSelf = self else {
|
guard let strongSelf = self else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -28,7 +28,7 @@ protocol ContextControllerPresentationNode: ASDisplayNode {
|
|||||||
stateTransition: ContextControllerPresentationNodeStateTransition?
|
stateTransition: ContextControllerPresentationNodeStateTransition?
|
||||||
)
|
)
|
||||||
|
|
||||||
func animateOutToReaction(value: MessageReaction.Reaction, targetView: UIView, hideNode: Bool, animateTargetContainer: UIView?, addStandaloneReactionAnimation: ((StandaloneReactionAnimation) -> Void)?, reducedCurve: Bool, completion: @escaping () -> Void)
|
func animateOutToReaction(value: MessageReaction.Reaction, targetView: UIView, hideNode: Bool, animateTargetContainer: UIView?, addStandaloneReactionAnimation: ((StandaloneReactionAnimation) -> Void)?, reducedCurve: Bool, onHit: (() -> Void)?, completion: @escaping () -> Void)
|
||||||
func cancelReactionAnimation()
|
func cancelReactionAnimation()
|
||||||
|
|
||||||
func highlightGestureMoved(location: CGPoint, hover: Bool)
|
func highlightGestureMoved(location: CGPoint, hover: Bool)
|
||||||
|
@ -269,8 +269,8 @@ final class ContextSourceContainer: ASDisplayNode {
|
|||||||
self.presentationNode.cancelReactionAnimation()
|
self.presentationNode.cancelReactionAnimation()
|
||||||
}
|
}
|
||||||
|
|
||||||
func animateOutToReaction(value: MessageReaction.Reaction, targetView: UIView, hideNode: Bool, animateTargetContainer: UIView?, addStandaloneReactionAnimation: ((StandaloneReactionAnimation) -> Void)?, reducedCurve: Bool, completion: @escaping () -> Void) {
|
func animateOutToReaction(value: MessageReaction.Reaction, targetView: UIView, hideNode: Bool, animateTargetContainer: UIView?, addStandaloneReactionAnimation: ((StandaloneReactionAnimation) -> Void)?, reducedCurve: Bool, onHit: (() -> Void)?, completion: @escaping () -> Void) {
|
||||||
self.presentationNode.animateOutToReaction(value: value, targetView: targetView, hideNode: hideNode, animateTargetContainer: animateTargetContainer, addStandaloneReactionAnimation: addStandaloneReactionAnimation, reducedCurve: reducedCurve, completion: completion)
|
self.presentationNode.animateOutToReaction(value: value, targetView: targetView, hideNode: hideNode, animateTargetContainer: animateTargetContainer, addStandaloneReactionAnimation: addStandaloneReactionAnimation, reducedCurve: reducedCurve, onHit: onHit, completion: completion)
|
||||||
}
|
}
|
||||||
|
|
||||||
func setItems(items: Signal<ContextController.Items, NoError>, animated: Bool) {
|
func setItems(items: Signal<ContextController.Items, NoError>, animated: Bool) {
|
||||||
@ -543,9 +543,9 @@ final class ContextSourceContainer: ASDisplayNode {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func animateOutToReaction(value: MessageReaction.Reaction, targetView: UIView, hideNode: Bool, animateTargetContainer: UIView?, addStandaloneReactionAnimation: ((StandaloneReactionAnimation) -> Void)?, reducedCurve: Bool, completion: @escaping () -> Void) {
|
func animateOutToReaction(value: MessageReaction.Reaction, targetView: UIView, hideNode: Bool, animateTargetContainer: UIView?, addStandaloneReactionAnimation: ((StandaloneReactionAnimation) -> Void)?, reducedCurve: Bool, onHit: (() -> Void)?, completion: @escaping () -> Void) {
|
||||||
if let activeSource = self.activeSource {
|
if let activeSource = self.activeSource {
|
||||||
activeSource.animateOutToReaction(value: value, targetView: targetView, hideNode: hideNode, animateTargetContainer: animateTargetContainer, addStandaloneReactionAnimation: addStandaloneReactionAnimation, reducedCurve: reducedCurve, completion: completion)
|
activeSource.animateOutToReaction(value: value, targetView: targetView, hideNode: hideNode, animateTargetContainer: animateTargetContainer, addStandaloneReactionAnimation: addStandaloneReactionAnimation, reducedCurve: reducedCurve, onHit: onHit, completion: completion)
|
||||||
} else {
|
} else {
|
||||||
completion()
|
completion()
|
||||||
}
|
}
|
||||||
|
@ -264,6 +264,24 @@ public class DrawingReactionEntityView: DrawingStickerEntityView {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
case .stars:
|
||||||
|
let _ = (self.context.engine.stickers.availableReactions()
|
||||||
|
|> take(1)
|
||||||
|
|> deliverOnMainQueue).start(next: { availableReactions in
|
||||||
|
guard let availableReactions else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
var animation: TelegramMediaFile?
|
||||||
|
for reaction in availableReactions.reactions {
|
||||||
|
if reaction.value == updateReaction.reaction {
|
||||||
|
animation = reaction.selectAnimation
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if let animation {
|
||||||
|
continueWithAnimationFile(animation)
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -538,7 +538,7 @@ public func peerAllowedReactionListController(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if initialAllowedReactions != .known(updatedValue) {
|
if initialAllowedReactions != .known(updatedValue) {
|
||||||
let _ = context.engine.peers.updatePeerReactionSettings(peerId: peerId, reactionSettings: PeerReactionSettings(allowedReactions: updatedValue, maxReactionCount: 11)).start()
|
let _ = context.engine.peers.updatePeerReactionSettings(peerId: peerId, reactionSettings: PeerReactionSettings(allowedReactions: updatedValue, maxReactionCount: 11, starsAllowed: nil)).start()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -69,6 +69,8 @@ public final class ReactionItem {
|
|||||||
return .builtin(value)
|
return .builtin(value)
|
||||||
case let .custom(fileId):
|
case let .custom(fileId):
|
||||||
return .custom(fileId: fileId, file: self.listAnimation)
|
return .custom(fileId: fileId, file: self.listAnimation)
|
||||||
|
case .stars:
|
||||||
|
return .stars
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -965,6 +967,8 @@ public final class ReactionContextNode: ASDisplayNode, ASScrollViewDelegate {
|
|||||||
break
|
break
|
||||||
case .custom:
|
case .custom:
|
||||||
loopIdle = true
|
loopIdle = true
|
||||||
|
case .stars:
|
||||||
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1668,6 +1672,8 @@ public final class ReactionContextNode: ASDisplayNode, ASScrollViewDelegate {
|
|||||||
updateReaction = .builtin(value)
|
updateReaction = .builtin(value)
|
||||||
case let .custom(fileId):
|
case let .custom(fileId):
|
||||||
updateReaction = .custom(fileId: fileId, file: nil)
|
updateReaction = .custom(fileId: fileId, file: nil)
|
||||||
|
case .stars:
|
||||||
|
updateReaction = .stars
|
||||||
}
|
}
|
||||||
|
|
||||||
let reactionItem = ReactionItem(
|
let reactionItem = ReactionItem(
|
||||||
@ -2604,7 +2610,7 @@ public final class ReactionContextNode: ASDisplayNode, ASScrollViewDelegate {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public func animateOutToReaction(value: MessageReaction.Reaction, targetView: UIView, hideNode: Bool, forceSwitchToInlineImmediately: Bool = false, animateTargetContainer: UIView?, addStandaloneReactionAnimation: ((StandaloneReactionAnimation) -> Void)?, completion: @escaping () -> Void) {
|
public func animateOutToReaction(value: MessageReaction.Reaction, targetView: UIView, hideNode: Bool, forceSwitchToInlineImmediately: Bool = false, animateTargetContainer: UIView?, addStandaloneReactionAnimation: ((StandaloneReactionAnimation) -> Void)?, onHit: (() -> Void)?, completion: @escaping () -> Void) {
|
||||||
self.isAnimatingOutToReaction = true
|
self.isAnimatingOutToReaction = true
|
||||||
|
|
||||||
var foundItemNode: ReactionNode?
|
var foundItemNode: ReactionNode?
|
||||||
@ -2639,6 +2645,8 @@ public final class ReactionContextNode: ASDisplayNode, ASScrollViewDelegate {
|
|||||||
switchToInlineImmediately = forceSwitchToInlineImmediately
|
switchToInlineImmediately = forceSwitchToInlineImmediately
|
||||||
case .custom:
|
case .custom:
|
||||||
switchToInlineImmediately = !self.didTriggerExpandedReaction
|
switchToInlineImmediately = !self.didTriggerExpandedReaction
|
||||||
|
case .stars:
|
||||||
|
switchToInlineImmediately = forceSwitchToInlineImmediately
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
switchToInlineImmediately = !self.didTriggerExpandedReaction
|
switchToInlineImmediately = !self.didTriggerExpandedReaction
|
||||||
@ -2853,6 +2861,7 @@ public final class ReactionContextNode: ASDisplayNode, ASScrollViewDelegate {
|
|||||||
strongSelf.hapticFeedback = HapticFeedback()
|
strongSelf.hapticFeedback = HapticFeedback()
|
||||||
}
|
}
|
||||||
strongSelf.hapticFeedback?.tap()
|
strongSelf.hapticFeedback?.tap()
|
||||||
|
onHit?()
|
||||||
|
|
||||||
if let targetView = targetView as? ReactionIconView {
|
if let targetView = targetView as? ReactionIconView {
|
||||||
if switchToInlineImmediately {
|
if switchToInlineImmediately {
|
||||||
@ -3283,13 +3292,13 @@ public final class StandaloneReactionAnimation: ASDisplayNode {
|
|||||||
self.isUserInteractionEnabled = false
|
self.isUserInteractionEnabled = false
|
||||||
}
|
}
|
||||||
|
|
||||||
public func animateReactionSelection(context: AccountContext, theme: PresentationTheme, animationCache: AnimationCache, reaction: ReactionItem, customEffectResource: MediaResource? = nil, avatarPeers: [EnginePeer], playHaptic: Bool, isLarge: Bool, playCenterReaction: Bool = true, forceSmallEffectAnimation: Bool = false, hideCenterAnimation: Bool = false, targetView: UIView, addStandaloneReactionAnimation: ((StandaloneReactionAnimation) -> Void)?, completion: @escaping () -> Void) {
|
public func animateReactionSelection(context: AccountContext, theme: PresentationTheme, animationCache: AnimationCache, reaction: ReactionItem, customEffectResource: MediaResource? = nil, avatarPeers: [EnginePeer], playHaptic: Bool, isLarge: Bool, playCenterReaction: Bool = true, forceSmallEffectAnimation: Bool = false, hideCenterAnimation: Bool = false, targetView: UIView, addStandaloneReactionAnimation: ((StandaloneReactionAnimation) -> Void)?, onHit: (() -> Void)? = nil, completion: @escaping () -> Void) {
|
||||||
self.animateReactionSelection(context: context, theme: theme, animationCache: animationCache, reaction: reaction, customEffectResource: customEffectResource, avatarPeers: avatarPeers, playHaptic: playHaptic, isLarge: isLarge, playCenterReaction: playCenterReaction, forceSmallEffectAnimation: forceSmallEffectAnimation, hideCenterAnimation: hideCenterAnimation, targetView: targetView, addStandaloneReactionAnimation: addStandaloneReactionAnimation, currentItemNode: nil, completion: completion)
|
self.animateReactionSelection(context: context, theme: theme, animationCache: animationCache, reaction: reaction, customEffectResource: customEffectResource, avatarPeers: avatarPeers, playHaptic: playHaptic, isLarge: isLarge, playCenterReaction: playCenterReaction, forceSmallEffectAnimation: forceSmallEffectAnimation, hideCenterAnimation: hideCenterAnimation, targetView: targetView, addStandaloneReactionAnimation: addStandaloneReactionAnimation, currentItemNode: nil, onHit: onHit, completion: completion)
|
||||||
}
|
}
|
||||||
|
|
||||||
public var currentDismissAnimation: (() -> Void)?
|
public var currentDismissAnimation: (() -> Void)?
|
||||||
|
|
||||||
public func animateReactionSelection(context: AccountContext, theme: PresentationTheme, animationCache: AnimationCache, reaction: ReactionItem, customEffectResource: MediaResource? = nil, avatarPeers: [EnginePeer], playHaptic: Bool, isLarge: Bool, playCenterReaction: Bool = true, forceSmallEffectAnimation: Bool = false, hideCenterAnimation: Bool = false, targetView: UIView, addStandaloneReactionAnimation: ((StandaloneReactionAnimation) -> Void)?, currentItemNode: ReactionNode?, completion: @escaping () -> Void) {
|
public func animateReactionSelection(context: AccountContext, theme: PresentationTheme, animationCache: AnimationCache, reaction: ReactionItem, customEffectResource: MediaResource? = nil, avatarPeers: [EnginePeer], playHaptic: Bool, isLarge: Bool, playCenterReaction: Bool = true, forceSmallEffectAnimation: Bool = false, hideCenterAnimation: Bool = false, targetView: UIView, addStandaloneReactionAnimation: ((StandaloneReactionAnimation) -> Void)?, currentItemNode: ReactionNode?, onHit: (() -> Void)? = nil, completion: @escaping () -> Void) {
|
||||||
guard let sourceSnapshotView = targetView.snapshotContentTree() else {
|
guard let sourceSnapshotView = targetView.snapshotContentTree() else {
|
||||||
completion()
|
completion()
|
||||||
return
|
return
|
||||||
@ -3298,6 +3307,7 @@ public final class StandaloneReactionAnimation: ASDisplayNode {
|
|||||||
if playHaptic {
|
if playHaptic {
|
||||||
self.hapticFeedback.tap()
|
self.hapticFeedback.tap()
|
||||||
}
|
}
|
||||||
|
onHit?()
|
||||||
|
|
||||||
self.targetView = targetView
|
self.targetView = targetView
|
||||||
|
|
||||||
@ -3322,6 +3332,8 @@ public final class StandaloneReactionAnimation: ASDisplayNode {
|
|||||||
switchToInlineImmediately = false
|
switchToInlineImmediately = false
|
||||||
case .custom:
|
case .custom:
|
||||||
switchToInlineImmediately = true
|
switchToInlineImmediately = true
|
||||||
|
case .stars:
|
||||||
|
switchToInlineImmediately = false
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
switchToInlineImmediately = false
|
switchToInlineImmediately = false
|
||||||
@ -3708,12 +3720,16 @@ public final class StandaloneReactionAnimation: ASDisplayNode {
|
|||||||
var selfTargetBounds = targetView.bounds
|
var selfTargetBounds = targetView.bounds
|
||||||
if let itemNode = self.itemNode, case .builtin = itemNode.item.reaction.rawValue {
|
if let itemNode = self.itemNode, case .builtin = itemNode.item.reaction.rawValue {
|
||||||
selfTargetBounds = selfTargetBounds.insetBy(dx: -selfTargetBounds.width * 0.5, dy: -selfTargetBounds.height * 0.5)
|
selfTargetBounds = selfTargetBounds.insetBy(dx: -selfTargetBounds.width * 0.5, dy: -selfTargetBounds.height * 0.5)
|
||||||
|
} else if let itemNode = self.itemNode, case .stars = itemNode.item.reaction.rawValue {
|
||||||
|
selfTargetBounds = selfTargetBounds.insetBy(dx: -selfTargetBounds.width * 0.5, dy: -selfTargetBounds.height * 0.5)
|
||||||
}
|
}
|
||||||
|
|
||||||
var targetFrame = self.view.convert(targetView.convert(selfTargetBounds, to: nil), from: nil)
|
var targetFrame = self.view.convert(targetView.convert(selfTargetBounds, to: nil), from: nil)
|
||||||
|
|
||||||
if let itemNode = self.itemNode, case .builtin = itemNode.item.reaction.rawValue {
|
if let itemNode = self.itemNode, case .builtin = itemNode.item.reaction.rawValue {
|
||||||
targetFrame = targetFrame.insetBy(dx: -targetFrame.width * 0.5, dy: -targetFrame.height * 0.5)
|
targetFrame = targetFrame.insetBy(dx: -targetFrame.width * 0.5, dy: -targetFrame.height * 0.5)
|
||||||
|
} else if let itemNode = self.itemNode, case .stars = itemNode.item.reaction.rawValue {
|
||||||
|
targetFrame = targetFrame.insetBy(dx: -targetFrame.width * 0.5, dy: -targetFrame.height * 0.5)
|
||||||
}
|
}
|
||||||
|
|
||||||
targetSnapshotView.frame = targetFrame
|
targetSnapshotView.frame = targetFrame
|
||||||
|
@ -60,7 +60,7 @@ private final class StarsReactionEffectLayer: SimpleLayer {
|
|||||||
override init() {
|
override init() {
|
||||||
super.init()
|
super.init()
|
||||||
|
|
||||||
self.backgroundColor = UIColor.lightGray.withAlphaComponent(0.2).cgColor
|
//self.backgroundColor = UIColor.lightGray.withAlphaComponent(0.2).cgColor
|
||||||
}
|
}
|
||||||
|
|
||||||
override init(layer: Any) {
|
override init(layer: Any) {
|
||||||
@ -150,7 +150,7 @@ public final class ReactionNode: ASDisplayNode, ReactionItemNode {
|
|||||||
|
|
||||||
super.init()
|
super.init()
|
||||||
|
|
||||||
if case .custom(MessageReaction.starsReactionId) = item.reaction.rawValue {
|
if case .stars = item.reaction.rawValue {
|
||||||
let starsEffectLayer = StarsReactionEffectLayer()
|
let starsEffectLayer = StarsReactionEffectLayer()
|
||||||
self.starsEffectLayer = starsEffectLayer
|
self.starsEffectLayer = starsEffectLayer
|
||||||
self.layer.addSublayer(starsEffectLayer)
|
self.layer.addSublayer(starsEffectLayer)
|
||||||
|
@ -178,12 +178,12 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
|
|||||||
dict[-1078612597] = { return Api.ChannelLocation.parse_channelLocationEmpty($0) }
|
dict[-1078612597] = { return Api.ChannelLocation.parse_channelLocationEmpty($0) }
|
||||||
dict[-847783593] = { return Api.ChannelMessagesFilter.parse_channelMessagesFilter($0) }
|
dict[-847783593] = { return Api.ChannelMessagesFilter.parse_channelMessagesFilter($0) }
|
||||||
dict[-1798033689] = { return Api.ChannelMessagesFilter.parse_channelMessagesFilterEmpty($0) }
|
dict[-1798033689] = { return Api.ChannelMessagesFilter.parse_channelMessagesFilterEmpty($0) }
|
||||||
dict[-1072953408] = { return Api.ChannelParticipant.parse_channelParticipant($0) }
|
dict[-885426663] = { return Api.ChannelParticipant.parse_channelParticipant($0) }
|
||||||
dict[885242707] = { return Api.ChannelParticipant.parse_channelParticipantAdmin($0) }
|
dict[885242707] = { return Api.ChannelParticipant.parse_channelParticipantAdmin($0) }
|
||||||
dict[1844969806] = { return Api.ChannelParticipant.parse_channelParticipantBanned($0) }
|
dict[1844969806] = { return Api.ChannelParticipant.parse_channelParticipantBanned($0) }
|
||||||
dict[803602899] = { return Api.ChannelParticipant.parse_channelParticipantCreator($0) }
|
dict[803602899] = { return Api.ChannelParticipant.parse_channelParticipantCreator($0) }
|
||||||
dict[453242886] = { return Api.ChannelParticipant.parse_channelParticipantLeft($0) }
|
dict[453242886] = { return Api.ChannelParticipant.parse_channelParticipantLeft($0) }
|
||||||
dict[900251559] = { return Api.ChannelParticipant.parse_channelParticipantSelf($0) }
|
dict[1331723247] = { return Api.ChannelParticipant.parse_channelParticipantSelf($0) }
|
||||||
dict[-1268741783] = { return Api.ChannelParticipantsFilter.parse_channelParticipantsAdmins($0) }
|
dict[-1268741783] = { return Api.ChannelParticipantsFilter.parse_channelParticipantsAdmins($0) }
|
||||||
dict[338142689] = { return Api.ChannelParticipantsFilter.parse_channelParticipantsBanned($0) }
|
dict[338142689] = { return Api.ChannelParticipantsFilter.parse_channelParticipantsBanned($0) }
|
||||||
dict[-1328445861] = { return Api.ChannelParticipantsFilter.parse_channelParticipantsBots($0) }
|
dict[-1328445861] = { return Api.ChannelParticipantsFilter.parse_channelParticipantsBots($0) }
|
||||||
@ -192,7 +192,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
|
|||||||
dict[-531931925] = { return Api.ChannelParticipantsFilter.parse_channelParticipantsMentions($0) }
|
dict[-531931925] = { return Api.ChannelParticipantsFilter.parse_channelParticipantsMentions($0) }
|
||||||
dict[-566281095] = { return Api.ChannelParticipantsFilter.parse_channelParticipantsRecent($0) }
|
dict[-566281095] = { return Api.ChannelParticipantsFilter.parse_channelParticipantsRecent($0) }
|
||||||
dict[106343499] = { return Api.ChannelParticipantsFilter.parse_channelParticipantsSearch($0) }
|
dict[106343499] = { return Api.ChannelParticipantsFilter.parse_channelParticipantsSearch($0) }
|
||||||
dict[179174543] = { return Api.Chat.parse_channel($0) }
|
dict[-29067075] = { return Api.Chat.parse_channel($0) }
|
||||||
dict[399807445] = { return Api.Chat.parse_channelForbidden($0) }
|
dict[399807445] = { return Api.Chat.parse_channelForbidden($0) }
|
||||||
dict[1103884886] = { return Api.Chat.parse_chat($0) }
|
dict[1103884886] = { return Api.Chat.parse_chat($0) }
|
||||||
dict[693512293] = { return Api.Chat.parse_chatEmpty($0) }
|
dict[693512293] = { return Api.Chat.parse_chatEmpty($0) }
|
||||||
@ -202,7 +202,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
|
|||||||
dict[-1626209256] = { return Api.ChatBannedRights.parse_chatBannedRights($0) }
|
dict[-1626209256] = { return Api.ChatBannedRights.parse_chatBannedRights($0) }
|
||||||
dict[-1146407795] = { return Api.ChatFull.parse_channelFull($0) }
|
dict[-1146407795] = { return Api.ChatFull.parse_channelFull($0) }
|
||||||
dict[640893467] = { return Api.ChatFull.parse_chatFull($0) }
|
dict[640893467] = { return Api.ChatFull.parse_chatFull($0) }
|
||||||
dict[-840897472] = { return Api.ChatInvite.parse_chatInvite($0) }
|
dict[-26920803] = { return Api.ChatInvite.parse_chatInvite($0) }
|
||||||
dict[1516793212] = { return Api.ChatInvite.parse_chatInviteAlready($0) }
|
dict[1516793212] = { return Api.ChatInvite.parse_chatInviteAlready($0) }
|
||||||
dict[1634294960] = { return Api.ChatInvite.parse_chatInvitePeek($0) }
|
dict[1634294960] = { return Api.ChatInvite.parse_chatInvitePeek($0) }
|
||||||
dict[-1940201511] = { return Api.ChatInviteImporter.parse_chatInviteImporter($0) }
|
dict[-1940201511] = { return Api.ChatInviteImporter.parse_chatInviteImporter($0) }
|
||||||
@ -274,7 +274,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
|
|||||||
dict[-1038136962] = { return Api.EncryptedFile.parse_encryptedFileEmpty($0) }
|
dict[-1038136962] = { return Api.EncryptedFile.parse_encryptedFileEmpty($0) }
|
||||||
dict[-317144808] = { return Api.EncryptedMessage.parse_encryptedMessage($0) }
|
dict[-317144808] = { return Api.EncryptedMessage.parse_encryptedMessage($0) }
|
||||||
dict[594758406] = { return Api.EncryptedMessage.parse_encryptedMessageService($0) }
|
dict[594758406] = { return Api.EncryptedMessage.parse_encryptedMessageService($0) }
|
||||||
dict[179611673] = { return Api.ExportedChatInvite.parse_chatInviteExported($0) }
|
dict[-1812799720] = { return Api.ExportedChatInvite.parse_chatInviteExported($0) }
|
||||||
dict[-317687113] = { return Api.ExportedChatInvite.parse_chatInvitePublicJoinRequests($0) }
|
dict[-317687113] = { return Api.ExportedChatInvite.parse_chatInvitePublicJoinRequests($0) }
|
||||||
dict[206668204] = { return Api.ExportedChatlistInvite.parse_exportedChatlistInvite($0) }
|
dict[206668204] = { return Api.ExportedChatlistInvite.parse_exportedChatlistInvite($0) }
|
||||||
dict[1103040667] = { return Api.ExportedContactToken.parse_exportedContactToken($0) }
|
dict[1103040667] = { return Api.ExportedContactToken.parse_exportedContactToken($0) }
|
||||||
@ -372,6 +372,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
|
|||||||
dict[1210199983] = { return Api.InputGeoPoint.parse_inputGeoPoint($0) }
|
dict[1210199983] = { return Api.InputGeoPoint.parse_inputGeoPoint($0) }
|
||||||
dict[-457104426] = { return Api.InputGeoPoint.parse_inputGeoPointEmpty($0) }
|
dict[-457104426] = { return Api.InputGeoPoint.parse_inputGeoPointEmpty($0) }
|
||||||
dict[-659913713] = { return Api.InputGroupCall.parse_inputGroupCall($0) }
|
dict[-659913713] = { return Api.InputGroupCall.parse_inputGroupCall($0) }
|
||||||
|
dict[887591921] = { return Api.InputInvoice.parse_inputInvoiceChatInviteSubscription($0) }
|
||||||
dict[-977967015] = { return Api.InputInvoice.parse_inputInvoiceMessage($0) }
|
dict[-977967015] = { return Api.InputInvoice.parse_inputInvoiceMessage($0) }
|
||||||
dict[-1734841331] = { return Api.InputInvoice.parse_inputInvoicePremiumGiftCode($0) }
|
dict[-1734841331] = { return Api.InputInvoice.parse_inputInvoicePremiumGiftCode($0) }
|
||||||
dict[-1020867857] = { return Api.InputInvoice.parse_inputInvoiceSlug($0) }
|
dict[-1020867857] = { return Api.InputInvoice.parse_inputInvoiceSlug($0) }
|
||||||
@ -618,7 +619,8 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
|
|||||||
dict[1959634180] = { return Api.MessagePeerVote.parse_messagePeerVoteInputOption($0) }
|
dict[1959634180] = { return Api.MessagePeerVote.parse_messagePeerVoteInputOption($0) }
|
||||||
dict[1177089766] = { return Api.MessagePeerVote.parse_messagePeerVoteMultiple($0) }
|
dict[1177089766] = { return Api.MessagePeerVote.parse_messagePeerVoteMultiple($0) }
|
||||||
dict[182649427] = { return Api.MessageRange.parse_messageRange($0) }
|
dict[182649427] = { return Api.MessageRange.parse_messageRange($0) }
|
||||||
dict[1328256121] = { return Api.MessageReactions.parse_messageReactions($0) }
|
dict[171155211] = { return Api.MessageReactions.parse_messageReactions($0) }
|
||||||
|
dict[-285158328] = { return Api.MessageReactor.parse_messageReactor($0) }
|
||||||
dict[-2083123262] = { return Api.MessageReplies.parse_messageReplies($0) }
|
dict[-2083123262] = { return Api.MessageReplies.parse_messageReplies($0) }
|
||||||
dict[-1346631205] = { return Api.MessageReplyHeader.parse_messageReplyHeader($0) }
|
dict[-1346631205] = { return Api.MessageReplyHeader.parse_messageReplyHeader($0) }
|
||||||
dict[240843065] = { return Api.MessageReplyHeader.parse_messageReplyStoryHeader($0) }
|
dict[240843065] = { return Api.MessageReplyHeader.parse_messageReplyStoryHeader($0) }
|
||||||
@ -767,6 +769,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
|
|||||||
dict[-1992950669] = { return Api.Reaction.parse_reactionCustomEmoji($0) }
|
dict[-1992950669] = { return Api.Reaction.parse_reactionCustomEmoji($0) }
|
||||||
dict[455247544] = { return Api.Reaction.parse_reactionEmoji($0) }
|
dict[455247544] = { return Api.Reaction.parse_reactionEmoji($0) }
|
||||||
dict[2046153753] = { return Api.Reaction.parse_reactionEmpty($0) }
|
dict[2046153753] = { return Api.Reaction.parse_reactionEmpty($0) }
|
||||||
|
dict[1379771627] = { return Api.Reaction.parse_reactionPaid($0) }
|
||||||
dict[-1546531968] = { return Api.ReactionCount.parse_reactionCount($0) }
|
dict[-1546531968] = { return Api.ReactionCount.parse_reactionCount($0) }
|
||||||
dict[1268654752] = { return Api.ReactionNotificationsFrom.parse_reactionNotificationsFromAll($0) }
|
dict[1268654752] = { return Api.ReactionNotificationsFrom.parse_reactionNotificationsFromAll($0) }
|
||||||
dict[-1161583078] = { return Api.ReactionNotificationsFrom.parse_reactionNotificationsFromContacts($0) }
|
dict[-1161583078] = { return Api.ReactionNotificationsFrom.parse_reactionNotificationsFromContacts($0) }
|
||||||
@ -881,8 +884,10 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
|
|||||||
dict[1124938064] = { return Api.SponsoredMessageReportOption.parse_sponsoredMessageReportOption($0) }
|
dict[1124938064] = { return Api.SponsoredMessageReportOption.parse_sponsoredMessageReportOption($0) }
|
||||||
dict[1577421297] = { return Api.StarsGiftOption.parse_starsGiftOption($0) }
|
dict[1577421297] = { return Api.StarsGiftOption.parse_starsGiftOption($0) }
|
||||||
dict[2033461574] = { return Api.StarsRevenueStatus.parse_starsRevenueStatus($0) }
|
dict[2033461574] = { return Api.StarsRevenueStatus.parse_starsRevenueStatus($0) }
|
||||||
|
dict[-797707802] = { return Api.StarsSubscription.parse_starsSubscription($0) }
|
||||||
|
dict[88173912] = { return Api.StarsSubscriptionPricing.parse_starsSubscriptionPricing($0) }
|
||||||
dict[198776256] = { return Api.StarsTopupOption.parse_starsTopupOption($0) }
|
dict[198776256] = { return Api.StarsTopupOption.parse_starsTopupOption($0) }
|
||||||
dict[766853519] = { return Api.StarsTransaction.parse_starsTransaction($0) }
|
dict[1127934763] = { return Api.StarsTransaction.parse_starsTransaction($0) }
|
||||||
dict[-670195363] = { return Api.StarsTransactionPeer.parse_starsTransactionPeer($0) }
|
dict[-670195363] = { return Api.StarsTransactionPeer.parse_starsTransactionPeer($0) }
|
||||||
dict[1617438738] = { return Api.StarsTransactionPeer.parse_starsTransactionPeerAds($0) }
|
dict[1617438738] = { return Api.StarsTransactionPeer.parse_starsTransactionPeerAds($0) }
|
||||||
dict[-1269320843] = { return Api.StarsTransactionPeer.parse_starsTransactionPeerAppStore($0) }
|
dict[-1269320843] = { return Api.StarsTransactionPeer.parse_starsTransactionPeerAppStore($0) }
|
||||||
@ -1327,7 +1332,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
|
|||||||
dict[961445665] = { return Api.payments.StarsRevenueAdsAccountUrl.parse_starsRevenueAdsAccountUrl($0) }
|
dict[961445665] = { return Api.payments.StarsRevenueAdsAccountUrl.parse_starsRevenueAdsAccountUrl($0) }
|
||||||
dict[-919881925] = { return Api.payments.StarsRevenueStats.parse_starsRevenueStats($0) }
|
dict[-919881925] = { return Api.payments.StarsRevenueStats.parse_starsRevenueStats($0) }
|
||||||
dict[497778871] = { return Api.payments.StarsRevenueWithdrawalUrl.parse_starsRevenueWithdrawalUrl($0) }
|
dict[497778871] = { return Api.payments.StarsRevenueWithdrawalUrl.parse_starsRevenueWithdrawalUrl($0) }
|
||||||
dict[-1930105248] = { return Api.payments.StarsStatus.parse_starsStatus($0) }
|
dict[-1141231252] = { return Api.payments.StarsStatus.parse_starsStatus($0) }
|
||||||
dict[-784000893] = { return Api.payments.ValidatedRequestedInfo.parse_validatedRequestedInfo($0) }
|
dict[-784000893] = { return Api.payments.ValidatedRequestedInfo.parse_validatedRequestedInfo($0) }
|
||||||
dict[541839704] = { return Api.phone.ExportedGroupCallInvite.parse_exportedGroupCallInvite($0) }
|
dict[541839704] = { return Api.phone.ExportedGroupCallInvite.parse_exportedGroupCallInvite($0) }
|
||||||
dict[-1636664659] = { return Api.phone.GroupCall.parse_groupCall($0) }
|
dict[-1636664659] = { return Api.phone.GroupCall.parse_groupCall($0) }
|
||||||
@ -1402,7 +1407,7 @@ public extension Api {
|
|||||||
return parser(reader)
|
return parser(reader)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
telegramApiLog("Type constructor \(String(signature, radix: 16, uppercase: false)) not found")
|
telegramApiLog("Type constructor \(String(UInt32(bitPattern: signature), radix: 16, uppercase: false)) not found")
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1824,6 +1829,8 @@ public extension Api {
|
|||||||
_1.serialize(buffer, boxed)
|
_1.serialize(buffer, boxed)
|
||||||
case let _1 as Api.MessageReactions:
|
case let _1 as Api.MessageReactions:
|
||||||
_1.serialize(buffer, boxed)
|
_1.serialize(buffer, boxed)
|
||||||
|
case let _1 as Api.MessageReactor:
|
||||||
|
_1.serialize(buffer, boxed)
|
||||||
case let _1 as Api.MessageReplies:
|
case let _1 as Api.MessageReplies:
|
||||||
_1.serialize(buffer, boxed)
|
_1.serialize(buffer, boxed)
|
||||||
case let _1 as Api.MessageReplyHeader:
|
case let _1 as Api.MessageReplyHeader:
|
||||||
@ -2000,6 +2007,10 @@ public extension Api {
|
|||||||
_1.serialize(buffer, boxed)
|
_1.serialize(buffer, boxed)
|
||||||
case let _1 as Api.StarsRevenueStatus:
|
case let _1 as Api.StarsRevenueStatus:
|
||||||
_1.serialize(buffer, boxed)
|
_1.serialize(buffer, boxed)
|
||||||
|
case let _1 as Api.StarsSubscription:
|
||||||
|
_1.serialize(buffer, boxed)
|
||||||
|
case let _1 as Api.StarsSubscriptionPricing:
|
||||||
|
_1.serialize(buffer, boxed)
|
||||||
case let _1 as Api.StarsTopupOption:
|
case let _1 as Api.StarsTopupOption:
|
||||||
_1.serialize(buffer, boxed)
|
_1.serialize(buffer, boxed)
|
||||||
case let _1 as Api.StarsTransaction:
|
case let _1 as Api.StarsTransaction:
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
public extension Api {
|
public extension Api {
|
||||||
indirect enum InputInvoice: TypeConstructorDescription {
|
indirect enum InputInvoice: TypeConstructorDescription {
|
||||||
|
case inputInvoiceChatInviteSubscription(hash: String)
|
||||||
case inputInvoiceMessage(peer: Api.InputPeer, msgId: Int32)
|
case inputInvoiceMessage(peer: Api.InputPeer, msgId: Int32)
|
||||||
case inputInvoicePremiumGiftCode(purpose: Api.InputStorePaymentPurpose, option: Api.PremiumGiftCodeOption)
|
case inputInvoicePremiumGiftCode(purpose: Api.InputStorePaymentPurpose, option: Api.PremiumGiftCodeOption)
|
||||||
case inputInvoiceSlug(slug: String)
|
case inputInvoiceSlug(slug: String)
|
||||||
@ -7,6 +8,12 @@ public extension Api {
|
|||||||
|
|
||||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||||
switch self {
|
switch self {
|
||||||
|
case .inputInvoiceChatInviteSubscription(let hash):
|
||||||
|
if boxed {
|
||||||
|
buffer.appendInt32(887591921)
|
||||||
|
}
|
||||||
|
serializeString(hash, buffer: buffer, boxed: false)
|
||||||
|
break
|
||||||
case .inputInvoiceMessage(let peer, let msgId):
|
case .inputInvoiceMessage(let peer, let msgId):
|
||||||
if boxed {
|
if boxed {
|
||||||
buffer.appendInt32(-977967015)
|
buffer.appendInt32(-977967015)
|
||||||
@ -38,6 +45,8 @@ public extension Api {
|
|||||||
|
|
||||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||||
switch self {
|
switch self {
|
||||||
|
case .inputInvoiceChatInviteSubscription(let hash):
|
||||||
|
return ("inputInvoiceChatInviteSubscription", [("hash", hash as Any)])
|
||||||
case .inputInvoiceMessage(let peer, let msgId):
|
case .inputInvoiceMessage(let peer, let msgId):
|
||||||
return ("inputInvoiceMessage", [("peer", peer as Any), ("msgId", msgId as Any)])
|
return ("inputInvoiceMessage", [("peer", peer as Any), ("msgId", msgId as Any)])
|
||||||
case .inputInvoicePremiumGiftCode(let purpose, let option):
|
case .inputInvoicePremiumGiftCode(let purpose, let option):
|
||||||
@ -49,6 +58,17 @@ public extension Api {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static func parse_inputInvoiceChatInviteSubscription(_ reader: BufferReader) -> InputInvoice? {
|
||||||
|
var _1: String?
|
||||||
|
_1 = parseString(reader)
|
||||||
|
let _c1 = _1 != nil
|
||||||
|
if _c1 {
|
||||||
|
return Api.InputInvoice.inputInvoiceChatInviteSubscription(hash: _1!)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
public static func parse_inputInvoiceMessage(_ reader: BufferReader) -> InputInvoice? {
|
public static func parse_inputInvoiceMessage(_ reader: BufferReader) -> InputInvoice? {
|
||||||
var _1: Api.InputPeer?
|
var _1: Api.InputPeer?
|
||||||
if let signature = reader.readInt32() {
|
if let signature = reader.readInt32() {
|
||||||
@ -920,113 +940,3 @@ public extension Api {
|
|||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public extension Api {
|
|
||||||
enum InputPaymentCredentials: TypeConstructorDescription {
|
|
||||||
case inputPaymentCredentials(flags: Int32, data: Api.DataJSON)
|
|
||||||
case inputPaymentCredentialsApplePay(paymentData: Api.DataJSON)
|
|
||||||
case inputPaymentCredentialsGooglePay(paymentToken: Api.DataJSON)
|
|
||||||
case inputPaymentCredentialsSaved(id: String, tmpPassword: Buffer)
|
|
||||||
|
|
||||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
|
||||||
switch self {
|
|
||||||
case .inputPaymentCredentials(let flags, let data):
|
|
||||||
if boxed {
|
|
||||||
buffer.appendInt32(873977640)
|
|
||||||
}
|
|
||||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
|
||||||
data.serialize(buffer, true)
|
|
||||||
break
|
|
||||||
case .inputPaymentCredentialsApplePay(let paymentData):
|
|
||||||
if boxed {
|
|
||||||
buffer.appendInt32(178373535)
|
|
||||||
}
|
|
||||||
paymentData.serialize(buffer, true)
|
|
||||||
break
|
|
||||||
case .inputPaymentCredentialsGooglePay(let paymentToken):
|
|
||||||
if boxed {
|
|
||||||
buffer.appendInt32(-1966921727)
|
|
||||||
}
|
|
||||||
paymentToken.serialize(buffer, true)
|
|
||||||
break
|
|
||||||
case .inputPaymentCredentialsSaved(let id, let tmpPassword):
|
|
||||||
if boxed {
|
|
||||||
buffer.appendInt32(-1056001329)
|
|
||||||
}
|
|
||||||
serializeString(id, buffer: buffer, boxed: false)
|
|
||||||
serializeBytes(tmpPassword, buffer: buffer, boxed: false)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
|
||||||
switch self {
|
|
||||||
case .inputPaymentCredentials(let flags, let data):
|
|
||||||
return ("inputPaymentCredentials", [("flags", flags as Any), ("data", data as Any)])
|
|
||||||
case .inputPaymentCredentialsApplePay(let paymentData):
|
|
||||||
return ("inputPaymentCredentialsApplePay", [("paymentData", paymentData as Any)])
|
|
||||||
case .inputPaymentCredentialsGooglePay(let paymentToken):
|
|
||||||
return ("inputPaymentCredentialsGooglePay", [("paymentToken", paymentToken as Any)])
|
|
||||||
case .inputPaymentCredentialsSaved(let id, let tmpPassword):
|
|
||||||
return ("inputPaymentCredentialsSaved", [("id", id as Any), ("tmpPassword", tmpPassword as Any)])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static func parse_inputPaymentCredentials(_ reader: BufferReader) -> InputPaymentCredentials? {
|
|
||||||
var _1: Int32?
|
|
||||||
_1 = reader.readInt32()
|
|
||||||
var _2: Api.DataJSON?
|
|
||||||
if let signature = reader.readInt32() {
|
|
||||||
_2 = Api.parse(reader, signature: signature) as? Api.DataJSON
|
|
||||||
}
|
|
||||||
let _c1 = _1 != nil
|
|
||||||
let _c2 = _2 != nil
|
|
||||||
if _c1 && _c2 {
|
|
||||||
return Api.InputPaymentCredentials.inputPaymentCredentials(flags: _1!, data: _2!)
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public static func parse_inputPaymentCredentialsApplePay(_ reader: BufferReader) -> InputPaymentCredentials? {
|
|
||||||
var _1: Api.DataJSON?
|
|
||||||
if let signature = reader.readInt32() {
|
|
||||||
_1 = Api.parse(reader, signature: signature) as? Api.DataJSON
|
|
||||||
}
|
|
||||||
let _c1 = _1 != nil
|
|
||||||
if _c1 {
|
|
||||||
return Api.InputPaymentCredentials.inputPaymentCredentialsApplePay(paymentData: _1!)
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public static func parse_inputPaymentCredentialsGooglePay(_ reader: BufferReader) -> InputPaymentCredentials? {
|
|
||||||
var _1: Api.DataJSON?
|
|
||||||
if let signature = reader.readInt32() {
|
|
||||||
_1 = Api.parse(reader, signature: signature) as? Api.DataJSON
|
|
||||||
}
|
|
||||||
let _c1 = _1 != nil
|
|
||||||
if _c1 {
|
|
||||||
return Api.InputPaymentCredentials.inputPaymentCredentialsGooglePay(paymentToken: _1!)
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public static func parse_inputPaymentCredentialsSaved(_ reader: BufferReader) -> InputPaymentCredentials? {
|
|
||||||
var _1: String?
|
|
||||||
_1 = parseString(reader)
|
|
||||||
var _2: Buffer?
|
|
||||||
_2 = parseBytes(reader)
|
|
||||||
let _c1 = _1 != nil
|
|
||||||
let _c2 = _2 != nil
|
|
||||||
if _c1 && _c2 {
|
|
||||||
return Api.InputPaymentCredentials.inputPaymentCredentialsSaved(id: _1!, tmpPassword: _2!)
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -1,3 +1,113 @@
|
|||||||
|
public extension Api {
|
||||||
|
enum InputPaymentCredentials: TypeConstructorDescription {
|
||||||
|
case inputPaymentCredentials(flags: Int32, data: Api.DataJSON)
|
||||||
|
case inputPaymentCredentialsApplePay(paymentData: Api.DataJSON)
|
||||||
|
case inputPaymentCredentialsGooglePay(paymentToken: Api.DataJSON)
|
||||||
|
case inputPaymentCredentialsSaved(id: String, tmpPassword: Buffer)
|
||||||
|
|
||||||
|
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||||
|
switch self {
|
||||||
|
case .inputPaymentCredentials(let flags, let data):
|
||||||
|
if boxed {
|
||||||
|
buffer.appendInt32(873977640)
|
||||||
|
}
|
||||||
|
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||||
|
data.serialize(buffer, true)
|
||||||
|
break
|
||||||
|
case .inputPaymentCredentialsApplePay(let paymentData):
|
||||||
|
if boxed {
|
||||||
|
buffer.appendInt32(178373535)
|
||||||
|
}
|
||||||
|
paymentData.serialize(buffer, true)
|
||||||
|
break
|
||||||
|
case .inputPaymentCredentialsGooglePay(let paymentToken):
|
||||||
|
if boxed {
|
||||||
|
buffer.appendInt32(-1966921727)
|
||||||
|
}
|
||||||
|
paymentToken.serialize(buffer, true)
|
||||||
|
break
|
||||||
|
case .inputPaymentCredentialsSaved(let id, let tmpPassword):
|
||||||
|
if boxed {
|
||||||
|
buffer.appendInt32(-1056001329)
|
||||||
|
}
|
||||||
|
serializeString(id, buffer: buffer, boxed: false)
|
||||||
|
serializeBytes(tmpPassword, buffer: buffer, boxed: false)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||||
|
switch self {
|
||||||
|
case .inputPaymentCredentials(let flags, let data):
|
||||||
|
return ("inputPaymentCredentials", [("flags", flags as Any), ("data", data as Any)])
|
||||||
|
case .inputPaymentCredentialsApplePay(let paymentData):
|
||||||
|
return ("inputPaymentCredentialsApplePay", [("paymentData", paymentData as Any)])
|
||||||
|
case .inputPaymentCredentialsGooglePay(let paymentToken):
|
||||||
|
return ("inputPaymentCredentialsGooglePay", [("paymentToken", paymentToken as Any)])
|
||||||
|
case .inputPaymentCredentialsSaved(let id, let tmpPassword):
|
||||||
|
return ("inputPaymentCredentialsSaved", [("id", id as Any), ("tmpPassword", tmpPassword as Any)])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static func parse_inputPaymentCredentials(_ reader: BufferReader) -> InputPaymentCredentials? {
|
||||||
|
var _1: Int32?
|
||||||
|
_1 = reader.readInt32()
|
||||||
|
var _2: Api.DataJSON?
|
||||||
|
if let signature = reader.readInt32() {
|
||||||
|
_2 = Api.parse(reader, signature: signature) as? Api.DataJSON
|
||||||
|
}
|
||||||
|
let _c1 = _1 != nil
|
||||||
|
let _c2 = _2 != nil
|
||||||
|
if _c1 && _c2 {
|
||||||
|
return Api.InputPaymentCredentials.inputPaymentCredentials(flags: _1!, data: _2!)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public static func parse_inputPaymentCredentialsApplePay(_ reader: BufferReader) -> InputPaymentCredentials? {
|
||||||
|
var _1: Api.DataJSON?
|
||||||
|
if let signature = reader.readInt32() {
|
||||||
|
_1 = Api.parse(reader, signature: signature) as? Api.DataJSON
|
||||||
|
}
|
||||||
|
let _c1 = _1 != nil
|
||||||
|
if _c1 {
|
||||||
|
return Api.InputPaymentCredentials.inputPaymentCredentialsApplePay(paymentData: _1!)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public static func parse_inputPaymentCredentialsGooglePay(_ reader: BufferReader) -> InputPaymentCredentials? {
|
||||||
|
var _1: Api.DataJSON?
|
||||||
|
if let signature = reader.readInt32() {
|
||||||
|
_1 = Api.parse(reader, signature: signature) as? Api.DataJSON
|
||||||
|
}
|
||||||
|
let _c1 = _1 != nil
|
||||||
|
if _c1 {
|
||||||
|
return Api.InputPaymentCredentials.inputPaymentCredentialsGooglePay(paymentToken: _1!)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public static func parse_inputPaymentCredentialsSaved(_ reader: BufferReader) -> InputPaymentCredentials? {
|
||||||
|
var _1: String?
|
||||||
|
_1 = parseString(reader)
|
||||||
|
var _2: Buffer?
|
||||||
|
_2 = parseBytes(reader)
|
||||||
|
let _c1 = _1 != nil
|
||||||
|
let _c2 = _2 != nil
|
||||||
|
if _c1 && _c2 {
|
||||||
|
return Api.InputPaymentCredentials.inputPaymentCredentialsSaved(id: _1!, tmpPassword: _2!)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
public extension Api {
|
public extension Api {
|
||||||
indirect enum InputPeer: TypeConstructorDescription {
|
indirect enum InputPeer: TypeConstructorDescription {
|
||||||
case inputPeerChannel(channelId: Int64, accessHash: Int64)
|
case inputPeerChannel(channelId: Int64, accessHash: Int64)
|
||||||
|
@ -200,13 +200,13 @@ public extension Api {
|
|||||||
}
|
}
|
||||||
public extension Api {
|
public extension Api {
|
||||||
enum MessageReactions: TypeConstructorDescription {
|
enum MessageReactions: TypeConstructorDescription {
|
||||||
case messageReactions(flags: Int32, results: [Api.ReactionCount], recentReactions: [Api.MessagePeerReaction]?)
|
case messageReactions(flags: Int32, results: [Api.ReactionCount], recentReactions: [Api.MessagePeerReaction]?, topReactors: [Api.MessageReactor]?)
|
||||||
|
|
||||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||||
switch self {
|
switch self {
|
||||||
case .messageReactions(let flags, let results, let recentReactions):
|
case .messageReactions(let flags, let results, let recentReactions, let topReactors):
|
||||||
if boxed {
|
if boxed {
|
||||||
buffer.appendInt32(1328256121)
|
buffer.appendInt32(171155211)
|
||||||
}
|
}
|
||||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||||
buffer.appendInt32(481674261)
|
buffer.appendInt32(481674261)
|
||||||
@ -219,14 +219,19 @@ public extension Api {
|
|||||||
for item in recentReactions! {
|
for item in recentReactions! {
|
||||||
item.serialize(buffer, true)
|
item.serialize(buffer, true)
|
||||||
}}
|
}}
|
||||||
|
if Int(flags) & Int(1 << 4) != 0 {buffer.appendInt32(481674261)
|
||||||
|
buffer.appendInt32(Int32(topReactors!.count))
|
||||||
|
for item in topReactors! {
|
||||||
|
item.serialize(buffer, true)
|
||||||
|
}}
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||||
switch self {
|
switch self {
|
||||||
case .messageReactions(let flags, let results, let recentReactions):
|
case .messageReactions(let flags, let results, let recentReactions, let topReactors):
|
||||||
return ("messageReactions", [("flags", flags as Any), ("results", results as Any), ("recentReactions", recentReactions as Any)])
|
return ("messageReactions", [("flags", flags as Any), ("results", results as Any), ("recentReactions", recentReactions as Any), ("topReactors", topReactors as Any)])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -241,11 +246,62 @@ public extension Api {
|
|||||||
if Int(_1!) & Int(1 << 1) != 0 {if let _ = reader.readInt32() {
|
if Int(_1!) & Int(1 << 1) != 0 {if let _ = reader.readInt32() {
|
||||||
_3 = Api.parseVector(reader, elementSignature: 0, elementType: Api.MessagePeerReaction.self)
|
_3 = Api.parseVector(reader, elementSignature: 0, elementType: Api.MessagePeerReaction.self)
|
||||||
} }
|
} }
|
||||||
|
var _4: [Api.MessageReactor]?
|
||||||
|
if Int(_1!) & Int(1 << 4) != 0 {if let _ = reader.readInt32() {
|
||||||
|
_4 = Api.parseVector(reader, elementSignature: 0, elementType: Api.MessageReactor.self)
|
||||||
|
} }
|
||||||
let _c1 = _1 != nil
|
let _c1 = _1 != nil
|
||||||
let _c2 = _2 != nil
|
let _c2 = _2 != nil
|
||||||
let _c3 = (Int(_1!) & Int(1 << 1) == 0) || _3 != nil
|
let _c3 = (Int(_1!) & Int(1 << 1) == 0) || _3 != nil
|
||||||
|
let _c4 = (Int(_1!) & Int(1 << 4) == 0) || _4 != nil
|
||||||
|
if _c1 && _c2 && _c3 && _c4 {
|
||||||
|
return Api.MessageReactions.messageReactions(flags: _1!, results: _2!, recentReactions: _3, topReactors: _4)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public extension Api {
|
||||||
|
enum MessageReactor: TypeConstructorDescription {
|
||||||
|
case messageReactor(flags: Int32, peerId: Api.Peer, count: Int32)
|
||||||
|
|
||||||
|
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||||
|
switch self {
|
||||||
|
case .messageReactor(let flags, let peerId, let count):
|
||||||
|
if boxed {
|
||||||
|
buffer.appendInt32(-285158328)
|
||||||
|
}
|
||||||
|
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||||
|
peerId.serialize(buffer, true)
|
||||||
|
serializeInt32(count, buffer: buffer, boxed: false)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||||
|
switch self {
|
||||||
|
case .messageReactor(let flags, let peerId, let count):
|
||||||
|
return ("messageReactor", [("flags", flags as Any), ("peerId", peerId as Any), ("count", count as Any)])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static func parse_messageReactor(_ reader: BufferReader) -> MessageReactor? {
|
||||||
|
var _1: Int32?
|
||||||
|
_1 = reader.readInt32()
|
||||||
|
var _2: Api.Peer?
|
||||||
|
if let signature = reader.readInt32() {
|
||||||
|
_2 = Api.parse(reader, signature: signature) as? Api.Peer
|
||||||
|
}
|
||||||
|
var _3: Int32?
|
||||||
|
_3 = reader.readInt32()
|
||||||
|
let _c1 = _1 != nil
|
||||||
|
let _c2 = _2 != nil
|
||||||
|
let _c3 = _3 != nil
|
||||||
if _c1 && _c2 && _c3 {
|
if _c1 && _c2 && _c3 {
|
||||||
return Api.MessageReactions.messageReactions(flags: _1!, results: _2!, recentReactions: _3)
|
return Api.MessageReactor.messageReactor(flags: _1!, peerId: _2!, count: _3!)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return nil
|
return nil
|
||||||
|
@ -309,6 +309,7 @@ public extension Api {
|
|||||||
case reactionCustomEmoji(documentId: Int64)
|
case reactionCustomEmoji(documentId: Int64)
|
||||||
case reactionEmoji(emoticon: String)
|
case reactionEmoji(emoticon: String)
|
||||||
case reactionEmpty
|
case reactionEmpty
|
||||||
|
case reactionPaid
|
||||||
|
|
||||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||||
switch self {
|
switch self {
|
||||||
@ -329,6 +330,12 @@ public extension Api {
|
|||||||
buffer.appendInt32(2046153753)
|
buffer.appendInt32(2046153753)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
break
|
||||||
|
case .reactionPaid:
|
||||||
|
if boxed {
|
||||||
|
buffer.appendInt32(1379771627)
|
||||||
|
}
|
||||||
|
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -341,6 +348,8 @@ public extension Api {
|
|||||||
return ("reactionEmoji", [("emoticon", emoticon as Any)])
|
return ("reactionEmoji", [("emoticon", emoticon as Any)])
|
||||||
case .reactionEmpty:
|
case .reactionEmpty:
|
||||||
return ("reactionEmpty", [])
|
return ("reactionEmpty", [])
|
||||||
|
case .reactionPaid:
|
||||||
|
return ("reactionPaid", [])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -369,6 +378,9 @@ public extension Api {
|
|||||||
public static func parse_reactionEmpty(_ reader: BufferReader) -> Reaction? {
|
public static func parse_reactionEmpty(_ reader: BufferReader) -> Reaction? {
|
||||||
return Api.Reaction.reactionEmpty
|
return Api.Reaction.reactionEmpty
|
||||||
}
|
}
|
||||||
|
public static func parse_reactionPaid(_ reader: BufferReader) -> Reaction? {
|
||||||
|
return Api.Reaction.reactionPaid
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -858,139 +870,3 @@ public extension Api {
|
|||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public extension Api {
|
|
||||||
enum ReportReason: TypeConstructorDescription {
|
|
||||||
case inputReportReasonChildAbuse
|
|
||||||
case inputReportReasonCopyright
|
|
||||||
case inputReportReasonFake
|
|
||||||
case inputReportReasonGeoIrrelevant
|
|
||||||
case inputReportReasonIllegalDrugs
|
|
||||||
case inputReportReasonOther
|
|
||||||
case inputReportReasonPersonalDetails
|
|
||||||
case inputReportReasonPornography
|
|
||||||
case inputReportReasonSpam
|
|
||||||
case inputReportReasonViolence
|
|
||||||
|
|
||||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
|
||||||
switch self {
|
|
||||||
case .inputReportReasonChildAbuse:
|
|
||||||
if boxed {
|
|
||||||
buffer.appendInt32(-1376497949)
|
|
||||||
}
|
|
||||||
|
|
||||||
break
|
|
||||||
case .inputReportReasonCopyright:
|
|
||||||
if boxed {
|
|
||||||
buffer.appendInt32(-1685456582)
|
|
||||||
}
|
|
||||||
|
|
||||||
break
|
|
||||||
case .inputReportReasonFake:
|
|
||||||
if boxed {
|
|
||||||
buffer.appendInt32(-170010905)
|
|
||||||
}
|
|
||||||
|
|
||||||
break
|
|
||||||
case .inputReportReasonGeoIrrelevant:
|
|
||||||
if boxed {
|
|
||||||
buffer.appendInt32(-606798099)
|
|
||||||
}
|
|
||||||
|
|
||||||
break
|
|
||||||
case .inputReportReasonIllegalDrugs:
|
|
||||||
if boxed {
|
|
||||||
buffer.appendInt32(177124030)
|
|
||||||
}
|
|
||||||
|
|
||||||
break
|
|
||||||
case .inputReportReasonOther:
|
|
||||||
if boxed {
|
|
||||||
buffer.appendInt32(-1041980751)
|
|
||||||
}
|
|
||||||
|
|
||||||
break
|
|
||||||
case .inputReportReasonPersonalDetails:
|
|
||||||
if boxed {
|
|
||||||
buffer.appendInt32(-1631091139)
|
|
||||||
}
|
|
||||||
|
|
||||||
break
|
|
||||||
case .inputReportReasonPornography:
|
|
||||||
if boxed {
|
|
||||||
buffer.appendInt32(777640226)
|
|
||||||
}
|
|
||||||
|
|
||||||
break
|
|
||||||
case .inputReportReasonSpam:
|
|
||||||
if boxed {
|
|
||||||
buffer.appendInt32(1490799288)
|
|
||||||
}
|
|
||||||
|
|
||||||
break
|
|
||||||
case .inputReportReasonViolence:
|
|
||||||
if boxed {
|
|
||||||
buffer.appendInt32(505595789)
|
|
||||||
}
|
|
||||||
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
|
||||||
switch self {
|
|
||||||
case .inputReportReasonChildAbuse:
|
|
||||||
return ("inputReportReasonChildAbuse", [])
|
|
||||||
case .inputReportReasonCopyright:
|
|
||||||
return ("inputReportReasonCopyright", [])
|
|
||||||
case .inputReportReasonFake:
|
|
||||||
return ("inputReportReasonFake", [])
|
|
||||||
case .inputReportReasonGeoIrrelevant:
|
|
||||||
return ("inputReportReasonGeoIrrelevant", [])
|
|
||||||
case .inputReportReasonIllegalDrugs:
|
|
||||||
return ("inputReportReasonIllegalDrugs", [])
|
|
||||||
case .inputReportReasonOther:
|
|
||||||
return ("inputReportReasonOther", [])
|
|
||||||
case .inputReportReasonPersonalDetails:
|
|
||||||
return ("inputReportReasonPersonalDetails", [])
|
|
||||||
case .inputReportReasonPornography:
|
|
||||||
return ("inputReportReasonPornography", [])
|
|
||||||
case .inputReportReasonSpam:
|
|
||||||
return ("inputReportReasonSpam", [])
|
|
||||||
case .inputReportReasonViolence:
|
|
||||||
return ("inputReportReasonViolence", [])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static func parse_inputReportReasonChildAbuse(_ reader: BufferReader) -> ReportReason? {
|
|
||||||
return Api.ReportReason.inputReportReasonChildAbuse
|
|
||||||
}
|
|
||||||
public static func parse_inputReportReasonCopyright(_ reader: BufferReader) -> ReportReason? {
|
|
||||||
return Api.ReportReason.inputReportReasonCopyright
|
|
||||||
}
|
|
||||||
public static func parse_inputReportReasonFake(_ reader: BufferReader) -> ReportReason? {
|
|
||||||
return Api.ReportReason.inputReportReasonFake
|
|
||||||
}
|
|
||||||
public static func parse_inputReportReasonGeoIrrelevant(_ reader: BufferReader) -> ReportReason? {
|
|
||||||
return Api.ReportReason.inputReportReasonGeoIrrelevant
|
|
||||||
}
|
|
||||||
public static func parse_inputReportReasonIllegalDrugs(_ reader: BufferReader) -> ReportReason? {
|
|
||||||
return Api.ReportReason.inputReportReasonIllegalDrugs
|
|
||||||
}
|
|
||||||
public static func parse_inputReportReasonOther(_ reader: BufferReader) -> ReportReason? {
|
|
||||||
return Api.ReportReason.inputReportReasonOther
|
|
||||||
}
|
|
||||||
public static func parse_inputReportReasonPersonalDetails(_ reader: BufferReader) -> ReportReason? {
|
|
||||||
return Api.ReportReason.inputReportReasonPersonalDetails
|
|
||||||
}
|
|
||||||
public static func parse_inputReportReasonPornography(_ reader: BufferReader) -> ReportReason? {
|
|
||||||
return Api.ReportReason.inputReportReasonPornography
|
|
||||||
}
|
|
||||||
public static func parse_inputReportReasonSpam(_ reader: BufferReader) -> ReportReason? {
|
|
||||||
return Api.ReportReason.inputReportReasonSpam
|
|
||||||
}
|
|
||||||
public static func parse_inputReportReasonViolence(_ reader: BufferReader) -> ReportReason? {
|
|
||||||
return Api.ReportReason.inputReportReasonViolence
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -1,3 +1,139 @@
|
|||||||
|
public extension Api {
|
||||||
|
enum ReportReason: TypeConstructorDescription {
|
||||||
|
case inputReportReasonChildAbuse
|
||||||
|
case inputReportReasonCopyright
|
||||||
|
case inputReportReasonFake
|
||||||
|
case inputReportReasonGeoIrrelevant
|
||||||
|
case inputReportReasonIllegalDrugs
|
||||||
|
case inputReportReasonOther
|
||||||
|
case inputReportReasonPersonalDetails
|
||||||
|
case inputReportReasonPornography
|
||||||
|
case inputReportReasonSpam
|
||||||
|
case inputReportReasonViolence
|
||||||
|
|
||||||
|
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||||
|
switch self {
|
||||||
|
case .inputReportReasonChildAbuse:
|
||||||
|
if boxed {
|
||||||
|
buffer.appendInt32(-1376497949)
|
||||||
|
}
|
||||||
|
|
||||||
|
break
|
||||||
|
case .inputReportReasonCopyright:
|
||||||
|
if boxed {
|
||||||
|
buffer.appendInt32(-1685456582)
|
||||||
|
}
|
||||||
|
|
||||||
|
break
|
||||||
|
case .inputReportReasonFake:
|
||||||
|
if boxed {
|
||||||
|
buffer.appendInt32(-170010905)
|
||||||
|
}
|
||||||
|
|
||||||
|
break
|
||||||
|
case .inputReportReasonGeoIrrelevant:
|
||||||
|
if boxed {
|
||||||
|
buffer.appendInt32(-606798099)
|
||||||
|
}
|
||||||
|
|
||||||
|
break
|
||||||
|
case .inputReportReasonIllegalDrugs:
|
||||||
|
if boxed {
|
||||||
|
buffer.appendInt32(177124030)
|
||||||
|
}
|
||||||
|
|
||||||
|
break
|
||||||
|
case .inputReportReasonOther:
|
||||||
|
if boxed {
|
||||||
|
buffer.appendInt32(-1041980751)
|
||||||
|
}
|
||||||
|
|
||||||
|
break
|
||||||
|
case .inputReportReasonPersonalDetails:
|
||||||
|
if boxed {
|
||||||
|
buffer.appendInt32(-1631091139)
|
||||||
|
}
|
||||||
|
|
||||||
|
break
|
||||||
|
case .inputReportReasonPornography:
|
||||||
|
if boxed {
|
||||||
|
buffer.appendInt32(777640226)
|
||||||
|
}
|
||||||
|
|
||||||
|
break
|
||||||
|
case .inputReportReasonSpam:
|
||||||
|
if boxed {
|
||||||
|
buffer.appendInt32(1490799288)
|
||||||
|
}
|
||||||
|
|
||||||
|
break
|
||||||
|
case .inputReportReasonViolence:
|
||||||
|
if boxed {
|
||||||
|
buffer.appendInt32(505595789)
|
||||||
|
}
|
||||||
|
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||||
|
switch self {
|
||||||
|
case .inputReportReasonChildAbuse:
|
||||||
|
return ("inputReportReasonChildAbuse", [])
|
||||||
|
case .inputReportReasonCopyright:
|
||||||
|
return ("inputReportReasonCopyright", [])
|
||||||
|
case .inputReportReasonFake:
|
||||||
|
return ("inputReportReasonFake", [])
|
||||||
|
case .inputReportReasonGeoIrrelevant:
|
||||||
|
return ("inputReportReasonGeoIrrelevant", [])
|
||||||
|
case .inputReportReasonIllegalDrugs:
|
||||||
|
return ("inputReportReasonIllegalDrugs", [])
|
||||||
|
case .inputReportReasonOther:
|
||||||
|
return ("inputReportReasonOther", [])
|
||||||
|
case .inputReportReasonPersonalDetails:
|
||||||
|
return ("inputReportReasonPersonalDetails", [])
|
||||||
|
case .inputReportReasonPornography:
|
||||||
|
return ("inputReportReasonPornography", [])
|
||||||
|
case .inputReportReasonSpam:
|
||||||
|
return ("inputReportReasonSpam", [])
|
||||||
|
case .inputReportReasonViolence:
|
||||||
|
return ("inputReportReasonViolence", [])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static func parse_inputReportReasonChildAbuse(_ reader: BufferReader) -> ReportReason? {
|
||||||
|
return Api.ReportReason.inputReportReasonChildAbuse
|
||||||
|
}
|
||||||
|
public static func parse_inputReportReasonCopyright(_ reader: BufferReader) -> ReportReason? {
|
||||||
|
return Api.ReportReason.inputReportReasonCopyright
|
||||||
|
}
|
||||||
|
public static func parse_inputReportReasonFake(_ reader: BufferReader) -> ReportReason? {
|
||||||
|
return Api.ReportReason.inputReportReasonFake
|
||||||
|
}
|
||||||
|
public static func parse_inputReportReasonGeoIrrelevant(_ reader: BufferReader) -> ReportReason? {
|
||||||
|
return Api.ReportReason.inputReportReasonGeoIrrelevant
|
||||||
|
}
|
||||||
|
public static func parse_inputReportReasonIllegalDrugs(_ reader: BufferReader) -> ReportReason? {
|
||||||
|
return Api.ReportReason.inputReportReasonIllegalDrugs
|
||||||
|
}
|
||||||
|
public static func parse_inputReportReasonOther(_ reader: BufferReader) -> ReportReason? {
|
||||||
|
return Api.ReportReason.inputReportReasonOther
|
||||||
|
}
|
||||||
|
public static func parse_inputReportReasonPersonalDetails(_ reader: BufferReader) -> ReportReason? {
|
||||||
|
return Api.ReportReason.inputReportReasonPersonalDetails
|
||||||
|
}
|
||||||
|
public static func parse_inputReportReasonPornography(_ reader: BufferReader) -> ReportReason? {
|
||||||
|
return Api.ReportReason.inputReportReasonPornography
|
||||||
|
}
|
||||||
|
public static func parse_inputReportReasonSpam(_ reader: BufferReader) -> ReportReason? {
|
||||||
|
return Api.ReportReason.inputReportReasonSpam
|
||||||
|
}
|
||||||
|
public static func parse_inputReportReasonViolence(_ reader: BufferReader) -> ReportReason? {
|
||||||
|
return Api.ReportReason.inputReportReasonViolence
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
public extension Api {
|
public extension Api {
|
||||||
enum RequestPeerType: TypeConstructorDescription {
|
enum RequestPeerType: TypeConstructorDescription {
|
||||||
case requestPeerTypeBroadcast(flags: Int32, hasUsername: Api.Bool?, userAdminRights: Api.ChatAdminRights?, botAdminRights: Api.ChatAdminRights?)
|
case requestPeerTypeBroadcast(flags: Int32, hasUsername: Api.Bool?, userAdminRights: Api.ChatAdminRights?, botAdminRights: Api.ChatAdminRights?)
|
||||||
@ -688,399 +824,3 @@ public extension Api {
|
|||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public extension Api {
|
|
||||||
enum SavedContact: TypeConstructorDescription {
|
|
||||||
case savedPhoneContact(phone: String, firstName: String, lastName: String, date: Int32)
|
|
||||||
|
|
||||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
|
||||||
switch self {
|
|
||||||
case .savedPhoneContact(let phone, let firstName, let lastName, let date):
|
|
||||||
if boxed {
|
|
||||||
buffer.appendInt32(289586518)
|
|
||||||
}
|
|
||||||
serializeString(phone, buffer: buffer, boxed: false)
|
|
||||||
serializeString(firstName, buffer: buffer, boxed: false)
|
|
||||||
serializeString(lastName, buffer: buffer, boxed: false)
|
|
||||||
serializeInt32(date, buffer: buffer, boxed: false)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
|
||||||
switch self {
|
|
||||||
case .savedPhoneContact(let phone, let firstName, let lastName, let date):
|
|
||||||
return ("savedPhoneContact", [("phone", phone as Any), ("firstName", firstName as Any), ("lastName", lastName as Any), ("date", date as Any)])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static func parse_savedPhoneContact(_ reader: BufferReader) -> SavedContact? {
|
|
||||||
var _1: String?
|
|
||||||
_1 = parseString(reader)
|
|
||||||
var _2: String?
|
|
||||||
_2 = parseString(reader)
|
|
||||||
var _3: String?
|
|
||||||
_3 = parseString(reader)
|
|
||||||
var _4: Int32?
|
|
||||||
_4 = reader.readInt32()
|
|
||||||
let _c1 = _1 != nil
|
|
||||||
let _c2 = _2 != nil
|
|
||||||
let _c3 = _3 != nil
|
|
||||||
let _c4 = _4 != nil
|
|
||||||
if _c1 && _c2 && _c3 && _c4 {
|
|
||||||
return Api.SavedContact.savedPhoneContact(phone: _1!, firstName: _2!, lastName: _3!, date: _4!)
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public extension Api {
|
|
||||||
enum SavedDialog: TypeConstructorDescription {
|
|
||||||
case savedDialog(flags: Int32, peer: Api.Peer, topMessage: Int32)
|
|
||||||
|
|
||||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
|
||||||
switch self {
|
|
||||||
case .savedDialog(let flags, let peer, let topMessage):
|
|
||||||
if boxed {
|
|
||||||
buffer.appendInt32(-1115174036)
|
|
||||||
}
|
|
||||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
|
||||||
peer.serialize(buffer, true)
|
|
||||||
serializeInt32(topMessage, buffer: buffer, boxed: false)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
|
||||||
switch self {
|
|
||||||
case .savedDialog(let flags, let peer, let topMessage):
|
|
||||||
return ("savedDialog", [("flags", flags as Any), ("peer", peer as Any), ("topMessage", topMessage as Any)])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static func parse_savedDialog(_ reader: BufferReader) -> SavedDialog? {
|
|
||||||
var _1: Int32?
|
|
||||||
_1 = reader.readInt32()
|
|
||||||
var _2: Api.Peer?
|
|
||||||
if let signature = reader.readInt32() {
|
|
||||||
_2 = Api.parse(reader, signature: signature) as? Api.Peer
|
|
||||||
}
|
|
||||||
var _3: Int32?
|
|
||||||
_3 = reader.readInt32()
|
|
||||||
let _c1 = _1 != nil
|
|
||||||
let _c2 = _2 != nil
|
|
||||||
let _c3 = _3 != nil
|
|
||||||
if _c1 && _c2 && _c3 {
|
|
||||||
return Api.SavedDialog.savedDialog(flags: _1!, peer: _2!, topMessage: _3!)
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public extension Api {
|
|
||||||
enum SavedReactionTag: TypeConstructorDescription {
|
|
||||||
case savedReactionTag(flags: Int32, reaction: Api.Reaction, title: String?, count: Int32)
|
|
||||||
|
|
||||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
|
||||||
switch self {
|
|
||||||
case .savedReactionTag(let flags, let reaction, let title, let count):
|
|
||||||
if boxed {
|
|
||||||
buffer.appendInt32(-881854424)
|
|
||||||
}
|
|
||||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
|
||||||
reaction.serialize(buffer, true)
|
|
||||||
if Int(flags) & Int(1 << 0) != 0 {serializeString(title!, buffer: buffer, boxed: false)}
|
|
||||||
serializeInt32(count, buffer: buffer, boxed: false)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
|
||||||
switch self {
|
|
||||||
case .savedReactionTag(let flags, let reaction, let title, let count):
|
|
||||||
return ("savedReactionTag", [("flags", flags as Any), ("reaction", reaction as Any), ("title", title as Any), ("count", count as Any)])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static func parse_savedReactionTag(_ reader: BufferReader) -> SavedReactionTag? {
|
|
||||||
var _1: Int32?
|
|
||||||
_1 = reader.readInt32()
|
|
||||||
var _2: Api.Reaction?
|
|
||||||
if let signature = reader.readInt32() {
|
|
||||||
_2 = Api.parse(reader, signature: signature) as? Api.Reaction
|
|
||||||
}
|
|
||||||
var _3: String?
|
|
||||||
if Int(_1!) & Int(1 << 0) != 0 {_3 = parseString(reader) }
|
|
||||||
var _4: Int32?
|
|
||||||
_4 = reader.readInt32()
|
|
||||||
let _c1 = _1 != nil
|
|
||||||
let _c2 = _2 != nil
|
|
||||||
let _c3 = (Int(_1!) & Int(1 << 0) == 0) || _3 != nil
|
|
||||||
let _c4 = _4 != nil
|
|
||||||
if _c1 && _c2 && _c3 && _c4 {
|
|
||||||
return Api.SavedReactionTag.savedReactionTag(flags: _1!, reaction: _2!, title: _3, count: _4!)
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public extension Api {
|
|
||||||
enum SearchResultsCalendarPeriod: TypeConstructorDescription {
|
|
||||||
case searchResultsCalendarPeriod(date: Int32, minMsgId: Int32, maxMsgId: Int32, count: Int32)
|
|
||||||
|
|
||||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
|
||||||
switch self {
|
|
||||||
case .searchResultsCalendarPeriod(let date, let minMsgId, let maxMsgId, let count):
|
|
||||||
if boxed {
|
|
||||||
buffer.appendInt32(-911191137)
|
|
||||||
}
|
|
||||||
serializeInt32(date, buffer: buffer, boxed: false)
|
|
||||||
serializeInt32(minMsgId, buffer: buffer, boxed: false)
|
|
||||||
serializeInt32(maxMsgId, buffer: buffer, boxed: false)
|
|
||||||
serializeInt32(count, buffer: buffer, boxed: false)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
|
||||||
switch self {
|
|
||||||
case .searchResultsCalendarPeriod(let date, let minMsgId, let maxMsgId, let count):
|
|
||||||
return ("searchResultsCalendarPeriod", [("date", date as Any), ("minMsgId", minMsgId as Any), ("maxMsgId", maxMsgId as Any), ("count", count as Any)])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static func parse_searchResultsCalendarPeriod(_ reader: BufferReader) -> SearchResultsCalendarPeriod? {
|
|
||||||
var _1: Int32?
|
|
||||||
_1 = reader.readInt32()
|
|
||||||
var _2: Int32?
|
|
||||||
_2 = reader.readInt32()
|
|
||||||
var _3: Int32?
|
|
||||||
_3 = reader.readInt32()
|
|
||||||
var _4: Int32?
|
|
||||||
_4 = reader.readInt32()
|
|
||||||
let _c1 = _1 != nil
|
|
||||||
let _c2 = _2 != nil
|
|
||||||
let _c3 = _3 != nil
|
|
||||||
let _c4 = _4 != nil
|
|
||||||
if _c1 && _c2 && _c3 && _c4 {
|
|
||||||
return Api.SearchResultsCalendarPeriod.searchResultsCalendarPeriod(date: _1!, minMsgId: _2!, maxMsgId: _3!, count: _4!)
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public extension Api {
|
|
||||||
enum SearchResultsPosition: TypeConstructorDescription {
|
|
||||||
case searchResultPosition(msgId: Int32, date: Int32, offset: Int32)
|
|
||||||
|
|
||||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
|
||||||
switch self {
|
|
||||||
case .searchResultPosition(let msgId, let date, let offset):
|
|
||||||
if boxed {
|
|
||||||
buffer.appendInt32(2137295719)
|
|
||||||
}
|
|
||||||
serializeInt32(msgId, buffer: buffer, boxed: false)
|
|
||||||
serializeInt32(date, buffer: buffer, boxed: false)
|
|
||||||
serializeInt32(offset, buffer: buffer, boxed: false)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
|
||||||
switch self {
|
|
||||||
case .searchResultPosition(let msgId, let date, let offset):
|
|
||||||
return ("searchResultPosition", [("msgId", msgId as Any), ("date", date as Any), ("offset", offset as Any)])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static func parse_searchResultPosition(_ reader: BufferReader) -> SearchResultsPosition? {
|
|
||||||
var _1: Int32?
|
|
||||||
_1 = reader.readInt32()
|
|
||||||
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.SearchResultsPosition.searchResultPosition(msgId: _1!, date: _2!, offset: _3!)
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public extension Api {
|
|
||||||
enum SecureCredentialsEncrypted: TypeConstructorDescription {
|
|
||||||
case secureCredentialsEncrypted(data: Buffer, hash: Buffer, secret: Buffer)
|
|
||||||
|
|
||||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
|
||||||
switch self {
|
|
||||||
case .secureCredentialsEncrypted(let data, let hash, let secret):
|
|
||||||
if boxed {
|
|
||||||
buffer.appendInt32(871426631)
|
|
||||||
}
|
|
||||||
serializeBytes(data, buffer: buffer, boxed: false)
|
|
||||||
serializeBytes(hash, buffer: buffer, boxed: false)
|
|
||||||
serializeBytes(secret, buffer: buffer, boxed: false)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
|
||||||
switch self {
|
|
||||||
case .secureCredentialsEncrypted(let data, let hash, let secret):
|
|
||||||
return ("secureCredentialsEncrypted", [("data", data as Any), ("hash", hash as Any), ("secret", secret as Any)])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static func parse_secureCredentialsEncrypted(_ reader: BufferReader) -> SecureCredentialsEncrypted? {
|
|
||||||
var _1: Buffer?
|
|
||||||
_1 = parseBytes(reader)
|
|
||||||
var _2: Buffer?
|
|
||||||
_2 = parseBytes(reader)
|
|
||||||
var _3: Buffer?
|
|
||||||
_3 = parseBytes(reader)
|
|
||||||
let _c1 = _1 != nil
|
|
||||||
let _c2 = _2 != nil
|
|
||||||
let _c3 = _3 != nil
|
|
||||||
if _c1 && _c2 && _c3 {
|
|
||||||
return Api.SecureCredentialsEncrypted.secureCredentialsEncrypted(data: _1!, hash: _2!, secret: _3!)
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public extension Api {
|
|
||||||
enum SecureData: TypeConstructorDescription {
|
|
||||||
case secureData(data: Buffer, dataHash: Buffer, secret: Buffer)
|
|
||||||
|
|
||||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
|
||||||
switch self {
|
|
||||||
case .secureData(let data, let dataHash, let secret):
|
|
||||||
if boxed {
|
|
||||||
buffer.appendInt32(-1964327229)
|
|
||||||
}
|
|
||||||
serializeBytes(data, buffer: buffer, boxed: false)
|
|
||||||
serializeBytes(dataHash, buffer: buffer, boxed: false)
|
|
||||||
serializeBytes(secret, buffer: buffer, boxed: false)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
|
||||||
switch self {
|
|
||||||
case .secureData(let data, let dataHash, let secret):
|
|
||||||
return ("secureData", [("data", data as Any), ("dataHash", dataHash as Any), ("secret", secret as Any)])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static func parse_secureData(_ reader: BufferReader) -> SecureData? {
|
|
||||||
var _1: Buffer?
|
|
||||||
_1 = parseBytes(reader)
|
|
||||||
var _2: Buffer?
|
|
||||||
_2 = parseBytes(reader)
|
|
||||||
var _3: Buffer?
|
|
||||||
_3 = parseBytes(reader)
|
|
||||||
let _c1 = _1 != nil
|
|
||||||
let _c2 = _2 != nil
|
|
||||||
let _c3 = _3 != nil
|
|
||||||
if _c1 && _c2 && _c3 {
|
|
||||||
return Api.SecureData.secureData(data: _1!, dataHash: _2!, secret: _3!)
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public extension Api {
|
|
||||||
enum SecureFile: TypeConstructorDescription {
|
|
||||||
case secureFile(id: Int64, accessHash: Int64, size: Int64, dcId: Int32, date: Int32, fileHash: Buffer, secret: Buffer)
|
|
||||||
case secureFileEmpty
|
|
||||||
|
|
||||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
|
||||||
switch self {
|
|
||||||
case .secureFile(let id, let accessHash, let size, let dcId, let date, let fileHash, let secret):
|
|
||||||
if boxed {
|
|
||||||
buffer.appendInt32(2097791614)
|
|
||||||
}
|
|
||||||
serializeInt64(id, buffer: buffer, boxed: false)
|
|
||||||
serializeInt64(accessHash, buffer: buffer, boxed: false)
|
|
||||||
serializeInt64(size, buffer: buffer, boxed: false)
|
|
||||||
serializeInt32(dcId, buffer: buffer, boxed: false)
|
|
||||||
serializeInt32(date, buffer: buffer, boxed: false)
|
|
||||||
serializeBytes(fileHash, buffer: buffer, boxed: false)
|
|
||||||
serializeBytes(secret, buffer: buffer, boxed: false)
|
|
||||||
break
|
|
||||||
case .secureFileEmpty:
|
|
||||||
if boxed {
|
|
||||||
buffer.appendInt32(1679398724)
|
|
||||||
}
|
|
||||||
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
|
||||||
switch self {
|
|
||||||
case .secureFile(let id, let accessHash, let size, let dcId, let date, let fileHash, let secret):
|
|
||||||
return ("secureFile", [("id", id as Any), ("accessHash", accessHash as Any), ("size", size as Any), ("dcId", dcId as Any), ("date", date as Any), ("fileHash", fileHash as Any), ("secret", secret as Any)])
|
|
||||||
case .secureFileEmpty:
|
|
||||||
return ("secureFileEmpty", [])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static func parse_secureFile(_ reader: BufferReader) -> SecureFile? {
|
|
||||||
var _1: Int64?
|
|
||||||
_1 = reader.readInt64()
|
|
||||||
var _2: Int64?
|
|
||||||
_2 = reader.readInt64()
|
|
||||||
var _3: Int64?
|
|
||||||
_3 = reader.readInt64()
|
|
||||||
var _4: Int32?
|
|
||||||
_4 = reader.readInt32()
|
|
||||||
var _5: Int32?
|
|
||||||
_5 = reader.readInt32()
|
|
||||||
var _6: Buffer?
|
|
||||||
_6 = parseBytes(reader)
|
|
||||||
var _7: Buffer?
|
|
||||||
_7 = parseBytes(reader)
|
|
||||||
let _c1 = _1 != nil
|
|
||||||
let _c2 = _2 != nil
|
|
||||||
let _c3 = _3 != nil
|
|
||||||
let _c4 = _4 != nil
|
|
||||||
let _c5 = _5 != nil
|
|
||||||
let _c6 = _6 != nil
|
|
||||||
let _c7 = _7 != nil
|
|
||||||
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 {
|
|
||||||
return Api.SecureFile.secureFile(id: _1!, accessHash: _2!, size: _3!, dcId: _4!, date: _5!, fileHash: _6!, secret: _7!)
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public static func parse_secureFileEmpty(_ reader: BufferReader) -> SecureFile? {
|
|
||||||
return Api.SecureFile.secureFileEmpty
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -1,3 +1,399 @@
|
|||||||
|
public extension Api {
|
||||||
|
enum SavedContact: TypeConstructorDescription {
|
||||||
|
case savedPhoneContact(phone: String, firstName: String, lastName: String, date: Int32)
|
||||||
|
|
||||||
|
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||||
|
switch self {
|
||||||
|
case .savedPhoneContact(let phone, let firstName, let lastName, let date):
|
||||||
|
if boxed {
|
||||||
|
buffer.appendInt32(289586518)
|
||||||
|
}
|
||||||
|
serializeString(phone, buffer: buffer, boxed: false)
|
||||||
|
serializeString(firstName, buffer: buffer, boxed: false)
|
||||||
|
serializeString(lastName, buffer: buffer, boxed: false)
|
||||||
|
serializeInt32(date, buffer: buffer, boxed: false)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||||
|
switch self {
|
||||||
|
case .savedPhoneContact(let phone, let firstName, let lastName, let date):
|
||||||
|
return ("savedPhoneContact", [("phone", phone as Any), ("firstName", firstName as Any), ("lastName", lastName as Any), ("date", date as Any)])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static func parse_savedPhoneContact(_ reader: BufferReader) -> SavedContact? {
|
||||||
|
var _1: String?
|
||||||
|
_1 = parseString(reader)
|
||||||
|
var _2: String?
|
||||||
|
_2 = parseString(reader)
|
||||||
|
var _3: String?
|
||||||
|
_3 = parseString(reader)
|
||||||
|
var _4: Int32?
|
||||||
|
_4 = reader.readInt32()
|
||||||
|
let _c1 = _1 != nil
|
||||||
|
let _c2 = _2 != nil
|
||||||
|
let _c3 = _3 != nil
|
||||||
|
let _c4 = _4 != nil
|
||||||
|
if _c1 && _c2 && _c3 && _c4 {
|
||||||
|
return Api.SavedContact.savedPhoneContact(phone: _1!, firstName: _2!, lastName: _3!, date: _4!)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public extension Api {
|
||||||
|
enum SavedDialog: TypeConstructorDescription {
|
||||||
|
case savedDialog(flags: Int32, peer: Api.Peer, topMessage: Int32)
|
||||||
|
|
||||||
|
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||||
|
switch self {
|
||||||
|
case .savedDialog(let flags, let peer, let topMessage):
|
||||||
|
if boxed {
|
||||||
|
buffer.appendInt32(-1115174036)
|
||||||
|
}
|
||||||
|
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||||
|
peer.serialize(buffer, true)
|
||||||
|
serializeInt32(topMessage, buffer: buffer, boxed: false)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||||
|
switch self {
|
||||||
|
case .savedDialog(let flags, let peer, let topMessage):
|
||||||
|
return ("savedDialog", [("flags", flags as Any), ("peer", peer as Any), ("topMessage", topMessage as Any)])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static func parse_savedDialog(_ reader: BufferReader) -> SavedDialog? {
|
||||||
|
var _1: Int32?
|
||||||
|
_1 = reader.readInt32()
|
||||||
|
var _2: Api.Peer?
|
||||||
|
if let signature = reader.readInt32() {
|
||||||
|
_2 = Api.parse(reader, signature: signature) as? Api.Peer
|
||||||
|
}
|
||||||
|
var _3: Int32?
|
||||||
|
_3 = reader.readInt32()
|
||||||
|
let _c1 = _1 != nil
|
||||||
|
let _c2 = _2 != nil
|
||||||
|
let _c3 = _3 != nil
|
||||||
|
if _c1 && _c2 && _c3 {
|
||||||
|
return Api.SavedDialog.savedDialog(flags: _1!, peer: _2!, topMessage: _3!)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public extension Api {
|
||||||
|
enum SavedReactionTag: TypeConstructorDescription {
|
||||||
|
case savedReactionTag(flags: Int32, reaction: Api.Reaction, title: String?, count: Int32)
|
||||||
|
|
||||||
|
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||||
|
switch self {
|
||||||
|
case .savedReactionTag(let flags, let reaction, let title, let count):
|
||||||
|
if boxed {
|
||||||
|
buffer.appendInt32(-881854424)
|
||||||
|
}
|
||||||
|
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||||
|
reaction.serialize(buffer, true)
|
||||||
|
if Int(flags) & Int(1 << 0) != 0 {serializeString(title!, buffer: buffer, boxed: false)}
|
||||||
|
serializeInt32(count, buffer: buffer, boxed: false)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||||
|
switch self {
|
||||||
|
case .savedReactionTag(let flags, let reaction, let title, let count):
|
||||||
|
return ("savedReactionTag", [("flags", flags as Any), ("reaction", reaction as Any), ("title", title as Any), ("count", count as Any)])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static func parse_savedReactionTag(_ reader: BufferReader) -> SavedReactionTag? {
|
||||||
|
var _1: Int32?
|
||||||
|
_1 = reader.readInt32()
|
||||||
|
var _2: Api.Reaction?
|
||||||
|
if let signature = reader.readInt32() {
|
||||||
|
_2 = Api.parse(reader, signature: signature) as? Api.Reaction
|
||||||
|
}
|
||||||
|
var _3: String?
|
||||||
|
if Int(_1!) & Int(1 << 0) != 0 {_3 = parseString(reader) }
|
||||||
|
var _4: Int32?
|
||||||
|
_4 = reader.readInt32()
|
||||||
|
let _c1 = _1 != nil
|
||||||
|
let _c2 = _2 != nil
|
||||||
|
let _c3 = (Int(_1!) & Int(1 << 0) == 0) || _3 != nil
|
||||||
|
let _c4 = _4 != nil
|
||||||
|
if _c1 && _c2 && _c3 && _c4 {
|
||||||
|
return Api.SavedReactionTag.savedReactionTag(flags: _1!, reaction: _2!, title: _3, count: _4!)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public extension Api {
|
||||||
|
enum SearchResultsCalendarPeriod: TypeConstructorDescription {
|
||||||
|
case searchResultsCalendarPeriod(date: Int32, minMsgId: Int32, maxMsgId: Int32, count: Int32)
|
||||||
|
|
||||||
|
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||||
|
switch self {
|
||||||
|
case .searchResultsCalendarPeriod(let date, let minMsgId, let maxMsgId, let count):
|
||||||
|
if boxed {
|
||||||
|
buffer.appendInt32(-911191137)
|
||||||
|
}
|
||||||
|
serializeInt32(date, buffer: buffer, boxed: false)
|
||||||
|
serializeInt32(minMsgId, buffer: buffer, boxed: false)
|
||||||
|
serializeInt32(maxMsgId, buffer: buffer, boxed: false)
|
||||||
|
serializeInt32(count, buffer: buffer, boxed: false)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||||
|
switch self {
|
||||||
|
case .searchResultsCalendarPeriod(let date, let minMsgId, let maxMsgId, let count):
|
||||||
|
return ("searchResultsCalendarPeriod", [("date", date as Any), ("minMsgId", minMsgId as Any), ("maxMsgId", maxMsgId as Any), ("count", count as Any)])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static func parse_searchResultsCalendarPeriod(_ reader: BufferReader) -> SearchResultsCalendarPeriod? {
|
||||||
|
var _1: Int32?
|
||||||
|
_1 = reader.readInt32()
|
||||||
|
var _2: Int32?
|
||||||
|
_2 = reader.readInt32()
|
||||||
|
var _3: Int32?
|
||||||
|
_3 = reader.readInt32()
|
||||||
|
var _4: Int32?
|
||||||
|
_4 = reader.readInt32()
|
||||||
|
let _c1 = _1 != nil
|
||||||
|
let _c2 = _2 != nil
|
||||||
|
let _c3 = _3 != nil
|
||||||
|
let _c4 = _4 != nil
|
||||||
|
if _c1 && _c2 && _c3 && _c4 {
|
||||||
|
return Api.SearchResultsCalendarPeriod.searchResultsCalendarPeriod(date: _1!, minMsgId: _2!, maxMsgId: _3!, count: _4!)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public extension Api {
|
||||||
|
enum SearchResultsPosition: TypeConstructorDescription {
|
||||||
|
case searchResultPosition(msgId: Int32, date: Int32, offset: Int32)
|
||||||
|
|
||||||
|
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||||
|
switch self {
|
||||||
|
case .searchResultPosition(let msgId, let date, let offset):
|
||||||
|
if boxed {
|
||||||
|
buffer.appendInt32(2137295719)
|
||||||
|
}
|
||||||
|
serializeInt32(msgId, buffer: buffer, boxed: false)
|
||||||
|
serializeInt32(date, buffer: buffer, boxed: false)
|
||||||
|
serializeInt32(offset, buffer: buffer, boxed: false)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||||
|
switch self {
|
||||||
|
case .searchResultPosition(let msgId, let date, let offset):
|
||||||
|
return ("searchResultPosition", [("msgId", msgId as Any), ("date", date as Any), ("offset", offset as Any)])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static func parse_searchResultPosition(_ reader: BufferReader) -> SearchResultsPosition? {
|
||||||
|
var _1: Int32?
|
||||||
|
_1 = reader.readInt32()
|
||||||
|
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.SearchResultsPosition.searchResultPosition(msgId: _1!, date: _2!, offset: _3!)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public extension Api {
|
||||||
|
enum SecureCredentialsEncrypted: TypeConstructorDescription {
|
||||||
|
case secureCredentialsEncrypted(data: Buffer, hash: Buffer, secret: Buffer)
|
||||||
|
|
||||||
|
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||||
|
switch self {
|
||||||
|
case .secureCredentialsEncrypted(let data, let hash, let secret):
|
||||||
|
if boxed {
|
||||||
|
buffer.appendInt32(871426631)
|
||||||
|
}
|
||||||
|
serializeBytes(data, buffer: buffer, boxed: false)
|
||||||
|
serializeBytes(hash, buffer: buffer, boxed: false)
|
||||||
|
serializeBytes(secret, buffer: buffer, boxed: false)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||||
|
switch self {
|
||||||
|
case .secureCredentialsEncrypted(let data, let hash, let secret):
|
||||||
|
return ("secureCredentialsEncrypted", [("data", data as Any), ("hash", hash as Any), ("secret", secret as Any)])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static func parse_secureCredentialsEncrypted(_ reader: BufferReader) -> SecureCredentialsEncrypted? {
|
||||||
|
var _1: Buffer?
|
||||||
|
_1 = parseBytes(reader)
|
||||||
|
var _2: Buffer?
|
||||||
|
_2 = parseBytes(reader)
|
||||||
|
var _3: Buffer?
|
||||||
|
_3 = parseBytes(reader)
|
||||||
|
let _c1 = _1 != nil
|
||||||
|
let _c2 = _2 != nil
|
||||||
|
let _c3 = _3 != nil
|
||||||
|
if _c1 && _c2 && _c3 {
|
||||||
|
return Api.SecureCredentialsEncrypted.secureCredentialsEncrypted(data: _1!, hash: _2!, secret: _3!)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public extension Api {
|
||||||
|
enum SecureData: TypeConstructorDescription {
|
||||||
|
case secureData(data: Buffer, dataHash: Buffer, secret: Buffer)
|
||||||
|
|
||||||
|
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||||
|
switch self {
|
||||||
|
case .secureData(let data, let dataHash, let secret):
|
||||||
|
if boxed {
|
||||||
|
buffer.appendInt32(-1964327229)
|
||||||
|
}
|
||||||
|
serializeBytes(data, buffer: buffer, boxed: false)
|
||||||
|
serializeBytes(dataHash, buffer: buffer, boxed: false)
|
||||||
|
serializeBytes(secret, buffer: buffer, boxed: false)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||||
|
switch self {
|
||||||
|
case .secureData(let data, let dataHash, let secret):
|
||||||
|
return ("secureData", [("data", data as Any), ("dataHash", dataHash as Any), ("secret", secret as Any)])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static func parse_secureData(_ reader: BufferReader) -> SecureData? {
|
||||||
|
var _1: Buffer?
|
||||||
|
_1 = parseBytes(reader)
|
||||||
|
var _2: Buffer?
|
||||||
|
_2 = parseBytes(reader)
|
||||||
|
var _3: Buffer?
|
||||||
|
_3 = parseBytes(reader)
|
||||||
|
let _c1 = _1 != nil
|
||||||
|
let _c2 = _2 != nil
|
||||||
|
let _c3 = _3 != nil
|
||||||
|
if _c1 && _c2 && _c3 {
|
||||||
|
return Api.SecureData.secureData(data: _1!, dataHash: _2!, secret: _3!)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public extension Api {
|
||||||
|
enum SecureFile: TypeConstructorDescription {
|
||||||
|
case secureFile(id: Int64, accessHash: Int64, size: Int64, dcId: Int32, date: Int32, fileHash: Buffer, secret: Buffer)
|
||||||
|
case secureFileEmpty
|
||||||
|
|
||||||
|
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||||
|
switch self {
|
||||||
|
case .secureFile(let id, let accessHash, let size, let dcId, let date, let fileHash, let secret):
|
||||||
|
if boxed {
|
||||||
|
buffer.appendInt32(2097791614)
|
||||||
|
}
|
||||||
|
serializeInt64(id, buffer: buffer, boxed: false)
|
||||||
|
serializeInt64(accessHash, buffer: buffer, boxed: false)
|
||||||
|
serializeInt64(size, buffer: buffer, boxed: false)
|
||||||
|
serializeInt32(dcId, buffer: buffer, boxed: false)
|
||||||
|
serializeInt32(date, buffer: buffer, boxed: false)
|
||||||
|
serializeBytes(fileHash, buffer: buffer, boxed: false)
|
||||||
|
serializeBytes(secret, buffer: buffer, boxed: false)
|
||||||
|
break
|
||||||
|
case .secureFileEmpty:
|
||||||
|
if boxed {
|
||||||
|
buffer.appendInt32(1679398724)
|
||||||
|
}
|
||||||
|
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||||
|
switch self {
|
||||||
|
case .secureFile(let id, let accessHash, let size, let dcId, let date, let fileHash, let secret):
|
||||||
|
return ("secureFile", [("id", id as Any), ("accessHash", accessHash as Any), ("size", size as Any), ("dcId", dcId as Any), ("date", date as Any), ("fileHash", fileHash as Any), ("secret", secret as Any)])
|
||||||
|
case .secureFileEmpty:
|
||||||
|
return ("secureFileEmpty", [])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static func parse_secureFile(_ reader: BufferReader) -> SecureFile? {
|
||||||
|
var _1: Int64?
|
||||||
|
_1 = reader.readInt64()
|
||||||
|
var _2: Int64?
|
||||||
|
_2 = reader.readInt64()
|
||||||
|
var _3: Int64?
|
||||||
|
_3 = reader.readInt64()
|
||||||
|
var _4: Int32?
|
||||||
|
_4 = reader.readInt32()
|
||||||
|
var _5: Int32?
|
||||||
|
_5 = reader.readInt32()
|
||||||
|
var _6: Buffer?
|
||||||
|
_6 = parseBytes(reader)
|
||||||
|
var _7: Buffer?
|
||||||
|
_7 = parseBytes(reader)
|
||||||
|
let _c1 = _1 != nil
|
||||||
|
let _c2 = _2 != nil
|
||||||
|
let _c3 = _3 != nil
|
||||||
|
let _c4 = _4 != nil
|
||||||
|
let _c5 = _5 != nil
|
||||||
|
let _c6 = _6 != nil
|
||||||
|
let _c7 = _7 != nil
|
||||||
|
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 {
|
||||||
|
return Api.SecureFile.secureFile(id: _1!, accessHash: _2!, size: _3!, dcId: _4!, date: _5!, fileHash: _6!, secret: _7!)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public static func parse_secureFileEmpty(_ reader: BufferReader) -> SecureFile? {
|
||||||
|
return Api.SecureFile.secureFileEmpty
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
public extension Api {
|
public extension Api {
|
||||||
enum SecurePasswordKdfAlgo: TypeConstructorDescription {
|
enum SecurePasswordKdfAlgo: TypeConstructorDescription {
|
||||||
case securePasswordKdfAlgoPBKDF2HMACSHA512iter100000(salt: Buffer)
|
case securePasswordKdfAlgoPBKDF2HMACSHA512iter100000(salt: Buffer)
|
||||||
|
@ -670,6 +670,102 @@ public extension Api {
|
|||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
public extension Api {
|
||||||
|
enum StarsSubscription: TypeConstructorDescription {
|
||||||
|
case starsSubscription(flags: Int32, id: String, peer: Api.Peer, untilDate: Int32, pricing: Api.StarsSubscriptionPricing)
|
||||||
|
|
||||||
|
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||||
|
switch self {
|
||||||
|
case .starsSubscription(let flags, let id, let peer, let untilDate, let pricing):
|
||||||
|
if boxed {
|
||||||
|
buffer.appendInt32(-797707802)
|
||||||
|
}
|
||||||
|
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||||
|
serializeString(id, buffer: buffer, boxed: false)
|
||||||
|
peer.serialize(buffer, true)
|
||||||
|
serializeInt32(untilDate, buffer: buffer, boxed: false)
|
||||||
|
pricing.serialize(buffer, true)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||||
|
switch self {
|
||||||
|
case .starsSubscription(let flags, let id, let peer, let untilDate, let pricing):
|
||||||
|
return ("starsSubscription", [("flags", flags as Any), ("id", id as Any), ("peer", peer as Any), ("untilDate", untilDate as Any), ("pricing", pricing as Any)])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static func parse_starsSubscription(_ reader: BufferReader) -> StarsSubscription? {
|
||||||
|
var _1: Int32?
|
||||||
|
_1 = reader.readInt32()
|
||||||
|
var _2: String?
|
||||||
|
_2 = parseString(reader)
|
||||||
|
var _3: Api.Peer?
|
||||||
|
if let signature = reader.readInt32() {
|
||||||
|
_3 = Api.parse(reader, signature: signature) as? Api.Peer
|
||||||
|
}
|
||||||
|
var _4: Int32?
|
||||||
|
_4 = reader.readInt32()
|
||||||
|
var _5: Api.StarsSubscriptionPricing?
|
||||||
|
if let signature = reader.readInt32() {
|
||||||
|
_5 = Api.parse(reader, signature: signature) as? Api.StarsSubscriptionPricing
|
||||||
|
}
|
||||||
|
let _c1 = _1 != nil
|
||||||
|
let _c2 = _2 != nil
|
||||||
|
let _c3 = _3 != nil
|
||||||
|
let _c4 = _4 != nil
|
||||||
|
let _c5 = _5 != nil
|
||||||
|
if _c1 && _c2 && _c3 && _c4 && _c5 {
|
||||||
|
return Api.StarsSubscription.starsSubscription(flags: _1!, id: _2!, peer: _3!, untilDate: _4!, pricing: _5!)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public extension Api {
|
||||||
|
enum StarsSubscriptionPricing: TypeConstructorDescription {
|
||||||
|
case starsSubscriptionPricing(period: Int32, amount: Int64)
|
||||||
|
|
||||||
|
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||||
|
switch self {
|
||||||
|
case .starsSubscriptionPricing(let period, let amount):
|
||||||
|
if boxed {
|
||||||
|
buffer.appendInt32(88173912)
|
||||||
|
}
|
||||||
|
serializeInt32(period, buffer: buffer, boxed: false)
|
||||||
|
serializeInt64(amount, buffer: buffer, boxed: false)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||||
|
switch self {
|
||||||
|
case .starsSubscriptionPricing(let period, let amount):
|
||||||
|
return ("starsSubscriptionPricing", [("period", period as Any), ("amount", amount as Any)])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static func parse_starsSubscriptionPricing(_ reader: BufferReader) -> StarsSubscriptionPricing? {
|
||||||
|
var _1: Int32?
|
||||||
|
_1 = reader.readInt32()
|
||||||
|
var _2: Int64?
|
||||||
|
_2 = reader.readInt64()
|
||||||
|
let _c1 = _1 != nil
|
||||||
|
let _c2 = _2 != nil
|
||||||
|
if _c1 && _c2 {
|
||||||
|
return Api.StarsSubscriptionPricing.starsSubscriptionPricing(period: _1!, amount: _2!)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
public extension Api {
|
public extension Api {
|
||||||
enum StarsTopupOption: TypeConstructorDescription {
|
enum StarsTopupOption: TypeConstructorDescription {
|
||||||
case starsTopupOption(flags: Int32, stars: Int64, storeProduct: String?, currency: String, amount: Int64)
|
case starsTopupOption(flags: Int32, stars: Int64, storeProduct: String?, currency: String, amount: Int64)
|
||||||
@ -724,13 +820,13 @@ public extension Api {
|
|||||||
}
|
}
|
||||||
public extension Api {
|
public extension Api {
|
||||||
enum StarsTransaction: TypeConstructorDescription {
|
enum StarsTransaction: TypeConstructorDescription {
|
||||||
case starsTransaction(flags: Int32, id: String, stars: Int64, date: Int32, peer: Api.StarsTransactionPeer, title: String?, description: String?, photo: Api.WebDocument?, transactionDate: Int32?, transactionUrl: String?, botPayload: Buffer?, msgId: Int32?, extendedMedia: [Api.MessageMedia]?)
|
case starsTransaction(flags: Int32, id: String, stars: Int64, date: Int32, peer: Api.StarsTransactionPeer, title: String?, description: String?, photo: Api.WebDocument?, transactionDate: Int32?, transactionUrl: String?, botPayload: Buffer?, msgId: Int32?, extendedMedia: [Api.MessageMedia]?, subscriptionPeriod: Int32?)
|
||||||
|
|
||||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||||
switch self {
|
switch self {
|
||||||
case .starsTransaction(let flags, let id, let stars, let date, let peer, let title, let description, let photo, let transactionDate, let transactionUrl, let botPayload, let msgId, let extendedMedia):
|
case .starsTransaction(let flags, let id, let stars, let date, let peer, let title, let description, let photo, let transactionDate, let transactionUrl, let botPayload, let msgId, let extendedMedia, let subscriptionPeriod):
|
||||||
if boxed {
|
if boxed {
|
||||||
buffer.appendInt32(766853519)
|
buffer.appendInt32(1127934763)
|
||||||
}
|
}
|
||||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||||
serializeString(id, buffer: buffer, boxed: false)
|
serializeString(id, buffer: buffer, boxed: false)
|
||||||
@ -749,14 +845,15 @@ public extension Api {
|
|||||||
for item in extendedMedia! {
|
for item in extendedMedia! {
|
||||||
item.serialize(buffer, true)
|
item.serialize(buffer, true)
|
||||||
}}
|
}}
|
||||||
|
if Int(flags) & Int(1 << 12) != 0 {serializeInt32(subscriptionPeriod!, buffer: buffer, boxed: false)}
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||||
switch self {
|
switch self {
|
||||||
case .starsTransaction(let flags, let id, let stars, let date, let peer, let title, let description, let photo, let transactionDate, let transactionUrl, let botPayload, let msgId, let extendedMedia):
|
case .starsTransaction(let flags, let id, let stars, let date, let peer, let title, let description, let photo, let transactionDate, let transactionUrl, let botPayload, let msgId, let extendedMedia, let subscriptionPeriod):
|
||||||
return ("starsTransaction", [("flags", flags as Any), ("id", id as Any), ("stars", stars as Any), ("date", date as Any), ("peer", peer as Any), ("title", title as Any), ("description", description as Any), ("photo", photo as Any), ("transactionDate", transactionDate as Any), ("transactionUrl", transactionUrl as Any), ("botPayload", botPayload as Any), ("msgId", msgId as Any), ("extendedMedia", extendedMedia as Any)])
|
return ("starsTransaction", [("flags", flags as Any), ("id", id as Any), ("stars", stars as Any), ("date", date as Any), ("peer", peer as Any), ("title", title as Any), ("description", description as Any), ("photo", photo as Any), ("transactionDate", transactionDate as Any), ("transactionUrl", transactionUrl as Any), ("botPayload", botPayload as Any), ("msgId", msgId as Any), ("extendedMedia", extendedMedia as Any), ("subscriptionPeriod", subscriptionPeriod as Any)])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -793,6 +890,8 @@ public extension Api {
|
|||||||
if Int(_1!) & Int(1 << 9) != 0 {if let _ = reader.readInt32() {
|
if Int(_1!) & Int(1 << 9) != 0 {if let _ = reader.readInt32() {
|
||||||
_13 = Api.parseVector(reader, elementSignature: 0, elementType: Api.MessageMedia.self)
|
_13 = Api.parseVector(reader, elementSignature: 0, elementType: Api.MessageMedia.self)
|
||||||
} }
|
} }
|
||||||
|
var _14: Int32?
|
||||||
|
if Int(_1!) & Int(1 << 12) != 0 {_14 = reader.readInt32() }
|
||||||
let _c1 = _1 != nil
|
let _c1 = _1 != nil
|
||||||
let _c2 = _2 != nil
|
let _c2 = _2 != nil
|
||||||
let _c3 = _3 != nil
|
let _c3 = _3 != nil
|
||||||
@ -806,8 +905,9 @@ public extension Api {
|
|||||||
let _c11 = (Int(_1!) & Int(1 << 7) == 0) || _11 != nil
|
let _c11 = (Int(_1!) & Int(1 << 7) == 0) || _11 != nil
|
||||||
let _c12 = (Int(_1!) & Int(1 << 8) == 0) || _12 != nil
|
let _c12 = (Int(_1!) & Int(1 << 8) == 0) || _12 != nil
|
||||||
let _c13 = (Int(_1!) & Int(1 << 9) == 0) || _13 != nil
|
let _c13 = (Int(_1!) & Int(1 << 9) == 0) || _13 != nil
|
||||||
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 && _c9 && _c10 && _c11 && _c12 && _c13 {
|
let _c14 = (Int(_1!) & Int(1 << 12) == 0) || _14 != nil
|
||||||
return Api.StarsTransaction.starsTransaction(flags: _1!, id: _2!, stars: _3!, date: _4!, peer: _5!, title: _6, description: _7, photo: _8, transactionDate: _9, transactionUrl: _10, botPayload: _11, msgId: _12, extendedMedia: _13)
|
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 && _c9 && _c10 && _c11 && _c12 && _c13 && _c14 {
|
||||||
|
return Api.StarsTransaction.starsTransaction(flags: _1!, id: _2!, stars: _3!, date: _4!, peer: _5!, title: _6, description: _7, photo: _8, transactionDate: _9, transactionUrl: _10, botPayload: _11, msgId: _12, extendedMedia: _13, subscriptionPeriod: _14)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return nil
|
return nil
|
||||||
|
@ -1246,21 +1246,28 @@ public extension Api.payments {
|
|||||||
}
|
}
|
||||||
public extension Api.payments {
|
public extension Api.payments {
|
||||||
enum StarsStatus: TypeConstructorDescription {
|
enum StarsStatus: TypeConstructorDescription {
|
||||||
case starsStatus(flags: Int32, balance: Int64, history: [Api.StarsTransaction], nextOffset: String?, chats: [Api.Chat], users: [Api.User])
|
case starsStatus(flags: Int32, balance: Int64, subscriptions: [Api.StarsSubscription]?, subscriptionsNextOffset: String?, subscriptionsMissingBalance: Int64?, history: [Api.StarsTransaction]?, nextOffset: String?, chats: [Api.Chat], users: [Api.User])
|
||||||
|
|
||||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||||
switch self {
|
switch self {
|
||||||
case .starsStatus(let flags, let balance, let history, let nextOffset, let chats, let users):
|
case .starsStatus(let flags, let balance, let subscriptions, let subscriptionsNextOffset, let subscriptionsMissingBalance, let history, let nextOffset, let chats, let users):
|
||||||
if boxed {
|
if boxed {
|
||||||
buffer.appendInt32(-1930105248)
|
buffer.appendInt32(-1141231252)
|
||||||
}
|
}
|
||||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||||
serializeInt64(balance, buffer: buffer, boxed: false)
|
serializeInt64(balance, buffer: buffer, boxed: false)
|
||||||
buffer.appendInt32(481674261)
|
if Int(flags) & Int(1 << 1) != 0 {buffer.appendInt32(481674261)
|
||||||
buffer.appendInt32(Int32(history.count))
|
buffer.appendInt32(Int32(subscriptions!.count))
|
||||||
for item in history {
|
for item in subscriptions! {
|
||||||
item.serialize(buffer, true)
|
item.serialize(buffer, true)
|
||||||
}
|
}}
|
||||||
|
if Int(flags) & Int(1 << 2) != 0 {serializeString(subscriptionsNextOffset!, buffer: buffer, boxed: false)}
|
||||||
|
if Int(flags) & Int(1 << 4) != 0 {serializeInt64(subscriptionsMissingBalance!, buffer: buffer, boxed: false)}
|
||||||
|
if Int(flags) & Int(1 << 3) != 0 {buffer.appendInt32(481674261)
|
||||||
|
buffer.appendInt32(Int32(history!.count))
|
||||||
|
for item in history! {
|
||||||
|
item.serialize(buffer, true)
|
||||||
|
}}
|
||||||
if Int(flags) & Int(1 << 0) != 0 {serializeString(nextOffset!, buffer: buffer, boxed: false)}
|
if Int(flags) & Int(1 << 0) != 0 {serializeString(nextOffset!, buffer: buffer, boxed: false)}
|
||||||
buffer.appendInt32(481674261)
|
buffer.appendInt32(481674261)
|
||||||
buffer.appendInt32(Int32(chats.count))
|
buffer.appendInt32(Int32(chats.count))
|
||||||
@ -1278,8 +1285,8 @@ public extension Api.payments {
|
|||||||
|
|
||||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||||
switch self {
|
switch self {
|
||||||
case .starsStatus(let flags, let balance, let history, let nextOffset, let chats, let users):
|
case .starsStatus(let flags, let balance, let subscriptions, let subscriptionsNextOffset, let subscriptionsMissingBalance, let history, let nextOffset, let chats, let users):
|
||||||
return ("starsStatus", [("flags", flags as Any), ("balance", balance as Any), ("history", history as Any), ("nextOffset", nextOffset as Any), ("chats", chats as Any), ("users", users as Any)])
|
return ("starsStatus", [("flags", flags as Any), ("balance", balance as Any), ("subscriptions", subscriptions as Any), ("subscriptionsNextOffset", subscriptionsNextOffset as Any), ("subscriptionsMissingBalance", subscriptionsMissingBalance as Any), ("history", history as Any), ("nextOffset", nextOffset as Any), ("chats", chats as Any), ("users", users as Any)])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1288,28 +1295,39 @@ public extension Api.payments {
|
|||||||
_1 = reader.readInt32()
|
_1 = reader.readInt32()
|
||||||
var _2: Int64?
|
var _2: Int64?
|
||||||
_2 = reader.readInt64()
|
_2 = reader.readInt64()
|
||||||
var _3: [Api.StarsTransaction]?
|
var _3: [Api.StarsSubscription]?
|
||||||
if let _ = reader.readInt32() {
|
if Int(_1!) & Int(1 << 1) != 0 {if let _ = reader.readInt32() {
|
||||||
_3 = Api.parseVector(reader, elementSignature: 0, elementType: Api.StarsTransaction.self)
|
_3 = Api.parseVector(reader, elementSignature: 0, elementType: Api.StarsSubscription.self)
|
||||||
}
|
} }
|
||||||
var _4: String?
|
var _4: String?
|
||||||
if Int(_1!) & Int(1 << 0) != 0 {_4 = parseString(reader) }
|
if Int(_1!) & Int(1 << 2) != 0 {_4 = parseString(reader) }
|
||||||
var _5: [Api.Chat]?
|
var _5: Int64?
|
||||||
|
if Int(_1!) & Int(1 << 4) != 0 {_5 = reader.readInt64() }
|
||||||
|
var _6: [Api.StarsTransaction]?
|
||||||
|
if Int(_1!) & Int(1 << 3) != 0 {if let _ = reader.readInt32() {
|
||||||
|
_6 = Api.parseVector(reader, elementSignature: 0, elementType: Api.StarsTransaction.self)
|
||||||
|
} }
|
||||||
|
var _7: String?
|
||||||
|
if Int(_1!) & Int(1 << 0) != 0 {_7 = parseString(reader) }
|
||||||
|
var _8: [Api.Chat]?
|
||||||
if let _ = reader.readInt32() {
|
if let _ = reader.readInt32() {
|
||||||
_5 = Api.parseVector(reader, elementSignature: 0, elementType: Api.Chat.self)
|
_8 = Api.parseVector(reader, elementSignature: 0, elementType: Api.Chat.self)
|
||||||
}
|
}
|
||||||
var _6: [Api.User]?
|
var _9: [Api.User]?
|
||||||
if let _ = reader.readInt32() {
|
if let _ = reader.readInt32() {
|
||||||
_6 = Api.parseVector(reader, elementSignature: 0, elementType: Api.User.self)
|
_9 = Api.parseVector(reader, elementSignature: 0, elementType: Api.User.self)
|
||||||
}
|
}
|
||||||
let _c1 = _1 != nil
|
let _c1 = _1 != nil
|
||||||
let _c2 = _2 != nil
|
let _c2 = _2 != nil
|
||||||
let _c3 = _3 != nil
|
let _c3 = (Int(_1!) & Int(1 << 1) == 0) || _3 != nil
|
||||||
let _c4 = (Int(_1!) & Int(1 << 0) == 0) || _4 != nil
|
let _c4 = (Int(_1!) & Int(1 << 2) == 0) || _4 != nil
|
||||||
let _c5 = _5 != nil
|
let _c5 = (Int(_1!) & Int(1 << 4) == 0) || _5 != nil
|
||||||
let _c6 = _6 != nil
|
let _c6 = (Int(_1!) & Int(1 << 3) == 0) || _6 != nil
|
||||||
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 {
|
let _c7 = (Int(_1!) & Int(1 << 0) == 0) || _7 != nil
|
||||||
return Api.payments.StarsStatus.starsStatus(flags: _1!, balance: _2!, history: _3!, nextOffset: _4, chats: _5!, users: _6!)
|
let _c8 = _8 != nil
|
||||||
|
let _c9 = _9 != nil
|
||||||
|
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 && _c9 {
|
||||||
|
return Api.payments.StarsStatus.starsStatus(flags: _1!, balance: _2!, subscriptions: _3, subscriptionsNextOffset: _4, subscriptionsMissingBalance: _5, history: _6, nextOffset: _7, chats: _8!, users: _9!)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return nil
|
return nil
|
||||||
|
@ -5439,15 +5439,16 @@ public extension Api.functions.messages {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
public extension Api.functions.messages {
|
public extension Api.functions.messages {
|
||||||
static func exportChatInvite(flags: Int32, peer: Api.InputPeer, expireDate: Int32?, usageLimit: Int32?, title: String?) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.ExportedChatInvite>) {
|
static func exportChatInvite(flags: Int32, peer: Api.InputPeer, expireDate: Int32?, usageLimit: Int32?, title: String?, subscriptionPricing: Api.StarsSubscriptionPricing?) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.ExportedChatInvite>) {
|
||||||
let buffer = Buffer()
|
let buffer = Buffer()
|
||||||
buffer.appendInt32(-1607670315)
|
buffer.appendInt32(-1537876336)
|
||||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||||
peer.serialize(buffer, true)
|
peer.serialize(buffer, true)
|
||||||
if Int(flags) & Int(1 << 0) != 0 {serializeInt32(expireDate!, buffer: buffer, boxed: false)}
|
if Int(flags) & Int(1 << 0) != 0 {serializeInt32(expireDate!, buffer: buffer, boxed: false)}
|
||||||
if Int(flags) & Int(1 << 1) != 0 {serializeInt32(usageLimit!, buffer: buffer, boxed: false)}
|
if Int(flags) & Int(1 << 1) != 0 {serializeInt32(usageLimit!, buffer: buffer, boxed: false)}
|
||||||
if Int(flags) & Int(1 << 4) != 0 {serializeString(title!, buffer: buffer, boxed: false)}
|
if Int(flags) & Int(1 << 4) != 0 {serializeString(title!, buffer: buffer, boxed: false)}
|
||||||
return (FunctionDescription(name: "messages.exportChatInvite", parameters: [("flags", String(describing: flags)), ("peer", String(describing: peer)), ("expireDate", String(describing: expireDate)), ("usageLimit", String(describing: usageLimit)), ("title", String(describing: title))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.ExportedChatInvite? in
|
if Int(flags) & Int(1 << 5) != 0 {subscriptionPricing!.serialize(buffer, true)}
|
||||||
|
return (FunctionDescription(name: "messages.exportChatInvite", parameters: [("flags", String(describing: flags)), ("peer", String(describing: peer)), ("expireDate", String(describing: expireDate)), ("usageLimit", String(describing: usageLimit)), ("title", String(describing: title)), ("subscriptionPricing", String(describing: subscriptionPricing))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.ExportedChatInvite? in
|
||||||
let reader = BufferReader(buffer)
|
let reader = BufferReader(buffer)
|
||||||
var result: Api.ExportedChatInvite?
|
var result: Api.ExportedChatInvite?
|
||||||
if let signature = reader.readInt32() {
|
if let signature = reader.readInt32() {
|
||||||
@ -7933,6 +7934,24 @@ public extension Api.functions.messages {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
public extension Api.functions.messages {
|
||||||
|
static func sendPaidReaction(peer: Api.InputPeer, msgId: Int32, count: Int32, randomId: Int64) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Updates>) {
|
||||||
|
let buffer = Buffer()
|
||||||
|
buffer.appendInt32(508941107)
|
||||||
|
peer.serialize(buffer, true)
|
||||||
|
serializeInt32(msgId, buffer: buffer, boxed: false)
|
||||||
|
serializeInt32(count, buffer: buffer, boxed: false)
|
||||||
|
serializeInt64(randomId, buffer: buffer, boxed: false)
|
||||||
|
return (FunctionDescription(name: "messages.sendPaidReaction", parameters: [("peer", String(describing: peer)), ("msgId", String(describing: msgId)), ("count", String(describing: count)), ("randomId", String(describing: randomId))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.Updates? in
|
||||||
|
let reader = BufferReader(buffer)
|
||||||
|
var result: Api.Updates?
|
||||||
|
if let signature = reader.readInt32() {
|
||||||
|
result = Api.parse(reader, signature: signature) as? Api.Updates
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
public extension Api.functions.messages {
|
public extension Api.functions.messages {
|
||||||
static func sendQuickReplyMessages(peer: Api.InputPeer, shortcutId: Int32, id: [Int32], randomId: [Int64]) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Updates>) {
|
static func sendQuickReplyMessages(peer: Api.InputPeer, shortcutId: Int32, id: [Int32], randomId: [Int64]) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Updates>) {
|
||||||
let buffer = Buffer()
|
let buffer = Buffer()
|
||||||
@ -8132,14 +8151,15 @@ public extension Api.functions.messages {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
public extension Api.functions.messages {
|
public extension Api.functions.messages {
|
||||||
static func setChatAvailableReactions(flags: Int32, peer: Api.InputPeer, availableReactions: Api.ChatReactions, reactionsLimit: Int32?) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Updates>) {
|
static func setChatAvailableReactions(flags: Int32, peer: Api.InputPeer, availableReactions: Api.ChatReactions, reactionsLimit: Int32?, paidEnabled: Api.Bool?) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Updates>) {
|
||||||
let buffer = Buffer()
|
let buffer = Buffer()
|
||||||
buffer.appendInt32(1511328724)
|
buffer.appendInt32(-2041895551)
|
||||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||||
peer.serialize(buffer, true)
|
peer.serialize(buffer, true)
|
||||||
availableReactions.serialize(buffer, true)
|
availableReactions.serialize(buffer, true)
|
||||||
if Int(flags) & Int(1 << 0) != 0 {serializeInt32(reactionsLimit!, buffer: buffer, boxed: false)}
|
if Int(flags) & Int(1 << 0) != 0 {serializeInt32(reactionsLimit!, buffer: buffer, boxed: false)}
|
||||||
return (FunctionDescription(name: "messages.setChatAvailableReactions", parameters: [("flags", String(describing: flags)), ("peer", String(describing: peer)), ("availableReactions", String(describing: availableReactions)), ("reactionsLimit", String(describing: reactionsLimit))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.Updates? in
|
if Int(flags) & Int(1 << 1) != 0 {paidEnabled!.serialize(buffer, true)}
|
||||||
|
return (FunctionDescription(name: "messages.setChatAvailableReactions", parameters: [("flags", String(describing: flags)), ("peer", String(describing: peer)), ("availableReactions", String(describing: availableReactions)), ("reactionsLimit", String(describing: reactionsLimit)), ("paidEnabled", String(describing: paidEnabled))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.Updates? in
|
||||||
let reader = BufferReader(buffer)
|
let reader = BufferReader(buffer)
|
||||||
var result: Api.Updates?
|
var result: Api.Updates?
|
||||||
if let signature = reader.readInt32() {
|
if let signature = reader.readInt32() {
|
||||||
@ -8735,6 +8755,24 @@ public extension Api.functions.payments {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
public extension Api.functions.payments {
|
||||||
|
static func changeStarsSubscription(flags: Int32, peer: Api.InputPeer, subscriptionId: String, canceled: Api.Bool?) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Bool>) {
|
||||||
|
let buffer = Buffer()
|
||||||
|
buffer.appendInt32(-948500360)
|
||||||
|
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||||
|
peer.serialize(buffer, true)
|
||||||
|
serializeString(subscriptionId, buffer: buffer, boxed: false)
|
||||||
|
if Int(flags) & Int(1 << 0) != 0 {canceled!.serialize(buffer, true)}
|
||||||
|
return (FunctionDescription(name: "payments.changeStarsSubscription", parameters: [("flags", String(describing: flags)), ("peer", String(describing: peer)), ("subscriptionId", String(describing: subscriptionId)), ("canceled", String(describing: canceled))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.Bool? in
|
||||||
|
let reader = BufferReader(buffer)
|
||||||
|
var result: Api.Bool?
|
||||||
|
if let signature = reader.readInt32() {
|
||||||
|
result = Api.parse(reader, signature: signature) as? Api.Bool
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
public extension Api.functions.payments {
|
public extension Api.functions.payments {
|
||||||
static func checkGiftCode(slug: String) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.payments.CheckedGiftCode>) {
|
static func checkGiftCode(slug: String) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.payments.CheckedGiftCode>) {
|
||||||
let buffer = Buffer()
|
let buffer = Buffer()
|
||||||
@ -8780,6 +8818,22 @@ public extension Api.functions.payments {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
public extension Api.functions.payments {
|
||||||
|
static func fulfillStarsSubscription(peer: Api.InputPeer, subscriptionId: String) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Bool>) {
|
||||||
|
let buffer = Buffer()
|
||||||
|
buffer.appendInt32(-866391117)
|
||||||
|
peer.serialize(buffer, true)
|
||||||
|
serializeString(subscriptionId, buffer: buffer, boxed: false)
|
||||||
|
return (FunctionDescription(name: "payments.fulfillStarsSubscription", parameters: [("peer", String(describing: peer)), ("subscriptionId", String(describing: subscriptionId))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.Bool? in
|
||||||
|
let reader = BufferReader(buffer)
|
||||||
|
var result: Api.Bool?
|
||||||
|
if let signature = reader.readInt32() {
|
||||||
|
result = Api.parse(reader, signature: signature) as? Api.Bool
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
public extension Api.functions.payments {
|
public extension Api.functions.payments {
|
||||||
static func getBankCardData(number: String) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.payments.BankCardData>) {
|
static func getBankCardData(number: String) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.payments.BankCardData>) {
|
||||||
let buffer = Buffer()
|
let buffer = Buffer()
|
||||||
@ -8954,6 +9008,23 @@ public extension Api.functions.payments {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
public extension Api.functions.payments {
|
||||||
|
static func getStarsSubscriptions(flags: Int32, peer: Api.InputPeer, offset: String) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.payments.StarsStatus>) {
|
||||||
|
let buffer = Buffer()
|
||||||
|
buffer.appendInt32(52761285)
|
||||||
|
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||||
|
peer.serialize(buffer, true)
|
||||||
|
serializeString(offset, buffer: buffer, boxed: false)
|
||||||
|
return (FunctionDescription(name: "payments.getStarsSubscriptions", parameters: [("flags", String(describing: flags)), ("peer", String(describing: peer)), ("offset", String(describing: offset))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.payments.StarsStatus? in
|
||||||
|
let reader = BufferReader(buffer)
|
||||||
|
var result: Api.payments.StarsStatus?
|
||||||
|
if let signature = reader.readInt32() {
|
||||||
|
result = Api.parse(reader, signature: signature) as? Api.payments.StarsStatus
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
public extension Api.functions.payments {
|
public extension Api.functions.payments {
|
||||||
static func getStarsTopupOptions() -> (FunctionDescription, Buffer, DeserializeFunctionResponse<[Api.StarsTopupOption]>) {
|
static func getStarsTopupOptions() -> (FunctionDescription, Buffer, DeserializeFunctionResponse<[Api.StarsTopupOption]>) {
|
||||||
let buffer = Buffer()
|
let buffer = Buffer()
|
||||||
@ -8970,14 +9041,15 @@ public extension Api.functions.payments {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
public extension Api.functions.payments {
|
public extension Api.functions.payments {
|
||||||
static func getStarsTransactions(flags: Int32, peer: Api.InputPeer, offset: String, limit: Int32) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.payments.StarsStatus>) {
|
static func getStarsTransactions(flags: Int32, subscriptionId: String?, peer: Api.InputPeer, offset: String, limit: Int32) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.payments.StarsStatus>) {
|
||||||
let buffer = Buffer()
|
let buffer = Buffer()
|
||||||
buffer.appendInt32(-1751937702)
|
buffer.appendInt32(1775912279)
|
||||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||||
|
if Int(flags) & Int(1 << 3) != 0 {serializeString(subscriptionId!, buffer: buffer, boxed: false)}
|
||||||
peer.serialize(buffer, true)
|
peer.serialize(buffer, true)
|
||||||
serializeString(offset, buffer: buffer, boxed: false)
|
serializeString(offset, buffer: buffer, boxed: false)
|
||||||
serializeInt32(limit, buffer: buffer, boxed: false)
|
serializeInt32(limit, buffer: buffer, boxed: false)
|
||||||
return (FunctionDescription(name: "payments.getStarsTransactions", parameters: [("flags", String(describing: flags)), ("peer", String(describing: peer)), ("offset", String(describing: offset)), ("limit", String(describing: limit))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.payments.StarsStatus? in
|
return (FunctionDescription(name: "payments.getStarsTransactions", parameters: [("flags", String(describing: flags)), ("subscriptionId", String(describing: subscriptionId)), ("peer", String(describing: peer)), ("offset", String(describing: offset)), ("limit", String(describing: limit))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.payments.StarsStatus? in
|
||||||
let reader = BufferReader(buffer)
|
let reader = BufferReader(buffer)
|
||||||
var result: Api.payments.StarsStatus?
|
var result: Api.payments.StarsStatus?
|
||||||
if let signature = reader.readInt32() {
|
if let signature = reader.readInt32() {
|
||||||
|
@ -148,21 +148,23 @@ public extension Api {
|
|||||||
}
|
}
|
||||||
public extension Api {
|
public extension Api {
|
||||||
enum ChannelParticipant: TypeConstructorDescription {
|
enum ChannelParticipant: TypeConstructorDescription {
|
||||||
case channelParticipant(userId: Int64, date: Int32)
|
case channelParticipant(flags: Int32, userId: Int64, date: Int32, subscriptionUntilDate: Int32?)
|
||||||
case channelParticipantAdmin(flags: Int32, userId: Int64, inviterId: Int64?, promotedBy: Int64, date: Int32, adminRights: Api.ChatAdminRights, rank: String?)
|
case channelParticipantAdmin(flags: Int32, userId: Int64, inviterId: Int64?, promotedBy: Int64, date: Int32, adminRights: Api.ChatAdminRights, rank: String?)
|
||||||
case channelParticipantBanned(flags: Int32, peer: Api.Peer, kickedBy: Int64, date: Int32, bannedRights: Api.ChatBannedRights)
|
case channelParticipantBanned(flags: Int32, peer: Api.Peer, kickedBy: Int64, date: Int32, bannedRights: Api.ChatBannedRights)
|
||||||
case channelParticipantCreator(flags: Int32, userId: Int64, adminRights: Api.ChatAdminRights, rank: String?)
|
case channelParticipantCreator(flags: Int32, userId: Int64, adminRights: Api.ChatAdminRights, rank: String?)
|
||||||
case channelParticipantLeft(peer: Api.Peer)
|
case channelParticipantLeft(peer: Api.Peer)
|
||||||
case channelParticipantSelf(flags: Int32, userId: Int64, inviterId: Int64, date: Int32)
|
case channelParticipantSelf(flags: Int32, userId: Int64, inviterId: Int64, date: Int32, subscriptionUntilDate: Int32?)
|
||||||
|
|
||||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||||
switch self {
|
switch self {
|
||||||
case .channelParticipant(let userId, let date):
|
case .channelParticipant(let flags, let userId, let date, let subscriptionUntilDate):
|
||||||
if boxed {
|
if boxed {
|
||||||
buffer.appendInt32(-1072953408)
|
buffer.appendInt32(-885426663)
|
||||||
}
|
}
|
||||||
|
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||||
serializeInt64(userId, buffer: buffer, boxed: false)
|
serializeInt64(userId, buffer: buffer, boxed: false)
|
||||||
serializeInt32(date, buffer: buffer, boxed: false)
|
serializeInt32(date, buffer: buffer, boxed: false)
|
||||||
|
if Int(flags) & Int(1 << 0) != 0 {serializeInt32(subscriptionUntilDate!, buffer: buffer, boxed: false)}
|
||||||
break
|
break
|
||||||
case .channelParticipantAdmin(let flags, let userId, let inviterId, let promotedBy, let date, let adminRights, let rank):
|
case .channelParticipantAdmin(let flags, let userId, let inviterId, let promotedBy, let date, let adminRights, let rank):
|
||||||
if boxed {
|
if boxed {
|
||||||
@ -201,22 +203,23 @@ public extension Api {
|
|||||||
}
|
}
|
||||||
peer.serialize(buffer, true)
|
peer.serialize(buffer, true)
|
||||||
break
|
break
|
||||||
case .channelParticipantSelf(let flags, let userId, let inviterId, let date):
|
case .channelParticipantSelf(let flags, let userId, let inviterId, let date, let subscriptionUntilDate):
|
||||||
if boxed {
|
if boxed {
|
||||||
buffer.appendInt32(900251559)
|
buffer.appendInt32(1331723247)
|
||||||
}
|
}
|
||||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||||
serializeInt64(userId, buffer: buffer, boxed: false)
|
serializeInt64(userId, buffer: buffer, boxed: false)
|
||||||
serializeInt64(inviterId, buffer: buffer, boxed: false)
|
serializeInt64(inviterId, buffer: buffer, boxed: false)
|
||||||
serializeInt32(date, buffer: buffer, boxed: false)
|
serializeInt32(date, buffer: buffer, boxed: false)
|
||||||
|
if Int(flags) & Int(1 << 1) != 0 {serializeInt32(subscriptionUntilDate!, buffer: buffer, boxed: false)}
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||||
switch self {
|
switch self {
|
||||||
case .channelParticipant(let userId, let date):
|
case .channelParticipant(let flags, let userId, let date, let subscriptionUntilDate):
|
||||||
return ("channelParticipant", [("userId", userId as Any), ("date", date as Any)])
|
return ("channelParticipant", [("flags", flags as Any), ("userId", userId as Any), ("date", date as Any), ("subscriptionUntilDate", subscriptionUntilDate as Any)])
|
||||||
case .channelParticipantAdmin(let flags, let userId, let inviterId, let promotedBy, let date, let adminRights, let rank):
|
case .channelParticipantAdmin(let flags, let userId, let inviterId, let promotedBy, let date, let adminRights, let rank):
|
||||||
return ("channelParticipantAdmin", [("flags", flags as Any), ("userId", userId as Any), ("inviterId", inviterId as Any), ("promotedBy", promotedBy as Any), ("date", date as Any), ("adminRights", adminRights as Any), ("rank", rank as Any)])
|
return ("channelParticipantAdmin", [("flags", flags as Any), ("userId", userId as Any), ("inviterId", inviterId as Any), ("promotedBy", promotedBy as Any), ("date", date as Any), ("adminRights", adminRights as Any), ("rank", rank as Any)])
|
||||||
case .channelParticipantBanned(let flags, let peer, let kickedBy, let date, let bannedRights):
|
case .channelParticipantBanned(let flags, let peer, let kickedBy, let date, let bannedRights):
|
||||||
@ -225,20 +228,26 @@ public extension Api {
|
|||||||
return ("channelParticipantCreator", [("flags", flags as Any), ("userId", userId as Any), ("adminRights", adminRights as Any), ("rank", rank as Any)])
|
return ("channelParticipantCreator", [("flags", flags as Any), ("userId", userId as Any), ("adminRights", adminRights as Any), ("rank", rank as Any)])
|
||||||
case .channelParticipantLeft(let peer):
|
case .channelParticipantLeft(let peer):
|
||||||
return ("channelParticipantLeft", [("peer", peer as Any)])
|
return ("channelParticipantLeft", [("peer", peer as Any)])
|
||||||
case .channelParticipantSelf(let flags, let userId, let inviterId, let date):
|
case .channelParticipantSelf(let flags, let userId, let inviterId, let date, let subscriptionUntilDate):
|
||||||
return ("channelParticipantSelf", [("flags", flags as Any), ("userId", userId as Any), ("inviterId", inviterId as Any), ("date", date as Any)])
|
return ("channelParticipantSelf", [("flags", flags as Any), ("userId", userId as Any), ("inviterId", inviterId as Any), ("date", date as Any), ("subscriptionUntilDate", subscriptionUntilDate as Any)])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static func parse_channelParticipant(_ reader: BufferReader) -> ChannelParticipant? {
|
public static func parse_channelParticipant(_ reader: BufferReader) -> ChannelParticipant? {
|
||||||
var _1: Int64?
|
var _1: Int32?
|
||||||
_1 = reader.readInt64()
|
_1 = reader.readInt32()
|
||||||
var _2: Int32?
|
var _2: Int64?
|
||||||
_2 = reader.readInt32()
|
_2 = reader.readInt64()
|
||||||
|
var _3: Int32?
|
||||||
|
_3 = reader.readInt32()
|
||||||
|
var _4: Int32?
|
||||||
|
if Int(_1!) & Int(1 << 0) != 0 {_4 = reader.readInt32() }
|
||||||
let _c1 = _1 != nil
|
let _c1 = _1 != nil
|
||||||
let _c2 = _2 != nil
|
let _c2 = _2 != nil
|
||||||
if _c1 && _c2 {
|
let _c3 = _3 != nil
|
||||||
return Api.ChannelParticipant.channelParticipant(userId: _1!, date: _2!)
|
let _c4 = (Int(_1!) & Int(1 << 0) == 0) || _4 != nil
|
||||||
|
if _c1 && _c2 && _c3 && _c4 {
|
||||||
|
return Api.ChannelParticipant.channelParticipant(flags: _1!, userId: _2!, date: _3!, subscriptionUntilDate: _4)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return nil
|
return nil
|
||||||
@ -346,12 +355,15 @@ public extension Api {
|
|||||||
_3 = reader.readInt64()
|
_3 = reader.readInt64()
|
||||||
var _4: Int32?
|
var _4: Int32?
|
||||||
_4 = reader.readInt32()
|
_4 = reader.readInt32()
|
||||||
|
var _5: Int32?
|
||||||
|
if Int(_1!) & Int(1 << 1) != 0 {_5 = reader.readInt32() }
|
||||||
let _c1 = _1 != nil
|
let _c1 = _1 != nil
|
||||||
let _c2 = _2 != nil
|
let _c2 = _2 != nil
|
||||||
let _c3 = _3 != nil
|
let _c3 = _3 != nil
|
||||||
let _c4 = _4 != nil
|
let _c4 = _4 != nil
|
||||||
if _c1 && _c2 && _c3 && _c4 {
|
let _c5 = (Int(_1!) & Int(1 << 1) == 0) || _5 != nil
|
||||||
return Api.ChannelParticipant.channelParticipantSelf(flags: _1!, userId: _2!, inviterId: _3!, date: _4!)
|
if _c1 && _c2 && _c3 && _c4 && _c5 {
|
||||||
|
return Api.ChannelParticipant.channelParticipantSelf(flags: _1!, userId: _2!, inviterId: _3!, date: _4!, subscriptionUntilDate: _5)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return nil
|
return nil
|
||||||
@ -522,7 +534,7 @@ public extension Api {
|
|||||||
}
|
}
|
||||||
public extension Api {
|
public extension Api {
|
||||||
indirect enum Chat: TypeConstructorDescription {
|
indirect enum Chat: TypeConstructorDescription {
|
||||||
case channel(flags: Int32, flags2: Int32, id: Int64, accessHash: Int64?, title: String, username: String?, photo: Api.ChatPhoto, date: Int32, restrictionReason: [Api.RestrictionReason]?, adminRights: Api.ChatAdminRights?, bannedRights: Api.ChatBannedRights?, defaultBannedRights: Api.ChatBannedRights?, participantsCount: Int32?, usernames: [Api.Username]?, storiesMaxId: Int32?, color: Api.PeerColor?, profileColor: Api.PeerColor?, emojiStatus: Api.EmojiStatus?, level: Int32?)
|
case channel(flags: Int32, flags2: Int32, id: Int64, accessHash: Int64?, title: String, username: String?, photo: Api.ChatPhoto, date: Int32, restrictionReason: [Api.RestrictionReason]?, adminRights: Api.ChatAdminRights?, bannedRights: Api.ChatBannedRights?, defaultBannedRights: Api.ChatBannedRights?, participantsCount: Int32?, usernames: [Api.Username]?, storiesMaxId: Int32?, color: Api.PeerColor?, profileColor: Api.PeerColor?, emojiStatus: Api.EmojiStatus?, level: Int32?, subscriptionUntilDate: Int32?)
|
||||||
case channelForbidden(flags: Int32, id: Int64, accessHash: Int64, title: String, untilDate: Int32?)
|
case channelForbidden(flags: Int32, id: Int64, accessHash: Int64, title: String, untilDate: Int32?)
|
||||||
case chat(flags: Int32, id: Int64, title: String, photo: Api.ChatPhoto, participantsCount: Int32, date: Int32, version: Int32, migratedTo: Api.InputChannel?, adminRights: Api.ChatAdminRights?, defaultBannedRights: Api.ChatBannedRights?)
|
case chat(flags: Int32, id: Int64, title: String, photo: Api.ChatPhoto, participantsCount: Int32, date: Int32, version: Int32, migratedTo: Api.InputChannel?, adminRights: Api.ChatAdminRights?, defaultBannedRights: Api.ChatBannedRights?)
|
||||||
case chatEmpty(id: Int64)
|
case chatEmpty(id: Int64)
|
||||||
@ -530,9 +542,9 @@ public extension Api {
|
|||||||
|
|
||||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||||
switch self {
|
switch self {
|
||||||
case .channel(let flags, let flags2, let id, let accessHash, let title, let username, let photo, let date, let restrictionReason, let adminRights, let bannedRights, let defaultBannedRights, let participantsCount, let usernames, let storiesMaxId, let color, let profileColor, let emojiStatus, let level):
|
case .channel(let flags, let flags2, let id, let accessHash, let title, let username, let photo, let date, let restrictionReason, let adminRights, let bannedRights, let defaultBannedRights, let participantsCount, let usernames, let storiesMaxId, let color, let profileColor, let emojiStatus, let level, let subscriptionUntilDate):
|
||||||
if boxed {
|
if boxed {
|
||||||
buffer.appendInt32(179174543)
|
buffer.appendInt32(-29067075)
|
||||||
}
|
}
|
||||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||||
serializeInt32(flags2, buffer: buffer, boxed: false)
|
serializeInt32(flags2, buffer: buffer, boxed: false)
|
||||||
@ -561,6 +573,7 @@ public extension Api {
|
|||||||
if Int(flags2) & Int(1 << 8) != 0 {profileColor!.serialize(buffer, true)}
|
if Int(flags2) & Int(1 << 8) != 0 {profileColor!.serialize(buffer, true)}
|
||||||
if Int(flags2) & Int(1 << 9) != 0 {emojiStatus!.serialize(buffer, true)}
|
if Int(flags2) & Int(1 << 9) != 0 {emojiStatus!.serialize(buffer, true)}
|
||||||
if Int(flags2) & Int(1 << 10) != 0 {serializeInt32(level!, buffer: buffer, boxed: false)}
|
if Int(flags2) & Int(1 << 10) != 0 {serializeInt32(level!, buffer: buffer, boxed: false)}
|
||||||
|
if Int(flags2) & Int(1 << 11) != 0 {serializeInt32(subscriptionUntilDate!, buffer: buffer, boxed: false)}
|
||||||
break
|
break
|
||||||
case .channelForbidden(let flags, let id, let accessHash, let title, let untilDate):
|
case .channelForbidden(let flags, let id, let accessHash, let title, let untilDate):
|
||||||
if boxed {
|
if boxed {
|
||||||
@ -605,8 +618,8 @@ public extension Api {
|
|||||||
|
|
||||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||||
switch self {
|
switch self {
|
||||||
case .channel(let flags, let flags2, let id, let accessHash, let title, let username, let photo, let date, let restrictionReason, let adminRights, let bannedRights, let defaultBannedRights, let participantsCount, let usernames, let storiesMaxId, let color, let profileColor, let emojiStatus, let level):
|
case .channel(let flags, let flags2, let id, let accessHash, let title, let username, let photo, let date, let restrictionReason, let adminRights, let bannedRights, let defaultBannedRights, let participantsCount, let usernames, let storiesMaxId, let color, let profileColor, let emojiStatus, let level, let subscriptionUntilDate):
|
||||||
return ("channel", [("flags", flags as Any), ("flags2", flags2 as Any), ("id", id as Any), ("accessHash", accessHash as Any), ("title", title as Any), ("username", username as Any), ("photo", photo as Any), ("date", date as Any), ("restrictionReason", restrictionReason as Any), ("adminRights", adminRights as Any), ("bannedRights", bannedRights as Any), ("defaultBannedRights", defaultBannedRights as Any), ("participantsCount", participantsCount as Any), ("usernames", usernames as Any), ("storiesMaxId", storiesMaxId as Any), ("color", color as Any), ("profileColor", profileColor as Any), ("emojiStatus", emojiStatus as Any), ("level", level as Any)])
|
return ("channel", [("flags", flags as Any), ("flags2", flags2 as Any), ("id", id as Any), ("accessHash", accessHash as Any), ("title", title as Any), ("username", username as Any), ("photo", photo as Any), ("date", date as Any), ("restrictionReason", restrictionReason as Any), ("adminRights", adminRights as Any), ("bannedRights", bannedRights as Any), ("defaultBannedRights", defaultBannedRights as Any), ("participantsCount", participantsCount as Any), ("usernames", usernames as Any), ("storiesMaxId", storiesMaxId as Any), ("color", color as Any), ("profileColor", profileColor as Any), ("emojiStatus", emojiStatus as Any), ("level", level as Any), ("subscriptionUntilDate", subscriptionUntilDate as Any)])
|
||||||
case .channelForbidden(let flags, let id, let accessHash, let title, let untilDate):
|
case .channelForbidden(let flags, let id, let accessHash, let title, let untilDate):
|
||||||
return ("channelForbidden", [("flags", flags as Any), ("id", id as Any), ("accessHash", accessHash as Any), ("title", title as Any), ("untilDate", untilDate as Any)])
|
return ("channelForbidden", [("flags", flags as Any), ("id", id as Any), ("accessHash", accessHash as Any), ("title", title as Any), ("untilDate", untilDate as Any)])
|
||||||
case .chat(let flags, let id, let title, let photo, let participantsCount, let date, let version, let migratedTo, let adminRights, let defaultBannedRights):
|
case .chat(let flags, let id, let title, let photo, let participantsCount, let date, let version, let migratedTo, let adminRights, let defaultBannedRights):
|
||||||
@ -675,6 +688,8 @@ public extension Api {
|
|||||||
} }
|
} }
|
||||||
var _19: Int32?
|
var _19: Int32?
|
||||||
if Int(_2!) & Int(1 << 10) != 0 {_19 = reader.readInt32() }
|
if Int(_2!) & Int(1 << 10) != 0 {_19 = reader.readInt32() }
|
||||||
|
var _20: Int32?
|
||||||
|
if Int(_2!) & Int(1 << 11) != 0 {_20 = reader.readInt32() }
|
||||||
let _c1 = _1 != nil
|
let _c1 = _1 != nil
|
||||||
let _c2 = _2 != nil
|
let _c2 = _2 != nil
|
||||||
let _c3 = _3 != nil
|
let _c3 = _3 != nil
|
||||||
@ -694,8 +709,9 @@ public extension Api {
|
|||||||
let _c17 = (Int(_2!) & Int(1 << 8) == 0) || _17 != nil
|
let _c17 = (Int(_2!) & Int(1 << 8) == 0) || _17 != nil
|
||||||
let _c18 = (Int(_2!) & Int(1 << 9) == 0) || _18 != nil
|
let _c18 = (Int(_2!) & Int(1 << 9) == 0) || _18 != nil
|
||||||
let _c19 = (Int(_2!) & Int(1 << 10) == 0) || _19 != nil
|
let _c19 = (Int(_2!) & Int(1 << 10) == 0) || _19 != nil
|
||||||
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 && _c9 && _c10 && _c11 && _c12 && _c13 && _c14 && _c15 && _c16 && _c17 && _c18 && _c19 {
|
let _c20 = (Int(_2!) & Int(1 << 11) == 0) || _20 != nil
|
||||||
return Api.Chat.channel(flags: _1!, flags2: _2!, id: _3!, accessHash: _4, title: _5!, username: _6, photo: _7!, date: _8!, restrictionReason: _9, adminRights: _10, bannedRights: _11, defaultBannedRights: _12, participantsCount: _13, usernames: _14, storiesMaxId: _15, color: _16, profileColor: _17, emojiStatus: _18, level: _19)
|
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 && _c9 && _c10 && _c11 && _c12 && _c13 && _c14 && _c15 && _c16 && _c17 && _c18 && _c19 && _c20 {
|
||||||
|
return Api.Chat.channel(flags: _1!, flags2: _2!, id: _3!, accessHash: _4, title: _5!, username: _6, photo: _7!, date: _8!, restrictionReason: _9, adminRights: _10, bannedRights: _11, defaultBannedRights: _12, participantsCount: _13, usernames: _14, storiesMaxId: _15, color: _16, profileColor: _17, emojiStatus: _18, level: _19, subscriptionUntilDate: _20)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return nil
|
return nil
|
||||||
@ -1280,15 +1296,15 @@ public extension Api {
|
|||||||
}
|
}
|
||||||
public extension Api {
|
public extension Api {
|
||||||
indirect enum ChatInvite: TypeConstructorDescription {
|
indirect enum ChatInvite: TypeConstructorDescription {
|
||||||
case chatInvite(flags: Int32, title: String, about: String?, photo: Api.Photo, participantsCount: Int32, participants: [Api.User]?, color: Int32)
|
case chatInvite(flags: Int32, title: String, about: String?, photo: Api.Photo, participantsCount: Int32, participants: [Api.User]?, color: Int32, subscriptionPricing: Api.StarsSubscriptionPricing?, subscriptionFormId: Int64?)
|
||||||
case chatInviteAlready(chat: Api.Chat)
|
case chatInviteAlready(chat: Api.Chat)
|
||||||
case chatInvitePeek(chat: Api.Chat, expires: Int32)
|
case chatInvitePeek(chat: Api.Chat, expires: Int32)
|
||||||
|
|
||||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||||
switch self {
|
switch self {
|
||||||
case .chatInvite(let flags, let title, let about, let photo, let participantsCount, let participants, let color):
|
case .chatInvite(let flags, let title, let about, let photo, let participantsCount, let participants, let color, let subscriptionPricing, let subscriptionFormId):
|
||||||
if boxed {
|
if boxed {
|
||||||
buffer.appendInt32(-840897472)
|
buffer.appendInt32(-26920803)
|
||||||
}
|
}
|
||||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||||
serializeString(title, buffer: buffer, boxed: false)
|
serializeString(title, buffer: buffer, boxed: false)
|
||||||
@ -1301,6 +1317,8 @@ public extension Api {
|
|||||||
item.serialize(buffer, true)
|
item.serialize(buffer, true)
|
||||||
}}
|
}}
|
||||||
serializeInt32(color, buffer: buffer, boxed: false)
|
serializeInt32(color, buffer: buffer, boxed: false)
|
||||||
|
if Int(flags) & Int(1 << 10) != 0 {subscriptionPricing!.serialize(buffer, true)}
|
||||||
|
if Int(flags) & Int(1 << 12) != 0 {serializeInt64(subscriptionFormId!, buffer: buffer, boxed: false)}
|
||||||
break
|
break
|
||||||
case .chatInviteAlready(let chat):
|
case .chatInviteAlready(let chat):
|
||||||
if boxed {
|
if boxed {
|
||||||
@ -1320,8 +1338,8 @@ public extension Api {
|
|||||||
|
|
||||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||||
switch self {
|
switch self {
|
||||||
case .chatInvite(let flags, let title, let about, let photo, let participantsCount, let participants, let color):
|
case .chatInvite(let flags, let title, let about, let photo, let participantsCount, let participants, let color, let subscriptionPricing, let subscriptionFormId):
|
||||||
return ("chatInvite", [("flags", flags as Any), ("title", title as Any), ("about", about as Any), ("photo", photo as Any), ("participantsCount", participantsCount as Any), ("participants", participants as Any), ("color", color as Any)])
|
return ("chatInvite", [("flags", flags as Any), ("title", title as Any), ("about", about as Any), ("photo", photo as Any), ("participantsCount", participantsCount as Any), ("participants", participants as Any), ("color", color as Any), ("subscriptionPricing", subscriptionPricing as Any), ("subscriptionFormId", subscriptionFormId as Any)])
|
||||||
case .chatInviteAlready(let chat):
|
case .chatInviteAlready(let chat):
|
||||||
return ("chatInviteAlready", [("chat", chat as Any)])
|
return ("chatInviteAlready", [("chat", chat as Any)])
|
||||||
case .chatInvitePeek(let chat, let expires):
|
case .chatInvitePeek(let chat, let expires):
|
||||||
@ -1348,6 +1366,12 @@ public extension Api {
|
|||||||
} }
|
} }
|
||||||
var _7: Int32?
|
var _7: Int32?
|
||||||
_7 = reader.readInt32()
|
_7 = reader.readInt32()
|
||||||
|
var _8: Api.StarsSubscriptionPricing?
|
||||||
|
if Int(_1!) & Int(1 << 10) != 0 {if let signature = reader.readInt32() {
|
||||||
|
_8 = Api.parse(reader, signature: signature) as? Api.StarsSubscriptionPricing
|
||||||
|
} }
|
||||||
|
var _9: Int64?
|
||||||
|
if Int(_1!) & Int(1 << 12) != 0 {_9 = reader.readInt64() }
|
||||||
let _c1 = _1 != nil
|
let _c1 = _1 != nil
|
||||||
let _c2 = _2 != nil
|
let _c2 = _2 != nil
|
||||||
let _c3 = (Int(_1!) & Int(1 << 5) == 0) || _3 != nil
|
let _c3 = (Int(_1!) & Int(1 << 5) == 0) || _3 != nil
|
||||||
@ -1355,8 +1379,10 @@ public extension Api {
|
|||||||
let _c5 = _5 != nil
|
let _c5 = _5 != nil
|
||||||
let _c6 = (Int(_1!) & Int(1 << 4) == 0) || _6 != nil
|
let _c6 = (Int(_1!) & Int(1 << 4) == 0) || _6 != nil
|
||||||
let _c7 = _7 != nil
|
let _c7 = _7 != nil
|
||||||
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 {
|
let _c8 = (Int(_1!) & Int(1 << 10) == 0) || _8 != nil
|
||||||
return Api.ChatInvite.chatInvite(flags: _1!, title: _2!, about: _3, photo: _4!, participantsCount: _5!, participants: _6, color: _7!)
|
let _c9 = (Int(_1!) & Int(1 << 12) == 0) || _9 != nil
|
||||||
|
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 && _c9 {
|
||||||
|
return Api.ChatInvite.chatInvite(flags: _1!, title: _2!, about: _3, photo: _4!, participantsCount: _5!, participants: _6, color: _7!, subscriptionPricing: _8, subscriptionFormId: _9)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return nil
|
return nil
|
||||||
|
@ -1012,14 +1012,14 @@ public extension Api {
|
|||||||
}
|
}
|
||||||
public extension Api {
|
public extension Api {
|
||||||
enum ExportedChatInvite: TypeConstructorDescription {
|
enum ExportedChatInvite: TypeConstructorDescription {
|
||||||
case chatInviteExported(flags: Int32, link: String, adminId: Int64, date: Int32, startDate: Int32?, expireDate: Int32?, usageLimit: Int32?, usage: Int32?, requested: Int32?, title: String?)
|
case chatInviteExported(flags: Int32, link: String, adminId: Int64, date: Int32, startDate: Int32?, expireDate: Int32?, usageLimit: Int32?, usage: Int32?, requested: Int32?, title: String?, subscriptionPricing: Api.StarsSubscriptionPricing?)
|
||||||
case chatInvitePublicJoinRequests
|
case chatInvitePublicJoinRequests
|
||||||
|
|
||||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||||
switch self {
|
switch self {
|
||||||
case .chatInviteExported(let flags, let link, let adminId, let date, let startDate, let expireDate, let usageLimit, let usage, let requested, let title):
|
case .chatInviteExported(let flags, let link, let adminId, let date, let startDate, let expireDate, let usageLimit, let usage, let requested, let title, let subscriptionPricing):
|
||||||
if boxed {
|
if boxed {
|
||||||
buffer.appendInt32(179611673)
|
buffer.appendInt32(-1812799720)
|
||||||
}
|
}
|
||||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||||
serializeString(link, buffer: buffer, boxed: false)
|
serializeString(link, buffer: buffer, boxed: false)
|
||||||
@ -1031,6 +1031,7 @@ public extension Api {
|
|||||||
if Int(flags) & Int(1 << 3) != 0 {serializeInt32(usage!, buffer: buffer, boxed: false)}
|
if Int(flags) & Int(1 << 3) != 0 {serializeInt32(usage!, buffer: buffer, boxed: false)}
|
||||||
if Int(flags) & Int(1 << 7) != 0 {serializeInt32(requested!, buffer: buffer, boxed: false)}
|
if Int(flags) & Int(1 << 7) != 0 {serializeInt32(requested!, buffer: buffer, boxed: false)}
|
||||||
if Int(flags) & Int(1 << 8) != 0 {serializeString(title!, buffer: buffer, boxed: false)}
|
if Int(flags) & Int(1 << 8) != 0 {serializeString(title!, buffer: buffer, boxed: false)}
|
||||||
|
if Int(flags) & Int(1 << 9) != 0 {subscriptionPricing!.serialize(buffer, true)}
|
||||||
break
|
break
|
||||||
case .chatInvitePublicJoinRequests:
|
case .chatInvitePublicJoinRequests:
|
||||||
if boxed {
|
if boxed {
|
||||||
@ -1043,8 +1044,8 @@ public extension Api {
|
|||||||
|
|
||||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||||
switch self {
|
switch self {
|
||||||
case .chatInviteExported(let flags, let link, let adminId, let date, let startDate, let expireDate, let usageLimit, let usage, let requested, let title):
|
case .chatInviteExported(let flags, let link, let adminId, let date, let startDate, let expireDate, let usageLimit, let usage, let requested, let title, let subscriptionPricing):
|
||||||
return ("chatInviteExported", [("flags", flags as Any), ("link", link as Any), ("adminId", adminId as Any), ("date", date as Any), ("startDate", startDate as Any), ("expireDate", expireDate as Any), ("usageLimit", usageLimit as Any), ("usage", usage as Any), ("requested", requested as Any), ("title", title as Any)])
|
return ("chatInviteExported", [("flags", flags as Any), ("link", link as Any), ("adminId", adminId as Any), ("date", date as Any), ("startDate", startDate as Any), ("expireDate", expireDate as Any), ("usageLimit", usageLimit as Any), ("usage", usage as Any), ("requested", requested as Any), ("title", title as Any), ("subscriptionPricing", subscriptionPricing as Any)])
|
||||||
case .chatInvitePublicJoinRequests:
|
case .chatInvitePublicJoinRequests:
|
||||||
return ("chatInvitePublicJoinRequests", [])
|
return ("chatInvitePublicJoinRequests", [])
|
||||||
}
|
}
|
||||||
@ -1071,6 +1072,10 @@ public extension Api {
|
|||||||
if Int(_1!) & Int(1 << 7) != 0 {_9 = reader.readInt32() }
|
if Int(_1!) & Int(1 << 7) != 0 {_9 = reader.readInt32() }
|
||||||
var _10: String?
|
var _10: String?
|
||||||
if Int(_1!) & Int(1 << 8) != 0 {_10 = parseString(reader) }
|
if Int(_1!) & Int(1 << 8) != 0 {_10 = parseString(reader) }
|
||||||
|
var _11: Api.StarsSubscriptionPricing?
|
||||||
|
if Int(_1!) & Int(1 << 9) != 0 {if let signature = reader.readInt32() {
|
||||||
|
_11 = Api.parse(reader, signature: signature) as? Api.StarsSubscriptionPricing
|
||||||
|
} }
|
||||||
let _c1 = _1 != nil
|
let _c1 = _1 != nil
|
||||||
let _c2 = _2 != nil
|
let _c2 = _2 != nil
|
||||||
let _c3 = _3 != nil
|
let _c3 = _3 != nil
|
||||||
@ -1081,8 +1086,9 @@ public extension Api {
|
|||||||
let _c8 = (Int(_1!) & Int(1 << 3) == 0) || _8 != nil
|
let _c8 = (Int(_1!) & Int(1 << 3) == 0) || _8 != nil
|
||||||
let _c9 = (Int(_1!) & Int(1 << 7) == 0) || _9 != nil
|
let _c9 = (Int(_1!) & Int(1 << 7) == 0) || _9 != nil
|
||||||
let _c10 = (Int(_1!) & Int(1 << 8) == 0) || _10 != nil
|
let _c10 = (Int(_1!) & Int(1 << 8) == 0) || _10 != nil
|
||||||
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 && _c9 && _c10 {
|
let _c11 = (Int(_1!) & Int(1 << 9) == 0) || _11 != nil
|
||||||
return Api.ExportedChatInvite.chatInviteExported(flags: _1!, link: _2!, adminId: _3!, date: _4!, startDate: _5, expireDate: _6, usageLimit: _7, usage: _8, requested: _9, title: _10)
|
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 && _c9 && _c10 && _c11 {
|
||||||
|
return Api.ExportedChatInvite.chatInviteExported(flags: _1!, link: _2!, adminId: _3!, date: _4!, startDate: _5, expireDate: _6, usageLimit: _7, usage: _8, requested: _9, title: _10, subscriptionPricing: _11)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return nil
|
return nil
|
||||||
|
@ -478,7 +478,7 @@ struct AccountMutableState {
|
|||||||
|
|
||||||
for chat in chats {
|
for chat in chats {
|
||||||
switch chat {
|
switch chat {
|
||||||
case let .channel(_, _, _, _, _, _, _, _, _, _, _, _, participantsCount, _, _, _, _, _, _):
|
case let .channel(_, _, _, _, _, _, _, _, _, _, _, _, participantsCount, _, _, _, _, _, _, _):
|
||||||
if let participantsCount = participantsCount {
|
if let participantsCount = participantsCount {
|
||||||
self.addOperation(.UpdateCachedPeerData(chat.peerId, { current in
|
self.addOperation(.UpdateCachedPeerData(chat.peerId, { current in
|
||||||
var previous: CachedChannelData
|
var previous: CachedChannelData
|
||||||
|
@ -109,6 +109,7 @@ private var declaredEncodables: Void = {
|
|||||||
declareEncodable(ReplyThreadMessageAttribute.self, f: { ReplyThreadMessageAttribute(decoder: $0) })
|
declareEncodable(ReplyThreadMessageAttribute.self, f: { ReplyThreadMessageAttribute(decoder: $0) })
|
||||||
declareEncodable(ReactionsMessageAttribute.self, f: { ReactionsMessageAttribute(decoder: $0) })
|
declareEncodable(ReactionsMessageAttribute.self, f: { ReactionsMessageAttribute(decoder: $0) })
|
||||||
declareEncodable(PendingReactionsMessageAttribute.self, f: { PendingReactionsMessageAttribute(decoder: $0) })
|
declareEncodable(PendingReactionsMessageAttribute.self, f: { PendingReactionsMessageAttribute(decoder: $0) })
|
||||||
|
declareEncodable(PendingStarsReactionsMessageAttribute.self, f: { PendingStarsReactionsMessageAttribute(decoder: $0) })
|
||||||
declareEncodable(CloudDocumentMediaResource.self, f: { CloudDocumentMediaResource(decoder: $0) })
|
declareEncodable(CloudDocumentMediaResource.self, f: { CloudDocumentMediaResource(decoder: $0) })
|
||||||
declareEncodable(TelegramMediaWebpage.self, f: { TelegramMediaWebpage(decoder: $0) })
|
declareEncodable(TelegramMediaWebpage.self, f: { TelegramMediaWebpage(decoder: $0) })
|
||||||
declareEncodable(ViewCountMessageAttribute.self, f: { ViewCountMessageAttribute(decoder: $0) })
|
declareEncodable(ViewCountMessageAttribute.self, f: { ViewCountMessageAttribute(decoder: $0) })
|
||||||
@ -188,6 +189,7 @@ private var declaredEncodables: Void = {
|
|||||||
declareEncodable(WasScheduledMessageAttribute.self, f: { WasScheduledMessageAttribute(decoder: $0) })
|
declareEncodable(WasScheduledMessageAttribute.self, f: { WasScheduledMessageAttribute(decoder: $0) })
|
||||||
declareEncodable(OutgoingScheduleInfoMessageAttribute.self, f: { OutgoingScheduleInfoMessageAttribute(decoder: $0) })
|
declareEncodable(OutgoingScheduleInfoMessageAttribute.self, f: { OutgoingScheduleInfoMessageAttribute(decoder: $0) })
|
||||||
declareEncodable(UpdateMessageReactionsAction.self, f: { UpdateMessageReactionsAction(decoder: $0) })
|
declareEncodable(UpdateMessageReactionsAction.self, f: { UpdateMessageReactionsAction(decoder: $0) })
|
||||||
|
declareEncodable(SendStarsReactionsAction.self, f: { SendStarsReactionsAction(decoder: $0) })
|
||||||
declareEncodable(RestrictedContentMessageAttribute.self, f: { RestrictedContentMessageAttribute(decoder: $0) })
|
declareEncodable(RestrictedContentMessageAttribute.self, f: { RestrictedContentMessageAttribute(decoder: $0) })
|
||||||
declareEncodable(SendScheduledMessageImmediatelyAction.self, f: { SendScheduledMessageImmediatelyAction(decoder: $0) })
|
declareEncodable(SendScheduledMessageImmediatelyAction.self, f: { SendScheduledMessageImmediatelyAction(decoder: $0) })
|
||||||
declareEncodable(EmbeddedMediaStickersMessageAttribute.self, f: { EmbeddedMediaStickersMessageAttribute(decoder: $0) })
|
declareEncodable(EmbeddedMediaStickersMessageAttribute.self, f: { EmbeddedMediaStickersMessageAttribute(decoder: $0) })
|
||||||
|
@ -61,7 +61,7 @@ func parseTelegramGroupOrChannel(chat: Api.Chat) -> Peer? {
|
|||||||
return TelegramGroup(id: PeerId(namespace: Namespaces.Peer.CloudGroup, id: PeerId.Id._internalFromInt64Value(id)), title: "", photo: [], participantCount: 0, role: .member, membership: .Removed, flags: [], defaultBannedRights: nil, migrationReference: nil, creationDate: 0, version: 0)
|
return TelegramGroup(id: PeerId(namespace: Namespaces.Peer.CloudGroup, id: PeerId.Id._internalFromInt64Value(id)), title: "", photo: [], participantCount: 0, role: .member, membership: .Removed, flags: [], defaultBannedRights: nil, migrationReference: nil, creationDate: 0, version: 0)
|
||||||
case let .chatForbidden(id, title):
|
case let .chatForbidden(id, title):
|
||||||
return TelegramGroup(id: PeerId(namespace: Namespaces.Peer.CloudGroup, id: PeerId.Id._internalFromInt64Value(id)), title: title, photo: [], participantCount: 0, role: .member, membership: .Removed, flags: [], defaultBannedRights: nil, migrationReference: nil, creationDate: 0, version: 0)
|
return TelegramGroup(id: PeerId(namespace: Namespaces.Peer.CloudGroup, id: PeerId.Id._internalFromInt64Value(id)), title: title, photo: [], participantCount: 0, role: .member, membership: .Removed, flags: [], defaultBannedRights: nil, migrationReference: nil, creationDate: 0, version: 0)
|
||||||
case let .channel(flags, flags2, id, accessHash, title, username, photo, date, restrictionReason, adminRights, bannedRights, defaultBannedRights, _, usernames, _, color, profileColor, emojiStatus, boostLevel):
|
case let .channel(flags, flags2, id, accessHash, title, username, photo, date, restrictionReason, adminRights, bannedRights, defaultBannedRights, _, usernames, _, color, profileColor, emojiStatus, boostLevel, _):
|
||||||
let isMin = (flags & (1 << 12)) != 0
|
let isMin = (flags & (1 << 12)) != 0
|
||||||
|
|
||||||
let participationStatus: TelegramChannelParticipationStatus
|
let participationStatus: TelegramChannelParticipationStatus
|
||||||
@ -190,7 +190,7 @@ func mergeGroupOrChannel(lhs: Peer?, rhs: Api.Chat) -> Peer? {
|
|||||||
switch rhs {
|
switch rhs {
|
||||||
case .chat, .chatEmpty, .chatForbidden, .channelForbidden:
|
case .chat, .chatEmpty, .chatForbidden, .channelForbidden:
|
||||||
return parseTelegramGroupOrChannel(chat: rhs)
|
return parseTelegramGroupOrChannel(chat: rhs)
|
||||||
case let .channel(flags, flags2, _, accessHash, title, username, photo, _, _, _, _, defaultBannedRights, _, usernames, _, color, profileColor, emojiStatus, boostLevel):
|
case let .channel(flags, flags2, _, accessHash, title, username, photo, _, _, _, _, defaultBannedRights, _, usernames, _, color, profileColor, emojiStatus, boostLevel, _):
|
||||||
let isMin = (flags & (1 << 12)) != 0
|
let isMin = (flags & (1 << 12)) != 0
|
||||||
if accessHash != nil && !isMin {
|
if accessHash != nil && !isMin {
|
||||||
return parseTelegramGroupOrChannel(chat: rhs)
|
return parseTelegramGroupOrChannel(chat: rhs)
|
||||||
|
@ -197,7 +197,7 @@ public final class CachedChannelParticipants: PostboxCoding, Equatable {
|
|||||||
extension ChannelParticipant {
|
extension ChannelParticipant {
|
||||||
init(apiParticipant: Api.ChannelParticipant) {
|
init(apiParticipant: Api.ChannelParticipant) {
|
||||||
switch apiParticipant {
|
switch apiParticipant {
|
||||||
case let .channelParticipant(userId, date):
|
case let .channelParticipant(_, userId, date, _):
|
||||||
self = .member(id: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(userId)), invitedAt: date, adminInfo: nil, banInfo: nil, rank: nil)
|
self = .member(id: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(userId)), invitedAt: date, adminInfo: nil, banInfo: nil, rank: nil)
|
||||||
case let .channelParticipantCreator(_, userId, adminRights, rank):
|
case let .channelParticipantCreator(_, userId, adminRights, rank):
|
||||||
self = .creator(id: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(userId)), adminInfo: ChannelParticipantAdminInfo(rights: TelegramChatAdminRights(apiAdminRights: adminRights) ?? TelegramChatAdminRights(rights: []), promotedBy: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(userId)), canBeEditedByAccountPeer: true), rank: rank)
|
self = .creator(id: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(userId)), adminInfo: ChannelParticipantAdminInfo(rights: TelegramChatAdminRights(apiAdminRights: adminRights) ?? TelegramChatAdminRights(rights: []), promotedBy: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(userId)), canBeEditedByAccountPeer: true), rank: rank)
|
||||||
@ -207,7 +207,7 @@ extension ChannelParticipant {
|
|||||||
self = .member(id: userId.peerId, invitedAt: date, adminInfo: nil, banInfo: banInfo, rank: nil)
|
self = .member(id: userId.peerId, invitedAt: date, adminInfo: nil, banInfo: banInfo, rank: nil)
|
||||||
case let .channelParticipantAdmin(flags, userId, _, promotedBy, date, adminRights, rank: rank):
|
case let .channelParticipantAdmin(flags, userId, _, promotedBy, date, adminRights, rank: rank):
|
||||||
self = .member(id: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(userId)), invitedAt: date, adminInfo: ChannelParticipantAdminInfo(rights: TelegramChatAdminRights(apiAdminRights: adminRights) ?? TelegramChatAdminRights(rights: []), promotedBy: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(promotedBy)), canBeEditedByAccountPeer: (flags & (1 << 0)) != 0), banInfo: nil, rank: rank)
|
self = .member(id: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(userId)), invitedAt: date, adminInfo: ChannelParticipantAdminInfo(rights: TelegramChatAdminRights(apiAdminRights: adminRights) ?? TelegramChatAdminRights(rights: []), promotedBy: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(promotedBy)), canBeEditedByAccountPeer: (flags & (1 << 0)) != 0), banInfo: nil, rank: rank)
|
||||||
case let .channelParticipantSelf(_, userId, _, date):
|
case let .channelParticipantSelf(_, userId, _, date, _):
|
||||||
self = .member(id: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(userId)), invitedAt: date, adminInfo: nil, banInfo: nil, rank: nil)
|
self = .member(id: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(userId)), invitedAt: date, adminInfo: nil, banInfo: nil, rank: nil)
|
||||||
case let .channelParticipantLeft(userId):
|
case let .channelParticipantLeft(userId):
|
||||||
self = .member(id: userId.peerId, invitedAt: 0, adminInfo: nil, banInfo: nil, rank: nil)
|
self = .member(id: userId.peerId, invitedAt: 0, adminInfo: nil, banInfo: nil, rank: nil)
|
||||||
|
@ -6,7 +6,7 @@ import TelegramApi
|
|||||||
extension ExportedInvitation {
|
extension ExportedInvitation {
|
||||||
init(apiExportedInvite: Api.ExportedChatInvite) {
|
init(apiExportedInvite: Api.ExportedChatInvite) {
|
||||||
switch apiExportedInvite {
|
switch apiExportedInvite {
|
||||||
case let .chatInviteExported(flags, link, adminId, date, startDate, expireDate, usageLimit, usage, requested, title):
|
case let .chatInviteExported(flags, link, adminId, date, startDate, expireDate, usageLimit, usage, requested, title, _):
|
||||||
self = .link(link: link, title: title, isPermanent: (flags & (1 << 5)) != 0, requestApproval: (flags & (1 << 6)) != 0, isRevoked: (flags & (1 << 0)) != 0, adminId: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(adminId)), date: date, startDate: startDate, expireDate: expireDate, usageLimit: usageLimit, count: usage, requestedCount: requested)
|
self = .link(link: link, title: title, isPermanent: (flags & (1 << 5)) != 0, requestApproval: (flags & (1 << 6)) != 0, isRevoked: (flags & (1 << 0)) != 0, adminId: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(adminId)), date: date, startDate: startDate, expireDate: expireDate, usageLimit: usageLimit, count: usage, requestedCount: requested)
|
||||||
case .chatInvitePublicJoinRequests:
|
case .chatInvitePublicJoinRequests:
|
||||||
self = .publicJoinRequest
|
self = .publicJoinRequest
|
||||||
|
@ -5,7 +5,10 @@ import TelegramApi
|
|||||||
extension ReactionsMessageAttribute {
|
extension ReactionsMessageAttribute {
|
||||||
func withUpdatedResults(_ reactions: Api.MessageReactions) -> ReactionsMessageAttribute {
|
func withUpdatedResults(_ reactions: Api.MessageReactions) -> ReactionsMessageAttribute {
|
||||||
switch reactions {
|
switch reactions {
|
||||||
case let .messageReactions(flags, results, recentReactions):
|
case let .messageReactions(flags, results, recentReactions, topReactors):
|
||||||
|
//TODO:release
|
||||||
|
let _ = topReactors
|
||||||
|
|
||||||
let min = (flags & (1 << 0)) != 0
|
let min = (flags & (1 << 0)) != 0
|
||||||
let canViewList = (flags & (1 << 2)) != 0
|
let canViewList = (flags & (1 << 2)) != 0
|
||||||
let isTags = (flags & (1 << 3)) != 0
|
let isTags = (flags & (1 << 3)) != 0
|
||||||
@ -94,26 +97,7 @@ public func mergedMessageReactionsAndPeers(accountPeerId: EnginePeer.Id, account
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if DEBUG
|
|
||||||
var reactions = attribute.reactions
|
|
||||||
if "".isEmpty {
|
|
||||||
if let index = reactions.firstIndex(where: {
|
|
||||||
if case .custom(MessageReaction.starsReactionId) = $0.value {
|
|
||||||
return true
|
|
||||||
} else {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}) {
|
|
||||||
let value = reactions[index]
|
|
||||||
reactions.remove(at: index)
|
|
||||||
reactions.insert(value, at: 0)
|
|
||||||
} else {
|
|
||||||
reactions.insert(MessageReaction(value: .custom(MessageReaction.starsReactionId), count: 1000000, chosenOrder: nil), at: 0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
let reactions = attribute.reactions
|
let reactions = attribute.reactions
|
||||||
#endif
|
|
||||||
|
|
||||||
return (reactions, recentPeers)
|
return (reactions, recentPeers)
|
||||||
}
|
}
|
||||||
@ -174,14 +158,18 @@ private func mergeReactions(reactions: [MessageReaction], recentPeers: [Reaction
|
|||||||
public func mergedMessageReactions(attributes: [MessageAttribute], isTags: Bool) -> ReactionsMessageAttribute? {
|
public func mergedMessageReactions(attributes: [MessageAttribute], isTags: Bool) -> ReactionsMessageAttribute? {
|
||||||
var current: ReactionsMessageAttribute?
|
var current: ReactionsMessageAttribute?
|
||||||
var pending: PendingReactionsMessageAttribute?
|
var pending: PendingReactionsMessageAttribute?
|
||||||
|
var pendingStars: PendingStarsReactionsMessageAttribute?
|
||||||
for attribute in attributes {
|
for attribute in attributes {
|
||||||
if let attribute = attribute as? ReactionsMessageAttribute {
|
if let attribute = attribute as? ReactionsMessageAttribute {
|
||||||
current = attribute
|
current = attribute
|
||||||
} else if let attribute = attribute as? PendingReactionsMessageAttribute {
|
} else if let attribute = attribute as? PendingReactionsMessageAttribute {
|
||||||
pending = attribute
|
pending = attribute
|
||||||
|
} else if let attribute = attribute as? PendingStarsReactionsMessageAttribute {
|
||||||
|
pendingStars = attribute
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let result: ReactionsMessageAttribute?
|
||||||
if let pending = pending, let accountPeerId = pending.accountPeerId {
|
if let pending = pending, let accountPeerId = pending.accountPeerId {
|
||||||
var reactions = current?.reactions ?? []
|
var reactions = current?.reactions ?? []
|
||||||
var recentPeers = current?.recentPeers ?? []
|
var recentPeers = current?.recentPeers ?? []
|
||||||
@ -191,21 +179,40 @@ public func mergedMessageReactions(attributes: [MessageAttribute], isTags: Bool)
|
|||||||
recentPeers = updatedRecentPeers
|
recentPeers = updatedRecentPeers
|
||||||
|
|
||||||
if !reactions.isEmpty {
|
if !reactions.isEmpty {
|
||||||
return ReactionsMessageAttribute(canViewList: current?.canViewList ?? false, isTags: current?.isTags ?? isTags, reactions: reactions, recentPeers: recentPeers)
|
result = ReactionsMessageAttribute(canViewList: current?.canViewList ?? false, isTags: current?.isTags ?? isTags, reactions: reactions, recentPeers: recentPeers)
|
||||||
} else {
|
} else {
|
||||||
return nil
|
result = nil
|
||||||
}
|
}
|
||||||
} else if let current = current {
|
} else if let current {
|
||||||
return current
|
result = current
|
||||||
} else {
|
} else {
|
||||||
return nil
|
result = nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if let pendingStars {
|
||||||
|
if let result {
|
||||||
|
var reactions = result.reactions
|
||||||
|
var updatedCount: Int32 = pendingStars.count
|
||||||
|
if let index = reactions.firstIndex(where: { $0.value == .stars }) {
|
||||||
|
updatedCount += reactions[index].count
|
||||||
|
reactions.remove(at: index)
|
||||||
|
}
|
||||||
|
reactions.insert(MessageReaction(value: .stars, count: updatedCount, chosenOrder: -1), at: 0)
|
||||||
|
return ReactionsMessageAttribute(canViewList: current?.canViewList ?? false, isTags: current?.isTags ?? isTags, reactions: reactions, recentPeers: result.recentPeers)
|
||||||
|
} else {
|
||||||
|
return ReactionsMessageAttribute(canViewList: current?.canViewList ?? false, isTags: current?.isTags ?? isTags, reactions: [MessageReaction(value: .stars, count: pendingStars.count, chosenOrder: -1)], recentPeers: [])
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return result
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extension ReactionsMessageAttribute {
|
extension ReactionsMessageAttribute {
|
||||||
convenience init(apiReactions: Api.MessageReactions) {
|
convenience init(apiReactions: Api.MessageReactions) {
|
||||||
switch apiReactions {
|
switch apiReactions {
|
||||||
case let .messageReactions(flags, results, recentReactions):
|
case let .messageReactions(flags, results, recentReactions, topReactors):
|
||||||
|
//TODO:release
|
||||||
|
let _ = topReactors
|
||||||
let canViewList = (flags & (1 << 2)) != 0
|
let canViewList = (flags & (1 << 2)) != 0
|
||||||
let isTags = (flags & (1 << 3)) != 0
|
let isTags = (flags & (1 << 3)) != 0
|
||||||
let parsedRecentReactions: [ReactionsMessageAttribute.RecentPeer]
|
let parsedRecentReactions: [ReactionsMessageAttribute.RecentPeer]
|
||||||
|
@ -22,6 +22,8 @@ public extension ReactionSettings {
|
|||||||
} else {
|
} else {
|
||||||
return ReactionSettings.default.quickReaction
|
return ReactionSettings.default.quickReaction
|
||||||
}
|
}
|
||||||
|
case .stars:
|
||||||
|
return self.quickReaction
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -87,6 +87,7 @@ final class AccountTaskManager {
|
|||||||
tasks.add(managedSynchronizeMarkAllUnseenPersonalMessagesOperations(postbox: self.stateManager.postbox, network: self.stateManager.network, stateManager: self.stateManager).start())
|
tasks.add(managedSynchronizeMarkAllUnseenPersonalMessagesOperations(postbox: self.stateManager.postbox, network: self.stateManager.network, stateManager: self.stateManager).start())
|
||||||
tasks.add(managedSynchronizeMarkAllUnseenReactionsOperations(postbox: self.stateManager.postbox, network: self.stateManager.network, stateManager: self.stateManager).start())
|
tasks.add(managedSynchronizeMarkAllUnseenReactionsOperations(postbox: self.stateManager.postbox, network: self.stateManager.network, stateManager: self.stateManager).start())
|
||||||
tasks.add(managedApplyPendingMessageReactionsActions(postbox: self.stateManager.postbox, network: self.stateManager.network, stateManager: self.stateManager).start())
|
tasks.add(managedApplyPendingMessageReactionsActions(postbox: self.stateManager.postbox, network: self.stateManager.network, stateManager: self.stateManager).start())
|
||||||
|
tasks.add(managedApplyPendingMessageStarsReactionsActions(postbox: self.stateManager.postbox, network: self.stateManager.network, stateManager: self.stateManager).start())
|
||||||
tasks.add(managedSynchronizeEmojiKeywordsOperations(postbox: self.stateManager.postbox, network: self.stateManager.network).start())
|
tasks.add(managedSynchronizeEmojiKeywordsOperations(postbox: self.stateManager.postbox, network: self.stateManager.network).start())
|
||||||
tasks.add(managedApplyPendingScheduledMessagesActions(postbox: self.stateManager.postbox, network: self.stateManager.network, stateManager: self.stateManager).start())
|
tasks.add(managedApplyPendingScheduledMessagesActions(postbox: self.stateManager.postbox, network: self.stateManager.network, stateManager: self.stateManager).start())
|
||||||
tasks.add(managedSynchronizeAvailableReactions(postbox: self.stateManager.postbox, network: self.stateManager.network).start())
|
tasks.add(managedSynchronizeAvailableReactions(postbox: self.stateManager.postbox, network: self.stateManager.network).start())
|
||||||
|
@ -142,6 +142,8 @@ public final class AvailableReactions: Equatable, Codable {
|
|||||||
try container.encode(value, forKey: .value)
|
try container.encode(value, forKey: .value)
|
||||||
case .custom:
|
case .custom:
|
||||||
break
|
break
|
||||||
|
case .stars:
|
||||||
|
break
|
||||||
}
|
}
|
||||||
try container.encode(self.title, forKey: .title)
|
try container.encode(self.title, forKey: .title)
|
||||||
|
|
||||||
@ -172,7 +174,29 @@ public final class AvailableReactions: Equatable, Codable {
|
|||||||
reactions: [Reaction]
|
reactions: [Reaction]
|
||||||
) {
|
) {
|
||||||
self.hash = hash
|
self.hash = hash
|
||||||
|
|
||||||
|
#if DEBUG
|
||||||
|
var reactions = reactions
|
||||||
|
reactions.removeAll(where: { if case .stars = $0.value { return true } else { return false } })
|
||||||
|
if let item = reactions.first(where: { if case .builtin("🤩") = $0.value { return true } else { return false } }) {
|
||||||
|
reactions.append(Reaction(
|
||||||
|
isEnabled: false,
|
||||||
|
isPremium: false,
|
||||||
|
value: .stars,
|
||||||
|
title: "Star",
|
||||||
|
staticIcon: item.staticIcon,
|
||||||
|
appearAnimation: item.appearAnimation,
|
||||||
|
selectAnimation: item.selectAnimation,
|
||||||
|
activateAnimation: item.activateAnimation,
|
||||||
|
effectAnimation: item.effectAnimation,
|
||||||
|
aroundAnimation: item.aroundAnimation,
|
||||||
|
centerAnimation: item.centerAnimation
|
||||||
|
))
|
||||||
|
}
|
||||||
self.reactions = reactions
|
self.reactions = reactions
|
||||||
|
#else
|
||||||
|
self.reactions = reactions
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
public static func ==(lhs: AvailableReactions, rhs: AvailableReactions) -> Bool {
|
public static func ==(lhs: AvailableReactions, rhs: AvailableReactions) -> Bool {
|
||||||
@ -189,7 +213,28 @@ public final class AvailableReactions: Equatable, Codable {
|
|||||||
let container = try decoder.container(keyedBy: CodingKeys.self)
|
let container = try decoder.container(keyedBy: CodingKeys.self)
|
||||||
|
|
||||||
self.hash = try container.decodeIfPresent(Int32.self, forKey: .newHash) ?? 0
|
self.hash = try container.decodeIfPresent(Int32.self, forKey: .newHash) ?? 0
|
||||||
|
#if DEBUG
|
||||||
|
var reactions = try container.decode([Reaction].self, forKey: .reactions)
|
||||||
|
reactions.removeAll(where: { if case .stars = $0.value { return true } else { return false } })
|
||||||
|
if let item = reactions.first(where: { if case .builtin("🤩") = $0.value { return true } else { return false } }) {
|
||||||
|
reactions.append(Reaction(
|
||||||
|
isEnabled: false,
|
||||||
|
isPremium: false,
|
||||||
|
value: .stars,
|
||||||
|
title: "Star",
|
||||||
|
staticIcon: item.staticIcon,
|
||||||
|
appearAnimation: item.appearAnimation,
|
||||||
|
selectAnimation: item.selectAnimation,
|
||||||
|
activateAnimation: item.activateAnimation,
|
||||||
|
effectAnimation: item.effectAnimation,
|
||||||
|
aroundAnimation: item.aroundAnimation,
|
||||||
|
centerAnimation: item.centerAnimation
|
||||||
|
))
|
||||||
|
}
|
||||||
|
self.reactions = reactions
|
||||||
|
#else
|
||||||
self.reactions = try container.decode([Reaction].self, forKey: .reactions)
|
self.reactions = try container.decode([Reaction].self, forKey: .reactions)
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
public func encode(to encoder: Encoder) throws {
|
public func encode(to encoder: Encoder) throws {
|
||||||
|
@ -656,6 +656,8 @@ func synchronizeSavedMessageTags(postbox: Postbox, network: Network, peerId: Pee
|
|||||||
reactionId = UInt64(bitPattern: id)
|
reactionId = UInt64(bitPattern: id)
|
||||||
case let .builtin(string):
|
case let .builtin(string):
|
||||||
reactionId = md5StringHash(string)
|
reactionId = md5StringHash(string)
|
||||||
|
case .stars:
|
||||||
|
reactionId = md5StringHash("star")
|
||||||
}
|
}
|
||||||
|
|
||||||
var titleId: UInt64?
|
var titleId: UInt64?
|
||||||
|
@ -411,6 +411,8 @@ func managedRecentReactions(postbox: Postbox, network: Network) -> Signal<Void,
|
|||||||
return 0
|
return 0
|
||||||
case let .custom(fileId):
|
case let .custom(fileId):
|
||||||
return fileId.id
|
return fileId.id
|
||||||
|
case .stars:
|
||||||
|
return 0
|
||||||
}
|
}
|
||||||
}, reverseHashOrder: false, forceFetch: false, fetch: { hash in
|
}, reverseHashOrder: false, forceFetch: false, fetch: { hash in
|
||||||
return network.request(Api.functions.messages.getRecentReactions(limit: 100, hash: hash))
|
return network.request(Api.functions.messages.getRecentReactions(limit: 100, hash: hash))
|
||||||
@ -428,6 +430,8 @@ func managedRecentReactions(postbox: Postbox, network: Network) -> Signal<Void,
|
|||||||
return nil
|
return nil
|
||||||
case let .custom(fileId):
|
case let .custom(fileId):
|
||||||
return fileId
|
return fileId
|
||||||
|
case .stars:
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|> map { files -> [OrderedItemListEntry] in
|
|> map { files -> [OrderedItemListEntry] in
|
||||||
@ -442,6 +446,8 @@ func managedRecentReactions(postbox: Postbox, network: Network) -> Signal<Void,
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
item = RecentReactionItem(.custom(file))
|
item = RecentReactionItem(.custom(file))
|
||||||
|
case .stars:
|
||||||
|
item = RecentReactionItem(.stars)
|
||||||
}
|
}
|
||||||
if let entry = CodableEntry(item) {
|
if let entry = CodableEntry(item) {
|
||||||
items.append(OrderedItemListEntry(id: item.id.rawValue, contents: entry))
|
items.append(OrderedItemListEntry(id: item.id.rawValue, contents: entry))
|
||||||
@ -462,6 +468,8 @@ func managedTopReactions(postbox: Postbox, network: Network) -> Signal<Void, NoE
|
|||||||
return 0
|
return 0
|
||||||
case let .custom(fileId):
|
case let .custom(fileId):
|
||||||
return fileId.id
|
return fileId.id
|
||||||
|
case .stars:
|
||||||
|
return 0
|
||||||
}
|
}
|
||||||
}, reverseHashOrder: false, forceFetch: false, fetch: { hash in
|
}, reverseHashOrder: false, forceFetch: false, fetch: { hash in
|
||||||
return network.request(Api.functions.messages.getTopReactions(limit: 32, hash: hash))
|
return network.request(Api.functions.messages.getTopReactions(limit: 32, hash: hash))
|
||||||
@ -479,6 +487,8 @@ func managedTopReactions(postbox: Postbox, network: Network) -> Signal<Void, NoE
|
|||||||
return nil
|
return nil
|
||||||
case let .custom(fileId):
|
case let .custom(fileId):
|
||||||
return fileId
|
return fileId
|
||||||
|
case .stars:
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|> map { files -> [OrderedItemListEntry] in
|
|> map { files -> [OrderedItemListEntry] in
|
||||||
@ -493,6 +503,8 @@ func managedTopReactions(postbox: Postbox, network: Network) -> Signal<Void, NoE
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
item = RecentReactionItem(.custom(file))
|
item = RecentReactionItem(.custom(file))
|
||||||
|
case .stars:
|
||||||
|
item = RecentReactionItem(.stars)
|
||||||
}
|
}
|
||||||
if let entry = CodableEntry(item) {
|
if let entry = CodableEntry(item) {
|
||||||
items.append(OrderedItemListEntry(id: item.id.rawValue, contents: entry))
|
items.append(OrderedItemListEntry(id: item.id.rawValue, contents: entry))
|
||||||
@ -513,6 +525,8 @@ func managedDefaultTagReactions(postbox: Postbox, network: Network) -> Signal<Vo
|
|||||||
return 0
|
return 0
|
||||||
case let .custom(fileId):
|
case let .custom(fileId):
|
||||||
return fileId.id
|
return fileId.id
|
||||||
|
case .stars:
|
||||||
|
return 0
|
||||||
}
|
}
|
||||||
}, reverseHashOrder: false, forceFetch: false, fetch: { hash in
|
}, reverseHashOrder: false, forceFetch: false, fetch: { hash in
|
||||||
return network.request(Api.functions.messages.getDefaultTagReactions(hash: hash))
|
return network.request(Api.functions.messages.getDefaultTagReactions(hash: hash))
|
||||||
@ -530,6 +544,8 @@ func managedDefaultTagReactions(postbox: Postbox, network: Network) -> Signal<Vo
|
|||||||
return nil
|
return nil
|
||||||
case let .custom(fileId):
|
case let .custom(fileId):
|
||||||
return fileId
|
return fileId
|
||||||
|
case .stars:
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|> map { files -> [OrderedItemListEntry] in
|
|> map { files -> [OrderedItemListEntry] in
|
||||||
@ -544,6 +560,8 @@ func managedDefaultTagReactions(postbox: Postbox, network: Network) -> Signal<Vo
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
item = RecentReactionItem(.custom(file))
|
item = RecentReactionItem(.custom(file))
|
||||||
|
case .stars:
|
||||||
|
item = RecentReactionItem(.stars)
|
||||||
}
|
}
|
||||||
if let entry = CodableEntry(item) {
|
if let entry = CodableEntry(item) {
|
||||||
items.append(OrderedItemListEntry(id: item.id.rawValue, contents: entry))
|
items.append(OrderedItemListEntry(id: item.id.rawValue, contents: entry))
|
||||||
|
@ -7,6 +7,7 @@ import MtProtoKit
|
|||||||
public enum UpdateMessageReaction {
|
public enum UpdateMessageReaction {
|
||||||
case builtin(String)
|
case builtin(String)
|
||||||
case custom(fileId: Int64, file: TelegramMediaFile?)
|
case custom(fileId: Int64, file: TelegramMediaFile?)
|
||||||
|
case stars
|
||||||
|
|
||||||
public var reaction: MessageReaction.Reaction {
|
public var reaction: MessageReaction.Reaction {
|
||||||
switch self {
|
switch self {
|
||||||
@ -14,6 +15,8 @@ public enum UpdateMessageReaction {
|
|||||||
return .builtin(value)
|
return .builtin(value)
|
||||||
case let .custom(fileId, _):
|
case let .custom(fileId, _):
|
||||||
return .custom(fileId)
|
return .custom(fileId)
|
||||||
|
case .stars:
|
||||||
|
return .stars
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -83,6 +86,8 @@ public func updateMessageReactionsInteractively(account: Account, messageIds: [M
|
|||||||
mappedValue = .builtin(value)
|
mappedValue = .builtin(value)
|
||||||
case let .custom(fileId):
|
case let .custom(fileId):
|
||||||
mappedValue = .custom(fileId: fileId, file: nil)
|
mappedValue = .custom(fileId: fileId, file: nil)
|
||||||
|
case .stars:
|
||||||
|
mappedValue = .stars
|
||||||
}
|
}
|
||||||
reactions.append(mappedValue)
|
reactions.append(mappedValue)
|
||||||
}
|
}
|
||||||
@ -99,6 +104,8 @@ public func updateMessageReactionsInteractively(account: Account, messageIds: [M
|
|||||||
}
|
}
|
||||||
case let .builtin(value):
|
case let .builtin(value):
|
||||||
mappedReactions.append(PendingReactionsMessageAttribute.PendingReaction(value: .builtin(value), sendAsPeerId: sendAsPeerId))
|
mappedReactions.append(PendingReactionsMessageAttribute.PendingReaction(value: .builtin(value), sendAsPeerId: sendAsPeerId))
|
||||||
|
case .stars:
|
||||||
|
mappedReactions.append(PendingReactionsMessageAttribute.PendingReaction(value: .stars, sendAsPeerId: sendAsPeerId))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -132,6 +139,8 @@ public func updateMessageReactionsInteractively(account: Account, messageIds: [M
|
|||||||
} else {
|
} else {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
case .stars:
|
||||||
|
recentReactionItem = RecentReactionItem(.stars)
|
||||||
}
|
}
|
||||||
|
|
||||||
if let entry = CodableEntry(recentReactionItem) {
|
if let entry = CodableEntry(recentReactionItem) {
|
||||||
@ -163,6 +172,32 @@ public func updateMessageReactionsInteractively(account: Account, messageIds: [M
|
|||||||
|> ignoreValues
|
|> ignoreValues
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public func sendStarsReactionsInteractively(account: Account, messageId: MessageId, count: Int) -> Signal<Never, NoError> {
|
||||||
|
return account.postbox.transaction { transaction -> Void in
|
||||||
|
transaction.setPendingMessageAction(type: .sendStarsReaction, id: messageId, action: SendStarsReactionsAction(randomId: Int64.random(in: Int64.min ... Int64.max)))
|
||||||
|
transaction.updateMessage(messageId, update: { currentMessage in
|
||||||
|
var storeForwardInfo: StoreMessageForwardInfo?
|
||||||
|
if let forwardInfo = currentMessage.forwardInfo {
|
||||||
|
storeForwardInfo = StoreMessageForwardInfo(authorId: forwardInfo.author?.id, sourceId: forwardInfo.source?.id, sourceMessageId: forwardInfo.sourceMessageId, date: forwardInfo.date, authorSignature: forwardInfo.authorSignature, psaType: forwardInfo.psaType, flags: forwardInfo.flags)
|
||||||
|
}
|
||||||
|
var mappedCount = Int32(count)
|
||||||
|
var attributes = currentMessage.attributes
|
||||||
|
loop: for j in 0 ..< attributes.count {
|
||||||
|
if let current = attributes[j] as? PendingStarsReactionsMessageAttribute {
|
||||||
|
mappedCount += current.count
|
||||||
|
attributes.remove(at: j)
|
||||||
|
break loop
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
attributes.append(PendingStarsReactionsMessageAttribute(accountPeerId: account.peerId, count: mappedCount))
|
||||||
|
|
||||||
|
return .update(StoreMessage(id: currentMessage.id, globallyUniqueId: currentMessage.globallyUniqueId, groupingKey: currentMessage.groupingKey, threadId: currentMessage.threadId, timestamp: currentMessage.timestamp, flags: StoreMessageFlags(currentMessage.flags), tags: currentMessage.tags, globalTags: currentMessage.globalTags, localTags: currentMessage.localTags, forwardInfo: storeForwardInfo, authorId: currentMessage.author?.id, text: currentMessage.text, attributes: attributes, media: currentMessage.media))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|> ignoreValues
|
||||||
|
}
|
||||||
|
|
||||||
private enum RequestUpdateMessageReactionError {
|
private enum RequestUpdateMessageReactionError {
|
||||||
case generic
|
case generic
|
||||||
}
|
}
|
||||||
@ -250,6 +285,76 @@ private func requestUpdateMessageReaction(postbox: Postbox, network: Network, st
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private func requestSendStarsReaction(postbox: Postbox, network: Network, stateManager: AccountStateManager, messageId: MessageId) -> Signal<Never, RequestUpdateMessageReactionError> {
|
||||||
|
return postbox.transaction { transaction -> (Peer, Int32)? in
|
||||||
|
guard let peer = transaction.getPeer(messageId.peerId) else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
guard let message = transaction.getMessage(messageId) else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
var count: Int32 = 0
|
||||||
|
for attribute in message.attributes {
|
||||||
|
if let attribute = attribute as? PendingStarsReactionsMessageAttribute {
|
||||||
|
count += attribute.count
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (peer, count)
|
||||||
|
}
|
||||||
|
|> castError(RequestUpdateMessageReactionError.self)
|
||||||
|
|> mapToSignal { peerAndValue in
|
||||||
|
guard let (peer, count) = peerAndValue else {
|
||||||
|
return .fail(.generic)
|
||||||
|
}
|
||||||
|
guard let inputPeer = apiInputPeer(peer) else {
|
||||||
|
return .fail(.generic)
|
||||||
|
}
|
||||||
|
if messageId.namespace != Namespaces.Message.Cloud {
|
||||||
|
return .fail(.generic)
|
||||||
|
}
|
||||||
|
|
||||||
|
if count > 0 {
|
||||||
|
let randomPartId = UInt64(UInt32(bitPattern: Int32.random(in: Int32.min ... Int32.max)))
|
||||||
|
let timestampPart = UInt64(UInt32(bitPattern: Int32(Date().timeIntervalSince1970)))
|
||||||
|
let randomId = (timestampPart << 32) | randomPartId
|
||||||
|
|
||||||
|
let signal: Signal<Never, RequestUpdateMessageReactionError> = network.request(Api.functions.messages.sendPaidReaction(peer: inputPeer, msgId: messageId.id, count: count, randomId: Int64(bitPattern: randomId)))
|
||||||
|
|> mapError { _ -> RequestUpdateMessageReactionError in
|
||||||
|
return .generic
|
||||||
|
}
|
||||||
|
|> mapToSignal { result -> Signal<Never, RequestUpdateMessageReactionError> in
|
||||||
|
return postbox.transaction { transaction -> Void in
|
||||||
|
transaction.setPendingMessageAction(type: .sendStarsReaction, id: messageId, action: UpdateMessageReactionsAction())
|
||||||
|
transaction.updateMessage(messageId, update: { currentMessage in
|
||||||
|
var storeForwardInfo: StoreMessageForwardInfo?
|
||||||
|
if let forwardInfo = currentMessage.forwardInfo {
|
||||||
|
storeForwardInfo = StoreMessageForwardInfo(authorId: forwardInfo.author?.id, sourceId: forwardInfo.source?.id, sourceMessageId: forwardInfo.sourceMessageId, date: forwardInfo.date, authorSignature: forwardInfo.authorSignature, psaType: forwardInfo.psaType, flags: forwardInfo.flags)
|
||||||
|
}
|
||||||
|
let reactions = mergedMessageReactions(attributes: currentMessage.attributes, isTags: currentMessage.areReactionsTags(accountPeerId: stateManager.accountPeerId))
|
||||||
|
var attributes = currentMessage.attributes
|
||||||
|
for j in (0 ..< attributes.count).reversed() {
|
||||||
|
if attributes[j] is PendingStarsReactionsMessageAttribute || attributes[j] is ReactionsMessageAttribute {
|
||||||
|
attributes.remove(at: j)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if let reactions {
|
||||||
|
attributes.append(reactions)
|
||||||
|
}
|
||||||
|
return .update(StoreMessage(id: currentMessage.id, globallyUniqueId: currentMessage.globallyUniqueId, groupingKey: currentMessage.groupingKey, threadId: currentMessage.threadId, timestamp: currentMessage.timestamp, flags: StoreMessageFlags(currentMessage.flags), tags: currentMessage.tags, globalTags: currentMessage.globalTags, localTags: currentMessage.localTags, forwardInfo: storeForwardInfo, authorId: currentMessage.author?.id, text: currentMessage.text, attributes: attributes, media: currentMessage.media))
|
||||||
|
})
|
||||||
|
stateManager.addUpdates(result)
|
||||||
|
}
|
||||||
|
|> castError(RequestUpdateMessageReactionError.self)
|
||||||
|
|> ignoreValues
|
||||||
|
}
|
||||||
|
return signal
|
||||||
|
} else {
|
||||||
|
return .complete()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private final class ManagedApplyPendingMessageReactionsActionsHelper {
|
private final class ManagedApplyPendingMessageReactionsActionsHelper {
|
||||||
var operationDisposables: [MessageId: Disposable] = [:]
|
var operationDisposables: [MessageId: Disposable] = [:]
|
||||||
|
|
||||||
@ -294,7 +399,7 @@ private final class ManagedApplyPendingMessageReactionsActionsHelper {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private func withTakenAction(postbox: Postbox, type: PendingMessageActionType, id: MessageId, _ f: @escaping (Transaction, PendingMessageActionsEntry?) -> Signal<Never, NoError>) -> Signal<Never, NoError> {
|
private func withTakenReactionsAction(postbox: Postbox, type: PendingMessageActionType, id: MessageId, _ f: @escaping (Transaction, PendingMessageActionsEntry?) -> Signal<Never, NoError>) -> Signal<Never, NoError> {
|
||||||
return postbox.transaction { transaction -> Signal<Never, NoError> in
|
return postbox.transaction { transaction -> Signal<Never, NoError> in
|
||||||
var result: PendingMessageActionsEntry?
|
var result: PendingMessageActionsEntry?
|
||||||
|
|
||||||
@ -307,6 +412,19 @@ private func withTakenAction(postbox: Postbox, type: PendingMessageActionType, i
|
|||||||
|> switchToLatest
|
|> switchToLatest
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private func withTakenStarsAction(postbox: Postbox, type: PendingMessageActionType, id: MessageId, _ f: @escaping (Transaction, PendingMessageActionsEntry?) -> Signal<Never, NoError>) -> Signal<Never, NoError> {
|
||||||
|
return postbox.transaction { transaction -> Signal<Never, NoError> in
|
||||||
|
var result: PendingMessageActionsEntry?
|
||||||
|
|
||||||
|
if let action = transaction.getPendingMessageAction(type: type, id: id) as? SendStarsReactionsAction {
|
||||||
|
result = PendingMessageActionsEntry(id: id, action: action)
|
||||||
|
}
|
||||||
|
|
||||||
|
return f(transaction, result)
|
||||||
|
}
|
||||||
|
|> switchToLatest
|
||||||
|
}
|
||||||
|
|
||||||
func managedApplyPendingMessageReactionsActions(postbox: Postbox, network: Network, stateManager: AccountStateManager) -> Signal<Void, NoError> {
|
func managedApplyPendingMessageReactionsActions(postbox: Postbox, network: Network, stateManager: AccountStateManager) -> Signal<Void, NoError> {
|
||||||
return Signal { _ in
|
return Signal { _ in
|
||||||
let helper = Atomic<ManagedApplyPendingMessageReactionsActionsHelper>(value: ManagedApplyPendingMessageReactionsActionsHelper())
|
let helper = Atomic<ManagedApplyPendingMessageReactionsActionsHelper>(value: ManagedApplyPendingMessageReactionsActionsHelper())
|
||||||
@ -327,7 +445,7 @@ func managedApplyPendingMessageReactionsActions(postbox: Postbox, network: Netwo
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (entry, disposable) in beginOperations {
|
for (entry, disposable) in beginOperations {
|
||||||
let signal = withTakenAction(postbox: postbox, type: .updateReaction, id: entry.id, { transaction, entry -> Signal<Never, NoError> in
|
let signal = withTakenReactionsAction(postbox: postbox, type: .updateReaction, id: entry.id, { transaction, entry -> Signal<Never, NoError> in
|
||||||
if let entry = entry {
|
if let entry = entry {
|
||||||
if let _ = entry.action as? UpdateMessageReactionsAction {
|
if let _ = entry.action as? UpdateMessageReactionsAction {
|
||||||
return synchronizeMessageReactions(transaction: transaction, postbox: postbox, network: network, stateManager: stateManager, id: entry.id)
|
return synchronizeMessageReactions(transaction: transaction, postbox: postbox, network: network, stateManager: stateManager, id: entry.id)
|
||||||
@ -360,6 +478,60 @@ func managedApplyPendingMessageReactionsActions(postbox: Postbox, network: Netwo
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func managedApplyPendingMessageStarsReactionsActions(postbox: Postbox, network: Network, stateManager: AccountStateManager) -> Signal<Void, NoError> {
|
||||||
|
return Signal { _ in
|
||||||
|
let helper = Atomic<ManagedApplyPendingMessageReactionsActionsHelper>(value: ManagedApplyPendingMessageReactionsActionsHelper())
|
||||||
|
|
||||||
|
let actionsKey = PostboxViewKey.pendingMessageActions(type: .sendStarsReaction)
|
||||||
|
let disposable = postbox.combinedView(keys: [actionsKey]).start(next: { view in
|
||||||
|
var entries: [PendingMessageActionsEntry] = []
|
||||||
|
if let v = view.views[actionsKey] as? PendingMessageActionsView {
|
||||||
|
entries = v.entries
|
||||||
|
}
|
||||||
|
|
||||||
|
let (disposeOperations, beginOperations) = helper.with { helper -> (disposeOperations: [Disposable], beginOperations: [(PendingMessageActionsEntry, MetaDisposable)]) in
|
||||||
|
return helper.update(entries: entries)
|
||||||
|
}
|
||||||
|
|
||||||
|
for disposable in disposeOperations {
|
||||||
|
disposable.dispose()
|
||||||
|
}
|
||||||
|
|
||||||
|
for (entry, disposable) in beginOperations {
|
||||||
|
let signal = withTakenStarsAction(postbox: postbox, type: .sendStarsReaction, id: entry.id, { transaction, entry -> Signal<Never, NoError> in
|
||||||
|
if let entry = entry {
|
||||||
|
if let _ = entry.action as? SendStarsReactionsAction {
|
||||||
|
return synchronizeMessageStarsReactions(transaction: transaction, postbox: postbox, network: network, stateManager: stateManager, id: entry.id)
|
||||||
|
|> delay(5.0, queue: .mainQueue())
|
||||||
|
} else {
|
||||||
|
assertionFailure()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return .complete()
|
||||||
|
})
|
||||||
|
|> then(
|
||||||
|
postbox.transaction { transaction -> Void in
|
||||||
|
transaction.setPendingMessageAction(type: .sendStarsReaction, id: entry.id, action: nil)
|
||||||
|
}
|
||||||
|
|> ignoreValues
|
||||||
|
)
|
||||||
|
|
||||||
|
disposable.set(signal.start())
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
return ActionDisposable {
|
||||||
|
let disposables = helper.with { helper -> [Disposable] in
|
||||||
|
return helper.reset()
|
||||||
|
}
|
||||||
|
for disposable in disposables {
|
||||||
|
disposable.dispose()
|
||||||
|
}
|
||||||
|
disposable.dispose()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private func synchronizeMessageReactions(transaction: Transaction, postbox: Postbox, network: Network, stateManager: AccountStateManager, id: MessageId) -> Signal<Never, NoError> {
|
private func synchronizeMessageReactions(transaction: Transaction, postbox: Postbox, network: Network, stateManager: AccountStateManager, id: MessageId) -> Signal<Never, NoError> {
|
||||||
return requestUpdateMessageReaction(postbox: postbox, network: network, stateManager: stateManager, messageId: id)
|
return requestUpdateMessageReaction(postbox: postbox, network: network, stateManager: stateManager, messageId: id)
|
||||||
|> `catch` { _ -> Signal<Never, NoError> in
|
|> `catch` { _ -> Signal<Never, NoError> in
|
||||||
@ -384,6 +556,30 @@ private func synchronizeMessageReactions(transaction: Transaction, postbox: Post
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private func synchronizeMessageStarsReactions(transaction: Transaction, postbox: Postbox, network: Network, stateManager: AccountStateManager, id: MessageId) -> Signal<Never, NoError> {
|
||||||
|
return requestSendStarsReaction(postbox: postbox, network: network, stateManager: stateManager, messageId: id)
|
||||||
|
|> `catch` { _ -> Signal<Never, NoError> in
|
||||||
|
return postbox.transaction { transaction -> Void in
|
||||||
|
transaction.setPendingMessageAction(type: .sendStarsReaction, id: id, action: nil)
|
||||||
|
transaction.updateMessage(id, update: { currentMessage in
|
||||||
|
var storeForwardInfo: StoreMessageForwardInfo?
|
||||||
|
if let forwardInfo = currentMessage.forwardInfo {
|
||||||
|
storeForwardInfo = StoreMessageForwardInfo(authorId: forwardInfo.author?.id, sourceId: forwardInfo.source?.id, sourceMessageId: forwardInfo.sourceMessageId, date: forwardInfo.date, authorSignature: forwardInfo.authorSignature, psaType: forwardInfo.psaType, flags: forwardInfo.flags)
|
||||||
|
}
|
||||||
|
var attributes = currentMessage.attributes
|
||||||
|
loop: for j in 0 ..< attributes.count {
|
||||||
|
if let _ = attributes[j] as? PendingStarsReactionsMessageAttribute {
|
||||||
|
attributes.remove(at: j)
|
||||||
|
break loop
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return .update(StoreMessage(id: currentMessage.id, globallyUniqueId: currentMessage.globallyUniqueId, groupingKey: currentMessage.groupingKey, threadId: currentMessage.threadId, timestamp: currentMessage.timestamp, flags: StoreMessageFlags(currentMessage.flags), tags: currentMessage.tags, globalTags: currentMessage.globalTags, localTags: currentMessage.localTags, forwardInfo: storeForwardInfo, authorId: currentMessage.author?.id, text: currentMessage.text, attributes: attributes, media: currentMessage.media))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|> ignoreValues
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public extension EngineMessageReactionListContext.State {
|
public extension EngineMessageReactionListContext.State {
|
||||||
init(message: EngineMessage, readStats: MessageReadStats?, reaction: MessageReaction.Reaction?) {
|
init(message: EngineMessage, readStats: MessageReadStats?, reaction: MessageReaction.Reaction?) {
|
||||||
var totalCount = 0
|
var totalCount = 0
|
||||||
@ -682,7 +878,13 @@ func _internal_updatePeerReactionSettings(account: Account, peerId: PeerId, reac
|
|||||||
reactionLimitValue = maxReactionCount
|
reactionLimitValue = maxReactionCount
|
||||||
}
|
}
|
||||||
|
|
||||||
return account.network.request(Api.functions.messages.setChatAvailableReactions(flags: flags, peer: inputPeer, availableReactions: mappedReactions, reactionsLimit: reactionLimitValue))
|
var paidEnabled: Api.Bool?
|
||||||
|
if let starsAllowed = reactionSettings.starsAllowed {
|
||||||
|
flags |= 1 << 1
|
||||||
|
paidEnabled = starsAllowed ? .boolTrue : .boolFalse
|
||||||
|
}
|
||||||
|
|
||||||
|
return account.network.request(Api.functions.messages.setChatAvailableReactions(flags: flags, peer: inputPeer, availableReactions: mappedReactions, reactionsLimit: reactionLimitValue, paidEnabled: paidEnabled))
|
||||||
|> map(Optional.init)
|
|> map(Optional.init)
|
||||||
|> `catch` { error -> Signal<Api.Updates?, UpdatePeerAllowedReactionsError> in
|
|> `catch` { error -> Signal<Api.Updates?, UpdatePeerAllowedReactionsError> in
|
||||||
if error.errorDescription == "CHAT_NOT_MODIFIED" {
|
if error.errorDescription == "CHAT_NOT_MODIFIED" {
|
||||||
|
@ -210,7 +210,7 @@ public class BoxedMessage: NSObject {
|
|||||||
|
|
||||||
public class Serialization: NSObject, MTSerialization {
|
public class Serialization: NSObject, MTSerialization {
|
||||||
public func currentLayer() -> UInt {
|
public func currentLayer() -> UInt {
|
||||||
return 185
|
return 186
|
||||||
}
|
}
|
||||||
|
|
||||||
public func parseMessage(_ data: Data!) -> Any! {
|
public func parseMessage(_ data: Data!) -> Any! {
|
||||||
|
@ -182,7 +182,7 @@ extension Api.Chat {
|
|||||||
return PeerId(namespace: Namespaces.Peer.CloudGroup, id: PeerId.Id._internalFromInt64Value(id))
|
return PeerId(namespace: Namespaces.Peer.CloudGroup, id: PeerId.Id._internalFromInt64Value(id))
|
||||||
case let .chatForbidden(id, _):
|
case let .chatForbidden(id, _):
|
||||||
return PeerId(namespace: Namespaces.Peer.CloudGroup, id: PeerId.Id._internalFromInt64Value(id))
|
return PeerId(namespace: Namespaces.Peer.CloudGroup, id: PeerId.Id._internalFromInt64Value(id))
|
||||||
case let .channel(_, _, id, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _):
|
case let .channel(_, _, id, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _):
|
||||||
return PeerId(namespace: Namespaces.Peer.CloudChannel, id: PeerId.Id._internalFromInt64Value(id))
|
return PeerId(namespace: Namespaces.Peer.CloudChannel, id: PeerId.Id._internalFromInt64Value(id))
|
||||||
case let .channelForbidden(_, id, _, _, _):
|
case let .channelForbidden(_, id, _, _, _):
|
||||||
return PeerId(namespace: Namespaces.Peer.CloudChannel, id: PeerId.Id._internalFromInt64Value(id))
|
return PeerId(namespace: Namespaces.Peer.CloudChannel, id: PeerId.Id._internalFromInt64Value(id))
|
||||||
|
@ -636,10 +636,10 @@ public final class CachedChannelData: CachedPeerData {
|
|||||||
self.reactionSettings = .known(reactionSettings)
|
self.reactionSettings = .known(reactionSettings)
|
||||||
} else if let legacyAllowedReactions = decoder.decodeOptionalStringArrayForKey("allowedReactions") {
|
} else if let legacyAllowedReactions = decoder.decodeOptionalStringArrayForKey("allowedReactions") {
|
||||||
let allowedReactions: PeerAllowedReactions = .limited(legacyAllowedReactions.map(MessageReaction.Reaction.builtin))
|
let allowedReactions: PeerAllowedReactions = .limited(legacyAllowedReactions.map(MessageReaction.Reaction.builtin))
|
||||||
self.reactionSettings = .known(PeerReactionSettings(allowedReactions: allowedReactions, maxReactionCount: nil))
|
self.reactionSettings = .known(PeerReactionSettings(allowedReactions: allowedReactions, maxReactionCount: nil, starsAllowed: nil))
|
||||||
} else if let allowedReactions = decoder.decode(PeerAllowedReactions.self, forKey: "allowedReactionSet") {
|
} else if let allowedReactions = decoder.decode(PeerAllowedReactions.self, forKey: "allowedReactionSet") {
|
||||||
let allowedReactions = allowedReactions
|
let allowedReactions = allowedReactions
|
||||||
self.reactionSettings = .known(PeerReactionSettings(allowedReactions: allowedReactions, maxReactionCount: nil))
|
self.reactionSettings = .known(PeerReactionSettings(allowedReactions: allowedReactions, maxReactionCount: nil, starsAllowed: nil))
|
||||||
} else {
|
} else {
|
||||||
self.reactionSettings = .unknown
|
self.reactionSettings = .unknown
|
||||||
}
|
}
|
||||||
|
@ -100,10 +100,12 @@ extension PeerAllowedReactions {
|
|||||||
public final class PeerReactionSettings: Equatable, Codable {
|
public final class PeerReactionSettings: Equatable, Codable {
|
||||||
public let allowedReactions: PeerAllowedReactions
|
public let allowedReactions: PeerAllowedReactions
|
||||||
public let maxReactionCount: Int32?
|
public let maxReactionCount: Int32?
|
||||||
|
public let starsAllowed: Bool?
|
||||||
|
|
||||||
public init(allowedReactions: PeerAllowedReactions, maxReactionCount: Int32?) {
|
public init(allowedReactions: PeerAllowedReactions, maxReactionCount: Int32?, starsAllowed: Bool?) {
|
||||||
self.allowedReactions = allowedReactions
|
self.allowedReactions = allowedReactions
|
||||||
self.maxReactionCount = maxReactionCount
|
self.maxReactionCount = maxReactionCount
|
||||||
|
self.starsAllowed = starsAllowed
|
||||||
}
|
}
|
||||||
|
|
||||||
public static func ==(lhs: PeerReactionSettings, rhs: PeerReactionSettings) -> Bool {
|
public static func ==(lhs: PeerReactionSettings, rhs: PeerReactionSettings) -> Bool {
|
||||||
@ -116,6 +118,9 @@ public final class PeerReactionSettings: Equatable, Codable {
|
|||||||
if lhs.maxReactionCount != rhs.maxReactionCount {
|
if lhs.maxReactionCount != rhs.maxReactionCount {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
if lhs.starsAllowed != rhs.starsAllowed {
|
||||||
|
return false
|
||||||
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -266,10 +271,10 @@ public final class CachedGroupData: CachedPeerData {
|
|||||||
self.reactionSettings = .known(reactionSettings)
|
self.reactionSettings = .known(reactionSettings)
|
||||||
} else if let legacyAllowedReactions = decoder.decodeOptionalStringArrayForKey("allowedReactions") {
|
} else if let legacyAllowedReactions = decoder.decodeOptionalStringArrayForKey("allowedReactions") {
|
||||||
let allowedReactions: PeerAllowedReactions = .limited(legacyAllowedReactions.map(MessageReaction.Reaction.builtin))
|
let allowedReactions: PeerAllowedReactions = .limited(legacyAllowedReactions.map(MessageReaction.Reaction.builtin))
|
||||||
self.reactionSettings = .known(PeerReactionSettings(allowedReactions: allowedReactions, maxReactionCount: nil))
|
self.reactionSettings = .known(PeerReactionSettings(allowedReactions: allowedReactions, maxReactionCount: nil, starsAllowed: nil))
|
||||||
} else if let allowedReactions = decoder.decode(PeerAllowedReactions.self, forKey: "allowedReactionSet") {
|
} else if let allowedReactions = decoder.decode(PeerAllowedReactions.self, forKey: "allowedReactionSet") {
|
||||||
let allowedReactions = allowedReactions
|
let allowedReactions = allowedReactions
|
||||||
self.reactionSettings = .known(PeerReactionSettings(allowedReactions: allowedReactions, maxReactionCount: nil))
|
self.reactionSettings = .known(PeerReactionSettings(allowedReactions: allowedReactions, maxReactionCount: nil, starsAllowed: nil))
|
||||||
} else {
|
} else {
|
||||||
self.reactionSettings = .unknown
|
self.reactionSettings = .unknown
|
||||||
}
|
}
|
||||||
|
@ -184,6 +184,7 @@ public extension PendingMessageActionType {
|
|||||||
static let updateReaction = PendingMessageActionType(rawValue: 1)
|
static let updateReaction = PendingMessageActionType(rawValue: 1)
|
||||||
static let sendScheduledMessageImmediately = PendingMessageActionType(rawValue: 2)
|
static let sendScheduledMessageImmediately = PendingMessageActionType(rawValue: 2)
|
||||||
static let readReaction = PendingMessageActionType(rawValue: 3)
|
static let readReaction = PendingMessageActionType(rawValue: 3)
|
||||||
|
static let sendStarsReaction = PendingMessageActionType(rawValue: 4)
|
||||||
}
|
}
|
||||||
|
|
||||||
public let peerIdNamespacesWithInitialCloudMessageHoles = [Namespaces.Peer.CloudUser, Namespaces.Peer.CloudGroup, Namespaces.Peer.CloudChannel]
|
public let peerIdNamespacesWithInitialCloudMessageHoles = [Namespaces.Peer.CloudUser, Namespaces.Peer.CloudGroup, Namespaces.Peer.CloudChannel]
|
||||||
|
@ -12,12 +12,15 @@ public struct MessageReaction: Equatable, PostboxCoding, Codable {
|
|||||||
public enum Reaction: Hashable, Comparable, Codable, PostboxCoding {
|
public enum Reaction: Hashable, Comparable, Codable, PostboxCoding {
|
||||||
case builtin(String)
|
case builtin(String)
|
||||||
case custom(Int64)
|
case custom(Int64)
|
||||||
|
case stars
|
||||||
|
|
||||||
public init(from decoder: Decoder) throws {
|
public init(from decoder: Decoder) throws {
|
||||||
let container = try decoder.container(keyedBy: StringCodingKey.self)
|
let container = try decoder.container(keyedBy: StringCodingKey.self)
|
||||||
|
|
||||||
if let value = try container.decodeIfPresent(String.self, forKey: "v") {
|
if let value = try container.decodeIfPresent(String.self, forKey: "v") {
|
||||||
self = .builtin(value)
|
self = .builtin(value)
|
||||||
|
} else if let _ = try container.decodeIfPresent(Int64.self, forKey: "star") {
|
||||||
|
self = .stars
|
||||||
} else {
|
} else {
|
||||||
self = .custom(try container.decode(Int64.self, forKey: "cfid"))
|
self = .custom(try container.decode(Int64.self, forKey: "cfid"))
|
||||||
}
|
}
|
||||||
@ -26,6 +29,8 @@ public struct MessageReaction: Equatable, PostboxCoding, Codable {
|
|||||||
public init(decoder: PostboxDecoder) {
|
public init(decoder: PostboxDecoder) {
|
||||||
if let value = decoder.decodeOptionalStringForKey("v") {
|
if let value = decoder.decodeOptionalStringForKey("v") {
|
||||||
self = .builtin(value)
|
self = .builtin(value)
|
||||||
|
} else if let _ = decoder.decodeOptionalInt64ForKey("star") {
|
||||||
|
self = .stars
|
||||||
} else {
|
} else {
|
||||||
self = .custom(decoder.decodeInt64ForKey("cfid", orElse: 0))
|
self = .custom(decoder.decodeInt64ForKey("cfid", orElse: 0))
|
||||||
}
|
}
|
||||||
@ -39,6 +44,8 @@ public struct MessageReaction: Equatable, PostboxCoding, Codable {
|
|||||||
try container.encode(value, forKey: "v")
|
try container.encode(value, forKey: "v")
|
||||||
case let .custom(fileId):
|
case let .custom(fileId):
|
||||||
try container.encode(fileId, forKey: "cfid")
|
try container.encode(fileId, forKey: "cfid")
|
||||||
|
case .stars:
|
||||||
|
try container.encode(0 as Int64, forKey: "star")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -48,6 +55,8 @@ public struct MessageReaction: Equatable, PostboxCoding, Codable {
|
|||||||
encoder.encodeString(value, forKey: "v")
|
encoder.encodeString(value, forKey: "v")
|
||||||
case let .custom(fileId):
|
case let .custom(fileId):
|
||||||
encoder.encodeInt64(fileId, forKey: "cfid")
|
encoder.encodeInt64(fileId, forKey: "cfid")
|
||||||
|
case .stars:
|
||||||
|
encoder.encodeInt64(0, forKey: "star")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -59,6 +68,8 @@ public struct MessageReaction: Equatable, PostboxCoding, Codable {
|
|||||||
return lhsValue < rhsValue
|
return lhsValue < rhsValue
|
||||||
case .custom:
|
case .custom:
|
||||||
return true
|
return true
|
||||||
|
case .stars:
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
case let .custom(lhsValue):
|
case let .custom(lhsValue):
|
||||||
switch rhs {
|
switch rhs {
|
||||||
@ -66,6 +77,17 @@ public struct MessageReaction: Equatable, PostboxCoding, Codable {
|
|||||||
return false
|
return false
|
||||||
case let .custom(rhsValue):
|
case let .custom(rhsValue):
|
||||||
return lhsValue < rhsValue
|
return lhsValue < rhsValue
|
||||||
|
case .stars:
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
case .stars:
|
||||||
|
switch rhs {
|
||||||
|
case .builtin:
|
||||||
|
return true
|
||||||
|
case .custom:
|
||||||
|
return true
|
||||||
|
case .stars:
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -88,6 +110,8 @@ public struct MessageReaction: Equatable, PostboxCoding, Codable {
|
|||||||
public init(decoder: PostboxDecoder) {
|
public init(decoder: PostboxDecoder) {
|
||||||
if let value = decoder.decodeOptionalStringForKey("v") {
|
if let value = decoder.decodeOptionalStringForKey("v") {
|
||||||
self.value = .builtin(value)
|
self.value = .builtin(value)
|
||||||
|
} else if let _ = decoder.decodeOptionalInt64ForKey("star") {
|
||||||
|
self.value = .stars
|
||||||
} else {
|
} else {
|
||||||
self.value = .custom(decoder.decodeInt64ForKey("cfid", orElse: 0))
|
self.value = .custom(decoder.decodeInt64ForKey("cfid", orElse: 0))
|
||||||
}
|
}
|
||||||
@ -106,6 +130,8 @@ public struct MessageReaction: Equatable, PostboxCoding, Codable {
|
|||||||
|
|
||||||
if let value = try container.decodeIfPresent(String.self, forKey: "v") {
|
if let value = try container.decodeIfPresent(String.self, forKey: "v") {
|
||||||
self.value = .builtin(value)
|
self.value = .builtin(value)
|
||||||
|
} else if let _ = try container.decodeIfPresent(Int64.self, forKey: "star") {
|
||||||
|
self.value = .stars
|
||||||
} else {
|
} else {
|
||||||
self.value = .custom(try container.decode(Int64.self, forKey: "cfid"))
|
self.value = .custom(try container.decode(Int64.self, forKey: "cfid"))
|
||||||
}
|
}
|
||||||
@ -125,6 +151,8 @@ public struct MessageReaction: Equatable, PostboxCoding, Codable {
|
|||||||
encoder.encodeString(value, forKey: "v")
|
encoder.encodeString(value, forKey: "v")
|
||||||
case let .custom(fileId):
|
case let .custom(fileId):
|
||||||
encoder.encodeInt64(fileId, forKey: "cfid")
|
encoder.encodeInt64(fileId, forKey: "cfid")
|
||||||
|
case .stars:
|
||||||
|
encoder.encodeInt64(0, forKey: "star")
|
||||||
}
|
}
|
||||||
encoder.encodeInt32(self.count, forKey: "c")
|
encoder.encodeInt32(self.count, forKey: "c")
|
||||||
if let chosenOrder = self.chosenOrder {
|
if let chosenOrder = self.chosenOrder {
|
||||||
@ -142,6 +170,8 @@ public struct MessageReaction: Equatable, PostboxCoding, Codable {
|
|||||||
try container.encode(value, forKey: "v")
|
try container.encode(value, forKey: "v")
|
||||||
case let .custom(fileId):
|
case let .custom(fileId):
|
||||||
try container.encode(fileId, forKey: "cfid")
|
try container.encode(fileId, forKey: "cfid")
|
||||||
|
case .stars:
|
||||||
|
try container.encode(0 as Int64, forKey: "star")
|
||||||
}
|
}
|
||||||
try container.encode(self.count, forKey: "c")
|
try container.encode(self.count, forKey: "c")
|
||||||
try container.encodeIfPresent(self.chosenOrder.flatMap(Int32.init), forKey: "cord")
|
try container.encodeIfPresent(self.chosenOrder.flatMap(Int32.init), forKey: "cord")
|
||||||
@ -157,6 +187,8 @@ extension MessageReaction.Reaction {
|
|||||||
self = .builtin(emoticon)
|
self = .builtin(emoticon)
|
||||||
case let .reactionCustomEmoji(documentId):
|
case let .reactionCustomEmoji(documentId):
|
||||||
self = .custom(documentId)
|
self = .custom(documentId)
|
||||||
|
case .reactionPaid:
|
||||||
|
self = .stars
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -166,6 +198,8 @@ extension MessageReaction.Reaction {
|
|||||||
return .reactionEmoji(emoticon: value)
|
return .reactionEmoji(emoticon: value)
|
||||||
case let .custom(fileId):
|
case let .custom(fileId):
|
||||||
return .reactionCustomEmoji(documentId: fileId)
|
return .reactionCustomEmoji(documentId: fileId)
|
||||||
|
case .stars:
|
||||||
|
return .reactionPaid
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -191,6 +225,9 @@ public final class ReactionsMessageAttribute: Equatable, MessageAttribute {
|
|||||||
var typeId: UInt8 = 1
|
var typeId: UInt8 = 1
|
||||||
buffer.write(&typeId, offset: 0, length: 1)
|
buffer.write(&typeId, offset: 0, length: 1)
|
||||||
buffer.write(&fileId, offset: 0, length: 8)
|
buffer.write(&fileId, offset: 0, length: 8)
|
||||||
|
case .stars:
|
||||||
|
var typeId: UInt8 = 2
|
||||||
|
buffer.write(&typeId, offset: 0, length: 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
return buffer
|
return buffer
|
||||||
@ -231,6 +268,8 @@ public final class ReactionsMessageAttribute: Equatable, MessageAttribute {
|
|||||||
var fileId: Int64 = 0
|
var fileId: Int64 = 0
|
||||||
readBuffer.read(&fileId, offset: 0, length: 8)
|
readBuffer.read(&fileId, offset: 0, length: 8)
|
||||||
return .custom(fileId)
|
return .custom(fileId)
|
||||||
|
case 2:
|
||||||
|
return .stars
|
||||||
default:
|
default:
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -256,6 +295,8 @@ public final class ReactionsMessageAttribute: Equatable, MessageAttribute {
|
|||||||
public init(decoder: PostboxDecoder) {
|
public init(decoder: PostboxDecoder) {
|
||||||
if let value = decoder.decodeOptionalStringForKey("v") {
|
if let value = decoder.decodeOptionalStringForKey("v") {
|
||||||
self.value = .builtin(value)
|
self.value = .builtin(value)
|
||||||
|
} else if let _ = decoder.decodeOptionalInt64ForKey("star") {
|
||||||
|
self.value = .stars
|
||||||
} else {
|
} else {
|
||||||
self.value = .custom(decoder.decodeInt64ForKey("cfid", orElse: 0))
|
self.value = .custom(decoder.decodeInt64ForKey("cfid", orElse: 0))
|
||||||
}
|
}
|
||||||
@ -272,6 +313,8 @@ public final class ReactionsMessageAttribute: Equatable, MessageAttribute {
|
|||||||
encoder.encodeString(value, forKey: "v")
|
encoder.encodeString(value, forKey: "v")
|
||||||
case let .custom(fileId):
|
case let .custom(fileId):
|
||||||
encoder.encodeInt64(fileId, forKey: "cfid")
|
encoder.encodeInt64(fileId, forKey: "cfid")
|
||||||
|
case .stars:
|
||||||
|
encoder.encodeInt64(0, forKey: "star")
|
||||||
}
|
}
|
||||||
encoder.encodeInt32(self.isLarge ? 1 : 0, forKey: "l")
|
encoder.encodeInt32(self.isLarge ? 1 : 0, forKey: "l")
|
||||||
encoder.encodeInt32(self.isUnseen ? 1 : 0, forKey: "u")
|
encoder.encodeInt32(self.isUnseen ? 1 : 0, forKey: "u")
|
||||||
@ -306,6 +349,8 @@ public final class ReactionsMessageAttribute: Equatable, MessageAttribute {
|
|||||||
if !result.contains(mediaId) {
|
if !result.contains(mediaId) {
|
||||||
result.append(mediaId)
|
result.append(mediaId)
|
||||||
}
|
}
|
||||||
|
case .stars:
|
||||||
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -430,6 +475,8 @@ public final class PendingReactionsMessageAttribute: MessageAttribute {
|
|||||||
if !result.contains(mediaId) {
|
if !result.contains(mediaId) {
|
||||||
result.append(mediaId)
|
result.append(mediaId)
|
||||||
}
|
}
|
||||||
|
case .stars:
|
||||||
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -466,3 +513,35 @@ public final class PendingReactionsMessageAttribute: MessageAttribute {
|
|||||||
encoder.encodeBool(self.isTags, forKey: "itag")
|
encoder.encodeBool(self.isTags, forKey: "itag")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public final class PendingStarsReactionsMessageAttribute: MessageAttribute {
|
||||||
|
public let accountPeerId: PeerId?
|
||||||
|
public let count: Int32
|
||||||
|
|
||||||
|
public var associatedPeerIds: [PeerId] {
|
||||||
|
var peerIds: [PeerId] = []
|
||||||
|
if let accountPeerId = self.accountPeerId {
|
||||||
|
peerIds.append(accountPeerId)
|
||||||
|
}
|
||||||
|
return peerIds
|
||||||
|
}
|
||||||
|
|
||||||
|
public init(accountPeerId: PeerId?, count: Int32) {
|
||||||
|
self.accountPeerId = accountPeerId
|
||||||
|
self.count = count
|
||||||
|
}
|
||||||
|
|
||||||
|
required public init(decoder: PostboxDecoder) {
|
||||||
|
self.accountPeerId = decoder.decodeOptionalInt64ForKey("ap").flatMap(PeerId.init)
|
||||||
|
self.count = decoder.decodeInt32ForKey("cnt", orElse: 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
public func encode(_ encoder: PostboxEncoder) {
|
||||||
|
if let accountPeerId = self.accountPeerId {
|
||||||
|
encoder.encodeInt64(accountPeerId.toInt64(), forKey: "ap")
|
||||||
|
} else {
|
||||||
|
encoder.encodeNil(forKey: "ap")
|
||||||
|
}
|
||||||
|
encoder.encodeInt32(self.count, forKey: "cnt")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -154,9 +154,10 @@ public final class RecentEmojiItem: Codable, Equatable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public struct RecentReactionItemId {
|
public struct RecentReactionItemId {
|
||||||
public enum Id : Hashable {
|
public enum Id: Hashable {
|
||||||
case custom(MediaId)
|
case custom(MediaId)
|
||||||
case builtin(String)
|
case builtin(String)
|
||||||
|
case stars
|
||||||
}
|
}
|
||||||
|
|
||||||
public let rawValue: MemoryBuffer
|
public let rawValue: MemoryBuffer
|
||||||
@ -184,6 +185,8 @@ public struct RecentReactionItemId {
|
|||||||
assert(rawValue.length >= 1 + 2 + Int(length))
|
assert(rawValue.length >= 1 + 2 + Int(length))
|
||||||
|
|
||||||
self.id = .builtin(String(data: Data(bytes: rawValue.memory.advanced(by: 1 + 2), count: Int(length)), encoding: .utf8) ?? ".")
|
self.id = .builtin(String(data: Data(bytes: rawValue.memory.advanced(by: 1 + 2), count: Int(length)), encoding: .utf8) ?? ".")
|
||||||
|
} else if type == 2 {
|
||||||
|
self.id = .stars
|
||||||
} else {
|
} else {
|
||||||
assert(false)
|
assert(false)
|
||||||
self.id = .builtin(".")
|
self.id = .builtin(".")
|
||||||
@ -216,12 +219,23 @@ public struct RecentReactionItemId {
|
|||||||
let _ = memcpy(self.rawValue.memory.advanced(by: 1 + 2), bytes.baseAddress!.assumingMemoryBound(to: UInt8.self), bytes.count)
|
let _ = memcpy(self.rawValue.memory.advanced(by: 1 + 2), bytes.baseAddress!.assumingMemoryBound(to: UInt8.self), bytes.count)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public init(_ id: Id) {
|
||||||
|
precondition(id == .stars)
|
||||||
|
self.id = id
|
||||||
|
|
||||||
|
self.rawValue = MemoryBuffer(memory: malloc(1)!, capacity: 1, length: 1, freeWhenDone: true)
|
||||||
|
|
||||||
|
var type: UInt8 = 2
|
||||||
|
memcpy(self.rawValue.memory.advanced(by: 0), &type, 1)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public final class RecentReactionItem: Codable, Equatable {
|
public final class RecentReactionItem: Codable, Equatable {
|
||||||
public enum Content: Equatable {
|
public enum Content: Equatable {
|
||||||
case custom(TelegramMediaFile)
|
case custom(TelegramMediaFile)
|
||||||
case builtin(String)
|
case builtin(String)
|
||||||
|
case stars
|
||||||
}
|
}
|
||||||
|
|
||||||
public let content: Content
|
public let content: Content
|
||||||
@ -232,6 +246,8 @@ public final class RecentReactionItem: Codable, Equatable {
|
|||||||
return RecentReactionItemId(value)
|
return RecentReactionItemId(value)
|
||||||
case let .custom(file):
|
case let .custom(file):
|
||||||
return RecentReactionItemId(file.fileId)
|
return RecentReactionItemId(file.fileId)
|
||||||
|
case .stars:
|
||||||
|
return RecentReactionItemId(.stars)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -244,6 +260,8 @@ public final class RecentReactionItem: Codable, Equatable {
|
|||||||
|
|
||||||
if let mediaData = try container.decodeIfPresent(AdaptedPostboxDecoder.RawObjectData.self, forKey: "m") {
|
if let mediaData = try container.decodeIfPresent(AdaptedPostboxDecoder.RawObjectData.self, forKey: "m") {
|
||||||
self.content = .custom(TelegramMediaFile(decoder: PostboxDecoder(buffer: MemoryBuffer(data: mediaData.data))))
|
self.content = .custom(TelegramMediaFile(decoder: PostboxDecoder(buffer: MemoryBuffer(data: mediaData.data))))
|
||||||
|
} else if let _ = try container.decodeIfPresent(Int64.self, forKey: "star") {
|
||||||
|
self.content = .stars
|
||||||
} else {
|
} else {
|
||||||
self.content = .builtin(try container.decode(String.self, forKey: "s"))
|
self.content = .builtin(try container.decode(String.self, forKey: "s"))
|
||||||
}
|
}
|
||||||
@ -257,6 +275,8 @@ public final class RecentReactionItem: Codable, Equatable {
|
|||||||
try container.encode(PostboxEncoder().encodeObjectToRawData(file), forKey: "m")
|
try container.encode(PostboxEncoder().encodeObjectToRawData(file), forKey: "m")
|
||||||
case let .builtin(string):
|
case let .builtin(string):
|
||||||
try container.encode(string, forKey: "s")
|
try container.encode(string, forKey: "s")
|
||||||
|
case .stars:
|
||||||
|
try container.encode(0 as Int64, forKey: "star")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,3 +18,30 @@ public final class UpdateMessageReactionsAction: PendingMessageActionData {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public final class SendStarsReactionsAction: PendingMessageActionData {
|
||||||
|
public let randomId: Int64
|
||||||
|
|
||||||
|
public init(randomId: Int64) {
|
||||||
|
self.randomId = randomId
|
||||||
|
}
|
||||||
|
|
||||||
|
public init(decoder: PostboxDecoder) {
|
||||||
|
self.randomId = decoder.decodeInt64ForKey("id", orElse: 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
public func encode(_ encoder: PostboxEncoder) {
|
||||||
|
encoder.encodeInt64(self.randomId, forKey: "id")
|
||||||
|
}
|
||||||
|
|
||||||
|
public func isEqual(to: PendingMessageActionData) -> Bool {
|
||||||
|
if let other = to as? SendStarsReactionsAction {
|
||||||
|
if self.randomId != other.randomId {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -2254,7 +2254,7 @@ func _internal_groupCallDisplayAsAvailablePeers(accountPeerId: PeerId, network:
|
|||||||
for chat in chats {
|
for chat in chats {
|
||||||
if let groupOrChannel = parseTelegramGroupOrChannel(chat: chat) {
|
if let groupOrChannel = parseTelegramGroupOrChannel(chat: chat) {
|
||||||
switch chat {
|
switch chat {
|
||||||
case let .channel(_, _, _, _, _, _, _, _, _, _, _, _, participantsCount, _, _, _, _, _, _):
|
case let .channel(_, _, _, _, _, _, _, _, _, _, _, _, participantsCount, _, _, _, _, _, _, _):
|
||||||
if let participantsCount = participantsCount {
|
if let participantsCount = participantsCount {
|
||||||
subscribers[groupOrChannel.id] = participantsCount
|
subscribers[groupOrChannel.id] = participantsCount
|
||||||
}
|
}
|
||||||
|
@ -505,6 +505,8 @@ public final class EngineStoryViewListContext {
|
|||||||
return nil
|
return nil
|
||||||
case let .custom(fileId):
|
case let .custom(fileId):
|
||||||
return transaction.getMedia(MediaId(namespace: Namespaces.Media.CloudFile, id: fileId)) as? TelegramMediaFile
|
return transaction.getMedia(MediaId(namespace: Namespaces.Media.CloudFile, id: fileId)) as? TelegramMediaFile
|
||||||
|
case .stars:
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)))
|
)))
|
||||||
@ -696,6 +698,8 @@ public final class EngineStoryViewListContext {
|
|||||||
reactionFile = nil
|
reactionFile = nil
|
||||||
case let .custom(fileId):
|
case let .custom(fileId):
|
||||||
reactionFile = transaction.getMedia(MediaId(namespace: Namespaces.Media.CloudFile, id: fileId)) as? TelegramMediaFile
|
reactionFile = transaction.getMedia(MediaId(namespace: Namespaces.Media.CloudFile, id: fileId)) as? TelegramMediaFile
|
||||||
|
case .stars:
|
||||||
|
reactionFile = nil
|
||||||
}
|
}
|
||||||
items.append(.view(Item.View(
|
items.append(.view(Item.View(
|
||||||
peer: EnginePeer(peer),
|
peer: EnginePeer(peer),
|
||||||
|
@ -138,7 +138,7 @@ func _internal_peerSendAsAvailablePeers(accountPeerId: PeerId, network: Network,
|
|||||||
for chat in chats {
|
for chat in chats {
|
||||||
if let groupOrChannel = parsedPeers.get(chat.peerId) {
|
if let groupOrChannel = parsedPeers.get(chat.peerId) {
|
||||||
switch chat {
|
switch chat {
|
||||||
case let .channel(_, _, _, _, _, _, _, _, _, _, _, _, participantsCount, _, _, _, _, _, _):
|
case let .channel(_, _, _, _, _, _, _, _, _, _, _, _, participantsCount, _, _, _, _, _, _, _):
|
||||||
if let participantsCount = participantsCount {
|
if let participantsCount = participantsCount {
|
||||||
subscribers[groupOrChannel.id] = participantsCount
|
subscribers[groupOrChannel.id] = participantsCount
|
||||||
}
|
}
|
||||||
|
@ -331,7 +331,11 @@ public extension TelegramEngine {
|
|||||||
isLarge: false,
|
isLarge: false,
|
||||||
storeAsRecentlyUsed: false,
|
storeAsRecentlyUsed: false,
|
||||||
add: true
|
add: true
|
||||||
).start()
|
).startStandalone()
|
||||||
|
}
|
||||||
|
|
||||||
|
public func sendStarsReaction(id: EngineMessage.Id, count: Int) {
|
||||||
|
let _ = sendStarsReactionsInteractively(account: self.account, messageId: id, count: count).startStandalone()
|
||||||
}
|
}
|
||||||
|
|
||||||
public func requestChatContextResults(botId: PeerId, peerId: PeerId, query: String, location: Signal<(Double, Double)?, NoError> = .single(nil), offset: String, incompleteResults: Bool = false, staleCachedResults: Bool = false) -> Signal<RequestChatContextResultsResult?, RequestChatContextResultsError> {
|
public func requestChatContextResults(botId: PeerId, peerId: PeerId, query: String, location: Signal<(Double, Double)?, NoError> = .single(nil), offset: String, incompleteResults: Bool = false, staleCachedResults: Bool = false) -> Signal<RequestChatContextResultsResult?, RequestChatContextResultsError> {
|
||||||
|
@ -176,7 +176,7 @@ private func _internal_requestStarsState(account: Account, peerId: EnginePeer.Id
|
|||||||
default:
|
default:
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
signal = account.network.request(Api.functions.payments.getStarsTransactions(flags: flags, peer: inputPeer, offset: offset, limit: limit))
|
signal = account.network.request(Api.functions.payments.getStarsTransactions(flags: flags, subscriptionId: nil, peer: inputPeer, offset: offset, limit: limit))
|
||||||
} else {
|
} else {
|
||||||
signal = account.network.request(Api.functions.payments.getStarsStatus(peer: inputPeer))
|
signal = account.network.request(Api.functions.payments.getStarsStatus(peer: inputPeer))
|
||||||
}
|
}
|
||||||
@ -187,12 +187,12 @@ private func _internal_requestStarsState(account: Account, peerId: EnginePeer.Id
|
|||||||
|> mapToSignal { result -> Signal<InternalStarsStatus, RequestStarsStateError> in
|
|> mapToSignal { result -> Signal<InternalStarsStatus, RequestStarsStateError> in
|
||||||
return account.postbox.transaction { transaction -> InternalStarsStatus in
|
return account.postbox.transaction { transaction -> InternalStarsStatus in
|
||||||
switch result {
|
switch result {
|
||||||
case let .starsStatus(_, balance, history, nextOffset, chats, users):
|
case let .starsStatus(_, balance, _, _, _, history, nextOffset, chats, users):
|
||||||
let peers = AccumulatedPeers(chats: chats, users: users)
|
let peers = AccumulatedPeers(chats: chats, users: users)
|
||||||
updatePeers(transaction: transaction, accountPeerId: account.peerId, peers: peers)
|
updatePeers(transaction: transaction, accountPeerId: account.peerId, peers: peers)
|
||||||
|
|
||||||
var parsedTransactions: [StarsContext.State.Transaction] = []
|
var parsedTransactions: [StarsContext.State.Transaction] = []
|
||||||
for entry in history {
|
for entry in history ?? [] {
|
||||||
if let parsedTransaction = StarsContext.State.Transaction(apiTransaction: entry, peerId: peerId != account.peerId ? peerId : nil, transaction: transaction) {
|
if let parsedTransaction = StarsContext.State.Transaction(apiTransaction: entry, peerId: peerId != account.peerId ? peerId : nil, transaction: transaction) {
|
||||||
parsedTransactions.append(parsedTransaction)
|
parsedTransactions.append(parsedTransaction)
|
||||||
}
|
}
|
||||||
@ -317,7 +317,7 @@ private final class StarsContextImpl {
|
|||||||
private extension StarsContext.State.Transaction {
|
private extension StarsContext.State.Transaction {
|
||||||
init?(apiTransaction: Api.StarsTransaction, peerId: EnginePeer.Id?, transaction: Transaction) {
|
init?(apiTransaction: Api.StarsTransaction, peerId: EnginePeer.Id?, transaction: Transaction) {
|
||||||
switch apiTransaction {
|
switch apiTransaction {
|
||||||
case let .starsTransaction(apiFlags, id, stars, date, transactionPeer, title, description, photo, transactionDate, transactionUrl, _, messageId, extendedMedia):
|
case let .starsTransaction(apiFlags, id, stars, date, transactionPeer, title, description, photo, transactionDate, transactionUrl, _, messageId, extendedMedia, _):
|
||||||
let parsedPeer: StarsContext.State.Transaction.Peer
|
let parsedPeer: StarsContext.State.Transaction.Peer
|
||||||
var paidMessageId: MessageId?
|
var paidMessageId: MessageId?
|
||||||
switch transactionPeer {
|
switch transactionPeer {
|
||||||
@ -889,7 +889,7 @@ func _internal_getStarsTransaction(accountPeerId: PeerId, postbox: Postbox, netw
|
|||||||
}
|
}
|
||||||
|> mapToSignal { result -> Signal<StarsContext.State.Transaction?, NoError> in
|
|> mapToSignal { result -> Signal<StarsContext.State.Transaction?, NoError> in
|
||||||
return postbox.transaction { transaction -> StarsContext.State.Transaction? in
|
return postbox.transaction { transaction -> StarsContext.State.Transaction? in
|
||||||
guard let result, case let .starsStatus(_, _, transactions, _, chats, users) = result, let matchingTransaction = transactions.first else {
|
guard let result, case let .starsStatus(_, _, _, _, _, transactions, _, chats, users) = result, let matchingTransaction = transactions?.first else {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
let peers = AccumulatedPeers(chats: chats, users: users)
|
let peers = AccumulatedPeers(chats: chats, users: users)
|
||||||
|
@ -558,7 +558,7 @@ func _internal_adminedPublicChannels(account: Account, scope: AdminedPublicChann
|
|||||||
case let .chats(apiChats):
|
case let .chats(apiChats):
|
||||||
chats = apiChats
|
chats = apiChats
|
||||||
for chat in apiChats {
|
for chat in apiChats {
|
||||||
if case let .channel(_, _, _, _, _, _, _, _, _, _, _, _, participantsCount, _, _, _, _, _, _) = chat {
|
if case let .channel(_, _, _, _, _, _, _, _, _, _, _, _, participantsCount, _, _, _, _, _, _, _) = chat {
|
||||||
subscriberCounts[chat.peerId] = participantsCount.flatMap(Int.init)
|
subscriberCounts[chat.peerId] = participantsCount.flatMap(Int.init)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -630,7 +630,7 @@ func _internal_channelsForStories(account: Account) -> Signal<[Peer], NoError> {
|
|||||||
if let peer = transaction.getPeer(chat.peerId) {
|
if let peer = transaction.getPeer(chat.peerId) {
|
||||||
peers.append(peer)
|
peers.append(peer)
|
||||||
|
|
||||||
if case let .channel(_, _, _, _, _, _, _, _, _, _, _, _, participantsCount, _, _, _, _, _, _) = chat, let participantsCount = participantsCount {
|
if case let .channel(_, _, _, _, _, _, _, _, _, _, _, _, participantsCount, _, _, _, _, _, _, _) = chat, let participantsCount = participantsCount {
|
||||||
transaction.updatePeerCachedData(peerIds: Set([peer.id]), update: { _, current in
|
transaction.updatePeerCachedData(peerIds: Set([peer.id]), update: { _, current in
|
||||||
var current = current as? CachedChannelData ?? CachedChannelData()
|
var current = current as? CachedChannelData ?? CachedChannelData()
|
||||||
var participantsSummary = current.participantsSummary
|
var participantsSummary = current.participantsSummary
|
||||||
|
@ -117,7 +117,7 @@ func _internal_requestRecommendedChannels(account: Account, peerId: EnginePeer.I
|
|||||||
for chat in chats {
|
for chat in chats {
|
||||||
if let peer = transaction.getPeer(chat.peerId) {
|
if let peer = transaction.getPeer(chat.peerId) {
|
||||||
peers.append(EnginePeer(peer))
|
peers.append(EnginePeer(peer))
|
||||||
if case let .channel(_, _, _, _, _, _, _, _, _, _, _, _, participantsCount, _, _, _, _, _, _) = chat, let participantsCount = participantsCount {
|
if case let .channel(_, _, _, _, _, _, _, _, _, _, _, _, participantsCount, _, _, _, _, _, _, _) = chat, let participantsCount = participantsCount {
|
||||||
transaction.updatePeerCachedData(peerIds: Set([peer.id]), update: { _, current in
|
transaction.updatePeerCachedData(peerIds: Set([peer.id]), update: { _, current in
|
||||||
var current = current as? CachedChannelData ?? CachedChannelData()
|
var current = current as? CachedChannelData ?? CachedChannelData()
|
||||||
var participantsSummary = current.participantsSummary
|
var participantsSummary = current.participantsSummary
|
||||||
|
@ -280,7 +280,7 @@ func _internal_checkChatFolderLink(account: Account, slug: String) -> Signal<Cha
|
|||||||
var memberCounts: [PeerId: Int] = [:]
|
var memberCounts: [PeerId: Int] = [:]
|
||||||
|
|
||||||
for chat in chats {
|
for chat in chats {
|
||||||
if case let .channel(_, _, _, _, _, _, _, _, _, _, _, _, participantsCount, _, _, _, _, _, _) = chat {
|
if case let .channel(_, _, _, _, _, _, _, _, _, _, _, _, participantsCount, _, _, _, _, _, _, _) = chat {
|
||||||
if let participantsCount = participantsCount {
|
if let participantsCount = participantsCount {
|
||||||
memberCounts[chat.peerId] = Int(participantsCount)
|
memberCounts[chat.peerId] = Int(participantsCount)
|
||||||
}
|
}
|
||||||
@ -307,7 +307,7 @@ func _internal_checkChatFolderLink(account: Account, slug: String) -> Signal<Cha
|
|||||||
var memberCounts: [PeerId: Int] = [:]
|
var memberCounts: [PeerId: Int] = [:]
|
||||||
|
|
||||||
for chat in chats {
|
for chat in chats {
|
||||||
if case let .channel(_, _, _, _, _, _, _, _, _, _, _, _, participantsCount, _, _, _, _, _, _) = chat {
|
if case let .channel(_, _, _, _, _, _, _, _, _, _, _, _, participantsCount, _, _, _, _, _, _, _) = chat {
|
||||||
if let participantsCount = participantsCount {
|
if let participantsCount = participantsCount {
|
||||||
memberCounts[chat.peerId] = Int(participantsCount)
|
memberCounts[chat.peerId] = Int(participantsCount)
|
||||||
}
|
}
|
||||||
@ -621,7 +621,7 @@ func _internal_pollChatFolderUpdatesOnce(account: Account, folderId: Int32) -> S
|
|||||||
var memberCounts: [ChatListFiltersState.ChatListFilterUpdates.MemberCount] = []
|
var memberCounts: [ChatListFiltersState.ChatListFilterUpdates.MemberCount] = []
|
||||||
|
|
||||||
for chat in chats {
|
for chat in chats {
|
||||||
if case let .channel(_, _, _, _, _, _, _, _, _, _, _, _, participantsCount, _, _, _, _, _, _) = chat {
|
if case let .channel(_, _, _, _, _, _, _, _, _, _, _, _, participantsCount, _, _, _, _, _, _, _) = chat {
|
||||||
if let participantsCount = participantsCount {
|
if let participantsCount = participantsCount {
|
||||||
memberCounts.append(ChatListFiltersState.ChatListFilterUpdates.MemberCount(id: chat.peerId, count: participantsCount))
|
memberCounts.append(ChatListFiltersState.ChatListFilterUpdates.MemberCount(id: chat.peerId, count: participantsCount))
|
||||||
}
|
}
|
||||||
|
@ -31,7 +31,7 @@ func _internal_inactiveChannelList(network: Network) -> Signal<[InactiveChannel]
|
|||||||
var participantsCounts: [PeerId: Int32] = [:]
|
var participantsCounts: [PeerId: Int32] = [:]
|
||||||
for chat in chats {
|
for chat in chats {
|
||||||
switch chat {
|
switch chat {
|
||||||
case let .channel(_, _, _, _, _, _, _, _, _, _, _, _, participantsCountValue, _, _, _, _, _, _):
|
case let .channel(_, _, _, _, _, _, _, _, _, _, _, _, participantsCountValue, _, _, _, _, _, _, _):
|
||||||
if let participantsCountValue = participantsCountValue {
|
if let participantsCountValue = participantsCountValue {
|
||||||
participantsCounts[chat.peerId] = participantsCountValue
|
participantsCounts[chat.peerId] = participantsCountValue
|
||||||
}
|
}
|
||||||
|
@ -44,7 +44,7 @@ func _internal_revokePersistentPeerExportedInvitation(account: Account, peerId:
|
|||||||
if let peer = transaction.getPeer(peerId), let inputPeer = apiInputPeer(peer) {
|
if let peer = transaction.getPeer(peerId), let inputPeer = apiInputPeer(peer) {
|
||||||
let flags: Int32 = (1 << 2)
|
let flags: Int32 = (1 << 2)
|
||||||
if let _ = peer as? TelegramChannel {
|
if let _ = peer as? TelegramChannel {
|
||||||
return account.network.request(Api.functions.messages.exportChatInvite(flags: flags, peer: inputPeer, expireDate: nil, usageLimit: nil, title: nil))
|
return account.network.request(Api.functions.messages.exportChatInvite(flags: flags, peer: inputPeer, expireDate: nil, usageLimit: nil, title: nil, subscriptionPricing: nil))
|
||||||
|> retryRequest
|
|> retryRequest
|
||||||
|> mapToSignal { result -> Signal<ExportedInvitation?, NoError> in
|
|> mapToSignal { result -> Signal<ExportedInvitation?, NoError> in
|
||||||
return account.postbox.transaction { transaction -> ExportedInvitation? in
|
return account.postbox.transaction { transaction -> ExportedInvitation? in
|
||||||
@ -61,7 +61,7 @@ func _internal_revokePersistentPeerExportedInvitation(account: Account, peerId:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if let _ = peer as? TelegramGroup {
|
} else if let _ = peer as? TelegramGroup {
|
||||||
return account.network.request(Api.functions.messages.exportChatInvite(flags: flags, peer: inputPeer, expireDate: nil, usageLimit: nil, title: nil))
|
return account.network.request(Api.functions.messages.exportChatInvite(flags: flags, peer: inputPeer, expireDate: nil, usageLimit: nil, title: nil, subscriptionPricing: nil))
|
||||||
|> retryRequest
|
|> retryRequest
|
||||||
|> mapToSignal { result -> Signal<ExportedInvitation?, NoError> in
|
|> mapToSignal { result -> Signal<ExportedInvitation?, NoError> in
|
||||||
return account.postbox.transaction { transaction -> ExportedInvitation? in
|
return account.postbox.transaction { transaction -> ExportedInvitation? in
|
||||||
@ -106,7 +106,7 @@ func _internal_createPeerExportedInvitation(account: Account, peerId: PeerId, ti
|
|||||||
if let _ = title {
|
if let _ = title {
|
||||||
flags |= (1 << 4)
|
flags |= (1 << 4)
|
||||||
}
|
}
|
||||||
return account.network.request(Api.functions.messages.exportChatInvite(flags: flags, peer: inputPeer, expireDate: expireDate, usageLimit: usageLimit, title: title))
|
return account.network.request(Api.functions.messages.exportChatInvite(flags: flags, peer: inputPeer, expireDate: expireDate, usageLimit: usageLimit, title: title, subscriptionPricing: nil))
|
||||||
|> mapError { _ in return CreatePeerExportedInvitationError.generic }
|
|> mapError { _ in return CreatePeerExportedInvitationError.generic }
|
||||||
|> map { result -> ExportedInvitation? in
|
|> map { result -> ExportedInvitation? in
|
||||||
return ExportedInvitation(apiExportedInvite: result)
|
return ExportedInvitation(apiExportedInvite: result)
|
||||||
|
@ -106,7 +106,7 @@ func _internal_joinLinkInformation(_ hash: String, account: Account) -> Signal<E
|
|||||||
|> mapToSignal { result -> Signal<ExternalJoiningChatState, JoinLinkInfoError> in
|
|> mapToSignal { result -> Signal<ExternalJoiningChatState, JoinLinkInfoError> in
|
||||||
if let result = result {
|
if let result = result {
|
||||||
switch result {
|
switch result {
|
||||||
case let .chatInvite(flags, title, about, invitePhoto, participantsCount, participants, nameColor):
|
case let .chatInvite(flags, title, about, invitePhoto, participantsCount, participants, nameColor, _, _):
|
||||||
let photo = telegramMediaImageFromApiPhoto(invitePhoto).flatMap({ smallestImageRepresentation($0.representations) })
|
let photo = telegramMediaImageFromApiPhoto(invitePhoto).flatMap({ smallestImageRepresentation($0.representations) })
|
||||||
let flags: ExternalJoiningChatState.Invite.Flags = .init(isChannel: (flags & (1 << 0)) != 0, isBroadcast: (flags & (1 << 1)) != 0, isPublic: (flags & (1 << 2)) != 0, isMegagroup: (flags & (1 << 3)) != 0, requestNeeded: (flags & (1 << 6)) != 0, isVerified: (flags & (1 << 7)) != 0, isScam: (flags & (1 << 8)) != 0, isFake: (flags & (1 << 9)) != 0)
|
let flags: ExternalJoiningChatState.Invite.Flags = .init(isChannel: (flags & (1 << 0)) != 0, isBroadcast: (flags & (1 << 1)) != 0, isPublic: (flags & (1 << 2)) != 0, isMegagroup: (flags & (1 << 3)) != 0, requestNeeded: (flags & (1 << 6)) != 0, isVerified: (flags & (1 << 7)) != 0, isScam: (flags & (1 << 8)) != 0, isFake: (flags & (1 << 9)) != 0)
|
||||||
return .single(.invite(ExternalJoiningChatState.Invite(flags: flags, title: title, about: about, photoRepresentation: photo, participantsCount: participantsCount, participants: participants?.map({ EnginePeer(TelegramUser(user: $0)) }), nameColor: PeerNameColor(rawValue: nameColor))))
|
return .single(.invite(ExternalJoiningChatState.Invite(flags: flags, title: title, about: about, photoRepresentation: photo, participantsCount: participantsCount, participants: participants?.map({ EnginePeer(TelegramUser(user: $0)) }), nameColor: PeerNameColor(rawValue: nameColor))))
|
||||||
|
@ -42,7 +42,7 @@ public func _internal_searchPeers(accountPeerId: PeerId, postbox: Postbox, netwo
|
|||||||
for chat in chats {
|
for chat in chats {
|
||||||
if let groupOrChannel = parseTelegramGroupOrChannel(chat: chat) {
|
if let groupOrChannel = parseTelegramGroupOrChannel(chat: chat) {
|
||||||
switch chat {
|
switch chat {
|
||||||
case let .channel(_, _, _, _, _, _, _, _, _, _, _, _, participantsCount, _, _, _, _, _, _):
|
case let .channel(_, _, _, _, _, _, _, _, _, _, _, _, participantsCount, _, _, _, _, _, _, _):
|
||||||
if let participantsCount = participantsCount {
|
if let participantsCount = participantsCount {
|
||||||
subscribers[groupOrChannel.id] = participantsCount
|
subscribers[groupOrChannel.id] = participantsCount
|
||||||
}
|
}
|
||||||
|
@ -367,7 +367,7 @@ func _internal_fetchAndUpdateCachedPeerData(accountPeerId: PeerId, peerId rawPee
|
|||||||
var subscriberCount: Int32?
|
var subscriberCount: Int32?
|
||||||
for chat in chats {
|
for chat in chats {
|
||||||
if chat.peerId == channelPeerId {
|
if chat.peerId == channelPeerId {
|
||||||
if case let .channel(_, _, _, _, _, _, _, _, _, _, _, _, participantsCount, _, _, _, _, _, _) = chat {
|
if case let .channel(_, _, _, _, _, _, _, _, _, _, _, _, participantsCount, _, _, _, _, _, _, _) = chat {
|
||||||
subscriberCount = participantsCount
|
subscriberCount = participantsCount
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -509,7 +509,8 @@ func _internal_fetchAndUpdateCachedPeerData(accountPeerId: PeerId, peerId rawPee
|
|||||||
} else {
|
} else {
|
||||||
mappedAllowedReactions = .empty
|
mappedAllowedReactions = .empty
|
||||||
}
|
}
|
||||||
let mappedReactionSettings = PeerReactionSettings(allowedReactions: mappedAllowedReactions, maxReactionCount: reactionsLimit)
|
|
||||||
|
let mappedReactionSettings = PeerReactionSettings(allowedReactions: mappedAllowedReactions, maxReactionCount: reactionsLimit, starsAllowed: nil)
|
||||||
|
|
||||||
return previous.withUpdatedParticipants(participants)
|
return previous.withUpdatedParticipants(participants)
|
||||||
.withUpdatedExportedInvitation(exportedInvitation)
|
.withUpdatedExportedInvitation(exportedInvitation)
|
||||||
@ -556,10 +557,10 @@ func _internal_fetchAndUpdateCachedPeerData(accountPeerId: PeerId, peerId rawPee
|
|||||||
switch result {
|
switch result {
|
||||||
case let .chatFull(fullChat, chats, users):
|
case let .chatFull(fullChat, chats, users):
|
||||||
switch fullChat {
|
switch fullChat {
|
||||||
case let .channelFull(_, _, _, _, _, _, _, _, _, _, _, _, _, notifySettings, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _):
|
case let .channelFull(_, _, _, _, _, _, _, _, _, _, _, _, _, notifySettings, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _):
|
||||||
transaction.updateCurrentPeerNotificationSettings([peerId: TelegramPeerNotificationSettings(apiSettings: notifySettings)])
|
transaction.updateCurrentPeerNotificationSettings([peerId: TelegramPeerNotificationSettings(apiSettings: notifySettings)])
|
||||||
case .chatFull:
|
case .chatFull:
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
switch fullChat {
|
switch fullChat {
|
||||||
@ -691,7 +692,7 @@ func _internal_fetchAndUpdateCachedPeerData(accountPeerId: PeerId, peerId rawPee
|
|||||||
switch participantResult {
|
switch participantResult {
|
||||||
case let .channelParticipant(participant, _, _):
|
case let .channelParticipant(participant, _, _):
|
||||||
switch participant {
|
switch participant {
|
||||||
case let .channelParticipantSelf(flags, _, inviterId, invitedDate):
|
case let .channelParticipantSelf(_, _, inviterId, invitedDate, _):
|
||||||
invitedBy = PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(inviterId))
|
invitedBy = PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(inviterId))
|
||||||
if (flags & (1 << 0)) != 0 {
|
if (flags & (1 << 0)) != 0 {
|
||||||
invitedOn = invitedDate
|
invitedOn = invitedDate
|
||||||
@ -754,7 +755,8 @@ func _internal_fetchAndUpdateCachedPeerData(accountPeerId: PeerId, peerId rawPee
|
|||||||
} else {
|
} else {
|
||||||
mappedAllowedReactions = .empty
|
mappedAllowedReactions = .empty
|
||||||
}
|
}
|
||||||
let mappedReactionSettings = PeerReactionSettings(allowedReactions: mappedAllowedReactions, maxReactionCount: reactionsLimit)
|
let starsAllowed: Bool = (flags2 & (1 << 16)) != 0
|
||||||
|
let mappedReactionSettings = PeerReactionSettings(allowedReactions: mappedAllowedReactions, maxReactionCount: reactionsLimit, starsAllowed: starsAllowed)
|
||||||
|
|
||||||
let membersHidden = (flags2 & (1 << 2)) != 0
|
let membersHidden = (flags2 & (1 << 2)) != 0
|
||||||
let forumViewAsMessages = (flags2 & (1 << 6)) != 0
|
let forumViewAsMessages = (flags2 & (1 << 6)) != 0
|
||||||
|
@ -180,7 +180,7 @@ func _internal_requestAccountPrivacySettings(account: Account) -> Signal<Account
|
|||||||
if let peer = parseTelegramGroupOrChannel(chat: chat) {
|
if let peer = parseTelegramGroupOrChannel(chat: chat) {
|
||||||
var participantCount: Int32? = nil
|
var participantCount: Int32? = nil
|
||||||
switch chat {
|
switch chat {
|
||||||
case let .channel(_, _, _, _, _, _, _, _, _, _, _, _, participantsCountValue, _, _, _, _, _, _):
|
case let .channel(_, _, _, _, _, _, _, _, _, _, _, _, participantsCountValue, _, _, _, _, _, _, _):
|
||||||
participantCount = participantsCountValue
|
participantCount = participantsCountValue
|
||||||
default:
|
default:
|
||||||
break
|
break
|
||||||
|
@ -72,7 +72,7 @@ func updatePeers(transaction: Transaction, accountPeerId: PeerId, peers: Accumul
|
|||||||
}
|
}
|
||||||
for (_, chat) in peers.chats {
|
for (_, chat) in peers.chats {
|
||||||
switch chat {
|
switch chat {
|
||||||
case let .channel(flags, flags2, _, _, _, _, _, _, _, _, _, _, _, _, storiesMaxId, _, _, _, _):
|
case let .channel(flags, flags2, _, _, _, _, _, _, _, _, _, _, _, _, storiesMaxId, _, _, _, _, _):
|
||||||
let isMin = (flags & (1 << 12)) != 0
|
let isMin = (flags & (1 << 12)) != 0
|
||||||
let storiesUnavailable = (flags2 & (1 << 3)) != 0
|
let storiesUnavailable = (flags2 & (1 << 3)) != 0
|
||||||
|
|
||||||
|
@ -727,7 +727,7 @@ public class ChatMessageDateAndStatusNode: ASDisplayNode {
|
|||||||
var animationFileId: Int64?
|
var animationFileId: Int64?
|
||||||
|
|
||||||
switch reaction.value {
|
switch reaction.value {
|
||||||
case .builtin:
|
case .builtin, .stars:
|
||||||
if let availableReactions = arguments.availableReactions {
|
if let availableReactions = arguments.availableReactions {
|
||||||
for availableReaction in availableReactions.reactions {
|
for availableReaction in availableReactions.reactions {
|
||||||
if availableReaction.value == reaction.value {
|
if availableReaction.value == reaction.value {
|
||||||
|
@ -159,6 +159,15 @@ public final class MessageReactionButtonsNode: ASDisplayNode {
|
|||||||
}
|
}
|
||||||
case let .custom(fileId):
|
case let .custom(fileId):
|
||||||
animationFileId = fileId
|
animationFileId = fileId
|
||||||
|
case .stars:
|
||||||
|
if let availableReactions = availableReactions {
|
||||||
|
for availableReaction in availableReactions.reactions {
|
||||||
|
if availableReaction.value == reaction.value {
|
||||||
|
centerAnimation = availableReaction.centerAnimation
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var peers: [EnginePeer] = []
|
var peers: [EnginePeer] = []
|
||||||
|
@ -318,6 +318,8 @@ public final class ChatMessageSelectionInputPanelNode: ChatInputPanelNode {
|
|||||||
return .builtin(value)
|
return .builtin(value)
|
||||||
case let .custom(fileId):
|
case let .custom(fileId):
|
||||||
return .custom(fileId: fileId, file: nil)
|
return .custom(fileId: fileId, file: nil)
|
||||||
|
case .stars:
|
||||||
|
return .stars
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if let selectionState = presentationInterfaceState.interfaceState.selectionState {
|
if let selectionState = presentationInterfaceState.interfaceState.selectionState {
|
||||||
|
@ -1636,6 +1636,8 @@ struct ChatRecentActionsEntry: Comparable, Identifiable {
|
|||||||
reactionText = "."
|
reactionText = "."
|
||||||
entities.append(MessageTextEntity(range: (text as NSString).length ..< (text as NSString).length + (reactionText as NSString).length, type: .CustomEmoji(stickerPack: nil, fileId: fileId)))
|
entities.append(MessageTextEntity(range: (text as NSString).length ..< (text as NSString).length + (reactionText as NSString).length, type: .CustomEmoji(stickerPack: nil, fileId: fileId)))
|
||||||
text.append(reactionText)
|
text.append(reactionText)
|
||||||
|
case .stars:
|
||||||
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -94,7 +94,7 @@ private final class BalanceComponent: CombinedComponent {
|
|||||||
animationCache: context.component.context.animationCache,
|
animationCache: context.component.context.animationCache,
|
||||||
animationRenderer: context.component.context.animationRenderer,
|
animationRenderer: context.component.context.animationRenderer,
|
||||||
content: .animation(
|
content: .animation(
|
||||||
content: .customEmoji(fileId: MessageReaction.starsReactionId),
|
content: .customEmoji(fileId: MessageReaction.starsReactionId), //TODO:release
|
||||||
size: iconSize,
|
size: iconSize,
|
||||||
placeholderColor: .gray,
|
placeholderColor: .gray,
|
||||||
themeColor: nil,
|
themeColor: nil,
|
||||||
|
@ -100,6 +100,13 @@ public final class ChatShareMessageTagView: UIView, UndoOverlayControllerAdditio
|
|||||||
}
|
}
|
||||||
case let .custom(_, fileValue):
|
case let .custom(_, fileValue):
|
||||||
file = fileValue
|
file = fileValue
|
||||||
|
case .stars:
|
||||||
|
for reaction in availableReactions.reactions {
|
||||||
|
if reaction.value == updateReaction.reaction {
|
||||||
|
file = reaction.centerAnimation
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
guard let file else {
|
guard let file else {
|
||||||
|
@ -10,13 +10,13 @@ public enum AllowedReactions {
|
|||||||
case all
|
case all
|
||||||
}
|
}
|
||||||
|
|
||||||
public func peerMessageAllowedReactions(context: AccountContext, message: Message) -> Signal<AllowedReactions?, NoError> {
|
public func peerMessageAllowedReactions(context: AccountContext, message: Message) -> Signal<(allowedReactions: AllowedReactions?, areStarsEnabled: Bool), NoError> {
|
||||||
if message.id.peerId == context.account.peerId {
|
if message.id.peerId == context.account.peerId {
|
||||||
return .single(.all)
|
return .single((.all, false))
|
||||||
}
|
}
|
||||||
|
|
||||||
if message.containsSecretMedia {
|
if message.containsSecretMedia {
|
||||||
return .single(AllowedReactions.set(Set()))
|
return .single((AllowedReactions.set(Set()), false))
|
||||||
}
|
}
|
||||||
|
|
||||||
return combineLatest(
|
return combineLatest(
|
||||||
@ -26,7 +26,7 @@ public func peerMessageAllowedReactions(context: AccountContext, message: Messag
|
|||||||
),
|
),
|
||||||
context.engine.stickers.availableReactions() |> take(1)
|
context.engine.stickers.availableReactions() |> take(1)
|
||||||
)
|
)
|
||||||
|> map { data, availableReactions -> AllowedReactions? in
|
|> map { data, availableReactions -> (allowedReactions: AllowedReactions?, areStarsEnabled: Bool) in
|
||||||
let (peer, reactionSettings) = data
|
let (peer, reactionSettings) = data
|
||||||
|
|
||||||
let maxReactionCount: Int
|
let maxReactionCount: Int
|
||||||
@ -35,35 +35,41 @@ public func peerMessageAllowedReactions(context: AccountContext, message: Messag
|
|||||||
} else {
|
} else {
|
||||||
maxReactionCount = 11
|
maxReactionCount = 11
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var areStarsEnabled: Bool = false
|
||||||
|
if let value = reactionSettings.knownValue?.starsAllowed {
|
||||||
|
areStarsEnabled = value
|
||||||
|
}
|
||||||
|
|
||||||
if let effectiveReactions = message.effectiveReactions(isTags: message.areReactionsTags(accountPeerId: context.account.peerId)), effectiveReactions.count >= maxReactionCount {
|
if let effectiveReactions = message.effectiveReactions(isTags: message.areReactionsTags(accountPeerId: context.account.peerId)), effectiveReactions.count >= maxReactionCount {
|
||||||
return .set(Set(effectiveReactions.map(\.value)))
|
return (.set(Set(effectiveReactions.map(\.value))), areStarsEnabled)
|
||||||
}
|
}
|
||||||
|
|
||||||
switch reactionSettings {
|
switch reactionSettings {
|
||||||
case .unknown:
|
case .unknown:
|
||||||
if case let .channel(channel) = peer, case .broadcast = channel.info {
|
if case let .channel(channel) = peer, case .broadcast = channel.info {
|
||||||
if let availableReactions = availableReactions {
|
if let availableReactions = availableReactions {
|
||||||
return .set(Set(availableReactions.reactions.map(\.value)))
|
return (.set(Set(availableReactions.reactions.map(\.value))), areStarsEnabled)
|
||||||
} else {
|
} else {
|
||||||
return .set(Set())
|
return (.set(Set()), areStarsEnabled)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return .all
|
return (.all, areStarsEnabled)
|
||||||
case let .known(value):
|
case let .known(value):
|
||||||
switch value.allowedReactions {
|
switch value.allowedReactions {
|
||||||
case .all:
|
case .all:
|
||||||
if case let .channel(channel) = peer, case .broadcast = channel.info {
|
if case let .channel(channel) = peer, case .broadcast = channel.info {
|
||||||
if let availableReactions = availableReactions {
|
if let availableReactions = availableReactions {
|
||||||
return .set(Set(availableReactions.reactions.map(\.value)))
|
return (.set(Set(availableReactions.reactions.map(\.value))), areStarsEnabled)
|
||||||
} else {
|
} else {
|
||||||
return .set(Set())
|
return (.set(Set()), areStarsEnabled)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return .all
|
return (.all, areStarsEnabled)
|
||||||
case let .limited(reactions):
|
case let .limited(reactions):
|
||||||
return .set(Set(reactions))
|
return (.set(Set(reactions)), areStarsEnabled)
|
||||||
case .empty:
|
case .empty:
|
||||||
return .set(Set())
|
return (.set(Set()), areStarsEnabled)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -160,6 +166,8 @@ public func tagMessageReactions(context: AccountContext, subPeerId: EnginePeer.I
|
|||||||
largeApplicationAnimation: nil,
|
largeApplicationAnimation: nil,
|
||||||
isCustom: true
|
isCustom: true
|
||||||
))
|
))
|
||||||
|
case .stars:
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -212,6 +220,33 @@ public func tagMessageReactions(context: AccountContext, subPeerId: EnginePeer.I
|
|||||||
largeApplicationAnimation: nil,
|
largeApplicationAnimation: nil,
|
||||||
isCustom: true
|
isCustom: true
|
||||||
))
|
))
|
||||||
|
case .stars:
|
||||||
|
if let reaction = availableReactions?.reactions.first(where: { $0.value == .stars }) {
|
||||||
|
guard let centerAnimation = reaction.centerAnimation else {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
guard let aroundAnimation = reaction.aroundAnimation else {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if existingIds.contains(reaction.value) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
existingIds.insert(reaction.value)
|
||||||
|
|
||||||
|
result.append(ReactionItem(
|
||||||
|
reaction: ReactionItem.Reaction(rawValue: reaction.value),
|
||||||
|
appearAnimation: reaction.appearAnimation,
|
||||||
|
stillAnimation: reaction.selectAnimation,
|
||||||
|
listAnimation: centerAnimation,
|
||||||
|
largeListAnimation: reaction.activateAnimation,
|
||||||
|
applicationAnimation: aroundAnimation,
|
||||||
|
largeApplicationAnimation: reaction.effectAnimation,
|
||||||
|
isCustom: false
|
||||||
|
))
|
||||||
|
} else {
|
||||||
|
continue
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -250,41 +285,28 @@ public func topMessageReactions(context: AccountContext, message: Message, subPe
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let allowedReactionsWithFiles: Signal<(reactions: AllowedReactions, files: [Int64: TelegramMediaFile])?, NoError> = peerMessageAllowedReactions(context: context, message: message)
|
let allowedReactionsWithFiles: Signal<(reactions: AllowedReactions, files: [Int64: TelegramMediaFile], areStarsEnabled: Bool)?, NoError> = peerMessageAllowedReactions(context: context, message: message)
|
||||||
|> mapToSignal { allowedReactions -> Signal<(reactions: AllowedReactions, files: [Int64: TelegramMediaFile])?, NoError> in
|
|> mapToSignal { allowedReactions, areStarsEnabled -> Signal<(reactions: AllowedReactions, files: [Int64: TelegramMediaFile], areStarsEnabled: Bool)?, NoError> in
|
||||||
guard let allowedReactions = allowedReactions else {
|
guard let allowedReactions = allowedReactions else {
|
||||||
return .single(nil)
|
return .single(nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
if case let .set(reactions) = allowedReactions {
|
if case let .set(reactions) = allowedReactions {
|
||||||
#if DEBUG
|
|
||||||
var reactions = reactions
|
|
||||||
if context.sharedContext.applicationBindings.appBuildType == .internal {
|
|
||||||
reactions.insert(.custom(MessageReaction.starsReactionId))
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return context.engine.stickers.resolveInlineStickers(fileIds: reactions.compactMap { item -> Int64? in
|
return context.engine.stickers.resolveInlineStickers(fileIds: reactions.compactMap { item -> Int64? in
|
||||||
switch item {
|
switch item {
|
||||||
case .builtin:
|
case .builtin:
|
||||||
return nil
|
return nil
|
||||||
case let .custom(fileId):
|
case let .custom(fileId):
|
||||||
return fileId
|
return fileId
|
||||||
|
case .stars:
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|> map { files -> (reactions: AllowedReactions, files: [Int64: TelegramMediaFile]) in
|
|> map { files -> (reactions: AllowedReactions, files: [Int64: TelegramMediaFile], areStarsEnabled: Bool) in
|
||||||
return (.set(reactions), files)
|
return (.set(reactions), files, areStarsEnabled)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
#if DEBUG
|
return .single((allowedReactions, [:], areStarsEnabled))
|
||||||
if context.sharedContext.applicationBindings.appBuildType == .internal {
|
|
||||||
return context.engine.stickers.resolveInlineStickers(fileIds: [MessageReaction.starsReactionId])
|
|
||||||
|> map { files -> (reactions: AllowedReactions, files: [Int64: TelegramMediaFile]) in
|
|
||||||
return (allowedReactions, files)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
return .single((allowedReactions, [:]))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -302,25 +324,6 @@ public func topMessageReactions(context: AccountContext, message: Message, subPe
|
|||||||
var result: [ReactionItem] = []
|
var result: [ReactionItem] = []
|
||||||
var existingIds = Set<MessageReaction.Reaction>()
|
var existingIds = Set<MessageReaction.Reaction>()
|
||||||
|
|
||||||
#if DEBUG
|
|
||||||
if context.sharedContext.applicationBindings.appBuildType == .internal {
|
|
||||||
if let file = allowedReactionsAndFiles.files[MessageReaction.starsReactionId] {
|
|
||||||
existingIds.insert(.custom(MessageReaction.starsReactionId))
|
|
||||||
|
|
||||||
result.append(ReactionItem(
|
|
||||||
reaction: ReactionItem.Reaction(rawValue: .custom(file.fileId.id)),
|
|
||||||
appearAnimation: file,
|
|
||||||
stillAnimation: file,
|
|
||||||
listAnimation: file,
|
|
||||||
largeListAnimation: file,
|
|
||||||
applicationAnimation: nil,
|
|
||||||
largeApplicationAnimation: nil,
|
|
||||||
isCustom: true
|
|
||||||
))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
for topReaction in topReactions {
|
for topReaction in topReactions {
|
||||||
switch topReaction.content {
|
switch topReaction.content {
|
||||||
case let .builtin(value):
|
case let .builtin(value):
|
||||||
@ -384,6 +387,8 @@ public func topMessageReactions(context: AccountContext, message: Message, subPe
|
|||||||
largeApplicationAnimation: nil,
|
largeApplicationAnimation: nil,
|
||||||
isCustom: true
|
isCustom: true
|
||||||
))
|
))
|
||||||
|
case .stars:
|
||||||
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -447,6 +452,28 @@ public func topMessageReactions(context: AccountContext, message: Message, subPe
|
|||||||
isCustom: true
|
isCustom: true
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
case .stars:
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if allowedReactionsAndFiles.areStarsEnabled {
|
||||||
|
result.removeAll(where: { $0.reaction.rawValue == .stars })
|
||||||
|
if let reaction = availableReactions.reactions.first(where: { $0.value == .stars }) {
|
||||||
|
if let centerAnimation = reaction.centerAnimation, let aroundAnimation = reaction.aroundAnimation {
|
||||||
|
existingIds.insert(reaction.value)
|
||||||
|
|
||||||
|
result.insert(ReactionItem(
|
||||||
|
reaction: ReactionItem.Reaction(rawValue: reaction.value),
|
||||||
|
appearAnimation: reaction.appearAnimation,
|
||||||
|
stillAnimation: reaction.selectAnimation,
|
||||||
|
listAnimation: centerAnimation,
|
||||||
|
largeListAnimation: reaction.activateAnimation,
|
||||||
|
applicationAnimation: aroundAnimation,
|
||||||
|
largeApplicationAnimation: reaction.effectAnimation,
|
||||||
|
isCustom: false
|
||||||
|
), at: 0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -793,6 +793,10 @@ public extension EmojiPagerContentComponent {
|
|||||||
}
|
}
|
||||||
case let .custom(file):
|
case let .custom(file):
|
||||||
topReactionItems.append(EmojiComponentReactionItem(reaction: .custom(file.fileId.id), file: file))
|
topReactionItems.append(EmojiComponentReactionItem(reaction: .custom(file.fileId.id), file: file))
|
||||||
|
case .stars:
|
||||||
|
if let reaction = availableReactions?.reactions.first(where: { $0.value == .stars }) {
|
||||||
|
topReactionItems.append(EmojiComponentReactionItem(reaction: .stars, file: reaction.selectAnimation))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -962,6 +966,22 @@ public extension EmojiPagerContentComponent {
|
|||||||
} else {
|
} else {
|
||||||
icon = .none
|
icon = .none
|
||||||
}
|
}
|
||||||
|
case .stars:
|
||||||
|
if existingIds.contains(.stars) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
existingIds.insert(.stars)
|
||||||
|
if let availableReactions = availableReactions, let availableReaction = availableReactions.reactions.first(where: { $0.value == .stars }) {
|
||||||
|
if let centerAnimation = availableReaction.centerAnimation {
|
||||||
|
animationFile = centerAnimation
|
||||||
|
} else {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
icon = .none
|
||||||
}
|
}
|
||||||
|
|
||||||
var tintMode: Item.TintMode = .none
|
var tintMode: Item.TintMode = .none
|
||||||
@ -1014,6 +1034,12 @@ public extension EmojiPagerContentComponent {
|
|||||||
}
|
}
|
||||||
case let .custom(file):
|
case let .custom(file):
|
||||||
topReactionItems.append(EmojiComponentReactionItem(reaction: .custom(file.fileId.id), file: file))
|
topReactionItems.append(EmojiComponentReactionItem(reaction: .custom(file.fileId.id), file: file))
|
||||||
|
case .stars:
|
||||||
|
if let reaction = availableReactions?.reactions.first(where: { $0.value == .stars }) {
|
||||||
|
topReactionItems.append(EmojiComponentReactionItem(reaction: .stars, file: reaction.selectAnimation))
|
||||||
|
} else {
|
||||||
|
continue
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8223,6 +8223,8 @@ private func allowedStoryReactions(context: AccountContext) -> Signal<[ReactionI
|
|||||||
largeApplicationAnimation: nil,
|
largeApplicationAnimation: nil,
|
||||||
isCustom: true
|
isCustom: true
|
||||||
))
|
))
|
||||||
|
case .stars:
|
||||||
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -157,7 +157,7 @@ final class PeerAllowedReactionsScreenComponent: Component {
|
|||||||
allowedReactions = .empty
|
allowedReactions = .empty
|
||||||
}
|
}
|
||||||
|
|
||||||
let reactionSettings = PeerReactionSettings(allowedReactions: allowedReactions, maxReactionCount: self.allowedReactionCount >= 11 ? nil : Int32(self.allowedReactionCount))
|
let reactionSettings = PeerReactionSettings(allowedReactions: allowedReactions, maxReactionCount: self.allowedReactionCount >= 11 ? nil : Int32(self.allowedReactionCount), starsAllowed: self.areStarsReactionsEnabled)
|
||||||
|
|
||||||
if self.appliedReactionSettings != reactionSettings {
|
if self.appliedReactionSettings != reactionSettings {
|
||||||
if case .empty = allowedReactions {
|
if case .empty = allowedReactions {
|
||||||
@ -223,6 +223,8 @@ final class PeerAllowedReactionsScreenComponent: Component {
|
|||||||
return true
|
return true
|
||||||
case .builtin:
|
case .builtin:
|
||||||
return false
|
return false
|
||||||
|
case .stars:
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -248,7 +250,7 @@ final class PeerAllowedReactionsScreenComponent: Component {
|
|||||||
} else {
|
} else {
|
||||||
allowedReactions = .empty
|
allowedReactions = .empty
|
||||||
}
|
}
|
||||||
let reactionSettings = PeerReactionSettings(allowedReactions: allowedReactions, maxReactionCount: self.allowedReactionCount == 11 ? nil : Int32(self.allowedReactionCount))
|
let reactionSettings = PeerReactionSettings(allowedReactions: allowedReactions, maxReactionCount: self.allowedReactionCount == 11 ? nil : Int32(self.allowedReactionCount), starsAllowed: self.areStarsReactionsEnabled)
|
||||||
|
|
||||||
let applyDisposable = (component.context.engine.peers.updatePeerReactionSettings(peerId: component.peerId, reactionSettings: reactionSettings)
|
let applyDisposable = (component.context.engine.peers.updatePeerReactionSettings(peerId: component.peerId, reactionSettings: reactionSettings)
|
||||||
|> deliverOnMainQueue).start(error: { [weak self] error in
|
|> deliverOnMainQueue).start(error: { [weak self] error in
|
||||||
@ -362,10 +364,16 @@ final class PeerAllowedReactionsScreenComponent: Component {
|
|||||||
self.appliedReactionSettings = component.initialContent.reactionSettings.flatMap { reactionSettings in
|
self.appliedReactionSettings = component.initialContent.reactionSettings.flatMap { reactionSettings in
|
||||||
return PeerReactionSettings(
|
return PeerReactionSettings(
|
||||||
allowedReactions: reactionSettings.allowedReactions,
|
allowedReactions: reactionSettings.allowedReactions,
|
||||||
maxReactionCount: reactionSettings.maxReactionCount == 11 ? nil : reactionSettings.maxReactionCount
|
maxReactionCount: reactionSettings.maxReactionCount == 11 ? nil : reactionSettings.maxReactionCount,
|
||||||
|
starsAllowed: reactionSettings.starsAllowed
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
self.allowedReactionCount = (component.initialContent.reactionSettings?.maxReactionCount).flatMap(Int.init) ?? 11
|
self.allowedReactionCount = (component.initialContent.reactionSettings?.maxReactionCount).flatMap(Int.init) ?? 11
|
||||||
|
if let value = component.initialContent.reactionSettings?.starsAllowed {
|
||||||
|
self.areStarsReactionsEnabled = value
|
||||||
|
} else {
|
||||||
|
self.areStarsReactionsEnabled = component.initialContent.isStarReactionAvailable
|
||||||
|
}
|
||||||
}
|
}
|
||||||
var caretPosition = self.caretPosition ?? enabledReactions.count
|
var caretPosition = self.caretPosition ?? enabledReactions.count
|
||||||
caretPosition = max(0, min(enabledReactions.count, caretPosition))
|
caretPosition = max(0, min(enabledReactions.count, caretPosition))
|
||||||
@ -443,6 +451,8 @@ final class PeerAllowedReactionsScreenComponent: Component {
|
|||||||
return true
|
return true
|
||||||
case .builtin:
|
case .builtin:
|
||||||
return false
|
return false
|
||||||
|
case .stars:
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -868,7 +878,7 @@ final class PeerAllowedReactionsScreenComponent: Component {
|
|||||||
}
|
}
|
||||||
contentHeight += reactionCountSectionSize.height
|
contentHeight += reactionCountSectionSize.height
|
||||||
|
|
||||||
if !"".isEmpty {
|
if component.initialContent.isStarReactionAvailable {
|
||||||
contentHeight += 32.0
|
contentHeight += 32.0
|
||||||
|
|
||||||
let paidReactionsSection: ComponentView<Empty>
|
let paidReactionsSection: ComponentView<Empty>
|
||||||
@ -926,7 +936,7 @@ final class PeerAllowedReactionsScreenComponent: Component {
|
|||||||
AnyComponentWithIdentity(id: 0, component: AnyComponent(ListSwitchItemComponent(
|
AnyComponentWithIdentity(id: 0, component: AnyComponent(ListSwitchItemComponent(
|
||||||
theme: environment.theme,
|
theme: environment.theme,
|
||||||
title: "Enable Paid Reactions",
|
title: "Enable Paid Reactions",
|
||||||
value: areStarsReactionsEnabled,
|
value: self.areStarsReactionsEnabled,
|
||||||
valueUpdated: { [weak self] value in
|
valueUpdated: { [weak self] value in
|
||||||
guard let self else {
|
guard let self else {
|
||||||
return
|
return
|
||||||
@ -1049,6 +1059,8 @@ final class PeerAllowedReactionsScreenComponent: Component {
|
|||||||
return true
|
return true
|
||||||
case .builtin:
|
case .builtin:
|
||||||
return false
|
return false
|
||||||
|
case .stars:
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
}).count : 0
|
}).count : 0
|
||||||
|
|
||||||
@ -1231,17 +1243,20 @@ public class PeerAllowedReactionsScreen: ViewControllerComponentContainer {
|
|||||||
public let enabledReactions: [EmojiComponentReactionItem]
|
public let enabledReactions: [EmojiComponentReactionItem]
|
||||||
public let availableReactions: AvailableReactions?
|
public let availableReactions: AvailableReactions?
|
||||||
public let reactionSettings: PeerReactionSettings?
|
public let reactionSettings: PeerReactionSettings?
|
||||||
|
public let isStarReactionAvailable: Bool
|
||||||
|
|
||||||
init(
|
init(
|
||||||
isEnabled: Bool,
|
isEnabled: Bool,
|
||||||
enabledReactions: [EmojiComponentReactionItem],
|
enabledReactions: [EmojiComponentReactionItem],
|
||||||
availableReactions: AvailableReactions?,
|
availableReactions: AvailableReactions?,
|
||||||
reactionSettings: PeerReactionSettings?
|
reactionSettings: PeerReactionSettings?,
|
||||||
|
isStarReactionAvailable: Bool
|
||||||
) {
|
) {
|
||||||
self.isEnabled = isEnabled
|
self.isEnabled = isEnabled
|
||||||
self.enabledReactions = enabledReactions
|
self.enabledReactions = enabledReactions
|
||||||
self.availableReactions = availableReactions
|
self.availableReactions = availableReactions
|
||||||
self.reactionSettings = reactionSettings
|
self.reactionSettings = reactionSettings
|
||||||
|
self.isStarReactionAvailable = isStarReactionAvailable
|
||||||
}
|
}
|
||||||
|
|
||||||
public static func ==(lhs: Content, rhs: Content) -> Bool {
|
public static func ==(lhs: Content, rhs: Content) -> Bool {
|
||||||
@ -1260,6 +1275,9 @@ public class PeerAllowedReactionsScreen: ViewControllerComponentContainer {
|
|||||||
if lhs.reactionSettings != rhs.reactionSettings {
|
if lhs.reactionSettings != rhs.reactionSettings {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
if lhs.isStarReactionAvailable != rhs.isStarReactionAvailable {
|
||||||
|
return false
|
||||||
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1370,7 +1388,7 @@ public class PeerAllowedReactionsScreen: ViewControllerComponentContainer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return Content(isEnabled: isEnabled, enabledReactions: result, availableReactions: availableReactions, reactionSettings: reactionSettings)
|
return Content(isEnabled: isEnabled, enabledReactions: result, availableReactions: availableReactions, reactionSettings: reactionSettings, isStarReactionAvailable: cachedData.flags.contains(.paidMediaAllowed))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|> distinctUntilChanged
|
|> distinctUntilChanged
|
||||||
|
@ -338,6 +338,15 @@ public class ItemListReactionItemNode: ListViewItemNode, ItemListItemNode {
|
|||||||
}
|
}
|
||||||
case let .custom(fileId):
|
case let .custom(fileId):
|
||||||
animationContent = .customEmoji(fileId: fileId)
|
animationContent = .customEmoji(fileId: fileId)
|
||||||
|
case .stars:
|
||||||
|
if let availableReactions = item.availableReactions {
|
||||||
|
for reaction in availableReactions.reactions {
|
||||||
|
if reaction.value == item.reaction {
|
||||||
|
animationContent = .file(file: reaction.selectAnimation)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -307,6 +307,13 @@ public func quickReactionSetupController(
|
|||||||
}
|
}
|
||||||
case let .custom(fileId):
|
case let .custom(fileId):
|
||||||
currentSelectedFileId = MediaId(namespace: Namespaces.Media.CloudFile, id: fileId)
|
currentSelectedFileId = MediaId(namespace: Namespaces.Media.CloudFile, id: fileId)
|
||||||
|
case .stars:
|
||||||
|
if let availableReactions = availableReactions {
|
||||||
|
if let reaction = availableReactions.reactions.first(where: { $0.value == settings.quickReaction }) {
|
||||||
|
currentSelectedFileId = reaction.selectAnimation.fileId
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var selectedItems = Set<MediaId>()
|
var selectedItems = Set<MediaId>()
|
||||||
|
@ -207,6 +207,31 @@ class ReactionChatPreviewItemNode: ListViewItemNode {
|
|||||||
strongSelf.beginReactionAnimation(reactionItem: reactionItem)
|
strongSelf.beginReactionAnimation(reactionItem: reactionItem)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
case .stars:
|
||||||
|
for reaction in availableReactions.reactions {
|
||||||
|
guard let centerAnimation = reaction.centerAnimation else {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
guard let aroundAnimation = reaction.aroundAnimation else {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if reaction.value == updatedReaction {
|
||||||
|
let reactionItem = ReactionItem(
|
||||||
|
reaction: ReactionItem.Reaction(rawValue: reaction.value),
|
||||||
|
appearAnimation: reaction.appearAnimation,
|
||||||
|
stillAnimation: reaction.selectAnimation,
|
||||||
|
listAnimation: centerAnimation,
|
||||||
|
largeListAnimation: reaction.activateAnimation,
|
||||||
|
applicationAnimation: aroundAnimation,
|
||||||
|
largeApplicationAnimation: reaction.effectAnimation,
|
||||||
|
isCustom: false
|
||||||
|
)
|
||||||
|
self.beginReactionAnimation(reactionItem: reactionItem)
|
||||||
|
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -987,6 +987,9 @@ public final class PeerListItemComponent: Component {
|
|||||||
self.file = file
|
self.file = file
|
||||||
self.updateReactionLayer()
|
self.updateReactionLayer()
|
||||||
})
|
})
|
||||||
|
case .stars:
|
||||||
|
self.file = reaction.file
|
||||||
|
self.updateReactionLayer()
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
self.file = nil
|
self.file = nil
|
||||||
|
@ -1859,6 +1859,8 @@ public func preloadStoryMedia(context: AccountContext, info: StoryPreloadInfo) -
|
|||||||
if !customReactions.contains(fileId) {
|
if !customReactions.contains(fileId) {
|
||||||
customReactions.append(fileId)
|
customReactions.append(fileId)
|
||||||
}
|
}
|
||||||
|
case .stars:
|
||||||
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !builtinReactions.isEmpty {
|
if !builtinReactions.isEmpty {
|
||||||
@ -2090,6 +2092,8 @@ public func waitUntilStoryMediaPreloaded(context: AccountContext, peerId: Engine
|
|||||||
if !customReactions.contains(fileId) {
|
if !customReactions.contains(fileId) {
|
||||||
customReactions.append(fileId)
|
customReactions.append(fileId)
|
||||||
}
|
}
|
||||||
|
case .stars:
|
||||||
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2198,6 +2198,8 @@ func allowedStoryReactions(context: AccountContext) -> Signal<[ReactionItem], No
|
|||||||
largeApplicationAnimation: nil,
|
largeApplicationAnimation: nil,
|
||||||
isCustom: true
|
isCustom: true
|
||||||
))
|
))
|
||||||
|
case .stars:
|
||||||
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -98,6 +98,8 @@ public func storyPreviewWithAddedReactions(
|
|||||||
if !customFileIds.contains(fileId) {
|
if !customFileIds.contains(fileId) {
|
||||||
customFileIds.append(fileId)
|
customFileIds.append(fileId)
|
||||||
}
|
}
|
||||||
|
case .stars:
|
||||||
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -361,6 +363,15 @@ final class StoryItemOverlaysView: UIView {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
case .stars:
|
||||||
|
if let availableReactions {
|
||||||
|
for reactionItem in availableReactions.reactionItems {
|
||||||
|
if reactionItem.reaction.rawValue == reaction {
|
||||||
|
file = reactionItem.stillAnimation
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1745,6 +1745,15 @@ public final class StoryItemSetContainerComponent: Component {
|
|||||||
}
|
}
|
||||||
case let .custom(fileId):
|
case let .custom(fileId):
|
||||||
animationFileId = fileId
|
animationFileId = fileId
|
||||||
|
case .stars:
|
||||||
|
if let availableReactions = component.availableReactions {
|
||||||
|
for availableReaction in availableReactions.reactionItems {
|
||||||
|
if availableReaction.reaction.rawValue == value {
|
||||||
|
centerAnimation = availableReaction.listAnimation
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if animationFileId == nil && centerAnimation == nil {
|
if animationFileId == nil && centerAnimation == nil {
|
||||||
@ -2944,6 +2953,15 @@ public final class StoryItemSetContainerComponent: Component {
|
|||||||
}
|
}
|
||||||
case let .custom(fileId):
|
case let .custom(fileId):
|
||||||
animationFileId = fileId
|
animationFileId = fileId
|
||||||
|
case .stars:
|
||||||
|
if let availableReactions = component.availableReactions {
|
||||||
|
for availableReaction in availableReactions.reactionItems {
|
||||||
|
if availableReaction.reaction.rawValue == value {
|
||||||
|
centerAnimation = availableReaction.listAnimation
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if animationFileId == nil && centerAnimation == nil {
|
if animationFileId == nil && centerAnimation == nil {
|
||||||
@ -4564,7 +4582,7 @@ public final class StoryItemSetContainerComponent: Component {
|
|||||||
|
|
||||||
standaloneReactionAnimation.frame = self.bounds
|
standaloneReactionAnimation.frame = self.bounds
|
||||||
self.addSubview(standaloneReactionAnimation.view)
|
self.addSubview(standaloneReactionAnimation.view)
|
||||||
}, completion: { [weak targetView, weak reactionContextNode] in
|
}, onHit: nil, completion: { [weak targetView, weak reactionContextNode] in
|
||||||
targetView?.removeFromSuperview()
|
targetView?.removeFromSuperview()
|
||||||
if let reactionContextNode {
|
if let reactionContextNode {
|
||||||
reactionContextNode.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.3, removeOnCompletion: false, completion: { [weak reactionContextNode] _ in
|
reactionContextNode.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.3, removeOnCompletion: false, completion: { [weak reactionContextNode] _ in
|
||||||
@ -4602,6 +4620,8 @@ public final class StoryItemSetContainerComponent: Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
case .stars:
|
||||||
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
let message: EnqueueMessage = .message(
|
let message: EnqueueMessage = .message(
|
||||||
@ -4748,7 +4768,7 @@ public final class StoryItemSetContainerComponent: Component {
|
|||||||
|
|
||||||
standaloneReactionAnimation.frame = self.bounds
|
standaloneReactionAnimation.frame = self.bounds
|
||||||
self.componentContainerView.addSubview(standaloneReactionAnimation.view)
|
self.componentContainerView.addSubview(standaloneReactionAnimation.view)
|
||||||
}, completion: { [weak reactionContextNode] in
|
}, onHit: nil, completion: { [weak reactionContextNode] in
|
||||||
if let reactionContextNode {
|
if let reactionContextNode {
|
||||||
reactionContextNode.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.3, removeOnCompletion: false, completion: { [weak reactionContextNode] _ in
|
reactionContextNode.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.3, removeOnCompletion: false, completion: { [weak reactionContextNode] _ in
|
||||||
reactionContextNode?.view.removeFromSuperview()
|
reactionContextNode?.view.removeFromSuperview()
|
||||||
|
@ -3577,6 +3577,15 @@ final class StoryItemSetContainerSendMessage {
|
|||||||
animateWithReactionItem(reactionItem)
|
animateWithReactionItem(reactionItem)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
case .stars:
|
||||||
|
if let availableReactions = component.availableReactions {
|
||||||
|
for reactionItem in availableReactions.reactionItems {
|
||||||
|
if reactionItem.reaction.rawValue == reaction {
|
||||||
|
animateWithReactionItem(reactionItem)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -569,6 +569,15 @@ final class StoryItemSetViewListComponent: Component {
|
|||||||
if case let .view(view) = item {
|
if case let .view(view) = item {
|
||||||
animationFile = view.reactionFile
|
animationFile = view.reactionFile
|
||||||
}
|
}
|
||||||
|
case .stars:
|
||||||
|
if let availableReactions = component.availableReactions {
|
||||||
|
for availableReaction in availableReactions.reactionItems {
|
||||||
|
if availableReaction.reaction.rawValue == reaction {
|
||||||
|
animationFile = availableReaction.listAnimation
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return PeerListItemComponent.Reaction(
|
return PeerListItemComponent.Reaction(
|
||||||
reaction: reaction,
|
reaction: reaction,
|
||||||
|
@ -1627,7 +1627,7 @@ extension ChatControllerImpl {
|
|||||||
var reactionItem: ReactionItem?
|
var reactionItem: ReactionItem?
|
||||||
|
|
||||||
switch updatedReaction {
|
switch updatedReaction {
|
||||||
case .builtin:
|
case .builtin, .stars:
|
||||||
for reaction in availableReactions.reactions {
|
for reaction in availableReactions.reactions {
|
||||||
guard let centerAnimation = reaction.centerAnimation else {
|
guard let centerAnimation = reaction.centerAnimation else {
|
||||||
continue
|
continue
|
||||||
|
@ -52,15 +52,12 @@ extension ChatControllerImpl {
|
|||||||
peerMessageSelectedReactions(context: self.context, message: topMessage),
|
peerMessageSelectedReactions(context: self.context, message: topMessage),
|
||||||
topMessageReactions(context: self.context, message: topMessage, subPeerId: self.chatLocation.threadId.flatMap(EnginePeer.Id.init)),
|
topMessageReactions(context: self.context, message: topMessage, subPeerId: self.chatLocation.threadId.flatMap(EnginePeer.Id.init)),
|
||||||
ApplicationSpecificNotice.getChatTextSelectionTips(accountManager: self.context.sharedContext.accountManager)
|
ApplicationSpecificNotice.getChatTextSelectionTips(accountManager: self.context.sharedContext.accountManager)
|
||||||
).startStandalone(next: { [weak self] peer, actions, allowedReactions, selectedReactions, topReactions, chatTextSelectionTips in
|
).startStandalone(next: { [weak self] peer, actions, allowedReactionsAndStars, selectedReactions, topReactions, chatTextSelectionTips in
|
||||||
guard let self else {
|
guard let self else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
/*var hasPremium = false
|
var (allowedReactions, _) = allowedReactionsAndStars
|
||||||
if case let .user(user) = peer, user.isPremium {
|
|
||||||
hasPremium = true
|
|
||||||
}*/
|
|
||||||
|
|
||||||
var actions = actions
|
var actions = actions
|
||||||
switch actions.content {
|
switch actions.content {
|
||||||
@ -72,7 +69,6 @@ extension ChatControllerImpl {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
var allowedReactions = allowedReactions
|
|
||||||
if allowedReactions != nil, case let .customChatContents(customChatContents) = self.presentationInterfaceState.subject {
|
if allowedReactions != nil, case let .customChatContents(customChatContents) = self.presentationInterfaceState.subject {
|
||||||
if case let .hashTagSearch(publicPosts) = customChatContents.kind, publicPosts {
|
if case let .hashTagSearch(publicPosts) = customChatContents.kind, publicPosts {
|
||||||
allowedReactions = nil
|
allowedReactions = nil
|
||||||
@ -335,44 +331,13 @@ extension ChatControllerImpl {
|
|||||||
|
|
||||||
controller?.view.endEditing(true)
|
controller?.view.endEditing(true)
|
||||||
|
|
||||||
let chosenReaction: MessageReaction.Reaction = chosenUpdatedReaction.reaction
|
if case .stars = chosenUpdatedReaction.reaction {
|
||||||
|
let isFirst = !"".isEmpty
|
||||||
let currentReactions = mergedMessageReactions(attributes: message.attributes, isTags: message.areReactionsTags(accountPeerId: self.context.account.peerId))?.reactions ?? []
|
|
||||||
var updatedReactions: [MessageReaction.Reaction] = currentReactions.filter(\.isSelected).map(\.value)
|
self.chatDisplayNode.historyNode.forEachItemNode { itemNode in
|
||||||
var removedReaction: MessageReaction.Reaction?
|
if let itemNode = itemNode as? ChatMessageItemView, let item = itemNode.item {
|
||||||
var isFirst = false
|
if item.message.id == message.id {
|
||||||
|
let chosenReaction: MessageReaction.Reaction = .stars
|
||||||
if let index = updatedReactions.firstIndex(where: { $0 == chosenReaction }) {
|
|
||||||
removedReaction = chosenReaction
|
|
||||||
updatedReactions.remove(at: index)
|
|
||||||
} else {
|
|
||||||
updatedReactions.append(chosenReaction)
|
|
||||||
isFirst = !currentReactions.contains(where: { $0.value == chosenReaction })
|
|
||||||
}
|
|
||||||
|
|
||||||
if message.areReactionsTags(accountPeerId: self.context.account.peerId) {
|
|
||||||
if removedReaction == nil, !topReactions.contains(where: { $0.reaction.rawValue == chosenReaction }) {
|
|
||||||
if !self.presentationInterfaceState.isPremium {
|
|
||||||
controller?.premiumReactionsSelected?()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if removedReaction == nil, case .custom = chosenReaction {
|
|
||||||
if let peer = self.presentationInterfaceState.renderedPeer?.peer as? TelegramChannel, case .broadcast = peer.info {
|
|
||||||
} else {
|
|
||||||
if !self.presentationInterfaceState.isPremium {
|
|
||||||
controller?.premiumReactionsSelected?()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
self.chatDisplayNode.historyNode.forEachItemNode { itemNode in
|
|
||||||
if let itemNode = itemNode as? ChatMessageItemView, let item = itemNode.item {
|
|
||||||
if item.message.id == message.id {
|
|
||||||
if removedReaction == nil && !updatedReactions.isEmpty {
|
|
||||||
itemNode.awaitingAppliedReaction = (chosenReaction, { [weak self, weak itemNode] in
|
itemNode.awaitingAppliedReaction = (chosenReaction, { [weak self, weak itemNode] in
|
||||||
guard let self, let controller = controller else {
|
guard let self, let controller = controller else {
|
||||||
return
|
return
|
||||||
@ -392,61 +357,139 @@ extension ChatControllerImpl {
|
|||||||
self.chatDisplayNode.messageTransitionNode.addMessageStandaloneReactionAnimation(messageId: item.message.id, standaloneReactionAnimation: standaloneReactionAnimation)
|
self.chatDisplayNode.messageTransitionNode.addMessageStandaloneReactionAnimation(messageId: item.message.id, standaloneReactionAnimation: standaloneReactionAnimation)
|
||||||
standaloneReactionAnimation.frame = self.chatDisplayNode.bounds
|
standaloneReactionAnimation.frame = self.chatDisplayNode.bounds
|
||||||
self.chatDisplayNode.addSubnode(standaloneReactionAnimation)
|
self.chatDisplayNode.addSubnode(standaloneReactionAnimation)
|
||||||
}, completion: { [weak self, weak itemNode, weak targetView] in
|
}, onHit: { [weak self, weak itemNode] in
|
||||||
guard let self, let itemNode, let targetView else {
|
guard let self else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if let itemNode = itemNode, let targetView = itemNode.targetReactionView(value: chosenReaction) {
|
||||||
if self.chatLocation.peerId == self.context.account.peerId {
|
self.chatDisplayNode.wrappingNode.triggerRipple(at: targetView.convert(targetView.bounds.center, to: self.chatDisplayNode.view))
|
||||||
let _ = (ApplicationSpecificNotice.getSavedMessageTagLabelSuggestion(accountManager: self.context.sharedContext.accountManager)
|
|
||||||
|> take(1)
|
|
||||||
|> deliverOnMainQueue).startStandalone(next: { [weak self, weak targetView, weak itemNode] value in
|
|
||||||
guard let self, let targetView, let itemNode else {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if value >= 3 {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
let _ = itemNode
|
|
||||||
|
|
||||||
let rect = self.chatDisplayNode.view.convert(targetView.bounds, from: targetView).insetBy(dx: -8.0, dy: -8.0)
|
|
||||||
let tooltipScreen = TooltipScreen(account: self.context.account, sharedContext: self.context.sharedContext, text: .plain(text: self.presentationData.strings.Chat_TooltipAddTagLabel), location: .point(rect, .bottom), displayDuration: .manual, shouldDismissOnTouch: { _, _ in
|
|
||||||
return .dismiss(consume: false)
|
|
||||||
})
|
|
||||||
self.present(tooltipScreen, in: .current)
|
|
||||||
|
|
||||||
let _ = ApplicationSpecificNotice.incrementSavedMessageTagLabelSuggestion(accountManager: self.context.sharedContext.accountManager).startStandalone()
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
})
|
}, completion: {})
|
||||||
} else {
|
} else {
|
||||||
controller.dismiss()
|
controller.dismiss()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
} else {
|
|
||||||
itemNode.awaitingAppliedReaction = (nil, {
|
|
||||||
controller?.dismiss()
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
let _ = sendStarsReactionsInteractively(account: self.context.account, messageId: message.id, count: 1).startStandalone()
|
||||||
let mappedUpdatedReactions = updatedReactions.map { reaction -> UpdateMessageReaction in
|
} else {
|
||||||
switch reaction {
|
let chosenReaction: MessageReaction.Reaction = chosenUpdatedReaction.reaction
|
||||||
case let .builtin(value):
|
|
||||||
return .builtin(value)
|
let currentReactions = mergedMessageReactions(attributes: message.attributes, isTags: message.areReactionsTags(accountPeerId: self.context.account.peerId))?.reactions ?? []
|
||||||
case let .custom(fileId):
|
var updatedReactions: [MessageReaction.Reaction] = currentReactions.filter(\.isSelected).map(\.value)
|
||||||
var customFile: TelegramMediaFile?
|
var removedReaction: MessageReaction.Reaction?
|
||||||
if case let .custom(customFileId, file) = chosenUpdatedReaction, fileId == customFileId {
|
var isFirst = false
|
||||||
customFile = file
|
|
||||||
}
|
if let index = updatedReactions.firstIndex(where: { $0 == chosenReaction }) {
|
||||||
return .custom(fileId: fileId, file: customFile)
|
removedReaction = chosenReaction
|
||||||
|
updatedReactions.remove(at: index)
|
||||||
|
} else {
|
||||||
|
updatedReactions.append(chosenReaction)
|
||||||
|
isFirst = !currentReactions.contains(where: { $0.value == chosenReaction })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if message.areReactionsTags(accountPeerId: self.context.account.peerId) {
|
||||||
|
if removedReaction == nil, !topReactions.contains(where: { $0.reaction.rawValue == chosenReaction }) {
|
||||||
|
if !self.presentationInterfaceState.isPremium {
|
||||||
|
controller?.premiumReactionsSelected?()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if removedReaction == nil, case .custom = chosenReaction {
|
||||||
|
if let peer = self.presentationInterfaceState.renderedPeer?.peer as? TelegramChannel, case .broadcast = peer.info {
|
||||||
|
} else {
|
||||||
|
if !self.presentationInterfaceState.isPremium {
|
||||||
|
controller?.premiumReactionsSelected?()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
self.chatDisplayNode.historyNode.forEachItemNode { itemNode in
|
||||||
|
if let itemNode = itemNode as? ChatMessageItemView, let item = itemNode.item {
|
||||||
|
if item.message.id == message.id {
|
||||||
|
if removedReaction == nil && !updatedReactions.isEmpty {
|
||||||
|
itemNode.awaitingAppliedReaction = (chosenReaction, { [weak self, weak itemNode] in
|
||||||
|
guard let self, let controller = controller else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if let itemNode = itemNode, let targetView = itemNode.targetReactionView(value: chosenReaction) {
|
||||||
|
self.chatDisplayNode.messageTransitionNode.addMessageContextController(messageId: item.message.id, contextController: controller)
|
||||||
|
|
||||||
|
var hideTargetButton: UIView?
|
||||||
|
if isFirst {
|
||||||
|
hideTargetButton = targetView.superview
|
||||||
|
}
|
||||||
|
|
||||||
|
controller.dismissWithReaction(value: chosenReaction, targetView: targetView, hideNode: true, animateTargetContainer: hideTargetButton, addStandaloneReactionAnimation: { [weak self] standaloneReactionAnimation in
|
||||||
|
guard let self else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
self.chatDisplayNode.messageTransitionNode.addMessageStandaloneReactionAnimation(messageId: item.message.id, standaloneReactionAnimation: standaloneReactionAnimation)
|
||||||
|
standaloneReactionAnimation.frame = self.chatDisplayNode.bounds
|
||||||
|
self.chatDisplayNode.addSubnode(standaloneReactionAnimation)
|
||||||
|
}, onHit: nil, completion: { [weak self, weak itemNode, weak targetView] in
|
||||||
|
guard let self, let itemNode, let targetView else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if self.chatLocation.peerId == self.context.account.peerId {
|
||||||
|
let _ = (ApplicationSpecificNotice.getSavedMessageTagLabelSuggestion(accountManager: self.context.sharedContext.accountManager)
|
||||||
|
|> take(1)
|
||||||
|
|> deliverOnMainQueue).startStandalone(next: { [weak self, weak targetView, weak itemNode] value in
|
||||||
|
guard let self, let targetView, let itemNode else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if value >= 3 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
let _ = itemNode
|
||||||
|
|
||||||
|
let rect = self.chatDisplayNode.view.convert(targetView.bounds, from: targetView).insetBy(dx: -8.0, dy: -8.0)
|
||||||
|
let tooltipScreen = TooltipScreen(account: self.context.account, sharedContext: self.context.sharedContext, text: .plain(text: self.presentationData.strings.Chat_TooltipAddTagLabel), location: .point(rect, .bottom), displayDuration: .manual, shouldDismissOnTouch: { _, _ in
|
||||||
|
return .dismiss(consume: false)
|
||||||
|
})
|
||||||
|
self.present(tooltipScreen, in: .current)
|
||||||
|
|
||||||
|
let _ = ApplicationSpecificNotice.incrementSavedMessageTagLabelSuggestion(accountManager: self.context.sharedContext.accountManager).startStandalone()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
controller.dismiss()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
itemNode.awaitingAppliedReaction = (nil, {
|
||||||
|
controller?.dismiss()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let mappedUpdatedReactions = updatedReactions.map { reaction -> UpdateMessageReaction in
|
||||||
|
switch reaction {
|
||||||
|
case let .builtin(value):
|
||||||
|
return .builtin(value)
|
||||||
|
case let .custom(fileId):
|
||||||
|
var customFile: TelegramMediaFile?
|
||||||
|
if case let .custom(customFileId, file) = chosenUpdatedReaction, fileId == customFileId {
|
||||||
|
customFile = file
|
||||||
|
}
|
||||||
|
return .custom(fileId: fileId, file: customFile)
|
||||||
|
case .stars:
|
||||||
|
return .stars
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let _ = updateMessageReactionsInteractively(account: self.context.account, messageIds: [message.id], reactions: mappedUpdatedReactions, isLarge: isLarge, storeAsRecentlyUsed: true).startStandalone()
|
||||||
}
|
}
|
||||||
|
|
||||||
let _ = updateMessageReactionsInteractively(account: self.context.account, messageIds: [message.id], reactions: mappedUpdatedReactions, isLarge: isLarge, storeAsRecentlyUsed: true).startStandalone()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
self.forEachController({ controller in
|
self.forEachController({ controller in
|
||||||
|
@ -19,7 +19,7 @@ func peerMessageSelectedReactions(context: AccountContext, message: Message) ->
|
|||||||
}
|
}
|
||||||
reactions.insert(reaction.value)
|
reactions.insert(reaction.value)
|
||||||
switch reaction.value {
|
switch reaction.value {
|
||||||
case .builtin:
|
case .builtin, .stars:
|
||||||
if let availableReaction = availableReactions?.reactions.first(where: { $0.value == reaction.value }) {
|
if let availableReaction = availableReactions?.reactions.first(where: { $0.value == reaction.value }) {
|
||||||
result.insert(availableReaction.selectAnimation.fileId)
|
result.insert(availableReaction.selectAnimation.fileId)
|
||||||
}
|
}
|
||||||
|
@ -1510,6 +1510,8 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
|||||||
chosenReaction = .builtin(value)
|
chosenReaction = .builtin(value)
|
||||||
case let .custom(fileId):
|
case let .custom(fileId):
|
||||||
chosenReaction = .custom(fileId)
|
chosenReaction = .custom(fileId)
|
||||||
|
case .stars:
|
||||||
|
chosenReaction = .stars
|
||||||
}
|
}
|
||||||
case let .reaction(value):
|
case let .reaction(value):
|
||||||
switch value {
|
switch value {
|
||||||
@ -1517,6 +1519,8 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
|||||||
chosenReaction = .builtin(value)
|
chosenReaction = .builtin(value)
|
||||||
case let .custom(fileId):
|
case let .custom(fileId):
|
||||||
chosenReaction = .custom(fileId)
|
chosenReaction = .custom(fileId)
|
||||||
|
case .stars:
|
||||||
|
chosenReaction = .stars
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1540,7 +1544,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
|||||||
}
|
}
|
||||||
|
|
||||||
let _ = (peerMessageAllowedReactions(context: strongSelf.context, message: message)
|
let _ = (peerMessageAllowedReactions(context: strongSelf.context, message: message)
|
||||||
|> deliverOnMainQueue).startStandalone(next: { allowedReactions in
|
|> deliverOnMainQueue).startStandalone(next: { allowedReactions, _ in
|
||||||
guard let strongSelf = self else {
|
guard let strongSelf = self else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -1564,6 +1568,8 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
|||||||
chosenReaction = .builtin(value)
|
chosenReaction = .builtin(value)
|
||||||
case let .custom(fileId):
|
case let .custom(fileId):
|
||||||
chosenReaction = .custom(fileId)
|
chosenReaction = .custom(fileId)
|
||||||
|
case .stars:
|
||||||
|
chosenReaction = .stars
|
||||||
}
|
}
|
||||||
case let .reaction(value):
|
case let .reaction(value):
|
||||||
switch value {
|
switch value {
|
||||||
@ -1571,6 +1577,8 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
|||||||
chosenReaction = .builtin(value)
|
chosenReaction = .builtin(value)
|
||||||
case let .custom(fileId):
|
case let .custom(fileId):
|
||||||
chosenReaction = .custom(fileId)
|
chosenReaction = .custom(fileId)
|
||||||
|
case .stars:
|
||||||
|
chosenReaction = .stars
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1578,48 +1586,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
var removedReaction: MessageReaction.Reaction?
|
if case .stars = chosenReaction {
|
||||||
var messageAlreadyHasThisReaction = false
|
|
||||||
|
|
||||||
let currentReactions = mergedMessageReactions(attributes: message.attributes, isTags: message.areReactionsTags(accountPeerId: context.account.peerId))?.reactions ?? []
|
|
||||||
var updatedReactions: [MessageReaction.Reaction] = currentReactions.filter(\.isSelected).map(\.value)
|
|
||||||
|
|
||||||
if let index = updatedReactions.firstIndex(where: { $0 == chosenReaction }) {
|
|
||||||
removedReaction = chosenReaction
|
|
||||||
updatedReactions.remove(at: index)
|
|
||||||
} else {
|
|
||||||
updatedReactions.append(chosenReaction)
|
|
||||||
messageAlreadyHasThisReaction = currentReactions.contains(where: { $0.value == chosenReaction })
|
|
||||||
}
|
|
||||||
|
|
||||||
if removedReaction == nil {
|
|
||||||
if !canAddMessageReactions(message: message) {
|
|
||||||
itemNode.openMessageContextMenu()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if strongSelf.context.sharedContext.immediateExperimentalUISettings.disableQuickReaction {
|
|
||||||
itemNode.openMessageContextMenu()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
guard let allowedReactions = allowedReactions else {
|
|
||||||
itemNode.openMessageContextMenu()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
switch allowedReactions {
|
|
||||||
case let .set(set):
|
|
||||||
if !messageAlreadyHasThisReaction && updatedReactions.contains(where: { !set.contains($0) }) {
|
|
||||||
itemNode.openMessageContextMenu()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
case .all:
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if removedReaction == nil && !updatedReactions.isEmpty {
|
|
||||||
if strongSelf.selectPollOptionFeedback == nil {
|
if strongSelf.selectPollOptionFeedback == nil {
|
||||||
strongSelf.selectPollOptionFeedback = HapticFeedback()
|
strongSelf.selectPollOptionFeedback = HapticFeedback()
|
||||||
}
|
}
|
||||||
@ -1633,7 +1600,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
|||||||
var reactionItem: ReactionItem?
|
var reactionItem: ReactionItem?
|
||||||
|
|
||||||
switch chosenReaction {
|
switch chosenReaction {
|
||||||
case .builtin:
|
case .builtin, .stars:
|
||||||
for reaction in availableReactions.reactions {
|
for reaction in availableReactions.reactions {
|
||||||
guard let centerAnimation = reaction.centerAnimation else {
|
guard let centerAnimation = reaction.centerAnimation else {
|
||||||
continue
|
continue
|
||||||
@ -1694,6 +1661,14 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
|||||||
standaloneReactionAnimation.frame = strongSelf.chatDisplayNode.bounds
|
standaloneReactionAnimation.frame = strongSelf.chatDisplayNode.bounds
|
||||||
strongSelf.chatDisplayNode.addSubnode(standaloneReactionAnimation)
|
strongSelf.chatDisplayNode.addSubnode(standaloneReactionAnimation)
|
||||||
},
|
},
|
||||||
|
onHit: { [weak itemNode] in
|
||||||
|
guard let strongSelf = self else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if let itemNode = itemNode, let targetView = itemNode.targetReactionView(value: chosenReaction) {
|
||||||
|
strongSelf.chatDisplayNode.wrappingNode.triggerRipple(at: targetView.convert(targetView.bounds.center, to: strongSelf.chatDisplayNode.view))
|
||||||
|
}
|
||||||
|
},
|
||||||
completion: { [weak standaloneReactionAnimation] in
|
completion: { [weak standaloneReactionAnimation] in
|
||||||
standaloneReactionAnimation?.removeFromSupernode()
|
standaloneReactionAnimation?.removeFromSupernode()
|
||||||
}
|
}
|
||||||
@ -1701,78 +1676,12 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
} else {
|
|
||||||
strongSelf.chatDisplayNode.messageTransitionNode.dismissMessageReactionContexts(itemNode: itemNode)
|
|
||||||
|
|
||||||
if let removedReaction = removedReaction, let targetView = itemNode.targetReactionView(value: removedReaction), shouldDisplayInlineDateReactions(message: message, isPremium: strongSelf.presentationInterfaceState.isPremium, forceInline: false) {
|
let _ = sendStarsReactionsInteractively(account: strongSelf.context.account, messageId: message.id, count: 1).startStandalone()
|
||||||
var hideRemovedReaction: Bool = false
|
|
||||||
if let reactions = mergedMessageReactions(attributes: message.attributes, isTags: message.areReactionsTags(accountPeerId: context.account.peerId)) {
|
if !"".isEmpty {
|
||||||
for reaction in reactions.reactions {
|
|
||||||
if reaction.value == removedReaction {
|
|
||||||
hideRemovedReaction = reaction.count == 1
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let standaloneDismissAnimation = StandaloneDismissReactionAnimation()
|
|
||||||
standaloneDismissAnimation.frame = strongSelf.chatDisplayNode.bounds
|
|
||||||
strongSelf.chatDisplayNode.addSubnode(standaloneDismissAnimation)
|
|
||||||
standaloneDismissAnimation.animateReactionDismiss(sourceView: targetView, hideNode: hideRemovedReaction, isIncoming: message.effectivelyIncoming(strongSelf.context.account.peerId), completion: { [weak standaloneDismissAnimation] in
|
|
||||||
standaloneDismissAnimation?.removeFromSupernode()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let mappedUpdatedReactions = updatedReactions.map { reaction -> UpdateMessageReaction in
|
|
||||||
switch reaction {
|
|
||||||
case let .builtin(value):
|
|
||||||
return .builtin(value)
|
|
||||||
case let .custom(fileId):
|
|
||||||
return .custom(fileId: fileId, file: nil)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if !strongSelf.presentationInterfaceState.isPremium && mappedUpdatedReactions.count > strongSelf.context.userLimits.maxReactionsPerMessage {
|
|
||||||
let _ = (ApplicationSpecificNotice.incrementMultipleReactionsSuggestion(accountManager: strongSelf.context.sharedContext.accountManager)
|
|
||||||
|> deliverOnMainQueue).startStandalone(next: { [weak self] count in
|
|
||||||
guard let self else {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if count < 1 {
|
|
||||||
let context = self.context
|
|
||||||
let controller = UndoOverlayController(
|
|
||||||
presentationData: self.presentationData,
|
|
||||||
content: .premiumPaywall(title: nil, text: self.presentationData.strings.Chat_Reactions_MultiplePremiumTooltip, customUndoText: nil, timeout: nil, linkAction: nil),
|
|
||||||
elevatedLayout: false,
|
|
||||||
action: { [weak self] action in
|
|
||||||
if case .info = action {
|
|
||||||
if let self {
|
|
||||||
let controller = context.sharedContext.makePremiumIntroController(context: context, source: .reactions, forceDark: false, dismissed: nil)
|
|
||||||
self.push(controller)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
)
|
|
||||||
self.present(controller, in: .current)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
let _ = updateMessageReactionsInteractively(account: strongSelf.context.account, messageIds: [message.id], reactions: mappedUpdatedReactions, isLarge: false, storeAsRecentlyUsed: false).startStandalone()
|
|
||||||
|
|
||||||
#if DEBUG
|
|
||||||
if strongSelf.context.sharedContext.applicationBindings.appBuildType == .internal {
|
|
||||||
if mappedUpdatedReactions.contains(where: {
|
|
||||||
if case let .custom(fileId, _) = $0, fileId == MessageReaction.starsReactionId {
|
|
||||||
return true
|
|
||||||
} else {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}) {
|
|
||||||
let _ = (strongSelf.context.engine.stickers.resolveInlineStickers(fileIds: [MessageReaction.starsReactionId])
|
let _ = (strongSelf.context.engine.stickers.resolveInlineStickers(fileIds: [MessageReaction.starsReactionId])
|
||||||
|> deliverOnMainQueue).start(next: { [weak strongSelf, weak itemNode] files in
|
|> deliverOnMainQueue).start(next: { [weak strongSelf, weak itemNode] files in
|
||||||
guard let strongSelf, let file = files[MessageReaction.starsReactionId] else {
|
guard let strongSelf, let file = files[MessageReaction.starsReactionId] else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -1786,8 +1695,193 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
var removedReaction: MessageReaction.Reaction?
|
||||||
|
var messageAlreadyHasThisReaction = false
|
||||||
|
|
||||||
|
let currentReactions = mergedMessageReactions(attributes: message.attributes, isTags: message.areReactionsTags(accountPeerId: context.account.peerId))?.reactions ?? []
|
||||||
|
var updatedReactions: [MessageReaction.Reaction] = currentReactions.filter(\.isSelected).map(\.value)
|
||||||
|
|
||||||
|
if let index = updatedReactions.firstIndex(where: { $0 == chosenReaction }) {
|
||||||
|
removedReaction = chosenReaction
|
||||||
|
updatedReactions.remove(at: index)
|
||||||
|
} else {
|
||||||
|
updatedReactions.append(chosenReaction)
|
||||||
|
messageAlreadyHasThisReaction = currentReactions.contains(where: { $0.value == chosenReaction })
|
||||||
|
}
|
||||||
|
|
||||||
|
if removedReaction == nil {
|
||||||
|
if !canAddMessageReactions(message: message) {
|
||||||
|
itemNode.openMessageContextMenu()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if strongSelf.context.sharedContext.immediateExperimentalUISettings.disableQuickReaction {
|
||||||
|
itemNode.openMessageContextMenu()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
guard let allowedReactions = allowedReactions else {
|
||||||
|
itemNode.openMessageContextMenu()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
switch allowedReactions {
|
||||||
|
case let .set(set):
|
||||||
|
if !messageAlreadyHasThisReaction && updatedReactions.contains(where: { !set.contains($0) }) {
|
||||||
|
itemNode.openMessageContextMenu()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
case .all:
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if removedReaction == nil && !updatedReactions.isEmpty {
|
||||||
|
if strongSelf.selectPollOptionFeedback == nil {
|
||||||
|
strongSelf.selectPollOptionFeedback = HapticFeedback()
|
||||||
|
}
|
||||||
|
strongSelf.selectPollOptionFeedback?.tap()
|
||||||
|
|
||||||
|
itemNode.awaitingAppliedReaction = (chosenReaction, { [weak itemNode] in
|
||||||
|
guard let strongSelf = self else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if let itemNode = itemNode, let item = itemNode.item, let availableReactions = item.associatedData.availableReactions, let targetView = itemNode.targetReactionView(value: chosenReaction) {
|
||||||
|
var reactionItem: ReactionItem?
|
||||||
|
|
||||||
|
switch chosenReaction {
|
||||||
|
case .builtin, .stars:
|
||||||
|
for reaction in availableReactions.reactions {
|
||||||
|
guard let centerAnimation = reaction.centerAnimation else {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
guard let aroundAnimation = reaction.aroundAnimation else {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if reaction.value == chosenReaction {
|
||||||
|
reactionItem = ReactionItem(
|
||||||
|
reaction: ReactionItem.Reaction(rawValue: reaction.value),
|
||||||
|
appearAnimation: reaction.appearAnimation,
|
||||||
|
stillAnimation: reaction.selectAnimation,
|
||||||
|
listAnimation: centerAnimation,
|
||||||
|
largeListAnimation: reaction.activateAnimation,
|
||||||
|
applicationAnimation: aroundAnimation,
|
||||||
|
largeApplicationAnimation: reaction.effectAnimation,
|
||||||
|
isCustom: false
|
||||||
|
)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case let .custom(fileId):
|
||||||
|
if let itemFile = item.message.associatedMedia[MediaId(namespace: Namespaces.Media.CloudFile, id: fileId)] as? TelegramMediaFile {
|
||||||
|
reactionItem = ReactionItem(
|
||||||
|
reaction: ReactionItem.Reaction(rawValue: chosenReaction),
|
||||||
|
appearAnimation: itemFile,
|
||||||
|
stillAnimation: itemFile,
|
||||||
|
listAnimation: itemFile,
|
||||||
|
largeListAnimation: itemFile,
|
||||||
|
applicationAnimation: nil,
|
||||||
|
largeApplicationAnimation: nil,
|
||||||
|
isCustom: true
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if let reactionItem = reactionItem {
|
||||||
|
let standaloneReactionAnimation = StandaloneReactionAnimation(genericReactionEffect: strongSelf.chatDisplayNode.historyNode.takeGenericReactionEffect())
|
||||||
|
|
||||||
|
strongSelf.chatDisplayNode.messageTransitionNode.addMessageStandaloneReactionAnimation(messageId: item.message.id, standaloneReactionAnimation: standaloneReactionAnimation)
|
||||||
|
|
||||||
|
strongSelf.chatDisplayNode.addSubnode(standaloneReactionAnimation)
|
||||||
|
standaloneReactionAnimation.frame = strongSelf.chatDisplayNode.bounds
|
||||||
|
standaloneReactionAnimation.animateReactionSelection(
|
||||||
|
context: strongSelf.context,
|
||||||
|
theme: strongSelf.presentationData.theme,
|
||||||
|
animationCache: strongSelf.controllerInteraction!.presentationContext.animationCache,
|
||||||
|
reaction: reactionItem,
|
||||||
|
avatarPeers: [],
|
||||||
|
playHaptic: false,
|
||||||
|
isLarge: false,
|
||||||
|
targetView: targetView,
|
||||||
|
addStandaloneReactionAnimation: { standaloneReactionAnimation in
|
||||||
|
guard let strongSelf = self else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
strongSelf.chatDisplayNode.messageTransitionNode.addMessageStandaloneReactionAnimation(messageId: item.message.id, standaloneReactionAnimation: standaloneReactionAnimation)
|
||||||
|
standaloneReactionAnimation.frame = strongSelf.chatDisplayNode.bounds
|
||||||
|
strongSelf.chatDisplayNode.addSubnode(standaloneReactionAnimation)
|
||||||
|
},
|
||||||
|
completion: { [weak standaloneReactionAnimation] in
|
||||||
|
standaloneReactionAnimation?.removeFromSupernode()
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
strongSelf.chatDisplayNode.messageTransitionNode.dismissMessageReactionContexts(itemNode: itemNode)
|
||||||
|
|
||||||
|
if let removedReaction = removedReaction, let targetView = itemNode.targetReactionView(value: removedReaction), shouldDisplayInlineDateReactions(message: message, isPremium: strongSelf.presentationInterfaceState.isPremium, forceInline: false) {
|
||||||
|
var hideRemovedReaction: Bool = false
|
||||||
|
if let reactions = mergedMessageReactions(attributes: message.attributes, isTags: message.areReactionsTags(accountPeerId: context.account.peerId)) {
|
||||||
|
for reaction in reactions.reactions {
|
||||||
|
if reaction.value == removedReaction {
|
||||||
|
hideRemovedReaction = reaction.count == 1
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let standaloneDismissAnimation = StandaloneDismissReactionAnimation()
|
||||||
|
standaloneDismissAnimation.frame = strongSelf.chatDisplayNode.bounds
|
||||||
|
strongSelf.chatDisplayNode.addSubnode(standaloneDismissAnimation)
|
||||||
|
standaloneDismissAnimation.animateReactionDismiss(sourceView: targetView, hideNode: hideRemovedReaction, isIncoming: message.effectivelyIncoming(strongSelf.context.account.peerId), completion: { [weak standaloneDismissAnimation] in
|
||||||
|
standaloneDismissAnimation?.removeFromSupernode()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let mappedUpdatedReactions = updatedReactions.map { reaction -> UpdateMessageReaction in
|
||||||
|
switch reaction {
|
||||||
|
case let .builtin(value):
|
||||||
|
return .builtin(value)
|
||||||
|
case let .custom(fileId):
|
||||||
|
return .custom(fileId: fileId, file: nil)
|
||||||
|
case .stars:
|
||||||
|
return .stars
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !strongSelf.presentationInterfaceState.isPremium && mappedUpdatedReactions.count > strongSelf.context.userLimits.maxReactionsPerMessage {
|
||||||
|
let _ = (ApplicationSpecificNotice.incrementMultipleReactionsSuggestion(accountManager: strongSelf.context.sharedContext.accountManager)
|
||||||
|
|> deliverOnMainQueue).startStandalone(next: { [weak self] count in
|
||||||
|
guard let self else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if count < 1 {
|
||||||
|
let context = self.context
|
||||||
|
let controller = UndoOverlayController(
|
||||||
|
presentationData: self.presentationData,
|
||||||
|
content: .premiumPaywall(title: nil, text: self.presentationData.strings.Chat_Reactions_MultiplePremiumTooltip, customUndoText: nil, timeout: nil, linkAction: nil),
|
||||||
|
elevatedLayout: false,
|
||||||
|
action: { [weak self] action in
|
||||||
|
if case .info = action {
|
||||||
|
if let self {
|
||||||
|
let controller = context.sharedContext.makePremiumIntroController(context: context, source: .reactions, forceDark: false, dismissed: nil)
|
||||||
|
self.push(controller)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
)
|
||||||
|
self.present(controller, in: .current)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
let _ = updateMessageReactionsInteractively(account: strongSelf.context.account, messageIds: [message.id], reactions: mappedUpdatedReactions, isLarge: false, storeAsRecentlyUsed: false).startStandalone()
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}, activateMessagePinch: { [weak self] sourceNode in
|
}, activateMessagePinch: { [weak self] sourceNode in
|
||||||
|
@ -41,7 +41,7 @@ extension ChatControllerImpl {
|
|||||||
|
|
||||||
let reactionFile: Signal<TelegramMediaFile?, NoError>
|
let reactionFile: Signal<TelegramMediaFile?, NoError>
|
||||||
switch value {
|
switch value {
|
||||||
case .builtin:
|
case .builtin, .stars:
|
||||||
reactionFile = self.context.engine.stickers.availableReactions()
|
reactionFile = self.context.engine.stickers.availableReactions()
|
||||||
|> take(1)
|
|> take(1)
|
||||||
|> map { availableReactions -> TelegramMediaFile? in
|
|> map { availableReactions -> TelegramMediaFile? in
|
||||||
@ -161,25 +161,21 @@ extension ChatControllerImpl {
|
|||||||
self.window?.presentInGlobalOverlay(controller)
|
self.window?.presentInGlobalOverlay(controller)
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
var debug = false
|
if case .stars = value {
|
||||||
#if DEBUG
|
gesture?.cancel()
|
||||||
debug = true
|
cancelParentGestures(view: sourceView)
|
||||||
#endif
|
|
||||||
if self.context.sharedContext.applicationBindings.appBuildType == .internal {
|
|
||||||
debug = true
|
|
||||||
}
|
|
||||||
|
|
||||||
if debug, case .custom(MessageReaction.starsReactionId) = value {
|
|
||||||
let _ = (ChatSendStarsScreen.initialData(context: self.context, peerId: message.id.peerId)
|
let _ = (ChatSendStarsScreen.initialData(context: self.context, peerId: message.id.peerId)
|
||||||
|> deliverOnMainQueue).start(next: { [weak self] initialData in
|
|> deliverOnMainQueue).start(next: { [weak self] initialData in
|
||||||
guard let self, let initialData else {
|
guard let self, let initialData else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
self.push(ChatSendStarsScreen(context: self.context, initialData: initialData, completion: { [weak self] amount in
|
self.push(ChatSendStarsScreen(context: self.context, initialData: initialData, completion: { [weak self] amount in
|
||||||
guard let self else {
|
guard let self, amount > 0 else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let _ = self.context.engine.messages.sendStarsReaction(id: message.id, count: Int(amount))
|
||||||
|
|
||||||
let _ = (self.context.engine.stickers.resolveInlineStickers(fileIds: [MessageReaction.starsReactionId])
|
let _ = (self.context.engine.stickers.resolveInlineStickers(fileIds: [MessageReaction.starsReactionId])
|
||||||
|> deliverOnMainQueue).start(next: { [weak self] files in
|
|> deliverOnMainQueue).start(next: { [weak self] files in
|
||||||
guard let self, let file = files[MessageReaction.starsReactionId] else {
|
guard let self, let file = files[MessageReaction.starsReactionId] else {
|
||||||
@ -369,7 +365,7 @@ extension ChatControllerImpl {
|
|||||||
|
|
||||||
let reactionFile: TelegramMediaFile?
|
let reactionFile: TelegramMediaFile?
|
||||||
switch value {
|
switch value {
|
||||||
case .builtin:
|
case .builtin, .stars:
|
||||||
reactionFile = availableReactions?.reactions.first(where: { $0.value == value })?.selectAnimation
|
reactionFile = availableReactions?.reactions.first(where: { $0.value == value })?.selectAnimation
|
||||||
case let .custom(fileId):
|
case let .custom(fileId):
|
||||||
reactionFile = customEmoji[fileId]
|
reactionFile = customEmoji[fileId]
|
||||||
|
@ -4031,7 +4031,7 @@ public final class ChatHistoryListNodeImpl: ListView, ChatHistoryNode, ChatHisto
|
|||||||
var reactionItem: ReactionItem?
|
var reactionItem: ReactionItem?
|
||||||
|
|
||||||
switch updatedReaction {
|
switch updatedReaction {
|
||||||
case .builtin:
|
case .builtin, .stars:
|
||||||
if let availableReactions = item.associatedData.availableReactions {
|
if let availableReactions = item.associatedData.availableReactions {
|
||||||
for reaction in availableReactions.reactions {
|
for reaction in availableReactions.reactions {
|
||||||
guard let centerAnimation = reaction.centerAnimation else {
|
guard let centerAnimation = reaction.centerAnimation else {
|
||||||
|
@ -484,6 +484,8 @@ final class ChatSearchTitleAccessoryPanelNode: ChatTitleAccessoryPanelNode, Chat
|
|||||||
break
|
break
|
||||||
case let .custom(fileId):
|
case let .custom(fileId):
|
||||||
customFileIds.append(fileId)
|
customFileIds.append(fileId)
|
||||||
|
case .stars:
|
||||||
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -510,7 +512,7 @@ final class ChatSearchTitleAccessoryPanelNode: ChatTitleAccessoryPanelNode, Chat
|
|||||||
let title = savedMessageTags?.tags.first(where: { $0.reaction == reaction })?.title
|
let title = savedMessageTags?.tags.first(where: { $0.reaction == reaction })?.title
|
||||||
|
|
||||||
switch reaction {
|
switch reaction {
|
||||||
case .builtin:
|
case .builtin, .stars:
|
||||||
if let availableReactions {
|
if let availableReactions {
|
||||||
inner: for availableReaction in availableReactions.reactions {
|
inner: for availableReaction in availableReactions.reactions {
|
||||||
if availableReaction.value == reaction {
|
if availableReaction.value == reaction {
|
||||||
@ -763,7 +765,7 @@ final class ChatSearchTitleAccessoryPanelNode: ChatTitleAccessoryPanelNode, Chat
|
|||||||
|
|
||||||
let reactionFile: Signal<TelegramMediaFile?, NoError>
|
let reactionFile: Signal<TelegramMediaFile?, NoError>
|
||||||
switch reaction {
|
switch reaction {
|
||||||
case .builtin:
|
case .builtin, .stars:
|
||||||
reactionFile = self.context.engine.stickers.availableReactions()
|
reactionFile = self.context.engine.stickers.availableReactions()
|
||||||
|> take(1)
|
|> take(1)
|
||||||
|> map { availableReactions -> TelegramMediaFile? in
|
|> map { availableReactions -> TelegramMediaFile? in
|
||||||
|
Loading…
x
Reference in New Issue
Block a user