Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios

This commit is contained in:
overtake 2021-02-12 17:12:40 +04:00
commit be7317bbb5
44 changed files with 4825 additions and 4475 deletions

View File

@ -6027,25 +6027,9 @@ Sorry for the inconvenience.";
"Channel.AdminLog.JoinedViaInviteLink" = "%1$@ joined via invite link %2$@"; "Channel.AdminLog.JoinedViaInviteLink" = "%1$@ joined via invite link %2$@";
"GroupInfo.Permissions.BroadcastTitle" = "Broadcast Channel"; "GroupInfo.Permissions.BroadcastTitle" = "Broadcast Group";
"GroupInfo.Permissions.BroadcastConvert" = "Convert Group to Channel"; "GroupInfo.Permissions.BroadcastConvert" = "Convert to Broadcast Group";
"GroupInfo.Permissions.BroadcastConvertInfo" = "You can permanently turn your group to a one to many channel ([like this]()) where only admins can post."; "GroupInfo.Permissions.BroadcastConvertInfo" = "Broadcast groups can have over %@ members, but only admins can send message in them.";
"ChannelIntro.ChannelsTitle" = "Telegram Channels";
"ChannelIntro.ChannelsText" = "• No limit on the number of members.\n\n• Only admins can post.\n\n• Only admins see members list\n\n• You can enable comments for posts.";
"ChannelIntro.ConvertToChannel" = "Convert to Channel";
"ChannelIntro.ConvertCancel" = "Cancel";
"ConvertToChannel.ConfirmationAlert.Title" = "Convert to Channel";
"ConvertToChannel.ConfirmationAlert.Text" = "Do you want to convert your group to a channel? This action cannot be undone.";
"ConvertToChannel.ConfirmationAlert.Proceed" = "Proceed";
"ConvertToChannel.CommentsAlert.Title" = "Comments for Posts";
"ConvertToChannel.CommentsAlert.Text" = "Do you want to allow subscribers of your channel to comment on posts of the channel?";
"ConvertToChannel.LimitAlert.Title" = "Limit Reached";
"ConvertToChannel.LimitAlert.Text" = "Your group has reached a limit of %@ members. You can increase this limit by converting the group to a broadcast channel where only admins can post, but users can comment (if you allow them). Interested?";
"ConvertToChannel.LimitAlert.LearnMore" = "Learn More";
"GroupInfo.GroupHistoryShort" = "Chat History"; "GroupInfo.GroupHistoryShort" = "Chat History";
@ -6061,9 +6045,9 @@ Sorry for the inconvenience.";
"Report.Report" = "Report"; "Report.Report" = "Report";
"Report.Succeed" = "Telegram moderators will study your report. Thank you!"; "Report.Succeed" = "Telegram moderators will study your report. Thank you!";
"Conversation.AutoremoveRemainingTime" = "auto-delete in %@"; "Conversation.AutoremoveRemainingTime" = "auto-deletes in %@";
"Conversation.AutoremoveRemainingDays_1" = "auto-delete in %@ day"; "Conversation.AutoremoveRemainingDays_1" = "auto-deletes in %@ day";
"Conversation.AutoremoveRemainingDays_any" = "auto-delete in %@ days"; "Conversation.AutoremoveRemainingDays_any" = "auto-deletes in %@ days";
"PeerInfo.AutoremoveMessages" = "Auto-Delete Messages"; "PeerInfo.AutoremoveMessages" = "Auto-Delete Messages";
"PeerInfo.AutoremoveMessagesDisabled" = "Never"; "PeerInfo.AutoremoveMessagesDisabled" = "Never";
@ -6074,3 +6058,17 @@ Sorry for the inconvenience.";
"PeerInfo.ReportProfileVideo" = "Report Profile Video"; "PeerInfo.ReportProfileVideo" = "Report Profile Video";
"Channel.AdminLog.CanInviteUsersViaLink" = "Invite Users via Link"; "Channel.AdminLog.CanInviteUsersViaLink" = "Invite Users via Link";
"BroadcastGroups.IntroTitle" = "Broadcast Groups";
"BroadcastGroups.IntroText" = "• No limit on the number of members.\n\n• Only admins can post.\n\n• Can't be turned back into a regular group.";
"BroadcastGroups.Convert" = "Convert to Broadcast Group";
"BroadcastGroups.Cancel" = "Leave as regular group";
"BroadcastGroups.ConfirmationAlert.Title" = "Are you sure?";
"BroadcastGroups.ConfirmationAlert.Text" = "Do you want to convert your group to a channel? This action cannot be undone.";
"BroadcastGroups.ConfirmationAlert.Convert" = "Convert";
"BroadcastGroups.LimitAlert.Title" = "Limit Reached";
"BroadcastGroups.LimitAlert.Text" = "Your group has reached a limit of **%@** members. You can increase this limit by converting the group to a **broadcast group** where only admins can post. Interested?";
"BroadcastGroups.LimitAlert.LearnMore" = "Learn More";

View File

@ -316,6 +316,7 @@ extension PeersWidgetData {
struct AvatarItemView: View { struct AvatarItemView: View {
var peer: ParsedPeer? var peer: ParsedPeer?
var itemSize: CGFloat var itemSize: CGFloat
var placeholderColor: Color
var displayBadge: Bool = true var displayBadge: Bool = true
var body: some View { var body: some View {
@ -324,11 +325,12 @@ struct AvatarItemView: View {
Image(uiImage: avatarImage(accountPeerId: peer.accountPeerId, peer: peer.peer, size: CGSize(width: itemSize, height: itemSize))) Image(uiImage: avatarImage(accountPeerId: peer.accountPeerId, peer: peer.peer, size: CGSize(width: itemSize, height: itemSize)))
.clipShape(Circle()) .clipShape(Circle())
} else { } else {
Image(uiImage: avatarImage(accountPeerId: nil, peer: nil, size: CGSize(width: itemSize, height: itemSize))) Circle()
//Rectangle() .fill(placeholderColor)
.frame(width: itemSize, height: itemSize) .frame(width: itemSize, height: itemSize)
.clipShape(Circle()) //Image(uiImage: avatarImage(accountPeerId: nil, peer: nil, size: CGSize(width: itemSize, height: itemSize)))
.redacted(reason: .placeholder) //.clipShape(Circle())
//.redacted(reason: .placeholder)
} }
/*if let peer = peer, displayBadge, let badge = peer.badge, badge.count > 0 { /*if let peer = peer, displayBadge, let badge = peer.badge, badge.count > 0 {
Text("\(badge.count)") Text("\(badge.count)")
@ -430,7 +432,8 @@ struct WidgetView: View {
Link(destination: URL(string: linkForPeer(accountId: peers.peers[i].accountId, id: peers.peers[i].peer.id))!, label: { Link(destination: URL(string: linkForPeer(accountId: peers.peers[i].accountId, id: peers.peers[i].peer.id))!, label: {
AvatarItemView( AvatarItemView(
peer: peers.peers[i], peer: peers.peers[i],
itemSize: itemSize itemSize: itemSize,
placeholderColor: getPlaceholderColor()
).frame(width: itemSize, height: itemSize) ).frame(width: itemSize, height: itemSize)
}).frame(width: itemSize, height: itemSize) }).frame(width: itemSize, height: itemSize)
.position(x: floor(horizontalInsetFraction * geometry.size.width + itemSize / 2.0 + CGFloat(i % columnCount) * (itemSize + horizontalSpacingFraction * geometry.size.width)), y: floor(verticalInsetFraction * geometry.size.height + itemSize / 2.0 + CGFloat(i / columnCount) * (itemSize + verticalSpacingFraction * geometry.size.height))) .position(x: floor(horizontalInsetFraction * geometry.size.width + itemSize / 2.0 + CGFloat(i % columnCount) * (itemSize + horizontalSpacingFraction * geometry.size.width)), y: floor(verticalInsetFraction * geometry.size.height + itemSize / 2.0 + CGFloat(i / columnCount) * (itemSize + verticalSpacingFraction * geometry.size.height)))
@ -461,7 +464,7 @@ struct WidgetView: View {
func chatTopLine(_ peer: ParsedPeer?) -> some View { func chatTopLine(_ peer: ParsedPeer?) -> some View {
let dateText: String let dateText: String
let chatTitle: Text let chatTitle: AnyView
let date: Text let date: Text
if let peer = peer { if let peer = peer {
@ -470,26 +473,44 @@ struct WidgetView: View {
} else { } else {
dateText = "" dateText = ""
} }
chatTitle = Text(peer.peer.name).font(Font.system(size: 16.0, weight: .medium, design: .default)).foregroundColor(.primary) chatTitle = AnyView(Text(peer.peer.name)
.lineLimit(1)
.font(Font.system(size: 16.0, weight: .medium, design: .default))
.foregroundColor(.primary))
date = Text(dateText) date = Text(dateText)
.font(Font.system(size: 14.0, weight: .regular, design: .default)).foregroundColor(.secondary) .font(Font.system(size: 14.0, weight: .regular, design: .default)).foregroundColor(.secondary)
} else { } else {
dateText = "10:00" dateText = " "
chatTitle = Text("Chat Title").font(Font.system(size: 16.0, weight: .medium, design: .default)).foregroundColor(.primary) chatTitle = AnyView(Text(" ").font(Font.system(size: 16.0, weight: .medium, design: .default)).foregroundColor(.primary))
date = Text(dateText) date = Text(dateText)
.font(Font.system(size: 14.0, weight: .regular, design: .default)).foregroundColor(.secondary) .font(Font.system(size: 16.0, weight: .regular, design: .default)).foregroundColor(.secondary)
} }
return HStack(alignment: .center, spacing: 0.0, content: { return HStack(alignment: .center, spacing: 0.0, content: {
if peer != nil { if peer != nil {
chatTitle chatTitle
} else { } else {
chatTitle.redacted(reason: .placeholder) chatTitle
.frame(minWidth: 48.0)
.background(GeometryReader { geometry in
RoundedRectangle(cornerRadius: 4.0)
.fill(getPlaceholderColor())
.frame(width: geometry.size.width, height: 8.0, alignment: .center)
.offset(x: 0.0, y: (geometry.size.height - 8.0) / 2.0 + 1.0)
}
)
} }
Spacer() Spacer()
if peer != nil { if peer != nil {
date date
} else { } else {
date.redacted(reason: .placeholder) date
.background(GeometryReader { geometry in
RoundedRectangle(cornerRadius: 4.0)
.fill(getPlaceholderColor())
.frame(width: geometry.size.width, height: 8.0, alignment: .center)
.offset(x: 0.0, y: (geometry.size.height - 8.0) / 2.0)
}
)
} }
}) })
.padding(0.0) .padding(0.0)
@ -580,15 +601,42 @@ struct WidgetView: View {
.foregroundColor(.secondary) .foregroundColor(.secondary)
.multilineTextAlignment(.leading) .multilineTextAlignment(.leading)
.padding(0.0) .padding(0.0)
//.frame(maxHeight: .infinity, alignment: .topLeading)
//.background(Rectangle().foregroundColor(.gray))
if peer != nil { if peer != nil {
return AnyView(textView) return AnyView(textView)
} else { } else {
return AnyView( return AnyView(
textView VStack(alignment: .leading, spacing: 0.0, content: {
.redacted(reason: .placeholder) Text(" ")
.lineLimit(1)
.font(Font.system(size: 15.0, weight: .regular, design: .default))
.foregroundColor(.secondary)
.multilineTextAlignment(.leading)
.padding(0.0)
.frame(minWidth: 182.0)
.background(GeometryReader { geometry in
RoundedRectangle(cornerRadius: 4.0)
.fill(getPlaceholderColor())
.frame(width: geometry.size.width, height: 8.0, alignment: .center)
.offset(x: 0.0, y: (geometry.size.height - 8.0) / 2.0 - 1.0)
}
)
Text(" ")
.lineLimit(1)
.font(Font.system(size: 15.0, weight: .regular, design: .default))
.foregroundColor(.secondary)
.multilineTextAlignment(.leading)
.padding(0.0)
.frame(minWidth: 96.0)
.background(GeometryReader { geometry in
RoundedRectangle(cornerRadius: 4.0)
.fill(getPlaceholderColor())
.frame(width: geometry.size.width, height: 8.0, alignment: .center)
.offset(x: 0.0, y: (geometry.size.height - 8.0) / 2.0 - 1.0)
}
)
})
//textView.redacted(reason: .placeholder)
) )
} }
@ -658,7 +706,7 @@ struct WidgetView: View {
return AnyView( return AnyView(
Link(destination: url, label: { Link(destination: url, label: {
HStack(alignment: .center, spacing: 0.0, content: { HStack(alignment: .center, spacing: 0.0, content: {
AvatarItemView(peer: peers?.peers[index], itemSize: 54.0, displayBadge: false).frame(width: 54.0, height: 54.0, alignment: .leading).padding(EdgeInsets(top: 0.0, leading: 10.0, bottom: 0.0, trailing: 10.0)) AvatarItemView(peer: peers?.peers[index], itemSize: 54.0, placeholderColor: getPlaceholderColor(), displayBadge: false).frame(width: 54.0, height: 54.0, alignment: .leading).padding(EdgeInsets(top: 0.0, leading: 10.0, bottom: 0.0, trailing: 10.0))
chatContent(peers?.peers[index]).frame(maxWidth: .infinity).padding(EdgeInsets(top: 0.0, leading: 0.0, bottom: 0.0, trailing: 10.0)) chatContent(peers?.peers[index]).frame(maxWidth: .infinity).padding(EdgeInsets(top: 0.0, leading: 0.0, bottom: 0.0, trailing: 10.0))
}) })
}) })
@ -718,7 +766,7 @@ struct WidgetView: View {
} }
} }
default: default:
text = "" text = "Long tap to edit widget"
} }
return Text(text) return Text(text)
@ -765,6 +813,17 @@ struct WidgetView: View {
} }
} }
func getPlaceholderColor() -> Color {
switch colorScheme {
case .light:
return Color(.sRGB, red: 242.0 / 255.0, green: 242.0 / 255.0, blue: 247.0 / 255.0, opacity: 1.0)
case .dark:
return Color(.sRGB, red: 21.0 / 255.0, green: 21.0 / 255.0, blue: 21.0 / 255.0, opacity: 1.0)
@unknown default:
return .secondary
}
}
var body: some View { var body: some View {
GeometryReader(content: { geometry in GeometryReader(content: { geometry in
return VStack(alignment: .center, spacing: 0.0, content: { return VStack(alignment: .center, spacing: 0.0, content: {

View File

@ -477,8 +477,13 @@ class ChatListItemNode: ItemListRevealOptionsItemNode {
return nil return nil
} }
switch item.content { switch item.content {
case .groupReference: case let .groupReference(_, _, _, unreadState, _):
return nil var result = item.presentationData.strings.ChatList_ArchivedChatsTitle
let allCount = unreadState.count(countingCategory: .chats, mutedCategory: .all)
if allCount > 0 {
result += "\n\(item.presentationData.strings.VoiceOver_Chat_UnreadMessages(allCount))"
}
return result
case let .peer(_, peer, combinedReadState, _, _, _, _, _, _, _, _, _): case let .peer(_, peer, combinedReadState, _, _, _, _, _, _, _, _, _):
guard let chatMainPeer = peer.chatMainPeer else { guard let chatMainPeer = peer.chatMainPeer else {
return nil return nil
@ -504,8 +509,41 @@ class ChatListItemNode: ItemListRevealOptionsItemNode {
return nil return nil
} }
switch item.content { switch item.content {
case .groupReference: case let .groupReference(_, peers, messageValue, _, _):
return nil if let message = messageValue, let peer = peers.first?.peer {
let messages = [message]
var result = ""
if message.flags.contains(.Incoming) {
result += item.presentationData.strings.VoiceOver_ChatList_Message
} else {
result += item.presentationData.strings.VoiceOver_ChatList_OutgoingMessage
}
let (_, initialHideAuthor, messageText) = chatListItemStrings(strings: item.presentationData.strings, nameDisplayOrder: item.presentationData.nameDisplayOrder, messages: messages, chatPeer: peer, accountPeerId: item.context.account.peerId, isPeerGroup: false)
if message.flags.contains(.Incoming), !initialHideAuthor, let author = message.author, author is TelegramUser {
result += "\n\(item.presentationData.strings.VoiceOver_ChatList_MessageFrom(author.displayTitle(strings: item.presentationData.strings, displayOrder: item.presentationData.nameDisplayOrder)).0)"
}
result += "\n\(messageText)"
return result
} else if !peers.isEmpty {
var result = ""
var isFirst = true
for peer in peers {
if let chatMainPeer = peer.peer.chatMainPeer {
let peerTitle = chatMainPeer.compactDisplayTitle
if !peerTitle.isEmpty {
if isFirst {
isFirst = false
} else {
result.append(", ")
}
result.append(peerTitle)
}
}
}
return result
} else {
return item.presentationData.strings.VoiceOver_ChatList_MessageEmpty
}
case let .peer(messages, peer, combinedReadState, _, _, _, _, _, _, _, _, _): case let .peer(messages, peer, combinedReadState, _, _, _, _, _, _, _, _, _):
if let message = messages.last { if let message = messages.last {
var result = "" var result = ""

View File

@ -10,7 +10,12 @@ enum ContextActionSibling {
case separator case separator
} }
final class ContextActionNode: ASDisplayNode { public protocol ContextActionNodeProtocol: ASDisplayNode {
func setIsHighlighted(_ value: Bool)
func performAction()
}
final class ContextActionNode: ASDisplayNode, ContextActionNodeProtocol {
private let action: ContextMenuActionItem private let action: ContextMenuActionItem
private let getController: () -> ContextController? private let getController: () -> ContextController?
private let actionSelected: (ContextMenuActionResult) -> Void private let actionSelected: (ContextMenuActionResult) -> Void

View File

@ -50,7 +50,7 @@ private final class InnerActionsContainerNode: ASDisplayNode {
private let feedbackTap: () -> Void private let feedbackTap: () -> Void
private(set) var gesture: UIGestureRecognizer? private(set) var gesture: UIGestureRecognizer?
private var currentHighlightedActionNode: ContextActionNode? private var currentHighlightedActionNode: ContextActionNodeProtocol?
var panSelectionGestureEnabled: Bool = true { var panSelectionGestureEnabled: Bool = true {
didSet { didSet {
@ -291,13 +291,17 @@ private final class InnerActionsContainerNode: ASDisplayNode {
self.containerNode.backgroundColor = presentationData.theme.contextMenu.backgroundColor self.containerNode.backgroundColor = presentationData.theme.contextMenu.backgroundColor
} }
func actionNode(at point: CGPoint) -> ContextActionNode? { func actionNode(at point: CGPoint) -> ContextActionNodeProtocol? {
for itemNode in self.itemNodes { for itemNode in self.itemNodes {
switch itemNode { switch itemNode {
case let .action(actionNode): case let .action(actionNode):
if actionNode.frame.contains(point) { if actionNode.frame.contains(point) {
return actionNode return actionNode
} }
case let .custom(node):
if let node = node as? ContextActionNodeProtocol, node.frame.contains(point) {
return node
}
default: default:
break break
} }
@ -536,7 +540,7 @@ final class ContextActionsContainerNode: ASDisplayNode {
self.scrollNode.frame = CGRect(origin: CGPoint(), size: containerSize) self.scrollNode.frame = CGRect(origin: CGPoint(), size: containerSize)
} }
func actionNode(at point: CGPoint) -> ContextActionNode? { func actionNode(at point: CGPoint) -> ContextActionNodeProtocol? {
return self.actionsNode.actionNode(at: self.view.convert(point, to: self.actionsNode.view)) return self.actionsNode.actionNode(at: self.view.convert(point, to: self.actionsNode.view))
} }

View File

@ -138,7 +138,7 @@ private final class ContextControllerNode: ViewControllerTracingNode, UIScrollVi
private var didCompleteAnimationIn = false private var didCompleteAnimationIn = false
private var initialContinueGesturePoint: CGPoint? private var initialContinueGesturePoint: CGPoint?
private var didMoveFromInitialGesturePoint = false private var didMoveFromInitialGesturePoint = false
private var highlightedActionNode: ContextActionNode? private var highlightedActionNode: ContextActionNodeProtocol?
private var highlightedReaction: ReactionContextItem.Reaction? private var highlightedReaction: ReactionContextItem.Reaction?
private let hapticFeedback = HapticFeedback() private let hapticFeedback = HapticFeedback()

View File

@ -270,16 +270,22 @@ public final class SecretMediaPreviewController: ViewController {
videoDuration = file.duration videoDuration = file.duration
} }
} }
for attribute in message.attributes {
if let attribute = attribute as? AutoremoveTimeoutMessageAttribute { if let attribute = message.autoclearAttribute {
if let countdownBeginTime = attribute.countdownBeginTime { if let countdownBeginTime = attribute.countdownBeginTime {
if let videoDuration = videoDuration { if let videoDuration = videoDuration {
beginTimeAndTimeout = (CFAbsoluteTimeGetCurrent() + NSTimeIntervalSince1970, Double(videoDuration)) beginTimeAndTimeout = (CFAbsoluteTimeGetCurrent() + NSTimeIntervalSince1970, Double(videoDuration))
} else { } else {
beginTimeAndTimeout = (Double(countdownBeginTime), Double(attribute.timeout)) beginTimeAndTimeout = (Double(countdownBeginTime), Double(attribute.timeout))
} }
}
} else if let attribute = message.autoremoveAttribute {
if let countdownBeginTime = attribute.countdownBeginTime {
if let videoDuration = videoDuration {
beginTimeAndTimeout = (CFAbsoluteTimeGetCurrent() + NSTimeIntervalSince1970, Double(videoDuration))
} else {
beginTimeAndTimeout = (Double(countdownBeginTime), Double(attribute.timeout))
} }
break
} }
} }
@ -453,16 +459,21 @@ public final class SecretMediaPreviewController: ViewController {
videoDuration = file.duration videoDuration = file.duration
} }
} }
for attribute in message.attributes { if let attribute = message.autoclearAttribute {
if let attribute = attribute as? AutoremoveTimeoutMessageAttribute { if let countdownBeginTime = attribute.countdownBeginTime {
if let countdownBeginTime = attribute.countdownBeginTime { if let videoDuration = videoDuration {
if let videoDuration = videoDuration { beginTimeAndTimeout = (CFAbsoluteTimeGetCurrent() + NSTimeIntervalSince1970, Double(videoDuration))
beginTimeAndTimeout = (CFAbsoluteTimeGetCurrent() + NSTimeIntervalSince1970, Double(videoDuration)) } else {
} else { beginTimeAndTimeout = (Double(countdownBeginTime), Double(attribute.timeout))
beginTimeAndTimeout = (Double(countdownBeginTime), Double(attribute.timeout)) }
} }
} else if let attribute = message.autoremoveAttribute {
if let countdownBeginTime = attribute.countdownBeginTime {
if let videoDuration = videoDuration {
beginTimeAndTimeout = (CFAbsoluteTimeGetCurrent() + NSTimeIntervalSince1970, Double(videoDuration))
} else {
beginTimeAndTimeout = (Double(countdownBeginTime), Double(attribute.timeout))
} }
break
} }
} }

View File

@ -163,6 +163,8 @@ class ItemListStickerPackItemNode: ItemListRevealOptionsItemNode {
private var editableControlNode: ItemListEditableControlNode? private var editableControlNode: ItemListEditableControlNode?
private var reorderControlNode: ItemListEditableReorderControlNode? private var reorderControlNode: ItemListEditableReorderControlNode?
private let activateArea: AccessibilityAreaNode
private let fetchDisposable = MetaDisposable() private let fetchDisposable = MetaDisposable()
override var canBeSelected: Bool { override var canBeSelected: Bool {
@ -234,6 +236,8 @@ class ItemListStickerPackItemNode: ItemListRevealOptionsItemNode {
self.highlightedBackgroundNode = ASDisplayNode() self.highlightedBackgroundNode = ASDisplayNode()
self.highlightedBackgroundNode.isLayerBacked = true self.highlightedBackgroundNode.isLayerBacked = true
self.activateArea = AccessibilityAreaNode()
super.init(layerBacked: false, dynamicBounce: false, rotated: false, seeThrough: false) super.init(layerBacked: false, dynamicBounce: false, rotated: false, seeThrough: false)
if let placeholderNode = self.placeholderNode { if let placeholderNode = self.placeholderNode {
@ -247,6 +251,7 @@ class ItemListStickerPackItemNode: ItemListRevealOptionsItemNode {
self.addSubnode(self.installationActionImageNode) self.addSubnode(self.installationActionImageNode)
self.addSubnode(self.installationActionNode) self.addSubnode(self.installationActionNode)
self.addSubnode(self.selectionIconNode) self.addSubnode(self.selectionIconNode)
self.addSubnode(self.activateArea)
self.installationActionNode.addTarget(self, action: #selector(self.installationActionPressed), forControlEvents: .touchUpInside) self.installationActionNode.addTarget(self, action: #selector(self.installationActionPressed), forControlEvents: .touchUpInside)
self.installationActionNode.highligthedChanged = { [weak self] highlighted in self.installationActionNode.highligthedChanged = { [weak self] highlighted in
@ -465,7 +470,16 @@ class ItemListStickerPackItemNode: ItemListRevealOptionsItemNode {
return (layout, { [weak self] animated in return (layout, { [weak self] animated in
if let strongSelf = self { if let strongSelf = self {
strongSelf.layoutParams = (item, params, neighbors) strongSelf.layoutParams = (item, params, neighbors)
strongSelf.activateArea.frame = CGRect(origin: CGPoint(x: params.leftInset, y: 0.0), size: CGSize(width: params.width - params.leftInset - params.rightInset, height: layout.contentSize.height))
strongSelf.activateArea.accessibilityLabel = titleAttributedString?.string ?? ""
strongSelf.activateArea.accessibilityValue = statusAttributedString?.string ?? ""
if item.enabled {
strongSelf.activateArea.accessibilityTraits = []
} else {
strongSelf.activateArea.accessibilityTraits = .notEnabled
}
if fileUpdated { if fileUpdated {
strongSelf.currentThumbnailItem = thumbnailItem strongSelf.currentThumbnailItem = thumbnailItem
} }

View File

@ -263,7 +263,25 @@ class ChannelMembersSearchControllerNode: ASDisplayNode {
} }
var entries: [ChannelMembersSearchEntry] = [] var entries: [ChannelMembersSearchEntry] = []
if case .inviteToCall = mode, !filters.contains(where: { filter in var canInviteByLink = false
if let peer = peerViewMainPeer(peerView) {
if !(peer.addressName?.isEmpty ?? true) {
canInviteByLink = true
} else if let peer = peer as? TelegramChannel {
if peer.flags.contains(.isCreator) || (peer.adminRights?.flags.contains(.canInviteUsers) == true) {
canInviteByLink = true
}
} else if let peer = peer as? TelegramGroup {
if case .creator = peer.role {
canInviteByLink = true
} else if case let .admin(rights, _) = peer.role, rights.flags.contains(.canInviteUsers) {
canInviteByLink = true
}
}
}
if case .inviteToCall = mode, canInviteByLink,
!filters.contains(where: { filter in
if case .excludeNonMembers = filter { if case .excludeNonMembers = filter {
return true return true
} else { } else {

View File

@ -756,9 +756,9 @@ public func channelPermissionsController(context: AccountContext, peerId origina
let presentationData = context.sharedContext.currentPresentationData.with { $0 } let presentationData = context.sharedContext.currentPresentationData.with { $0 }
let controller = PermissionController(context: context, splashScreen: true) let controller = PermissionController(context: context, splashScreen: true)
controller.navigationPresentation = .modal controller.navigationPresentation = .modal
controller.setState(.custom(icon: .animation("Channels"), title: presentationData.strings.ChannelIntro_ChannelsTitle, subtitle: nil, text: presentationData.strings.ChannelIntro_ChannelsText, buttonTitle: presentationData.strings.ChannelIntro_ConvertToChannel, secondaryButtonTitle: presentationData.strings.Common_Cancel, footerText: nil), animated: false) controller.setState(.custom(icon: .animation("BroadcastGroup"), title: presentationData.strings.BroadcastGroups_IntroTitle, subtitle: nil, text: presentationData.strings.BroadcastGroups_IntroText, buttonTitle: presentationData.strings.BroadcastGroups_Convert, secondaryButtonTitle: presentationData.strings.BroadcastGroups_Cancel, footerText: nil), animated: false)
controller.proceed = { result in controller.proceed = { result in
presentControllerImpl?(textAlertController(context: context, title: presentationData.strings.ConvertToChannel_ConfirmationAlert_Title, text: presentationData.strings.ConvertToChannel_ConfirmationAlert_Text, actions: [TextAlertAction(type: .genericAction, title: presentationData.strings.Common_Cancel, action: {}), TextAlertAction(type: .defaultAction, title: presentationData.strings.ConvertToChannel_ConfirmationAlert_Proceed, action: { presentControllerImpl?(textAlertController(context: context, title: presentationData.strings.BroadcastGroups_ConfirmationAlert_Title, text: presentationData.strings.BroadcastGroups_ConfirmationAlert_Text, actions: [TextAlertAction(type: .genericAction, title: presentationData.strings.Common_Cancel, action: {}), TextAlertAction(type: .defaultAction, title: presentationData.strings.BroadcastGroups_ConfirmationAlert_Convert, action: {
})]), nil) })]), nil)

View File

@ -268,19 +268,20 @@ public func peerAutoremoveSetupScreen(context: AccountContext, peerId: PeerId, c
if let globalValue = globalValue, globalValue != defaultGlobalValue { if let globalValue = globalValue, globalValue != defaultGlobalValue {
updated = true updated = true
} }
var resolvedValue: Int32? = changedValue ?? resolvedDefaultValue
if resolvedValue == Int32.max {
resolvedValue = nil
}
let resolvedMaxValue: Int32
if peer is TelegramUser {
resolvedMaxValue = peerValue
} else {
resolvedMaxValue = Int32.max
}
if updated { if updated {
var resolvedValue: Int32? = changedValue ?? resolvedDefaultValue
if resolvedValue == Int32.max {
resolvedValue = nil
}
let resolvedMaxValue: Int32
if peer is TelegramUser {
resolvedMaxValue = peerValue
} else {
resolvedMaxValue = Int32.max
}
let resolvedGlobalValue = globalValue ?? defaultGlobalValue let resolvedGlobalValue = globalValue ?? defaultGlobalValue
let signal = setChatMessageAutoremoveTimeoutInteractively(account: context.account, peerId: peerId, timeout: resolvedValue, isGlobal: resolvedGlobalValue) let signal = setChatMessageAutoremoveTimeoutInteractively(account: context.account, peerId: peerId, timeout: resolvedValue, isGlobal: resolvedGlobalValue)
@ -301,7 +302,12 @@ public func peerAutoremoveSetupScreen(context: AccountContext, peerId: PeerId, c
})) }))
} else { } else {
dismissImpl?() dismissImpl?()
completion(.unchanged)
if resolvedMaxValue != Int32.max {
completion(.updated(PeerAutoremoveSetupScreenResult.Updated(myValue: resolvedValue, limitedByValue: resolvedMaxValue)))
} else {
completion(.unchanged)
}
} }
}) })
} }

View File

@ -111,6 +111,8 @@ class LocalizationListItemNode: ItemListRevealOptionsItemNode {
private var editableControlNode: ItemListEditableControlNode? private var editableControlNode: ItemListEditableControlNode?
private var reorderControlNode: ItemListEditableReorderControlNode? private var reorderControlNode: ItemListEditableReorderControlNode?
private let activateArea: AccessibilityAreaNode
override var canBeSelected: Bool { override var canBeSelected: Bool {
if self.editableControlNode != nil { if self.editableControlNode != nil {
return false return false
@ -153,12 +155,16 @@ class LocalizationListItemNode: ItemListRevealOptionsItemNode {
self.highlightedBackgroundNode = ASDisplayNode() self.highlightedBackgroundNode = ASDisplayNode()
self.highlightedBackgroundNode.isLayerBacked = true self.highlightedBackgroundNode.isLayerBacked = true
self.activateArea = AccessibilityAreaNode()
super.init(layerBacked: false, dynamicBounce: false, rotated: false, seeThrough: false) super.init(layerBacked: false, dynamicBounce: false, rotated: false, seeThrough: false)
self.addSubnode(self.iconNode) self.addSubnode(self.iconNode)
self.addSubnode(self.activityNode) self.addSubnode(self.activityNode)
self.addSubnode(self.titleNode) self.addSubnode(self.titleNode)
self.addSubnode(self.subtitleNode) self.addSubnode(self.subtitleNode)
self.addSubnode(self.activateArea)
} }
func asyncLayout() -> (_ item: LocalizationListItem, _ params: ListViewItemLayoutParams, _ neighbors: ItemListNeighbors) -> (ListViewItemNodeLayout, (Bool) -> Void) { func asyncLayout() -> (_ item: LocalizationListItem, _ params: ListViewItemLayoutParams, _ neighbors: ItemListNeighbors) -> (ListViewItemNodeLayout, (Bool) -> Void) {
@ -210,6 +216,10 @@ class LocalizationListItemNode: ItemListRevealOptionsItemNode {
strongSelf.item = item strongSelf.item = item
strongSelf.layoutParams = (params, neighbors) strongSelf.layoutParams = (params, neighbors)
strongSelf.activateArea.frame = CGRect(origin: CGPoint(x: params.leftInset, y: 0.0), size: CGSize(width: params.width - params.leftInset - params.rightInset, height: layout.contentSize.height))
strongSelf.activateArea.accessibilityLabel = item.title
strongSelf.activateArea.accessibilityValue = item.subtitle
let revealOffset = strongSelf.revealOffset let revealOffset = strongSelf.revealOffset
let transition: ContainedViewLayoutTransition let transition: ContainedViewLayoutTransition

View File

@ -2,20 +2,14 @@ import Foundation
import Postbox import Postbox
public class AutoremoveTimeoutMessageAttribute: MessageAttribute { public class AutoremoveTimeoutMessageAttribute: MessageAttribute {
public enum Action: Int32 {
case remove = 0
case clear = 1
}
public let timeout: Int32 public let timeout: Int32
public let countdownBeginTime: Int32? public let countdownBeginTime: Int32?
public let action: Action
public var associatedMessageIds: [MessageId] = [] public var associatedMessageIds: [MessageId] = []
public let automaticTimestampBasedAttribute: (UInt16, Int32)? public let automaticTimestampBasedAttribute: (UInt16, Int32)?
public init(timeout: Int32, countdownBeginTime: Int32?, action: Action = .remove) { public init(timeout: Int32, countdownBeginTime: Int32?) {
self.timeout = timeout self.timeout = timeout
self.countdownBeginTime = countdownBeginTime self.countdownBeginTime = countdownBeginTime
@ -24,8 +18,6 @@ public class AutoremoveTimeoutMessageAttribute: MessageAttribute {
} else { } else {
self.automaticTimestampBasedAttribute = nil self.automaticTimestampBasedAttribute = nil
} }
self.action = action
} }
required public init(decoder: PostboxDecoder) { required public init(decoder: PostboxDecoder) {
@ -37,8 +29,6 @@ public class AutoremoveTimeoutMessageAttribute: MessageAttribute {
} else { } else {
self.automaticTimestampBasedAttribute = nil self.automaticTimestampBasedAttribute = nil
} }
self.action = Action(rawValue: decoder.decodeInt32ForKey("a", orElse: 0)) ?? .remove
} }
public func encode(_ encoder: PostboxEncoder) { public func encode(_ encoder: PostboxEncoder) {
@ -48,24 +38,93 @@ public class AutoremoveTimeoutMessageAttribute: MessageAttribute {
} else { } else {
encoder.encodeNil(forKey: "c") encoder.encodeNil(forKey: "c")
} }
encoder.encodeInt32(self.action.rawValue, forKey: "a") }
}
public class AutoclearTimeoutMessageAttribute: MessageAttribute {
public let timeout: Int32
public let countdownBeginTime: Int32?
public var associatedMessageIds: [MessageId] = []
public let automaticTimestampBasedAttribute: (UInt16, Int32)?
public init(timeout: Int32, countdownBeginTime: Int32?) {
self.timeout = timeout
self.countdownBeginTime = countdownBeginTime
if let countdownBeginTime = countdownBeginTime {
self.automaticTimestampBasedAttribute = (1, countdownBeginTime + timeout)
} else {
self.automaticTimestampBasedAttribute = nil
}
}
required public init(decoder: PostboxDecoder) {
self.timeout = decoder.decodeInt32ForKey("t", orElse: 0)
self.countdownBeginTime = decoder.decodeOptionalInt32ForKey("c")
if let countdownBeginTime = self.countdownBeginTime {
self.automaticTimestampBasedAttribute = (1, countdownBeginTime + self.timeout)
} else {
self.automaticTimestampBasedAttribute = nil
}
}
public func encode(_ encoder: PostboxEncoder) {
encoder.encodeInt32(self.timeout, forKey: "t")
if let countdownBeginTime = self.countdownBeginTime {
encoder.encodeInt32(countdownBeginTime, forKey: "c")
} else {
encoder.encodeNil(forKey: "c")
}
} }
} }
public extension Message { public extension Message {
var containsSecretMedia: Bool { var autoremoveAttribute: AutoremoveTimeoutMessageAttribute? {
var found = false
for attribute in self.attributes { for attribute in self.attributes {
if let attribute = attribute as? AutoremoveTimeoutMessageAttribute { if let attribute = attribute as? AutoremoveTimeoutMessageAttribute {
if attribute.timeout > 1 * 60 { return attribute
return false
}
found = true
break
} }
} }
return nil
if !found { }
var autoclearAttribute: AutoclearTimeoutMessageAttribute? {
for attribute in self.attributes {
if let attribute = attribute as? AutoclearTimeoutMessageAttribute {
return attribute
}
}
return nil
}
var minAutoremoveOrClearTimeout: Int32? {
var timeout: Int32?
for attribute in self.attributes {
if let attribute = attribute as? AutoremoveTimeoutMessageAttribute {
if let timeoutValue = timeout {
timeout = min(timeoutValue, attribute.timeout)
} else {
timeout = attribute.timeout
}
} else if let attribute = attribute as? AutoclearTimeoutMessageAttribute {
if let timeoutValue = timeout {
timeout = min(timeoutValue, attribute.timeout)
} else {
timeout = attribute.timeout
}
}
}
return timeout
}
var containsSecretMedia: Bool {
guard let timeout = self.minAutoremoveOrClearTimeout else {
return false
}
if timeout > 1 * 60 {
return false return false
} }
@ -86,11 +145,7 @@ public extension Message {
} }
var isSelfExpiring: Bool { var isSelfExpiring: Bool {
for attribute in self.attributes { return self.minAutoremoveOrClearTimeout != nil
if let _ = attribute as? AutoremoveTimeoutMessageAttribute {
return true
}
}
return false
} }
} }

View File

@ -199,6 +199,7 @@ public final class CachedChannelData: CachedPeerData {
public let invitedBy: PeerId? public let invitedBy: PeerId?
public let photo: TelegramMediaImage? public let photo: TelegramMediaImage?
public let activeCall: ActiveCall? public let activeCall: ActiveCall?
public let pendingSuggestions: [String]
public let peerIds: Set<PeerId> public let peerIds: Set<PeerId>
public let messageIds: Set<MessageId> public let messageIds: Set<MessageId>
@ -230,9 +231,10 @@ public final class CachedChannelData: CachedPeerData {
self.invitedBy = nil self.invitedBy = nil
self.photo = nil self.photo = nil
self.activeCall = nil self.activeCall = nil
self.pendingSuggestions = []
} }
public init(isNotAccessible: Bool, flags: CachedChannelFlags, about: String?, participantsSummary: CachedChannelParticipantsSummary, exportedInvitation: ExportedInvitation?, botInfos: [CachedPeerBotInfo], peerStatusSettings: PeerStatusSettings?, pinnedMessageId: MessageId?, stickerPack: StickerPackCollectionInfo?, minAvailableMessageId: MessageId?, migrationReference: ChannelMigrationReference?, linkedDiscussionPeerId: LinkedDiscussionPeerId, peerGeoLocation: PeerGeoLocation?, slowModeTimeout: Int32?, slowModeValidUntilTimestamp: Int32?, hasScheduledMessages: Bool, statsDatacenterId: Int32, invitedBy: PeerId?, photo: TelegramMediaImage?, activeCall: ActiveCall?, autoremoveTimeout: CachedPeerAutoremoveTimeout) { public init(isNotAccessible: Bool, flags: CachedChannelFlags, about: String?, participantsSummary: CachedChannelParticipantsSummary, exportedInvitation: ExportedInvitation?, botInfos: [CachedPeerBotInfo], peerStatusSettings: PeerStatusSettings?, pinnedMessageId: MessageId?, stickerPack: StickerPackCollectionInfo?, minAvailableMessageId: MessageId?, migrationReference: ChannelMigrationReference?, linkedDiscussionPeerId: LinkedDiscussionPeerId, peerGeoLocation: PeerGeoLocation?, slowModeTimeout: Int32?, slowModeValidUntilTimestamp: Int32?, hasScheduledMessages: Bool, statsDatacenterId: Int32, invitedBy: PeerId?, photo: TelegramMediaImage?, activeCall: ActiveCall?, autoremoveTimeout: CachedPeerAutoremoveTimeout, pendingSuggestions: [String]) {
self.isNotAccessible = isNotAccessible self.isNotAccessible = isNotAccessible
self.flags = flags self.flags = flags
self.about = about self.about = about
@ -254,6 +256,7 @@ public final class CachedChannelData: CachedPeerData {
self.photo = photo self.photo = photo
self.activeCall = activeCall self.activeCall = activeCall
self.autoremoveTimeout = autoremoveTimeout self.autoremoveTimeout = autoremoveTimeout
self.pendingSuggestions = pendingSuggestions
var peerIds = Set<PeerId>() var peerIds = Set<PeerId>()
for botInfo in botInfos { for botInfo in botInfos {
@ -281,87 +284,91 @@ public final class CachedChannelData: CachedPeerData {
} }
public func withUpdatedIsNotAccessible(_ isNotAccessible: Bool) -> CachedChannelData { public func withUpdatedIsNotAccessible(_ isNotAccessible: Bool) -> CachedChannelData {
return CachedChannelData(isNotAccessible: isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, photo: self.photo, activeCall: self.activeCall, autoremoveTimeout: self.autoremoveTimeout) return CachedChannelData(isNotAccessible: isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, photo: self.photo, activeCall: self.activeCall, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: self.pendingSuggestions)
} }
public func withUpdatedFlags(_ flags: CachedChannelFlags) -> CachedChannelData { public func withUpdatedFlags(_ flags: CachedChannelFlags) -> CachedChannelData {
return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, photo: self.photo, activeCall: self.activeCall, autoremoveTimeout: self.autoremoveTimeout) return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, photo: self.photo, activeCall: self.activeCall, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: self.pendingSuggestions)
} }
public func withUpdatedAbout(_ about: String?) -> CachedChannelData { public func withUpdatedAbout(_ about: String?) -> CachedChannelData {
return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, photo: self.photo, activeCall: self.activeCall, autoremoveTimeout: self.autoremoveTimeout) return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, photo: self.photo, activeCall: self.activeCall, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: self.pendingSuggestions)
} }
public func withUpdatedParticipantsSummary(_ participantsSummary: CachedChannelParticipantsSummary) -> CachedChannelData { public func withUpdatedParticipantsSummary(_ participantsSummary: CachedChannelParticipantsSummary) -> CachedChannelData {
return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, photo: self.photo, activeCall: self.activeCall, autoremoveTimeout: self.autoremoveTimeout) return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, photo: self.photo, activeCall: self.activeCall, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: self.pendingSuggestions)
} }
public func withUpdatedExportedInvitation(_ exportedInvitation: ExportedInvitation?) -> CachedChannelData { public func withUpdatedExportedInvitation(_ exportedInvitation: ExportedInvitation?) -> CachedChannelData {
return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, photo: self.photo, activeCall: self.activeCall, autoremoveTimeout: self.autoremoveTimeout) return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, photo: self.photo, activeCall: self.activeCall, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: self.pendingSuggestions)
} }
public func withUpdatedBotInfos(_ botInfos: [CachedPeerBotInfo]) -> CachedChannelData { public func withUpdatedBotInfos(_ botInfos: [CachedPeerBotInfo]) -> CachedChannelData {
return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, photo: self.photo, activeCall: self.activeCall, autoremoveTimeout: self.autoremoveTimeout) return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, photo: self.photo, activeCall: self.activeCall, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: self.pendingSuggestions)
} }
public func withUpdatedPeerStatusSettings(_ peerStatusSettings: PeerStatusSettings?) -> CachedChannelData { public func withUpdatedPeerStatusSettings(_ peerStatusSettings: PeerStatusSettings?) -> CachedChannelData {
return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, photo: self.photo, activeCall: self.activeCall, autoremoveTimeout: self.autoremoveTimeout) return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, photo: self.photo, activeCall: self.activeCall, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: self.pendingSuggestions)
} }
public func withUpdatedPinnedMessageId(_ pinnedMessageId: MessageId?) -> CachedChannelData { public func withUpdatedPinnedMessageId(_ pinnedMessageId: MessageId?) -> CachedChannelData {
return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, photo: self.photo, activeCall: self.activeCall, autoremoveTimeout: self.autoremoveTimeout) return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, photo: self.photo, activeCall: self.activeCall, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: self.pendingSuggestions)
} }
public func withUpdatedStickerPack(_ stickerPack: StickerPackCollectionInfo?) -> CachedChannelData { public func withUpdatedStickerPack(_ stickerPack: StickerPackCollectionInfo?) -> CachedChannelData {
return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, photo: self.photo, activeCall: self.activeCall, autoremoveTimeout: self.autoremoveTimeout) return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, photo: self.photo, activeCall: self.activeCall, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: self.pendingSuggestions)
} }
public func withUpdatedMinAvailableMessageId(_ minAvailableMessageId: MessageId?) -> CachedChannelData { public func withUpdatedMinAvailableMessageId(_ minAvailableMessageId: MessageId?) -> CachedChannelData {
return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, photo: self.photo, activeCall: self.activeCall, autoremoveTimeout: self.autoremoveTimeout) return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, photo: self.photo, activeCall: self.activeCall, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: self.pendingSuggestions)
} }
public func withUpdatedMigrationReference(_ migrationReference: ChannelMigrationReference?) -> CachedChannelData { public func withUpdatedMigrationReference(_ migrationReference: ChannelMigrationReference?) -> CachedChannelData {
return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, photo: self.photo, activeCall: self.activeCall, autoremoveTimeout: self.autoremoveTimeout) return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, photo: self.photo, activeCall: self.activeCall, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: self.pendingSuggestions)
} }
public func withUpdatedLinkedDiscussionPeerId(_ linkedDiscussionPeerId: LinkedDiscussionPeerId) -> CachedChannelData { public func withUpdatedLinkedDiscussionPeerId(_ linkedDiscussionPeerId: LinkedDiscussionPeerId) -> CachedChannelData {
return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, photo: self.photo, activeCall: self.activeCall, autoremoveTimeout: self.autoremoveTimeout) return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, photo: self.photo, activeCall: self.activeCall, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: self.pendingSuggestions)
} }
public func withUpdatedPeerGeoLocation(_ peerGeoLocation: PeerGeoLocation?) -> CachedChannelData { public func withUpdatedPeerGeoLocation(_ peerGeoLocation: PeerGeoLocation?) -> CachedChannelData {
return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, photo: self.photo, activeCall: self.activeCall, autoremoveTimeout: self.autoremoveTimeout) return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, photo: self.photo, activeCall: self.activeCall, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: self.pendingSuggestions)
} }
public func withUpdatedSlowModeTimeout(_ slowModeTimeout: Int32?) -> CachedChannelData { public func withUpdatedSlowModeTimeout(_ slowModeTimeout: Int32?) -> CachedChannelData {
return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, photo: self.photo, activeCall: self.activeCall, autoremoveTimeout: self.autoremoveTimeout) return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, photo: self.photo, activeCall: self.activeCall, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: self.pendingSuggestions)
} }
public func withUpdatedSlowModeValidUntilTimestamp(_ slowModeValidUntilTimestamp: Int32?) -> CachedChannelData { public func withUpdatedSlowModeValidUntilTimestamp(_ slowModeValidUntilTimestamp: Int32?) -> CachedChannelData {
return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, photo: self.photo, activeCall: self.activeCall, autoremoveTimeout: self.autoremoveTimeout) return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, photo: self.photo, activeCall: self.activeCall, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: self.pendingSuggestions)
} }
public func withUpdatedHasScheduledMessages(_ hasScheduledMessages: Bool) -> CachedChannelData { public func withUpdatedHasScheduledMessages(_ hasScheduledMessages: Bool) -> CachedChannelData {
return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, photo: self.photo, activeCall: self.activeCall, autoremoveTimeout: self.autoremoveTimeout) return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, photo: self.photo, activeCall: self.activeCall, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: self.pendingSuggestions)
} }
public func withUpdatedStatsDatacenterId(_ statsDatacenterId: Int32) -> CachedChannelData { public func withUpdatedStatsDatacenterId(_ statsDatacenterId: Int32) -> CachedChannelData {
return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: statsDatacenterId, invitedBy: self.invitedBy, photo: self.photo, activeCall: self.activeCall, autoremoveTimeout: self.autoremoveTimeout) return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: statsDatacenterId, invitedBy: self.invitedBy, photo: self.photo, activeCall: self.activeCall, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: self.pendingSuggestions)
} }
public func withUpdatedInvitedBy(_ invitedBy: PeerId?) -> CachedChannelData { public func withUpdatedInvitedBy(_ invitedBy: PeerId?) -> CachedChannelData {
return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: invitedBy, photo: self.photo, activeCall: self.activeCall, autoremoveTimeout: self.autoremoveTimeout) return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: invitedBy, photo: self.photo, activeCall: self.activeCall, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: self.pendingSuggestions)
} }
public func withUpdatedPhoto(_ photo: TelegramMediaImage?) -> CachedChannelData { public func withUpdatedPhoto(_ photo: TelegramMediaImage?) -> CachedChannelData {
return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, photo: photo, activeCall: self.activeCall, autoremoveTimeout: self.autoremoveTimeout) return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, photo: photo, activeCall: self.activeCall, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: self.pendingSuggestions)
} }
public func withUpdatedActiveCall(_ activeCall: ActiveCall?) -> CachedChannelData { public func withUpdatedActiveCall(_ activeCall: ActiveCall?) -> CachedChannelData {
return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, photo: self.photo, activeCall: activeCall, autoremoveTimeout: self.autoremoveTimeout) return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, photo: self.photo, activeCall: activeCall, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: self.pendingSuggestions)
} }
public func withUpdatedAutoremoveTimeout(_ autoremoveTimeout: CachedPeerAutoremoveTimeout) -> CachedChannelData { public func withUpdatedAutoremoveTimeout(_ autoremoveTimeout: CachedPeerAutoremoveTimeout) -> CachedChannelData {
return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, photo: self.photo, activeCall: self.activeCall, autoremoveTimeout: autoremoveTimeout) return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, photo: self.photo, activeCall: self.activeCall, autoremoveTimeout: autoremoveTimeout, pendingSuggestions: self.pendingSuggestions)
}
public func withUpdatedPendingSuggestions(_ pendingSuggestions: [String]) -> CachedChannelData {
return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, photo: self.photo, activeCall: self.activeCall, autoremoveTimeout: self.autoremoveTimeout, pendingSuggestions: pendingSuggestions)
} }
public init(decoder: PostboxDecoder) { public init(decoder: PostboxDecoder) {
@ -434,6 +441,8 @@ public final class CachedChannelData: CachedPeerData {
self.invitedBy = decoder.decodeOptionalInt64ForKey("invBy").flatMap(PeerId.init) self.invitedBy = decoder.decodeOptionalInt64ForKey("invBy").flatMap(PeerId.init)
self.pendingSuggestions = decoder.decodeStringArrayForKey("sug")
if let photo = decoder.decodeObjectForKey("ph", decoder: { TelegramMediaImage(decoder: $0) }) as? TelegramMediaImage { if let photo = decoder.decodeObjectForKey("ph", decoder: { TelegramMediaImage(decoder: $0) }) as? TelegramMediaImage {
self.photo = photo self.photo = photo
} else { } else {
@ -551,6 +560,8 @@ public final class CachedChannelData: CachedPeerData {
} else { } else {
encoder.encodeNil(forKey: "ph") encoder.encodeNil(forKey: "ph")
} }
encoder.encodeStringArray(self.pendingSuggestions, forKey: "sug")
} }
public func isEqual(to: CachedPeerData) -> Bool { public func isEqual(to: CachedPeerData) -> Bool {
@ -642,6 +653,10 @@ public final class CachedChannelData: CachedPeerData {
return false return false
} }
if other.pendingSuggestions != self.pendingSuggestions {
return false
}
return true return true
} }
} }

View File

@ -11,7 +11,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
dict[-457104426] = { return Api.InputGeoPoint.parse_inputGeoPointEmpty($0) } dict[-457104426] = { return Api.InputGeoPoint.parse_inputGeoPointEmpty($0) }
dict[1210199983] = { return Api.InputGeoPoint.parse_inputGeoPoint($0) } dict[1210199983] = { return Api.InputGeoPoint.parse_inputGeoPoint($0) }
dict[-784000893] = { return Api.payments.ValidatedRequestedInfo.parse_validatedRequestedInfo($0) } dict[-784000893] = { return Api.payments.ValidatedRequestedInfo.parse_validatedRequestedInfo($0) }
dict[-66811386] = { return Api.ChatFull.parse_channelFull($0) } dict[2086843688] = { return Api.ChatFull.parse_channelFull($0) }
dict[-500874592] = { return Api.ChatFull.parse_chatFull($0) } dict[-500874592] = { return Api.ChatFull.parse_chatFull($0) }
dict[-1159937629] = { return Api.PollResults.parse_pollResults($0) } dict[-1159937629] = { return Api.PollResults.parse_pollResults($0) }
dict[-925415106] = { return Api.ChatParticipant.parse_chatParticipant($0) } dict[-925415106] = { return Api.ChatParticipant.parse_chatParticipant($0) }

View File

@ -142,14 +142,14 @@ public extension Api {
} }
public enum ChatFull: TypeConstructorDescription { public enum ChatFull: TypeConstructorDescription {
case channelFull(flags: Int32, id: Int32, about: String, participantsCount: Int32?, adminsCount: Int32?, kickedCount: Int32?, bannedCount: Int32?, onlineCount: Int32?, readInboxMaxId: Int32, readOutboxMaxId: Int32, unreadCount: Int32, chatPhoto: Api.Photo, notifySettings: Api.PeerNotifySettings, exportedInvite: Api.ExportedChatInvite?, botInfo: [Api.BotInfo], migratedFromChatId: Int32?, migratedFromMaxId: Int32?, pinnedMsgId: Int32?, stickerset: Api.StickerSet?, availableMinId: Int32?, folderId: Int32?, linkedChatId: Int32?, location: Api.ChannelLocation?, slowmodeSeconds: Int32?, slowmodeNextSendDate: Int32?, statsDc: Int32?, pts: Int32, call: Api.InputGroupCall?, ttl: Api.PeerHistoryTTL?) case channelFull(flags: Int32, id: Int32, about: String, participantsCount: Int32?, adminsCount: Int32?, kickedCount: Int32?, bannedCount: Int32?, onlineCount: Int32?, readInboxMaxId: Int32, readOutboxMaxId: Int32, unreadCount: Int32, chatPhoto: Api.Photo, notifySettings: Api.PeerNotifySettings, exportedInvite: Api.ExportedChatInvite?, botInfo: [Api.BotInfo], migratedFromChatId: Int32?, migratedFromMaxId: Int32?, pinnedMsgId: Int32?, stickerset: Api.StickerSet?, availableMinId: Int32?, folderId: Int32?, linkedChatId: Int32?, location: Api.ChannelLocation?, slowmodeSeconds: Int32?, slowmodeNextSendDate: Int32?, statsDc: Int32?, pts: Int32, call: Api.InputGroupCall?, ttl: Api.PeerHistoryTTL?, pendingSuggestions: [String]?)
case chatFull(flags: Int32, id: Int32, about: String, participants: Api.ChatParticipants, chatPhoto: Api.Photo?, notifySettings: Api.PeerNotifySettings, exportedInvite: Api.ExportedChatInvite?, botInfo: [Api.BotInfo]?, pinnedMsgId: Int32?, folderId: Int32?, call: Api.InputGroupCall?, ttl: Api.PeerHistoryTTL?) case chatFull(flags: Int32, id: Int32, about: String, participants: Api.ChatParticipants, chatPhoto: Api.Photo?, notifySettings: Api.PeerNotifySettings, exportedInvite: Api.ExportedChatInvite?, botInfo: [Api.BotInfo]?, pinnedMsgId: Int32?, folderId: Int32?, call: Api.InputGroupCall?, ttl: Api.PeerHistoryTTL?)
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) { public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
switch self { switch self {
case .channelFull(let flags, let id, let about, let participantsCount, let adminsCount, let kickedCount, let bannedCount, let onlineCount, let readInboxMaxId, let readOutboxMaxId, let unreadCount, let chatPhoto, let notifySettings, let exportedInvite, let botInfo, let migratedFromChatId, let migratedFromMaxId, let pinnedMsgId, let stickerset, let availableMinId, let folderId, let linkedChatId, let location, let slowmodeSeconds, let slowmodeNextSendDate, let statsDc, let pts, let call, let ttl): case .channelFull(let flags, let id, let about, let participantsCount, let adminsCount, let kickedCount, let bannedCount, let onlineCount, let readInboxMaxId, let readOutboxMaxId, let unreadCount, let chatPhoto, let notifySettings, let exportedInvite, let botInfo, let migratedFromChatId, let migratedFromMaxId, let pinnedMsgId, let stickerset, let availableMinId, let folderId, let linkedChatId, let location, let slowmodeSeconds, let slowmodeNextSendDate, let statsDc, let pts, let call, let ttl, let pendingSuggestions):
if boxed { if boxed {
buffer.appendInt32(-66811386) buffer.appendInt32(2086843688)
} }
serializeInt32(flags, buffer: buffer, boxed: false) serializeInt32(flags, buffer: buffer, boxed: false)
serializeInt32(id, buffer: buffer, boxed: false) serializeInt32(id, buffer: buffer, boxed: false)
@ -184,6 +184,11 @@ public extension Api {
serializeInt32(pts, buffer: buffer, boxed: false) serializeInt32(pts, buffer: buffer, boxed: false)
if Int(flags) & Int(1 << 21) != 0 {call!.serialize(buffer, true)} if Int(flags) & Int(1 << 21) != 0 {call!.serialize(buffer, true)}
if Int(flags) & Int(1 << 24) != 0 {ttl!.serialize(buffer, true)} if Int(flags) & Int(1 << 24) != 0 {ttl!.serialize(buffer, true)}
if Int(flags) & Int(1 << 25) != 0 {buffer.appendInt32(481674261)
buffer.appendInt32(Int32(pendingSuggestions!.count))
for item in pendingSuggestions! {
serializeString(item, buffer: buffer, boxed: false)
}}
break break
case .chatFull(let flags, let id, let about, let participants, let chatPhoto, let notifySettings, let exportedInvite, let botInfo, let pinnedMsgId, let folderId, let call, let ttl): case .chatFull(let flags, let id, let about, let participants, let chatPhoto, let notifySettings, let exportedInvite, let botInfo, let pinnedMsgId, let folderId, let call, let ttl):
if boxed { if boxed {
@ -211,8 +216,8 @@ public extension Api {
public func descriptionFields() -> (String, [(String, Any)]) { public func descriptionFields() -> (String, [(String, Any)]) {
switch self { switch self {
case .channelFull(let flags, let id, let about, let participantsCount, let adminsCount, let kickedCount, let bannedCount, let onlineCount, let readInboxMaxId, let readOutboxMaxId, let unreadCount, let chatPhoto, let notifySettings, let exportedInvite, let botInfo, let migratedFromChatId, let migratedFromMaxId, let pinnedMsgId, let stickerset, let availableMinId, let folderId, let linkedChatId, let location, let slowmodeSeconds, let slowmodeNextSendDate, let statsDc, let pts, let call, let ttl): case .channelFull(let flags, let id, let about, let participantsCount, let adminsCount, let kickedCount, let bannedCount, let onlineCount, let readInboxMaxId, let readOutboxMaxId, let unreadCount, let chatPhoto, let notifySettings, let exportedInvite, let botInfo, let migratedFromChatId, let migratedFromMaxId, let pinnedMsgId, let stickerset, let availableMinId, let folderId, let linkedChatId, let location, let slowmodeSeconds, let slowmodeNextSendDate, let statsDc, let pts, let call, let ttl, let pendingSuggestions):
return ("channelFull", [("flags", flags), ("id", id), ("about", about), ("participantsCount", participantsCount), ("adminsCount", adminsCount), ("kickedCount", kickedCount), ("bannedCount", bannedCount), ("onlineCount", onlineCount), ("readInboxMaxId", readInboxMaxId), ("readOutboxMaxId", readOutboxMaxId), ("unreadCount", unreadCount), ("chatPhoto", chatPhoto), ("notifySettings", notifySettings), ("exportedInvite", exportedInvite), ("botInfo", botInfo), ("migratedFromChatId", migratedFromChatId), ("migratedFromMaxId", migratedFromMaxId), ("pinnedMsgId", pinnedMsgId), ("stickerset", stickerset), ("availableMinId", availableMinId), ("folderId", folderId), ("linkedChatId", linkedChatId), ("location", location), ("slowmodeSeconds", slowmodeSeconds), ("slowmodeNextSendDate", slowmodeNextSendDate), ("statsDc", statsDc), ("pts", pts), ("call", call), ("ttl", ttl)]) return ("channelFull", [("flags", flags), ("id", id), ("about", about), ("participantsCount", participantsCount), ("adminsCount", adminsCount), ("kickedCount", kickedCount), ("bannedCount", bannedCount), ("onlineCount", onlineCount), ("readInboxMaxId", readInboxMaxId), ("readOutboxMaxId", readOutboxMaxId), ("unreadCount", unreadCount), ("chatPhoto", chatPhoto), ("notifySettings", notifySettings), ("exportedInvite", exportedInvite), ("botInfo", botInfo), ("migratedFromChatId", migratedFromChatId), ("migratedFromMaxId", migratedFromMaxId), ("pinnedMsgId", pinnedMsgId), ("stickerset", stickerset), ("availableMinId", availableMinId), ("folderId", folderId), ("linkedChatId", linkedChatId), ("location", location), ("slowmodeSeconds", slowmodeSeconds), ("slowmodeNextSendDate", slowmodeNextSendDate), ("statsDc", statsDc), ("pts", pts), ("call", call), ("ttl", ttl), ("pendingSuggestions", pendingSuggestions)])
case .chatFull(let flags, let id, let about, let participants, let chatPhoto, let notifySettings, let exportedInvite, let botInfo, let pinnedMsgId, let folderId, let call, let ttl): case .chatFull(let flags, let id, let about, let participants, let chatPhoto, let notifySettings, let exportedInvite, let botInfo, let pinnedMsgId, let folderId, let call, let ttl):
return ("chatFull", [("flags", flags), ("id", id), ("about", about), ("participants", participants), ("chatPhoto", chatPhoto), ("notifySettings", notifySettings), ("exportedInvite", exportedInvite), ("botInfo", botInfo), ("pinnedMsgId", pinnedMsgId), ("folderId", folderId), ("call", call), ("ttl", ttl)]) return ("chatFull", [("flags", flags), ("id", id), ("about", about), ("participants", participants), ("chatPhoto", chatPhoto), ("notifySettings", notifySettings), ("exportedInvite", exportedInvite), ("botInfo", botInfo), ("pinnedMsgId", pinnedMsgId), ("folderId", folderId), ("call", call), ("ttl", ttl)])
} }
@ -293,6 +298,10 @@ public extension Api {
if Int(_1!) & Int(1 << 24) != 0 {if let signature = reader.readInt32() { if Int(_1!) & Int(1 << 24) != 0 {if let signature = reader.readInt32() {
_29 = Api.parse(reader, signature: signature) as? Api.PeerHistoryTTL _29 = Api.parse(reader, signature: signature) as? Api.PeerHistoryTTL
} } } }
var _30: [String]?
if Int(_1!) & Int(1 << 25) != 0 {if let _ = reader.readInt32() {
_30 = Api.parseVector(reader, elementSignature: -1255641564, elementType: String.self)
} }
let _c1 = _1 != nil let _c1 = _1 != nil
let _c2 = _2 != nil let _c2 = _2 != nil
let _c3 = _3 != nil let _c3 = _3 != nil
@ -322,8 +331,9 @@ public extension Api {
let _c27 = _27 != nil let _c27 = _27 != nil
let _c28 = (Int(_1!) & Int(1 << 21) == 0) || _28 != nil let _c28 = (Int(_1!) & Int(1 << 21) == 0) || _28 != nil
let _c29 = (Int(_1!) & Int(1 << 24) == 0) || _29 != nil let _c29 = (Int(_1!) & Int(1 << 24) == 0) || _29 != nil
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 && _c9 && _c10 && _c11 && _c12 && _c13 && _c14 && _c15 && _c16 && _c17 && _c18 && _c19 && _c20 && _c21 && _c22 && _c23 && _c24 && _c25 && _c26 && _c27 && _c28 && _c29 { let _c30 = (Int(_1!) & Int(1 << 25) == 0) || _30 != nil
return Api.ChatFull.channelFull(flags: _1!, id: _2!, about: _3!, participantsCount: _4, adminsCount: _5, kickedCount: _6, bannedCount: _7, onlineCount: _8, readInboxMaxId: _9!, readOutboxMaxId: _10!, unreadCount: _11!, chatPhoto: _12!, notifySettings: _13!, exportedInvite: _14, botInfo: _15!, migratedFromChatId: _16, migratedFromMaxId: _17, pinnedMsgId: _18, stickerset: _19, availableMinId: _20, folderId: _21, linkedChatId: _22, location: _23, slowmodeSeconds: _24, slowmodeNextSendDate: _25, statsDc: _26, pts: _27!, call: _28, ttl: _29) if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 && _c9 && _c10 && _c11 && _c12 && _c13 && _c14 && _c15 && _c16 && _c17 && _c18 && _c19 && _c20 && _c21 && _c22 && _c23 && _c24 && _c25 && _c26 && _c27 && _c28 && _c29 && _c30 {
return Api.ChatFull.channelFull(flags: _1!, id: _2!, about: _3!, participantsCount: _4, adminsCount: _5, kickedCount: _6, bannedCount: _7, onlineCount: _8, readInboxMaxId: _9!, readOutboxMaxId: _10!, unreadCount: _11!, chatPhoto: _12!, notifySettings: _13!, exportedInvite: _14, botInfo: _15!, migratedFromChatId: _16, migratedFromMaxId: _17, pinnedMsgId: _18, stickerset: _19, availableMinId: _20, folderId: _21, linkedChatId: _22, location: _23, slowmodeSeconds: _24, slowmodeNextSendDate: _25, statsDc: _26, pts: _27!, call: _28, ttl: _29, pendingSuggestions: _30)
} }
else { else {
return nil return nil

View File

@ -5903,20 +5903,6 @@ public extension Api {
}) })
} }
public static func dismissSuggestion(suggestion: String) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Bool>) {
let buffer = Buffer()
buffer.appendInt32(125807007)
serializeString(suggestion, buffer: buffer, boxed: false)
return (FunctionDescription(name: "help.dismissSuggestion", parameters: [("suggestion", suggestion)]), 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 static func getCountriesList(langCode: String, hash: Int32) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.help.CountriesList>) { public static func getCountriesList(langCode: String, hash: Int32) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.help.CountriesList>) {
let buffer = Buffer() let buffer = Buffer()
buffer.appendInt32(1935116200) buffer.appendInt32(1935116200)
@ -5931,6 +5917,21 @@ public extension Api {
return result return result
}) })
} }
public static func dismissSuggestion(peer: Api.InputPeer, suggestion: String) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Bool>) {
let buffer = Buffer()
buffer.appendInt32(-183649631)
peer.serialize(buffer, true)
serializeString(suggestion, buffer: buffer, boxed: false)
return (FunctionDescription(name: "help.dismissSuggestion", parameters: [("peer", peer), ("suggestion", suggestion)]), 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 struct updates { public struct updates {
public static func getState() -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.updates.State>) { public static func getState() -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.updates.State>) {

View File

@ -1026,7 +1026,8 @@ public class Account {
self.managedOperationsDisposable.add(managedSecretChatOutgoingOperations(auxiliaryMethods: auxiliaryMethods, postbox: self.postbox, network: self.network).start()) self.managedOperationsDisposable.add(managedSecretChatOutgoingOperations(auxiliaryMethods: auxiliaryMethods, postbox: self.postbox, network: self.network).start())
self.managedOperationsDisposable.add(managedCloudChatRemoveMessagesOperations(postbox: self.postbox, network: self.network, stateManager: self.stateManager).start()) self.managedOperationsDisposable.add(managedCloudChatRemoveMessagesOperations(postbox: self.postbox, network: self.network, stateManager: self.stateManager).start())
self.managedOperationsDisposable.add(managedAutoremoveMessageOperations(network: self.network, postbox: self.postbox).start()) self.managedOperationsDisposable.add(managedAutoremoveMessageOperations(network: self.network, postbox: self.postbox, isRemove: true).start())
self.managedOperationsDisposable.add(managedAutoremoveMessageOperations(network: self.network, postbox: self.postbox, isRemove: false).start())
self.managedOperationsDisposable.add(managedGlobalNotificationSettings(postbox: self.postbox, network: self.network).start()) self.managedOperationsDisposable.add(managedGlobalNotificationSettings(postbox: self.postbox, network: self.network).start())
self.managedOperationsDisposable.add(managedSynchronizePinnedChatsOperations(postbox: self.postbox, network: self.network, accountPeerId: self.peerId, stateManager: self.stateManager).start()) self.managedOperationsDisposable.add(managedSynchronizePinnedChatsOperations(postbox: self.postbox, network: self.network, accountPeerId: self.peerId, stateManager: self.stateManager).start())

View File

@ -67,6 +67,7 @@ private var declaredEncodables: Void = {
declareEncodable(SecretFileMediaResource.self, f: { SecretFileMediaResource(decoder: $0) }) declareEncodable(SecretFileMediaResource.self, f: { SecretFileMediaResource(decoder: $0) })
declareEncodable(CloudChatRemoveMessagesOperation.self, f: { CloudChatRemoveMessagesOperation(decoder: $0) }) declareEncodable(CloudChatRemoveMessagesOperation.self, f: { CloudChatRemoveMessagesOperation(decoder: $0) })
declareEncodable(AutoremoveTimeoutMessageAttribute.self, f: { AutoremoveTimeoutMessageAttribute(decoder: $0) }) declareEncodable(AutoremoveTimeoutMessageAttribute.self, f: { AutoremoveTimeoutMessageAttribute(decoder: $0) })
declareEncodable(AutoclearTimeoutMessageAttribute.self, f: { AutoclearTimeoutMessageAttribute(decoder: $0) })
declareEncodable(GlobalNotificationSettings.self, f: { GlobalNotificationSettings(decoder: $0) }) declareEncodable(GlobalNotificationSettings.self, f: { GlobalNotificationSettings(decoder: $0) })
declareEncodable(CloudChatRemoveChatOperation.self, f: { CloudChatRemoveChatOperation(decoder: $0) }) declareEncodable(CloudChatRemoveChatOperation.self, f: { CloudChatRemoveChatOperation(decoder: $0) })
declareEncodable(SynchronizePinnedChatsOperation.self, f: { SynchronizePinnedChatsOperation(decoder: $0) }) declareEncodable(SynchronizePinnedChatsOperation.self, f: { SynchronizePinnedChatsOperation(decoder: $0) })

View File

@ -1006,7 +1006,7 @@ private func finalStateWithUpdatesAndServerTime(postbox: Postbox, network: Netwo
medias.append(mediaValue) medias.append(mediaValue)
} }
if let expirationTimer = expirationTimer { if let expirationTimer = expirationTimer {
attributes.append(AutoremoveTimeoutMessageAttribute(timeout: expirationTimer, countdownBeginTime: nil)) attributes.append(AutoclearTimeoutMessageAttribute(timeout: expirationTimer, countdownBeginTime: nil))
} }
if type.hasPrefix("auth") { if type.hasPrefix("auth") {

View File

@ -324,36 +324,61 @@ func enqueueMessages(transaction: Transaction, account: Account, peerId: PeerId,
switch message { switch message {
case let .message(text, requestedAttributes, mediaReference, replyToMessageId, localGroupingKey): case let .message(text, requestedAttributes, mediaReference, replyToMessageId, localGroupingKey):
var peerAutoremoveTimeout: Int32?
if let peer = peer as? TelegramSecretChat { if let peer = peer as? TelegramSecretChat {
var isAction = false var isAction = false
if let _ = mediaReference?.media as? TelegramMediaAction { if let _ = mediaReference?.media as? TelegramMediaAction {
isAction = true isAction = true
} }
if !disableAutoremove, let messageAutoremoveTimeout = peer.messageAutoremoveTimeout, !isAction { if !disableAutoremove, let messageAutoremoveTimeout = peer.messageAutoremoveTimeout, !isAction {
attributes.append(AutoremoveTimeoutMessageAttribute(timeout: messageAutoremoveTimeout, countdownBeginTime: nil)) peerAutoremoveTimeout = messageAutoremoveTimeout
} }
} else if let cachedData = transaction.getPeerCachedData(peerId: peer.id) { } else if let cachedData = transaction.getPeerCachedData(peerId: peer.id), !disableAutoremove {
var messageAutoremoveTimeout: Int32? var isScheduled = false
if let cachedData = cachedData as? CachedUserData { for attribute in requestedAttributes {
if case let .known(value) = cachedData.autoremoveTimeout { if let _ = attribute as? OutgoingScheduleInfoMessageAttribute {
messageAutoremoveTimeout = value?.effectiveValue isScheduled = true
}
} else if let cachedData = cachedData as? CachedGroupData {
if case let .known(value) = cachedData.autoremoveTimeout {
messageAutoremoveTimeout = value?.effectiveValue
}
} else if let cachedData = cachedData as? CachedChannelData {
if case let .known(value) = cachedData.autoremoveTimeout {
messageAutoremoveTimeout = value?.effectiveValue
} }
} }
if let messageAutoremoveTimeout = messageAutoremoveTimeout { if !isScheduled {
attributes.append(AutoremoveTimeoutMessageAttribute(timeout: messageAutoremoveTimeout, countdownBeginTime: nil)) var messageAutoremoveTimeout: Int32?
if let cachedData = cachedData as? CachedUserData {
if case let .known(value) = cachedData.autoremoveTimeout {
messageAutoremoveTimeout = value?.effectiveValue
}
} else if let cachedData = cachedData as? CachedGroupData {
if case let .known(value) = cachedData.autoremoveTimeout {
messageAutoremoveTimeout = value?.effectiveValue
}
} else if let cachedData = cachedData as? CachedChannelData {
if case let .known(value) = cachedData.autoremoveTimeout {
messageAutoremoveTimeout = value?.effectiveValue
}
}
if let messageAutoremoveTimeout = messageAutoremoveTimeout {
peerAutoremoveTimeout = messageAutoremoveTimeout
}
} }
} }
attributes.append(contentsOf: filterMessageAttributesForOutgoingMessage(requestedAttributes)) for attribute in filterMessageAttributesForOutgoingMessage(requestedAttributes) {
if let attribute = attribute as? AutoremoveTimeoutMessageAttribute {
if let _ = peer as? TelegramSecretChat {
peerAutoremoveTimeout = nil
attributes.append(attribute)
} else {
attributes.append(AutoclearTimeoutMessageAttribute(timeout: attribute.timeout, countdownBeginTime: nil))
}
} else {
attributes.append(attribute)
}
}
if let peerAutoremoveTimeout = peerAutoremoveTimeout {
attributes.append(AutoremoveTimeoutMessageAttribute(timeout: peerAutoremoveTimeout, countdownBeginTime: nil))
}
if let replyToMessageId = replyToMessageId, replyToMessageId.peerId == peerId { if let replyToMessageId = replyToMessageId, replyToMessageId.peerId == peerId {
var threadMessageId: MessageId? var threadMessageId: MessageId?
@ -470,7 +495,7 @@ func enqueueMessages(transaction: Transaction, account: Account, peerId: PeerId,
} }
storeMessages.append(StoreMessage(peerId: peerId, namespace: messageNamespace, globallyUniqueId: randomId, groupingKey: localGroupingKey, threadId: threadId, timestamp: effectiveTimestamp, flags: flags, tags: tags, globalTags: globalTags, localTags: localTags, forwardInfo: nil, authorId: authorId, text: text, attributes: attributes, media: mediaList)) storeMessages.append(StoreMessage(peerId: peerId, namespace: messageNamespace, globallyUniqueId: randomId, groupingKey: localGroupingKey, threadId: threadId, timestamp: effectiveTimestamp, flags: flags, tags: tags, globalTags: globalTags, localTags: localTags, forwardInfo: nil, authorId: authorId, text: text, attributes: attributes, media: mediaList))
case let .forward(source, grouping, requestedAttributes): case let .forward(source, grouping, requestedAttributes):
let sourceMessage = transaction.getMessage(source) let sourceMessage = transaction.getMessage(source)
if let sourceMessage = sourceMessage, let author = sourceMessage.author ?? sourceMessage.peers[sourceMessage.id.peerId] { if let sourceMessage = sourceMessage, let author = sourceMessage.author ?? sourceMessage.peers[sourceMessage.id.peerId] {
if let peer = peer as? TelegramSecretChat { if let peer = peer as? TelegramSecretChat {
@ -483,6 +508,35 @@ func enqueueMessages(transaction: Transaction, account: Account, peerId: PeerId,
if !disableAutoremove, let messageAutoremoveTimeout = peer.messageAutoremoveTimeout, !isAction { if !disableAutoremove, let messageAutoremoveTimeout = peer.messageAutoremoveTimeout, !isAction {
attributes.append(AutoremoveTimeoutMessageAttribute(timeout: messageAutoremoveTimeout, countdownBeginTime: nil)) attributes.append(AutoremoveTimeoutMessageAttribute(timeout: messageAutoremoveTimeout, countdownBeginTime: nil))
} }
} else if let cachedData = transaction.getPeerCachedData(peerId: peer.id), !disableAutoremove {
var isScheduled = false
for attribute in attributes {
if let _ = attribute as? OutgoingScheduleInfoMessageAttribute {
isScheduled = true
break
}
}
if !isScheduled {
var messageAutoremoveTimeout: Int32?
if let cachedData = cachedData as? CachedUserData {
if case let .known(value) = cachedData.autoremoveTimeout {
messageAutoremoveTimeout = value?.effectiveValue
}
} else if let cachedData = cachedData as? CachedGroupData {
if case let .known(value) = cachedData.autoremoveTimeout {
messageAutoremoveTimeout = value?.effectiveValue
}
} else if let cachedData = cachedData as? CachedChannelData {
if case let .known(value) = cachedData.autoremoveTimeout {
messageAutoremoveTimeout = value?.effectiveValue
}
}
if let messageAutoremoveTimeout = messageAutoremoveTimeout {
attributes.append(AutoremoveTimeoutMessageAttribute(timeout: messageAutoremoveTimeout, countdownBeginTime: nil))
}
}
} }
var forwardInfo: StoreMessageForwardInfo? var forwardInfo: StoreMessageForwardInfo?

View File

@ -39,7 +39,7 @@ private final class ManagedAutoremoveMessageOperationsHelper {
} }
} }
func managedAutoremoveMessageOperations(network: Network, postbox: Postbox) -> Signal<Void, NoError> { func managedAutoremoveMessageOperations(network: Network, postbox: Postbox, isRemove: Bool) -> Signal<Void, NoError> {
return Signal { _ in return Signal { _ in
let helper = Atomic(value: ManagedAutoremoveMessageOperationsHelper()) let helper = Atomic(value: ManagedAutoremoveMessageOperationsHelper())
@ -61,7 +61,7 @@ func managedAutoremoveMessageOperations(network: Network, postbox: Postbox) -> S
} }
|> distinctUntilChanged |> distinctUntilChanged
let disposable = combineLatest(timeOffset, postbox.timestampBasedMessageAttributesView(tag: 0)).start(next: { timeOffset, view in let disposable = combineLatest(timeOffset, postbox.timestampBasedMessageAttributesView(tag: isRemove ? 0 : 1)).start(next: { timeOffset, view in
let (disposeOperations, beginOperations) = helper.with { helper -> (disposeOperations: [Disposable], beginOperations: [(TimestampBasedMessageAttributesEntry, MetaDisposable)]) in let (disposeOperations, beginOperations) = helper.with { helper -> (disposeOperations: [Disposable], beginOperations: [(TimestampBasedMessageAttributesEntry, MetaDisposable)]) in
return helper.update(view.head) return helper.update(view.head)
} }
@ -76,14 +76,7 @@ func managedAutoremoveMessageOperations(network: Network, postbox: Postbox) -> S
|> suspendAwareDelay(max(0.0, Double(entry.timestamp) - timestamp), queue: Queue.concurrentDefaultQueue()) |> suspendAwareDelay(max(0.0, Double(entry.timestamp) - timestamp), queue: Queue.concurrentDefaultQueue())
|> then(postbox.transaction { transaction -> Void in |> then(postbox.transaction { transaction -> Void in
if let message = transaction.getMessage(entry.messageId) { if let message = transaction.getMessage(entry.messageId) {
var action: AutoremoveTimeoutMessageAttribute.Action = .remove if message.id.peerId.namespace == Namespaces.Peer.SecretChat || isRemove {
for attribute in message.attributes {
if let attribute = attribute as? AutoremoveTimeoutMessageAttribute {
action = attribute.action
}
}
if message.id.peerId.namespace == Namespaces.Peer.SecretChat || action == .remove {
deleteMessages(transaction: transaction, mediaBox: postbox.mediaBox, ids: [entry.messageId]) deleteMessages(transaction: transaction, mediaBox: postbox.mediaBox, ids: [entry.messageId])
} else { } else {
transaction.updateMessage(message.id, update: { currentMessage in transaction.updateMessage(message.id, update: { currentMessage in
@ -101,7 +94,7 @@ func managedAutoremoveMessageOperations(network: Network, postbox: Postbox) -> S
} }
var updatedAttributes = currentMessage.attributes var updatedAttributes = currentMessage.attributes
for i in 0 ..< updatedAttributes.count { for i in 0 ..< updatedAttributes.count {
if let _ = updatedAttributes[i] as? AutoremoveTimeoutMessageAttribute { if let _ = updatedAttributes[i] as? AutoclearTimeoutMessageAttribute {
updatedAttributes.remove(at: i) updatedAttributes.remove(at: i)
break break
} }

View File

@ -82,7 +82,37 @@ public func markMessageContentAsConsumedInteractively(postbox: Postbox, messageI
} }
} }
} }
break } else if let attribute = updatedAttributes[i] as? AutoclearTimeoutMessageAttribute {
if attribute.countdownBeginTime == nil || attribute.countdownBeginTime == 0 {
var timeout = attribute.timeout
if let duration = message.secretMediaDuration {
timeout = max(timeout, duration)
}
updatedAttributes[i] = AutoclearTimeoutMessageAttribute(timeout: timeout, countdownBeginTime: timestamp)
updateMessage = true
if messageId.peerId.namespace == Namespaces.Peer.SecretChat {
var layer: SecretChatLayer?
let state = transaction.getPeerChatState(message.id.peerId) as? SecretChatState
if let state = state {
switch state.embeddedState {
case .terminated, .handshake:
break
case .basicLayer:
layer = .layer8
case let .sequenceBasedLayer(sequenceState):
layer = sequenceState.layerNegotiationState.activeLayer.secretChatLayer
}
}
if let state = state, let layer = layer, let globallyUniqueId = message.globallyUniqueId {
let updatedState = addSecretChatOutgoingOperation(transaction: transaction, peerId: messageId.peerId, operation: .readMessagesContent(layer: layer, actionGloballyUniqueId: arc4random64(), globallyUniqueIds: [globallyUniqueId]), state: state)
if updatedState != state {
transaction.setPeerChatState(messageId.peerId, state: updatedState)
}
}
}
}
} }
} }
@ -140,7 +170,22 @@ func markMessageContentAsConsumedRemotely(transaction: Transaction, messageId: M
} }
} }
} }
break } else if let attribute = updatedAttributes[i] as? AutoclearTimeoutMessageAttribute {
if (attribute.countdownBeginTime == nil || attribute.countdownBeginTime == 0) && message.containsSecretMedia {
updatedAttributes[i] = AutoclearTimeoutMessageAttribute(timeout: attribute.timeout, countdownBeginTime: timestamp)
updateMessage = true
if message.id.peerId.namespace == Namespaces.Peer.SecretChat {
} else {
for i in 0 ..< updatedMedia.count {
if let _ = updatedMedia[i] as? TelegramMediaImage {
updatedMedia[i] = TelegramMediaExpiredContent(data: .image)
} else if let _ = updatedMedia[i] as? TelegramMediaFile {
updatedMedia[i] = TelegramMediaExpiredContent(data: .file)
}
}
}
}
} }
} }

View File

@ -227,6 +227,9 @@ public extension Message {
if let _ = attribute as? AutoremoveTimeoutMessageAttribute { if let _ = attribute as? AutoremoveTimeoutMessageAttribute {
found = true found = true
break break
} else if let _ = attribute as? AutoclearTimeoutMessageAttribute {
found = true
break
} }
} }

View File

@ -58,14 +58,17 @@ func messageContentToUpload(network: Network, postbox: Postbox, auxiliaryMethods
func messageContentToUpload(network: Network, postbox: Postbox, auxiliaryMethods: AccountAuxiliaryMethods, transformOutgoingMessageMedia: TransformOutgoingMessageMedia?, messageMediaPreuploadManager: MessageMediaPreuploadManager, revalidationContext: MediaReferenceRevalidationContext, forceReupload: Bool, isGrouped: Bool, peerId: PeerId, messageId: MessageId?, attributes: [MessageAttribute], text: String, media: [Media]) -> MessageContentToUpload { func messageContentToUpload(network: Network, postbox: Postbox, auxiliaryMethods: AccountAuxiliaryMethods, transformOutgoingMessageMedia: TransformOutgoingMessageMedia?, messageMediaPreuploadManager: MessageMediaPreuploadManager, revalidationContext: MediaReferenceRevalidationContext, forceReupload: Bool, isGrouped: Bool, peerId: PeerId, messageId: MessageId?, attributes: [MessageAttribute], text: String, media: [Media]) -> MessageContentToUpload {
var contextResult: OutgoingChatContextResultMessageAttribute? var contextResult: OutgoingChatContextResultMessageAttribute?
var autoremoveAttribute: AutoremoveTimeoutMessageAttribute? var autoremoveMessageAttribute: AutoremoveTimeoutMessageAttribute?
var autoclearMessageAttribute: AutoclearTimeoutMessageAttribute?
for attribute in attributes { for attribute in attributes {
if let attribute = attribute as? OutgoingChatContextResultMessageAttribute { if let attribute = attribute as? OutgoingChatContextResultMessageAttribute {
if peerId.namespace != Namespaces.Peer.SecretChat { if peerId.namespace != Namespaces.Peer.SecretChat {
contextResult = attribute contextResult = attribute
} }
} else if let attribute = attribute as? AutoremoveTimeoutMessageAttribute { } else if let attribute = attribute as? AutoremoveTimeoutMessageAttribute {
autoremoveAttribute = attribute autoremoveMessageAttribute = attribute
} else if let attribute = attribute as? AutoclearTimeoutMessageAttribute {
autoclearMessageAttribute = attribute
} }
} }
@ -84,14 +87,14 @@ func messageContentToUpload(network: Network, postbox: Postbox, auxiliaryMethods
return .immediate(.content(PendingMessageUploadedContentAndReuploadInfo(content: .forward(forwardInfo), reuploadInfo: nil)), .text) return .immediate(.content(PendingMessageUploadedContentAndReuploadInfo(content: .forward(forwardInfo), reuploadInfo: nil)), .text)
} else if let contextResult = contextResult { } else if let contextResult = contextResult {
return .immediate(.content(PendingMessageUploadedContentAndReuploadInfo(content: .chatContextResult(contextResult), reuploadInfo: nil)), .text) return .immediate(.content(PendingMessageUploadedContentAndReuploadInfo(content: .chatContextResult(contextResult), reuploadInfo: nil)), .text)
} else if let media = media.first, let mediaResult = mediaContentToUpload(network: network, postbox: postbox, auxiliaryMethods: auxiliaryMethods, transformOutgoingMessageMedia: transformOutgoingMessageMedia, messageMediaPreuploadManager: messageMediaPreuploadManager, revalidationContext: revalidationContext, forceReupload: forceReupload, isGrouped: isGrouped, peerId: peerId, media: media, text: text, autoremoveAttribute: autoremoveAttribute, messageId: messageId, attributes: attributes) { } else if let media = media.first, let mediaResult = mediaContentToUpload(network: network, postbox: postbox, auxiliaryMethods: auxiliaryMethods, transformOutgoingMessageMedia: transformOutgoingMessageMedia, messageMediaPreuploadManager: messageMediaPreuploadManager, revalidationContext: revalidationContext, forceReupload: forceReupload, isGrouped: isGrouped, peerId: peerId, media: media, text: text, autoremoveMessageAttribute: autoremoveMessageAttribute, autoclearMessageAttribute: autoclearMessageAttribute, messageId: messageId, attributes: attributes) {
return .signal(mediaResult, .media) return .signal(mediaResult, .media)
} else { } else {
return .signal(.single(.content(PendingMessageUploadedContentAndReuploadInfo(content: .text(text), reuploadInfo: nil))), .text) return .signal(.single(.content(PendingMessageUploadedContentAndReuploadInfo(content: .text(text), reuploadInfo: nil))), .text)
} }
} }
func mediaContentToUpload(network: Network, postbox: Postbox, auxiliaryMethods: AccountAuxiliaryMethods, transformOutgoingMessageMedia: TransformOutgoingMessageMedia?, messageMediaPreuploadManager: MessageMediaPreuploadManager, revalidationContext: MediaReferenceRevalidationContext, forceReupload: Bool, isGrouped: Bool, peerId: PeerId, media: Media, text: String, autoremoveAttribute: AutoremoveTimeoutMessageAttribute?, messageId: MessageId?, attributes: [MessageAttribute]) -> Signal<PendingMessageUploadedContentResult, PendingMessageUploadError>? { func mediaContentToUpload(network: Network, postbox: Postbox, auxiliaryMethods: AccountAuxiliaryMethods, transformOutgoingMessageMedia: TransformOutgoingMessageMedia?, messageMediaPreuploadManager: MessageMediaPreuploadManager, revalidationContext: MediaReferenceRevalidationContext, forceReupload: Bool, isGrouped: Bool, peerId: PeerId, media: Media, text: String, autoremoveMessageAttribute: AutoremoveTimeoutMessageAttribute?, autoclearMessageAttribute: AutoclearTimeoutMessageAttribute?, messageId: MessageId?, attributes: [MessageAttribute]) -> Signal<PendingMessageUploadedContentResult, PendingMessageUploadError>? {
if let image = media as? TelegramMediaImage, let largest = largestImageRepresentation(image.representations) { if let image = media as? TelegramMediaImage, let largest = largestImageRepresentation(image.representations) {
if peerId.namespace == Namespaces.Peer.SecretChat, let resource = largest.resource as? SecretFileMediaResource { if peerId.namespace == Namespaces.Peer.SecretChat, let resource = largest.resource as? SecretFileMediaResource {
return .single(.content(PendingMessageUploadedContentAndReuploadInfo(content: .secretMedia(.inputEncryptedFile(id: resource.fileId, accessHash: resource.accessHash), resource.decryptedSize, resource.key), reuploadInfo: nil))) return .single(.content(PendingMessageUploadedContentAndReuploadInfo(content: .secretMedia(.inputEncryptedFile(id: resource.fileId, accessHash: resource.accessHash), resource.decryptedSize, resource.key), reuploadInfo: nil)))
@ -99,7 +102,7 @@ func mediaContentToUpload(network: Network, postbox: Postbox, auxiliaryMethods:
if peerId.namespace != Namespaces.Peer.SecretChat, let reference = image.reference, case let .cloud(id, accessHash, maybeFileReference) = reference, let fileReference = maybeFileReference { if peerId.namespace != Namespaces.Peer.SecretChat, let reference = image.reference, case let .cloud(id, accessHash, maybeFileReference) = reference, let fileReference = maybeFileReference {
return .single(.content(PendingMessageUploadedContentAndReuploadInfo(content: .media(Api.InputMedia.inputMediaPhoto(flags: 0, id: Api.InputPhoto.inputPhoto(id: id, accessHash: accessHash, fileReference: Buffer(data: fileReference)), ttlSeconds: nil), text), reuploadInfo: nil))) return .single(.content(PendingMessageUploadedContentAndReuploadInfo(content: .media(Api.InputMedia.inputMediaPhoto(flags: 0, id: Api.InputPhoto.inputPhoto(id: id, accessHash: accessHash, fileReference: Buffer(data: fileReference)), ttlSeconds: nil), text), reuploadInfo: nil)))
} else { } else {
return uploadedMediaImageContent(network: network, postbox: postbox, transformOutgoingMessageMedia: transformOutgoingMessageMedia, forceReupload: forceReupload, isGrouped: isGrouped, peerId: peerId, image: image, messageId: messageId, text: text, attributes: attributes, autoremoveAttribute: autoremoveAttribute) return uploadedMediaImageContent(network: network, postbox: postbox, transformOutgoingMessageMedia: transformOutgoingMessageMedia, forceReupload: forceReupload, isGrouped: isGrouped, peerId: peerId, image: image, messageId: messageId, text: text, attributes: attributes, autoremoveMessageAttribute: autoremoveMessageAttribute, autoclearMessageAttribute: autoclearMessageAttribute)
} }
} else if let file = media as? TelegramMediaFile { } else if let file = media as? TelegramMediaFile {
if let resource = file.resource as? CloudDocumentMediaResource { if let resource = file.resource as? CloudDocumentMediaResource {
@ -314,7 +317,7 @@ private func maybeCacheUploadedResource(postbox: Postbox, key: CachedSentMediaRe
} }
} }
private func uploadedMediaImageContent(network: Network, postbox: Postbox, transformOutgoingMessageMedia: TransformOutgoingMessageMedia?, forceReupload: Bool, isGrouped: Bool, peerId: PeerId, image: TelegramMediaImage, messageId: MessageId?, text: String, attributes: [MessageAttribute], autoremoveAttribute: AutoremoveTimeoutMessageAttribute?) -> Signal<PendingMessageUploadedContentResult, PendingMessageUploadError> { private func uploadedMediaImageContent(network: Network, postbox: Postbox, transformOutgoingMessageMedia: TransformOutgoingMessageMedia?, forceReupload: Bool, isGrouped: Bool, peerId: PeerId, image: TelegramMediaImage, messageId: MessageId?, text: String, attributes: [MessageAttribute], autoremoveMessageAttribute: AutoremoveTimeoutMessageAttribute?, autoclearMessageAttribute: AutoclearTimeoutMessageAttribute?) -> Signal<PendingMessageUploadedContentResult, PendingMessageUploadError> {
guard let largestRepresentation = largestImageRepresentation(image.representations) else { guard let largestRepresentation = largestImageRepresentation(image.representations) else {
return .single(.content(PendingMessageUploadedContentAndReuploadInfo(content: .text(text), reuploadInfo: nil))) return .single(.content(PendingMessageUploadedContentAndReuploadInfo(content: .text(text), reuploadInfo: nil)))
} }
@ -328,9 +331,9 @@ private func uploadedMediaImageContent(network: Network, postbox: Postbox, trans
if !forceReupload, let image = media as? TelegramMediaImage, let reference = image.reference, case let .cloud(id, accessHash, maybeFileReference) = reference, let fileReference = maybeFileReference { if !forceReupload, let image = media as? TelegramMediaImage, let reference = image.reference, case let .cloud(id, accessHash, maybeFileReference) = reference, let fileReference = maybeFileReference {
var flags: Int32 = 0 var flags: Int32 = 0
var ttlSeconds: Int32? var ttlSeconds: Int32?
if let autoremoveAttribute = autoremoveAttribute { if let autoclearMessageAttribute = autoclearMessageAttribute {
flags |= 1 << 0 flags |= 1 << 0
ttlSeconds = autoremoveAttribute.timeout ttlSeconds = autoclearMessageAttribute.timeout
} }
return .single(.progress(1.0)) return .single(.progress(1.0))
|> then( |> then(
@ -415,9 +418,9 @@ private func uploadedMediaImageContent(network: Network, postbox: Postbox, trans
case let .inputFile(file): case let .inputFile(file):
var flags: Int32 = 0 var flags: Int32 = 0
var ttlSeconds: Int32? var ttlSeconds: Int32?
if let autoremoveAttribute = autoremoveAttribute { if let autoclearMessageAttribute = autoclearMessageAttribute {
flags |= 1 << 1 flags |= 1 << 1
ttlSeconds = autoremoveAttribute.timeout ttlSeconds = autoclearMessageAttribute.timeout
} }
var stickers: [Api.InputDocument]? var stickers: [Api.InputDocument]?
for attribute in attributes { for attribute in attributes {
@ -441,7 +444,7 @@ private func uploadedMediaImageContent(network: Network, postbox: Postbox, trans
|> mapError { _ -> PendingMessageUploadError in return .generic } |> mapError { _ -> PendingMessageUploadError in return .generic }
|> mapToSignal { inputPeer -> Signal<PendingMessageUploadedContentResult, PendingMessageUploadError> in |> mapToSignal { inputPeer -> Signal<PendingMessageUploadedContentResult, PendingMessageUploadError> in
if let inputPeer = inputPeer { if let inputPeer = inputPeer {
if autoremoveAttribute != nil { if autoclearMessageAttribute != nil {
return .single(.content(PendingMessageUploadedContentAndReuploadInfo(content: .media(.inputMediaUploadedPhoto(flags: flags, file: file, stickers: stickers, ttlSeconds: ttlSeconds), text), reuploadInfo: nil))) return .single(.content(PendingMessageUploadedContentAndReuploadInfo(content: .media(.inputMediaUploadedPhoto(flags: flags, file: file, stickers: stickers, ttlSeconds: ttlSeconds), text), reuploadInfo: nil)))
} }
@ -453,9 +456,9 @@ private func uploadedMediaImageContent(network: Network, postbox: Postbox, trans
if let photo = photo, let mediaImage = telegramMediaImageFromApiPhoto(photo), let reference = mediaImage.reference, case let .cloud(id, accessHash, maybeFileReference) = reference, let fileReference = maybeFileReference { if let photo = photo, let mediaImage = telegramMediaImageFromApiPhoto(photo), let reference = mediaImage.reference, case let .cloud(id, accessHash, maybeFileReference) = reference, let fileReference = maybeFileReference {
var flags: Int32 = 0 var flags: Int32 = 0
var ttlSeconds: Int32? var ttlSeconds: Int32?
if let autoremoveAttribute = autoremoveAttribute { if let autoclearMessageAttribute = autoclearMessageAttribute {
flags |= 1 << 0 flags |= 1 << 0
ttlSeconds = autoremoveAttribute.timeout ttlSeconds = autoclearMessageAttribute.timeout
} }
return maybeCacheUploadedResource(postbox: postbox, key: referenceKey, result: .content(PendingMessageUploadedContentAndReuploadInfo(content: .media(.inputMediaPhoto(flags: flags, id: .inputPhoto(id: id, accessHash: accessHash, fileReference: Buffer(data: fileReference)), ttlSeconds: ttlSeconds), text), reuploadInfo: nil)), media: mediaImage) return maybeCacheUploadedResource(postbox: postbox, key: referenceKey, result: .content(PendingMessageUploadedContentAndReuploadInfo(content: .media(.inputMediaPhoto(flags: flags, id: .inputPhoto(id: id, accessHash: accessHash, fileReference: Buffer(data: fileReference)), ttlSeconds: ttlSeconds), text), reuploadInfo: nil)), media: mediaImage)
} }
@ -730,7 +733,7 @@ private func uploadedMediaFileContent(network: Network, postbox: Postbox, auxili
var ttlSeconds: Int32? var ttlSeconds: Int32?
for attribute in attributes { for attribute in attributes {
if let attribute = attribute as? AutoremoveTimeoutMessageAttribute { if let attribute = attribute as? AutoclearTimeoutMessageAttribute {
flags |= 1 << 1 flags |= 1 << 1
ttlSeconds = attribute.timeout ttlSeconds = attribute.timeout
} }

View File

@ -60,7 +60,7 @@ private func requestEditMessageInternal(postbox: Postbox, network: Network, stat
case let .update(media): case let .update(media):
let generateUploadSignal: (Bool) -> Signal<PendingMessageUploadedContentResult, PendingMessageUploadError>? = { forceReupload in let generateUploadSignal: (Bool) -> Signal<PendingMessageUploadedContentResult, PendingMessageUploadError>? = { forceReupload in
let augmentedMedia = augmentMediaWithReference(media) let augmentedMedia = augmentMediaWithReference(media)
return mediaContentToUpload(network: network, postbox: postbox, auxiliaryMethods: stateManager.auxiliaryMethods, transformOutgoingMessageMedia: transformOutgoingMessageMedia, messageMediaPreuploadManager: messageMediaPreuploadManager, revalidationContext: mediaReferenceRevalidationContext, forceReupload: forceReupload, isGrouped: false, peerId: messageId.peerId, media: augmentedMedia, text: "", autoremoveAttribute: nil, messageId: nil, attributes: []) return mediaContentToUpload(network: network, postbox: postbox, auxiliaryMethods: stateManager.auxiliaryMethods, transformOutgoingMessageMedia: transformOutgoingMessageMedia, messageMediaPreuploadManager: messageMediaPreuploadManager, revalidationContext: mediaReferenceRevalidationContext, forceReupload: forceReupload, isGrouped: false, peerId: messageId.peerId, media: augmentedMedia, text: "", autoremoveMessageAttribute: nil, autoclearMessageAttribute: nil, messageId: nil, attributes: [])
} }
if let uploadSignal = generateUploadSignal(forceReupload) { if let uploadSignal = generateUploadSignal(forceReupload) {
uploadedMedia = .single(.progress(0.027)) uploadedMedia = .single(.progress(0.027))

View File

@ -8,7 +8,11 @@ public func tagsForStoreMessage(incoming: Bool, attributes: [MessageAttribute],
var isSecret = false var isSecret = false
var isUnconsumedPersonalMention = false var isUnconsumedPersonalMention = false
for attribute in attributes { for attribute in attributes {
if let timerAttribute = attribute as? AutoremoveTimeoutMessageAttribute { if let timerAttribute = attribute as? AutoclearTimeoutMessageAttribute {
if timerAttribute.timeout > 0 && timerAttribute.timeout <= 60 {
isSecret = true
}
} else if let timerAttribute = attribute as? AutoremoveTimeoutMessageAttribute {
if timerAttribute.timeout > 0 && timerAttribute.timeout <= 60 { if timerAttribute.timeout > 0 && timerAttribute.timeout <= 60 {
isSecret = true isSecret = true
} }
@ -468,27 +472,21 @@ extension StoreMessage {
var consumableContent: (Bool, Bool)? = nil var consumableContent: (Bool, Bool)? = nil
var resolvedTtlPeriod: Int32? = ttlPeriod
if let media = media { if let media = media {
let (mediaValue, expirationTimer) = textMediaAndExpirationTimerFromApiMedia(media, peerId) let (mediaValue, expirationTimer) = textMediaAndExpirationTimerFromApiMedia(media, peerId)
if let mediaValue = mediaValue { if let mediaValue = mediaValue {
medias.append(mediaValue) medias.append(mediaValue)
if let expirationTimer = expirationTimer, expirationTimer > 0 { if let expirationTimer = expirationTimer, expirationTimer > 0 {
if let resolvedTtlPeriodValue = resolvedTtlPeriod { attributes.append(AutoclearTimeoutMessageAttribute(timeout: expirationTimer, countdownBeginTime: nil))
resolvedTtlPeriod = min(resolvedTtlPeriodValue, expirationTimer)
} else {
resolvedTtlPeriod = expirationTimer
}
consumableContent = (true, false) consumableContent = (true, false)
} }
} }
} }
if let resolvedTtlPeriod = resolvedTtlPeriod { if let ttlPeriod = ttlPeriod {
attributes.append(AutoremoveTimeoutMessageAttribute(timeout: resolvedTtlPeriod, countdownBeginTime: ttlPeriod == nil ? nil : date)) attributes.append(AutoremoveTimeoutMessageAttribute(timeout: ttlPeriod, countdownBeginTime: date))
} }
if let postAuthor = postAuthor { if let postAuthor = postAuthor {

View File

@ -30,9 +30,41 @@ public func getServerProvidedSuggestions(postbox: Postbox) -> Signal<[ServerProv
} }
public func dismissServerProvidedSuggestion(account: Account, suggestion: ServerProvidedSuggestion) -> Signal<Never, NoError> { public func dismissServerProvidedSuggestion(account: Account, suggestion: ServerProvidedSuggestion) -> Signal<Never, NoError> {
return account.network.request(Api.functions.help.dismissSuggestion(suggestion: suggestion.rawValue)) return account.network.request(Api.functions.help.dismissSuggestion(peer: .inputPeerEmpty, suggestion: suggestion.rawValue))
|> `catch` { _ -> Signal<Api.Bool, NoError> in |> `catch` { _ -> Signal<Api.Bool, NoError> in
return .single(.boolFalse) return .single(.boolFalse)
} }
|> ignoreValues |> ignoreValues
} }
public enum PeerSpecificServerProvidedSuggestion: String {
case convertToGigagroup = "CONVERT_TO_GIGAGROUP"
}
public func getPeerSpecificServerProvidedSuggestions(postbox: Postbox, peerId: PeerId) -> Signal<[PeerSpecificServerProvidedSuggestion], NoError> {
return postbox.peerView(id: peerId)
|> map { view in
if let cachedData = view.cachedData as? CachedChannelData {
return cachedData.pendingSuggestions.compactMap { item -> PeerSpecificServerProvidedSuggestion? in
return PeerSpecificServerProvidedSuggestion(rawValue: item)
}
}
return []
}
|> distinctUntilChanged
}
public func dismissPeerSpecificServerProvidedSuggestion(account: Account, peerId: PeerId, suggestion: PeerSpecificServerProvidedSuggestion) -> Signal<Never, NoError> {
return account.postbox.loadedPeerWithId(peerId)
|> mapToSignal { peer -> Signal<Never, NoError> in
guard let inputPeer = apiInputPeer(peer) else {
return .never()
}
return account.network.request(Api.functions.help.dismissSuggestion(peer: inputPeer, suggestion: suggestion.rawValue))
|> `catch` { _ -> Signal<Api.Bool, NoError> in
return .single(.boolFalse)
}
|> ignoreValues
}
}

View File

@ -355,7 +355,7 @@ func fetchAndUpdateCachedPeerData(accountPeerId: PeerId, peerId rawPeerId: PeerI
} }
switch fullChat { switch fullChat {
case let .channelFull(flags, _, about, participantsCount, adminsCount, kickedCount, bannedCount, _, _, _, _, chatPhoto, _, apiExportedInvite, apiBotInfos, migratedFromChatId, migratedFromMaxId, pinnedMsgId, stickerSet, minAvailableMsgId, folderId, linkedChatId, location, slowmodeSeconds, slowmodeNextSendDate, statsDc, pts, inputCall, ttl): case let .channelFull(flags, _, about, participantsCount, adminsCount, kickedCount, bannedCount, _, _, _, _, chatPhoto, _, apiExportedInvite, apiBotInfos, migratedFromChatId, migratedFromMaxId, pinnedMsgId, stickerSet, minAvailableMsgId, folderId, linkedChatId, location, slowmodeSeconds, slowmodeNextSendDate, statsDc, pts, inputCall, ttl, pendingSuggestions):
var channelFlags = CachedChannelFlags() var channelFlags = CachedChannelFlags()
if (flags & (1 << 3)) != 0 { if (flags & (1 << 3)) != 0 {
channelFlags.insert(.canDisplayParticipants) channelFlags.insert(.canDisplayParticipants)
@ -531,6 +531,7 @@ func fetchAndUpdateCachedPeerData(accountPeerId: PeerId, peerId rawPeerId: PeerI
.withUpdatedPhoto(photo) .withUpdatedPhoto(photo)
.withUpdatedActiveCall(updatedActiveCall) .withUpdatedActiveCall(updatedActiveCall)
.withUpdatedAutoremoveTimeout(autoremoveTimeout) .withUpdatedAutoremoveTimeout(autoremoveTimeout)
.withUpdatedPendingSuggestions(pendingSuggestions ?? [])
}) })
if let minAvailableMessageId = minAvailableMessageId, minAvailableMessageIdUpdated { if let minAvailableMessageId = minAvailableMessageId, minAvailableMessageIdUpdated {

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -5566,8 +5566,10 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
canSetupAutoremoveTimeout = true canSetupAutoremoveTimeout = true
} }
} }
} else if let _ = peer as? TelegramUser { } else if let user = peer as? TelegramUser {
canSetupAutoremoveTimeout = true if user.id != strongSelf.context.account.peerId {
canSetupAutoremoveTimeout = true
}
} else if let channel = peer as? TelegramChannel { } else if let channel = peer as? TelegramChannel {
if channel.hasPermission(.deleteAllMessages) { if channel.hasPermission(.deleteAllMessages) {
canSetupAutoremoveTimeout = true canSetupAutoremoveTimeout = true
@ -5585,7 +5587,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
if let tooltipController = strongSelf.silentPostTooltipController { if let tooltipController = strongSelf.silentPostTooltipController {
tooltipController.updateContent(.text(text), animated: true, extendTimer: true) tooltipController.updateContent(.text(text), animated: true, extendTimer: true)
} else { } else {
let tooltipController = TooltipController(content: .text(text), baseFontSize: strongSelf.presentationData.listsFontSize.baseDisplaySize) let tooltipController = TooltipController(content: .text(text), baseFontSize: strongSelf.presentationData.listsFontSize.baseDisplaySize, timeout: 4.0)
strongSelf.silentPostTooltipController = tooltipController strongSelf.silentPostTooltipController = tooltipController
tooltipController.dismissed = { [weak tooltipController] _ in tooltipController.dismissed = { [weak tooltipController] _ in
if let strongSelf = self, let tooltipController = tooltipController, strongSelf.silentPostTooltipController === tooltipController { if let strongSelf = self, let tooltipController = tooltipController, strongSelf.silentPostTooltipController === tooltipController {
@ -7737,9 +7739,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
var currentAutoremoveTimeout: Int32? = self.presentationInterfaceState.autoremoveTimeout var currentAutoremoveTimeout: Int32? = self.presentationInterfaceState.autoremoveTimeout
var canSetupAutoremoveTimeout = false var canSetupAutoremoveTimeout = false
if let secretChat = peer as? TelegramSecretChat { if let _ = peer as? TelegramSecretChat {
currentAutoremoveTimeout = secretChat.messageAutoremoveTimeout
canSetupAutoremoveTimeout = true
} else if let group = peer as? TelegramGroup { } else if let group = peer as? TelegramGroup {
if case .creator = group.role { if case .creator = group.role {
canSetupAutoremoveTimeout = true canSetupAutoremoveTimeout = true
@ -7748,8 +7748,10 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
canSetupAutoremoveTimeout = true canSetupAutoremoveTimeout = true
} }
} }
} else if let _ = self.presentationInterfaceState.renderedPeer?.peer as? TelegramUser { } else if let user = self.presentationInterfaceState.renderedPeer?.peer as? TelegramUser {
canSetupAutoremoveTimeout = true if user.id != self.context.account.peerId {
canSetupAutoremoveTimeout = true
}
} else if let channel = self.presentationInterfaceState.renderedPeer?.peer as? TelegramChannel { } else if let channel = self.presentationInterfaceState.renderedPeer?.peer as? TelegramChannel {
if channel.hasPermission(.deleteAllMessages) { if channel.hasPermission(.deleteAllMessages) {
canSetupAutoremoveTimeout = true canSetupAutoremoveTimeout = true

View File

@ -255,8 +255,11 @@ func inputTextPanelStateForChatPresentationInterfaceState(_ chatPresentationInte
} }
if canSetupAutoremoveTimeout { if canSetupAutoremoveTimeout {
if currentAutoremoveTimeout != nil || chatPresentationInterfaceState.renderedPeer?.peer is TelegramSecretChat { if case .scheduledMessages = chatPresentationInterfaceState.subject {
accessoryItems.append(.messageAutoremoveTimeout(currentAutoremoveTimeout)) } else if chatPresentationInterfaceState.renderedPeer?.peerId != context.account.peerId {
if currentAutoremoveTimeout != nil || chatPresentationInterfaceState.renderedPeer?.peer is TelegramSecretChat {
accessoryItems.append(.messageAutoremoveTimeout(currentAutoremoveTimeout))
}
} }
} }
@ -279,10 +282,13 @@ func inputTextPanelStateForChatPresentationInterfaceState(_ chatPresentationInte
} }
} }
if !extendedSearchLayout { if !extendedSearchLayout {
if let peer = chatPresentationInterfaceState.renderedPeer?.peer as? TelegramSecretChat { if case .scheduledMessages = chatPresentationInterfaceState.subject {
accessoryItems.append(.messageAutoremoveTimeout(peer.messageAutoremoveTimeout)) } else if chatPresentationInterfaceState.renderedPeer?.peerId != context.account.peerId {
} else if currentAutoremoveTimeout != nil && chatPresentationInterfaceState.interfaceState.composeInputState.inputText.length == 0 { if let peer = chatPresentationInterfaceState.renderedPeer?.peer as? TelegramSecretChat {
accessoryItems.append(.messageAutoremoveTimeout(currentAutoremoveTimeout)) accessoryItems.append(.messageAutoremoveTimeout(peer.messageAutoremoveTimeout))
} else if currentAutoremoveTimeout != nil && chatPresentationInterfaceState.interfaceState.composeInputState.inputText.length == 0 {
accessoryItems.append(.messageAutoremoveTimeout(currentAutoremoveTimeout))
}
} }
} }

View File

@ -209,6 +209,8 @@ func messageMediaEditingOptions(message: Message) -> MessageMediaEditingOptions
for attribute in message.attributes { for attribute in message.attributes {
if attribute is AutoremoveTimeoutMessageAttribute { if attribute is AutoremoveTimeoutMessageAttribute {
return [] return []
} else if attribute is AutoclearTimeoutMessageAttribute {
return []
} }
} }
@ -809,6 +811,9 @@ func contextMenuForChatPresentationInterfaceState(chatPresentationInterfaceState
if let _ = attribute as? AutoremoveTimeoutMessageAttribute { if let _ = attribute as? AutoremoveTimeoutMessageAttribute {
hasAutoremove = true hasAutoremove = true
break break
} else if let _ = attribute as? AutoclearTimeoutMessageAttribute {
hasAutoremove = true
break
} }
} }
@ -1245,7 +1250,7 @@ final class ChatDeleteMessageContextItem: ContextMenuCustomItem {
private let textFont = Font.regular(17.0) private let textFont = Font.regular(17.0)
private final class ChatDeleteMessageContextItemNode: ASDisplayNode, ContextMenuCustomNode { private final class ChatDeleteMessageContextItemNode: ASDisplayNode, ContextMenuCustomNode, ContextActionNodeProtocol {
private let item: ChatDeleteMessageContextItem private let item: ChatDeleteMessageContextItem
private let presentationData: PresentationData private let presentationData: PresentationData
private let getController: () -> ContextController? private let getController: () -> ContextController?

View File

@ -494,12 +494,13 @@ class ChatMessageInteractiveInstantVideoNode: ASDisplayNode {
let isSecretMedia = item.message.containsSecretMedia let isSecretMedia = item.message.containsSecretMedia
var secretBeginTimeAndTimeout: (Double, Double)? var secretBeginTimeAndTimeout: (Double, Double)?
if isSecretMedia { if isSecretMedia {
for attribute in item.message.attributes { if let attribute = item.message.autoclearAttribute {
if let attribute = attribute as? AutoremoveTimeoutMessageAttribute { if let countdownBeginTime = attribute.countdownBeginTime {
if let countdownBeginTime = attribute.countdownBeginTime { secretBeginTimeAndTimeout = (Double(countdownBeginTime), Double(attribute.timeout))
secretBeginTimeAndTimeout = (Double(countdownBeginTime), Double(attribute.timeout)) }
} } else if let attribute = item.message.autoremoveAttribute {
break if let countdownBeginTime = attribute.countdownBeginTime {
secretBeginTimeAndTimeout = (Double(countdownBeginTime), Double(attribute.timeout))
} }
} }
} }

View File

@ -261,12 +261,13 @@ final class ChatMessageInteractiveMediaNode: ASDisplayNode, GalleryItemTransitio
let isSecretMedia = message.containsSecretMedia let isSecretMedia = message.containsSecretMedia
var secretBeginTimeAndTimeout: (Double, Double)? var secretBeginTimeAndTimeout: (Double, Double)?
if isSecretMedia { if isSecretMedia {
for attribute in message.attributes { if let attribute = message.autoclearAttribute {
if let attribute = attribute as? AutoremoveTimeoutMessageAttribute { if let countdownBeginTime = attribute.countdownBeginTime {
if let countdownBeginTime = attribute.countdownBeginTime { secretBeginTimeAndTimeout = (Double(countdownBeginTime), Double(attribute.timeout))
secretBeginTimeAndTimeout = (Double(countdownBeginTime), Double(attribute.timeout)) }
} } else if let attribute = message.autoremoveAttribute {
break if let countdownBeginTime = attribute.countdownBeginTime {
secretBeginTimeAndTimeout = (Double(countdownBeginTime), Double(attribute.timeout))
} }
} }
} }
@ -934,14 +935,13 @@ final class ChatMessageInteractiveMediaNode: ASDisplayNode, GalleryItemTransitio
var secretBeginTimeAndTimeout: (Double?, Double)? var secretBeginTimeAndTimeout: (Double?, Double)?
let isSecretMedia = message.containsSecretMedia let isSecretMedia = message.containsSecretMedia
if isSecretMedia { if isSecretMedia {
for attribute in message.attributes { if let attribute = message.autoclearAttribute {
if let attribute = attribute as? AutoremoveTimeoutMessageAttribute { if let countdownBeginTime = attribute.countdownBeginTime {
if let countdownBeginTime = attribute.countdownBeginTime { secretBeginTimeAndTimeout = (Double(countdownBeginTime), Double(attribute.timeout))
secretBeginTimeAndTimeout = (Double(countdownBeginTime), Double(attribute.timeout)) }
} else { } else if let attribute = message.autoremoveAttribute {
secretBeginTimeAndTimeout = (nil, Double(attribute.timeout)) if let countdownBeginTime = attribute.countdownBeginTime {
} secretBeginTimeAndTimeout = (Double(countdownBeginTime), Double(attribute.timeout))
break
} }
} }
} }

View File

@ -656,7 +656,7 @@ func peerInfoScreenData(context: AccountContext, peerId: PeerId, strings: Presen
if currentInvitationsContext == nil { if currentInvitationsContext == nil {
var canManageInvitations = false var canManageInvitations = false
if let channel = peerViewMainPeer(peerView) as? TelegramChannel, let cachedData = peerView.cachedData as? CachedChannelData, channel.flags.contains(.isCreator) || channel.hasPermission(.inviteMembers) { if let channel = peerViewMainPeer(peerView) as? TelegramChannel, let cachedData = peerView.cachedData as? CachedChannelData, channel.flags.contains(.isCreator) || (channel.adminRights?.flags.contains(.canInviteUsers) == true) {
canManageInvitations = true canManageInvitations = true
} }
if canManageInvitations { if canManageInvitations {
@ -819,7 +819,7 @@ func peerInfoScreenData(context: AccountContext, peerId: PeerId, strings: Presen
} else if case let .admin(rights, _) = group.role, rights.flags.contains(.canInviteUsers) { } else if case let .admin(rights, _) = group.role, rights.flags.contains(.canInviteUsers) {
canManageInvitations = true canManageInvitations = true
} }
} else if let channel = peerViewMainPeer(peerView) as? TelegramChannel, channel.flags.contains(.isCreator) || channel.hasPermission(.inviteMembers) { } else if let channel = peerViewMainPeer(peerView) as? TelegramChannel, channel.flags.contains(.isCreator) || (channel.adminRights?.flags.contains(.canInviteUsers) == true) {
canManageInvitations = true canManageInvitations = true
} }
if canManageInvitations { if canManageInvitations {

View File

@ -1340,7 +1340,7 @@ private func editingItems(data: PeerInfoScreenData?, context: AccountContext, pr
} }
} }
if isCreator || (channel.hasPermission(.inviteMembers)) { if isCreator || (channel.adminRights?.flags.contains(.canInviteUsers) == true) {
let invitesText: String let invitesText: String
if let count = data.invitations?.count, count > 0 { if let count = data.invitations?.count, count > 0 {
invitesText = "\(count)" invitesText = "\(count)"
@ -6234,10 +6234,8 @@ func presentAddMembers(context: AccountContext, parentController: ViewController
break break
} }
} else if let channel = groupPeer as? TelegramChannel { } else if let channel = groupPeer as? TelegramChannel {
if channel.hasPermission(.inviteMembers) { if channel.flags.contains(.isCreator) || (channel.adminRights?.flags.contains(.canInviteUsers) == true) {
if channel.flags.contains(.isCreator) || (channel.hasPermission(.inviteMembers)) { canCreateInviteLink = true
canCreateInviteLink = true
}
} }
} }

View File

@ -152,43 +152,8 @@ final class WidgetDataContext {
} }
let processedRecent = recent let processedRecent = recent
|> map { result -> WidgetData in |> map { _ -> WidgetData in
switch result { return WidgetData(accountId: account.id.int64, content: .peers(WidgetDataPeers(accountPeerId: account.peerId.toInt64(), peers: [], updateTimestamp: Int32(Date().timeIntervalSince1970))), unlockedForLockId: nil)
case .disabled:
return WidgetData(accountId: account.id.int64, content: .empty, unlockedForLockId: nil)
case let .peers(peers, unread, messages):
return WidgetData(accountId: account.id.int64, content: .peers(WidgetDataPeers(accountPeerId: account.peerId.toInt64(), peers: peers.compactMap { peer -> WidgetDataPeer? in
var name: String = ""
var lastName: String?
if let user = peer as? TelegramUser {
if let firstName = user.firstName {
name = firstName
lastName = user.lastName
} else if let lastName = user.lastName {
name = lastName
} else if let phone = user.phone, !phone.isEmpty {
name = phone
}
} else {
name = peer.debugDisplayTitle
}
var badge: WidgetDataPeer.Badge?
if let unreadValue = unread[peer.id], unreadValue.count > 0 {
badge = WidgetDataPeer.Badge(
count: Int(unreadValue.count),
isMuted: unreadValue.isMuted
)
}
let message = messages[peer.id]
return WidgetDataPeer(id: peer.id.toInt64(), name: name, lastName: lastName, letters: peer.displayLetters, avatarPath: smallestImageRepresentation(peer.profileImageRepresentations).flatMap { representation in
return account.postbox.mediaBox.resourcePath(representation.resource)
}, badge: badge, message: message)
}, updateTimestamp: Int32(Date().timeIntervalSince1970))), unlockedForLockId: nil)
}
} }
|> distinctUntilChanged |> distinctUntilChanged

@ -1 +1 @@
Subproject commit e1e94e4e500e14251cf6a803af54e53cb7945dba Subproject commit 17d7e77771ba00e128b2755b6eac486190a5194d

View File

@ -147,7 +147,7 @@ final class UndoOverlayControllerNode: ViewControllerTracingNode {
} }
self.textNode.attributedText = NSAttributedString(string: text, font: Font.regular(14.0), textColor: .white) self.textNode.attributedText = NSAttributedString(string: text, font: Font.regular(14.0), textColor: .white)
displayUndo = false displayUndo = false
self.originalRemainingSeconds = 3 self.originalRemainingSeconds = 5
case let .succeed(text): case let .succeed(text):
self.avatarNode = nil self.avatarNode = nil
self.iconNode = nil self.iconNode = nil