mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
[WIP] Autoremove timer
This commit is contained in:
parent
e80c198605
commit
4cd27e7864
@ -1578,7 +1578,7 @@ ios_application(
|
|||||||
":NotificationContentExtension",
|
":NotificationContentExtension",
|
||||||
":NotificationServiceExtension",
|
":NotificationServiceExtension",
|
||||||
":IntentsExtension",
|
":IntentsExtension",
|
||||||
# ":WidgetExtension",
|
":WidgetExtension",
|
||||||
],
|
],
|
||||||
}),
|
}),
|
||||||
watch_application = select({
|
watch_application = select({
|
||||||
|
@ -701,7 +701,7 @@ class IntentHandler: INExtension, INSendMessageIntentHandling, INSearchForMessag
|
|||||||
}
|
}
|
||||||
|
|
||||||
@available(iOSApplicationExtension 14.0, iOS 14.0, *)
|
@available(iOSApplicationExtension 14.0, iOS 14.0, *)
|
||||||
func provideFriendsOptionsCollection(for intent: SelectFriendsIntent, with completion: @escaping (INObjectCollection<Friend>?, Error?) -> Void) {
|
func provideFriendsOptionsCollection(for intent: SelectFriendsIntent, with completion: @escaping (INObjectCollection<Friend>?, Error?) -> Void) {
|
||||||
let _ = (self.accountPromise.get()
|
let _ = (self.accountPromise.get()
|
||||||
|> take(1)
|
|> take(1)
|
||||||
|> mapToSignal { account -> Signal<[Friend], NoError> in
|
|> mapToSignal { account -> Signal<[Friend], NoError> in
|
||||||
|
@ -146,7 +146,7 @@
|
|||||||
</dict>
|
</dict>
|
||||||
<dict>
|
<dict>
|
||||||
<key>INIntentParameterArraySizeSize</key>
|
<key>INIntentParameterArraySizeSize</key>
|
||||||
<integer>8</integer>
|
<integer>2</integer>
|
||||||
<key>INIntentParameterArraySizeSizeClass</key>
|
<key>INIntentParameterArraySizeSizeClass</key>
|
||||||
<string>Medium</string>
|
<string>Medium</string>
|
||||||
</dict>
|
</dict>
|
||||||
|
@ -171,7 +171,7 @@ struct Provider: IntentTimelineProvider {
|
|||||||
}, badge: badge, message: mappedMessage))
|
}, badge: badge, message: mappedMessage))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return WidgetDataPeers(accountPeerId: widgetPeers.accountPeerId, peers: peers)
|
return WidgetDataPeers(accountPeerId: widgetPeers.accountPeerId, peers: peers, updateTimestamp: Int32(Date().timeIntervalSince1970))
|
||||||
})
|
})
|
||||||
|> deliverOnMainQueue).start(next: { peers in
|
|> deliverOnMainQueue).start(next: { peers in
|
||||||
completion(Timeline(entries: [SimpleEntry(date: entryDate, contents: .peers(peers))], policy: .atEnd))
|
completion(Timeline(entries: [SimpleEntry(date: entryDate, contents: .peers(peers))], policy: .atEnd))
|
||||||
@ -442,7 +442,7 @@ struct WidgetView: View {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func chatContentView(_ index: Int) -> AnyView {
|
func chatContentView(_ index: Int, size: CGSize) -> AnyView {
|
||||||
let peers: WidgetDataPeers
|
let peers: WidgetDataPeers
|
||||||
switch data {
|
switch data {
|
||||||
case let .peers(peersValue):
|
case let .peers(peersValue):
|
||||||
@ -454,16 +454,57 @@ struct WidgetView: View {
|
|||||||
return AnyView(Spacer())
|
return AnyView(Spacer())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let itemHeight = (size.height - 22.0) / 2.0
|
||||||
|
|
||||||
return AnyView(
|
return AnyView(
|
||||||
Link(destination: URL(string: linkForPeer(id: peers.peers[index].id))!, label: {
|
Link(destination: URL(string: linkForPeer(id: peers.peers[index].id))!, label: {
|
||||||
HStack(alignment: .center, spacing: 0.0, content: {
|
HStack(alignment: .center, spacing: 0.0, content: {
|
||||||
AvatarItemView(accountPeerId: peers.accountPeerId, peer: peers.peers[index], itemSize: 60.0, displayBadge: false).frame(width: 60.0, height: 60.0, alignment: .leading).padding(EdgeInsets(top: 0.0, leading: 10.0, bottom: 0.0, trailing: 10.0))
|
AvatarItemView(accountPeerId: peers.accountPeerId, 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))
|
||||||
chatContent(peers.peers[index]).frame(maxWidth: .infinity).padding(EdgeInsets(top: 10.0, leading: 0.0, bottom: 10.0, trailing: 10.0))
|
chatContent(peers.peers[index]).frame(maxWidth: .infinity).padding(EdgeInsets(top: 10.0, leading: 0.0, bottom: 10.0, trailing: 10.0))
|
||||||
})
|
})
|
||||||
})
|
}).position(x: size.width / 2.0, y: (itemHeight * 2.0) / 4.0 + CGFloat(index) * itemHeight).frame(width: size.width, height: itemHeight, alignment: .leading)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func chatSeparatorView(size: CGSize) -> some View {
|
||||||
|
let separatorWidth = size.width - 54.0 - 20.0
|
||||||
|
let itemHeight = (size.height - 22.0) / 2.0
|
||||||
|
return Rectangle().foregroundColor(getSeparatorColor()).position(x: (54.0 + 20.0 + separatorWidth) / 2.0, y: itemHeight / 2.0).frame(width: separatorWidth, height: 0.33, alignment: .leading)
|
||||||
|
}
|
||||||
|
|
||||||
|
func chatsUpdateBackgroundView(size: CGSize) -> some View {
|
||||||
|
return Rectangle().foregroundColor(getUpdatedBackgroundColor()).position(x: size.width / 2.0, y: size.height - 22.0 - 11.0).frame(width: size.width, height: 22.0, alignment: .leading)
|
||||||
|
}
|
||||||
|
|
||||||
|
func chatsUpdateTimestampView(size: CGSize) -> some View {
|
||||||
|
let text: String
|
||||||
|
switch data {
|
||||||
|
case let .peers(peersValue):
|
||||||
|
let date = Date(timeIntervalSince1970: Double(peersValue.updateTimestamp))
|
||||||
|
let calendar = Calendar.current
|
||||||
|
//TODO:localize
|
||||||
|
if !calendar.isDate(Date(), inSameDayAs: date) {
|
||||||
|
let formatter = DateFormatter()
|
||||||
|
formatter.dateStyle = .short
|
||||||
|
formatter.timeStyle = .none
|
||||||
|
text = "updated on \(formatter.string(from: date))"
|
||||||
|
} else {
|
||||||
|
let formatter = DateFormatter()
|
||||||
|
formatter.dateStyle = .none
|
||||||
|
formatter.timeStyle = .short
|
||||||
|
text = "updated at \(formatter.string(from: date))"
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
text = ""
|
||||||
|
}
|
||||||
|
|
||||||
|
return HStack(alignment: .center, spacing: 0.0, content: {
|
||||||
|
Text(text)
|
||||||
|
.font(Font.system(size: 12.0))
|
||||||
|
.foregroundColor(getUpdatedTextColor())
|
||||||
|
}).position(x: size.width / 2.0, y: size.height - 22.0 - 11.0).frame(width: size.width, height: 22.0, alignment: .leading)
|
||||||
|
}
|
||||||
|
|
||||||
func getSeparatorColor() -> Color {
|
func getSeparatorColor() -> Color {
|
||||||
switch colorScheme {
|
switch colorScheme {
|
||||||
case .light:
|
case .light:
|
||||||
@ -475,12 +516,36 @@ struct WidgetView: View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getUpdatedBackgroundColor() -> 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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func getUpdatedTextColor() -> Color {
|
||||||
|
switch colorScheme {
|
||||||
|
case .light:
|
||||||
|
return Color(.sRGB, red: 142.0 / 255.0, green: 142.0 / 255.0, blue: 146.0 / 255.0, opacity: 1.0)
|
||||||
|
case .dark:
|
||||||
|
return Color(.sRGB, red: 142.0 / 255.0, green: 142.0 / 255.0, blue: 146.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
|
||||||
ZStack {
|
return ZStack {
|
||||||
chatContentView(0).position(x: geometry.size.width / 2.0, y: geometry.size.height / 4.0).frame(width: geometry.size.width, height: geometry.size.height / 2.0, alignment: .leading)
|
chatContentView(0, size: geometry.size)
|
||||||
chatContentView(1).position(x: geometry.size.width / 2.0, y: geometry.size.height / 2.0 + geometry.size.height / 4.0).frame(width: geometry.size.width, height: geometry.size.height / 2.0, alignment: .leading)
|
chatContentView(1, size: geometry.size)
|
||||||
Rectangle().foregroundColor(getSeparatorColor()).position(x: geometry.size.width / 2.0, y: geometry.size.height / 4.0).frame(width: geometry.size.width, height: 0.33, alignment: .leading)
|
chatSeparatorView(size: geometry.size)
|
||||||
|
chatsUpdateBackgroundView(size: geometry.size)
|
||||||
|
chatsUpdateTimestampView(size: geometry.size)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.padding(0.0)
|
.padding(0.0)
|
||||||
|
@ -13,6 +13,7 @@ public enum ChatListFilterSettingsHeaderAnimation {
|
|||||||
case folders
|
case folders
|
||||||
case newFolder
|
case newFolder
|
||||||
case discussionGroupSetup
|
case discussionGroupSetup
|
||||||
|
case autoRemove
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ChatListFilterSettingsHeaderItem: ListViewItem, ItemListItem {
|
public class ChatListFilterSettingsHeaderItem: ListViewItem, ItemListItem {
|
||||||
@ -106,7 +107,26 @@ class ChatListFilterSettingsHeaderItemNode: ListViewItemNode {
|
|||||||
|
|
||||||
return { item, params, neighbors in
|
return { item, params, neighbors in
|
||||||
let leftInset: CGFloat = 32.0 + params.leftInset
|
let leftInset: CGFloat = 32.0 + params.leftInset
|
||||||
let topInset: CGFloat = 92.0
|
|
||||||
|
let animationName: String
|
||||||
|
var size = 192
|
||||||
|
var insetDifference = 100
|
||||||
|
var playbackMode: AnimatedStickerPlaybackMode = .once
|
||||||
|
switch item.animation {
|
||||||
|
case .folders:
|
||||||
|
animationName = "ChatListFolders"
|
||||||
|
case .newFolder:
|
||||||
|
animationName = "ChatListNewFolder"
|
||||||
|
case .discussionGroupSetup:
|
||||||
|
animationName = "DiscussionGroupSetup"
|
||||||
|
case .autoRemove:
|
||||||
|
animationName = "MessageAutoRemove"
|
||||||
|
size = 260
|
||||||
|
insetDifference = 120
|
||||||
|
playbackMode = .loop
|
||||||
|
}
|
||||||
|
|
||||||
|
let topInset: CGFloat = CGFloat(size - insetDifference)
|
||||||
|
|
||||||
let attributedText = NSAttributedString(string: item.text, font: titleFont, textColor: item.theme.list.freeTextColor)
|
let attributedText = NSAttributedString(string: item.text, font: titleFont, textColor: item.theme.list.freeTextColor)
|
||||||
let (titleLayout, titleApply) = makeTitleLayout(TextNodeLayoutArguments(attributedString: attributedText, backgroundColor: nil, maximumNumberOfLines: 0, truncationType: .end, constrainedSize: CGSize(width: params.width - params.rightInset - leftInset * 2.0, height: CGFloat.greatestFiniteMagnitude), alignment: .center, cutout: nil, insets: UIEdgeInsets()))
|
let (titleLayout, titleApply) = makeTitleLayout(TextNodeLayoutArguments(attributedString: attributedText, backgroundColor: nil, maximumNumberOfLines: 0, truncationType: .end, constrainedSize: CGSize(width: params.width - params.rightInset - leftInset * 2.0, height: CGFloat.greatestFiniteMagnitude), alignment: .center, cutout: nil, insets: UIEdgeInsets()))
|
||||||
@ -119,17 +139,8 @@ class ChatListFilterSettingsHeaderItemNode: ListViewItemNode {
|
|||||||
return (layout, { [weak self] in
|
return (layout, { [weak self] in
|
||||||
if let strongSelf = self {
|
if let strongSelf = self {
|
||||||
if strongSelf.item == nil {
|
if strongSelf.item == nil {
|
||||||
let animationName: String
|
|
||||||
switch item.animation {
|
|
||||||
case .folders:
|
|
||||||
animationName = "ChatListFolders"
|
|
||||||
case .newFolder:
|
|
||||||
animationName = "ChatListNewFolder"
|
|
||||||
case .discussionGroupSetup:
|
|
||||||
animationName = "DiscussionGroupSetup"
|
|
||||||
}
|
|
||||||
if let path = getAppBundle().path(forResource: animationName, ofType: "tgs") {
|
if let path = getAppBundle().path(forResource: animationName, ofType: "tgs") {
|
||||||
strongSelf.animationNode.setup(source: AnimatedStickerNodeLocalFileSource(path: path), width: 192, height: 192, playbackMode: .once, mode: .direct(cachePathPrefix: nil))
|
strongSelf.animationNode.setup(source: AnimatedStickerNodeLocalFileSource(path: path), width: size, height: size, playbackMode: playbackMode, mode: .direct(cachePathPrefix: nil))
|
||||||
strongSelf.animationNode.visibility = true
|
strongSelf.animationNode.visibility = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -137,7 +148,7 @@ class ChatListFilterSettingsHeaderItemNode: ListViewItemNode {
|
|||||||
strongSelf.item = item
|
strongSelf.item = item
|
||||||
strongSelf.accessibilityLabel = attributedText.string
|
strongSelf.accessibilityLabel = attributedText.string
|
||||||
|
|
||||||
let iconSize = CGSize(width: 96.0, height: 96.0)
|
let iconSize = CGSize(width: CGFloat(size) / 2.0, height: CGFloat(size) / 2.0)
|
||||||
strongSelf.animationNode.frame = CGRect(origin: CGPoint(x: floor((layout.size.width - iconSize.width) / 2.0), y: -10.0), size: iconSize)
|
strongSelf.animationNode.frame = CGRect(origin: CGPoint(x: floor((layout.size.width - iconSize.width) / 2.0), y: -10.0), size: iconSize)
|
||||||
strongSelf.animationNode.updateLayout(size: iconSize)
|
strongSelf.animationNode.updateLayout(size: iconSize)
|
||||||
|
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
|
|
||||||
@property (nonatomic, assign) CGFloat startValue;
|
@property (nonatomic, assign) CGFloat startValue;
|
||||||
@property (nonatomic, assign) CGFloat value;
|
@property (nonatomic, assign) CGFloat value;
|
||||||
|
@property (nonatomic, assign) int minimumUndottedValue;
|
||||||
|
|
||||||
@property (nonatomic, assign) CGFloat markValue;
|
@property (nonatomic, assign) CGFloat markValue;
|
||||||
|
|
||||||
|
@ -174,13 +174,59 @@ const CGFloat TGPhotoEditorSliderViewInternalMargin = 7.0f;
|
|||||||
CGContextSetBlendMode(context, kCGBlendModeCopy);
|
CGContextSetBlendMode(context, kCGBlendModeCopy);
|
||||||
}
|
}
|
||||||
|
|
||||||
CGContextSetFillColorWithColor(context, _backColor.CGColor);
|
if (_minimumUndottedValue > 0 && self.positionsCount > 1) {
|
||||||
[self drawRectangle:backFrame cornerRadius:self.trackCornerRadius context:context];
|
CGContextSetLineWidth(context, backFrame.size.height);
|
||||||
|
CGContextSetLineCap(context, kCGLineCapRound);
|
||||||
|
|
||||||
|
for (NSInteger i = 1; i < self.positionsCount; i++)
|
||||||
|
{
|
||||||
|
CGFloat previousX = margin + totalLength / (self.positionsCount - 1) * (i - 1);
|
||||||
|
CGFloat currentX = margin + totalLength / (self.positionsCount - 1) * i;
|
||||||
|
|
||||||
|
if (_minimumUndottedValue < i) {
|
||||||
|
CGFloat normalDashWidth = 16.0f;
|
||||||
|
CGFloat dashFraction = 0.6f;
|
||||||
|
CGFloat totalLineWidth = currentX - previousX;
|
||||||
|
int numberOfDashes = (int)floor((double)(totalLineWidth / normalDashWidth));
|
||||||
|
CGFloat dashWidth = (totalLineWidth / (CGFloat)numberOfDashes);
|
||||||
|
|
||||||
|
CGFloat innerWidth = dashWidth * dashFraction - 2.0f;
|
||||||
|
CGFloat innerOffset = (dashWidth - innerWidth) / 2.0f;
|
||||||
|
|
||||||
|
CGFloat dottedX = previousX;
|
||||||
|
|
||||||
|
while (dottedX + innerWidth < currentX) {
|
||||||
|
bool highlighted = dottedX + dashWidth / 2.0f < CGRectGetMaxX(trackFrame);
|
||||||
|
|
||||||
|
CGContextSetStrokeColorWithColor(context, highlighted ? _trackColor.CGColor : _backColor.CGColor);
|
||||||
|
|
||||||
|
CGContextMoveToPoint(context, dottedX + innerOffset, CGRectGetMidY(backFrame));
|
||||||
|
CGContextAddLineToPoint(context, dottedX + innerOffset + innerWidth, CGRectGetMidY(backFrame));
|
||||||
|
CGContextStrokePath(context);
|
||||||
|
|
||||||
|
dottedX += dashWidth;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
bool highlighted = (previousX + (currentX - previousX) / 2.0f) < CGRectGetMaxX(trackFrame);
|
||||||
|
CGContextSetStrokeColorWithColor(context, highlighted ? _trackColor.CGColor : _backColor.CGColor);
|
||||||
|
|
||||||
|
CGContextMoveToPoint(context, previousX, CGRectGetMidY(backFrame));
|
||||||
|
CGContextAddLineToPoint(context, currentX, CGRectGetMidY(backFrame));
|
||||||
|
CGContextStrokePath(context);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
CGContextSetFillColorWithColor(context, _backColor.CGColor);
|
||||||
|
[self drawRectangle:backFrame cornerRadius:self.trackCornerRadius context:context];
|
||||||
|
}
|
||||||
|
|
||||||
CGContextSetBlendMode(context, kCGBlendModeNormal);
|
CGContextSetBlendMode(context, kCGBlendModeNormal);
|
||||||
|
|
||||||
CGContextSetFillColorWithColor(context, _trackColor.CGColor);
|
if (_minimumUndottedValue > 0) {
|
||||||
[self drawRectangle:trackFrame cornerRadius:self.trackCornerRadius context:context];
|
} else {
|
||||||
|
CGContextSetFillColorWithColor(context, _trackColor.CGColor);
|
||||||
|
[self drawRectangle:trackFrame cornerRadius:self.trackCornerRadius context:context];
|
||||||
|
}
|
||||||
|
|
||||||
if (!_startHidden || self.displayEdges)
|
if (!_startHidden || self.displayEdges)
|
||||||
{
|
{
|
||||||
|
319
submodules/PeerInfoUI/Sources/PeerAutoremoveSetupScreen.swift
Normal file
319
submodules/PeerInfoUI/Sources/PeerAutoremoveSetupScreen.swift
Normal file
@ -0,0 +1,319 @@
|
|||||||
|
import Foundation
|
||||||
|
import UIKit
|
||||||
|
import Display
|
||||||
|
import SwiftSignalKit
|
||||||
|
import Postbox
|
||||||
|
import TelegramCore
|
||||||
|
import SyncCore
|
||||||
|
import TelegramPresentationData
|
||||||
|
import ItemListUI
|
||||||
|
import PresentationDataUtils
|
||||||
|
import AccountContext
|
||||||
|
import ChatListFilterSettingsHeaderItem
|
||||||
|
|
||||||
|
private final class PeerAutoremoveSetupArguments {
|
||||||
|
let toggleGlobal: (Bool) -> Void
|
||||||
|
let updateValue: (Int32) -> Void
|
||||||
|
|
||||||
|
init(toggleGlobal: @escaping (Bool) -> Void, updateValue: @escaping (Int32) -> Void) {
|
||||||
|
self.toggleGlobal = toggleGlobal
|
||||||
|
self.updateValue = updateValue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private enum PeerAutoremoveSetupSection: Int32 {
|
||||||
|
case header
|
||||||
|
case time
|
||||||
|
case global
|
||||||
|
}
|
||||||
|
|
||||||
|
private enum PeerAutoremoveSetupEntry: ItemListNodeEntry {
|
||||||
|
case header
|
||||||
|
case timeHeader(String)
|
||||||
|
case timeValue(Int32)
|
||||||
|
case timeComment(String)
|
||||||
|
case globalSwitch(String, Bool)
|
||||||
|
|
||||||
|
var section: ItemListSectionId {
|
||||||
|
switch self {
|
||||||
|
case .header:
|
||||||
|
return PeerAutoremoveSetupSection.header.rawValue
|
||||||
|
case .timeHeader, .timeValue, .timeComment:
|
||||||
|
return PeerAutoremoveSetupSection.time.rawValue
|
||||||
|
case .globalSwitch:
|
||||||
|
return PeerAutoremoveSetupSection.global.rawValue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var stableId: Int32 {
|
||||||
|
switch self {
|
||||||
|
case .header:
|
||||||
|
return 0
|
||||||
|
case .timeHeader:
|
||||||
|
return 1
|
||||||
|
case .timeValue:
|
||||||
|
return 2
|
||||||
|
case .timeComment:
|
||||||
|
return 3
|
||||||
|
case .globalSwitch:
|
||||||
|
return 4
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static func ==(lhs: PeerAutoremoveSetupEntry, rhs: PeerAutoremoveSetupEntry) -> Bool {
|
||||||
|
switch lhs {
|
||||||
|
case .header:
|
||||||
|
if case .header = rhs {
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
case let .timeHeader(lhsText):
|
||||||
|
if case let .timeHeader(rhsText) = rhs, lhsText == rhsText {
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
case let .timeValue(lhsValue):
|
||||||
|
if case let .timeValue(rhsValue) = rhs, lhsValue == rhsValue {
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
case let .timeComment(lhsText):
|
||||||
|
if case let .timeComment(rhsText) = rhs, lhsText == rhsText {
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
case let .globalSwitch(lhsText, lhsValue):
|
||||||
|
if case let .globalSwitch(rhsText, rhsValue) = rhs, lhsText == rhsText, lhsValue == rhsValue {
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static func <(lhs: PeerAutoremoveSetupEntry, rhs: PeerAutoremoveSetupEntry) -> Bool {
|
||||||
|
return lhs.stableId < rhs.stableId
|
||||||
|
}
|
||||||
|
|
||||||
|
func item(presentationData: ItemListPresentationData, arguments: Any) -> ListViewItem {
|
||||||
|
let arguments = arguments as! PeerAutoremoveSetupArguments
|
||||||
|
switch self {
|
||||||
|
case .header:
|
||||||
|
return ChatListFilterSettingsHeaderItem(theme: presentationData.theme, text: "", animation: .autoRemove, sectionId: self.section)
|
||||||
|
case let .timeHeader(text):
|
||||||
|
return ItemListSectionHeaderItem(presentationData: presentationData, text: text, sectionId: self.section)
|
||||||
|
case let .timeValue(value):
|
||||||
|
return PeerRemoveTimeoutItem(theme: presentationData.theme, value: value, maxValue: Int32.max, enabled: true, sectionId: self.section, updated: { value in
|
||||||
|
arguments.updateValue(value)
|
||||||
|
}, tag: nil)
|
||||||
|
case let .timeComment(text):
|
||||||
|
return ItemListTextItem(presentationData: presentationData, text: .plain(text), sectionId: self.section)
|
||||||
|
case let .globalSwitch(text, value):
|
||||||
|
return ItemListSwitchItem(presentationData: presentationData, title: text, value: value, sectionId: self.section, style: .blocks, updated: { value in
|
||||||
|
arguments.toggleGlobal(value)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private struct PeerAutoremoveSetupState: Equatable {
|
||||||
|
var changedValue: Int32?
|
||||||
|
var changedGlobalValue: Bool?
|
||||||
|
var applyingSetting: Bool = false
|
||||||
|
}
|
||||||
|
|
||||||
|
private func peerAutoremoveSetupEntries(peer: Peer?, presentationData: PresentationData, defaultValue: Int32?, defaultGlobalValue: Bool, state: PeerAutoremoveSetupState) -> [PeerAutoremoveSetupEntry] {
|
||||||
|
var entries: [PeerAutoremoveSetupEntry] = []
|
||||||
|
let value = state.changedValue ?? defaultValue
|
||||||
|
let globalValue = state.changedGlobalValue ?? defaultGlobalValue
|
||||||
|
|
||||||
|
//TODO:localize
|
||||||
|
entries.append(.header)
|
||||||
|
entries.append(.timeHeader("AUTO-DELETE MESSAGES"))
|
||||||
|
entries.append(.timeValue(value ?? Int32.max))
|
||||||
|
if let channel = peer as? TelegramChannel, case .broadcast = channel.info {
|
||||||
|
entries.append(.timeComment("Automatically delete messages sent in this channel after a certain period of time."))
|
||||||
|
} else {
|
||||||
|
entries.append(.timeComment("Automatically delete messages sent in this chat after a certain period of time."))
|
||||||
|
}
|
||||||
|
if let user = peer as? TelegramUser {
|
||||||
|
entries.append(.globalSwitch("Also auto-delete for \(user.compactDisplayTitle)", globalValue))
|
||||||
|
}
|
||||||
|
|
||||||
|
return entries
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum PeerAutoremoveSetupScreenResult {
|
||||||
|
case unchanged
|
||||||
|
case updated(Int32?)
|
||||||
|
}
|
||||||
|
|
||||||
|
public func peerAutoremoveSetupScreen(context: AccountContext, peerId: PeerId, completion: @escaping (PeerAutoremoveSetupScreenResult) -> Void = { _ in }) -> ViewController {
|
||||||
|
let statePromise = ValuePromise(PeerAutoremoveSetupState(), ignoreRepeated: true)
|
||||||
|
let stateValue = Atomic(value: PeerAutoremoveSetupState())
|
||||||
|
let updateState: ((PeerAutoremoveSetupState) -> PeerAutoremoveSetupState) -> Void = { f in
|
||||||
|
statePromise.set(stateValue.modify { f($0) })
|
||||||
|
}
|
||||||
|
|
||||||
|
var pushControllerImpl: ((ViewController) -> Void)?
|
||||||
|
var dismissImpl: (() -> Void)?
|
||||||
|
|
||||||
|
let actionsDisposable = DisposableSet()
|
||||||
|
|
||||||
|
let applyDisposable = MetaDisposable()
|
||||||
|
actionsDisposable.add(applyDisposable)
|
||||||
|
|
||||||
|
let arguments = PeerAutoremoveSetupArguments(toggleGlobal: { value in
|
||||||
|
updateState { state in
|
||||||
|
var state = state
|
||||||
|
state.changedGlobalValue = value
|
||||||
|
return state
|
||||||
|
}
|
||||||
|
}, updateValue: { value in
|
||||||
|
updateState { state in
|
||||||
|
var state = state
|
||||||
|
state.changedValue = value
|
||||||
|
return state
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
let signal = combineLatest(context.sharedContext.presentationData, statePromise.get(), context.account.viewTracker.peerView(peerId))
|
||||||
|
|> deliverOnMainQueue
|
||||||
|
|> map { presentationData, state, view -> (ItemListControllerState, (ItemListNodeState, Any)) in
|
||||||
|
var defaultValue: Int32 = Int32.max
|
||||||
|
var maxValue: Int32 = Int32.max
|
||||||
|
var defaultGlobalValue = true
|
||||||
|
if let cachedData = view.cachedData as? CachedChannelData {
|
||||||
|
if case let .known(value) = cachedData.autoremoveTimeout {
|
||||||
|
defaultValue = value?.myValue ?? Int32.max
|
||||||
|
maxValue = value?.peerValue ?? Int32.max
|
||||||
|
defaultGlobalValue = value?.isGlobal ?? true
|
||||||
|
}
|
||||||
|
} else if let cachedData = view.cachedData as? CachedGroupData {
|
||||||
|
if case let .known(value) = cachedData.autoremoveTimeout {
|
||||||
|
defaultValue = value?.myValue ?? Int32.max
|
||||||
|
maxValue = value?.peerValue ?? Int32.max
|
||||||
|
defaultGlobalValue = value?.isGlobal ?? true
|
||||||
|
}
|
||||||
|
} else if let cachedData = view.cachedData as? CachedUserData {
|
||||||
|
if case let .known(value) = cachedData.autoremoveTimeout {
|
||||||
|
defaultValue = value?.myValue ?? Int32.max
|
||||||
|
maxValue = value?.peerValue ?? Int32.max
|
||||||
|
defaultGlobalValue = value?.isGlobal ?? true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let peer = view.peers[view.peerId]
|
||||||
|
|
||||||
|
let leftNavigationButton = ItemListNavigationButton(content: .text(presentationData.strings.Common_Cancel), style: .regular, enabled: true, action: {
|
||||||
|
dismissImpl?()
|
||||||
|
})
|
||||||
|
var rightNavigationButton: ItemListNavigationButton?
|
||||||
|
if state.applyingSetting {
|
||||||
|
rightNavigationButton = ItemListNavigationButton(content: .none, style: .activity, enabled: true, action: {})
|
||||||
|
} else {
|
||||||
|
rightNavigationButton = ItemListNavigationButton(content: .text(presentationData.strings.Common_Done), style: .bold, enabled: true, action: {
|
||||||
|
var value: Int32?
|
||||||
|
var globalValue: Bool?
|
||||||
|
updateState { state in
|
||||||
|
var state = state
|
||||||
|
state.applyingSetting = true
|
||||||
|
value = state.changedValue
|
||||||
|
globalValue = state.changedGlobalValue
|
||||||
|
return state
|
||||||
|
}
|
||||||
|
var updated = false
|
||||||
|
if let value = value, value != defaultValue {
|
||||||
|
updated = true
|
||||||
|
}
|
||||||
|
if let globalValue = globalValue, globalValue != defaultGlobalValue {
|
||||||
|
updated = true
|
||||||
|
}
|
||||||
|
if updated {
|
||||||
|
let resolvedValue = value ?? defaultValue
|
||||||
|
let resolvedGlobalValue = globalValue ?? defaultGlobalValue
|
||||||
|
|
||||||
|
let signal = setChatMessageAutoremoveTimeoutInteractively(account: context.account, peerId: peerId, timeout: resolvedValue == Int32.max ? nil : resolvedValue, isGlobal: resolvedGlobalValue)
|
||||||
|
|> deliverOnMainQueue
|
||||||
|
|
||||||
|
applyDisposable.set((signal
|
||||||
|
|> deliverOnMainQueue).start(error: { _ in
|
||||||
|
}, completed: {
|
||||||
|
dismissImpl?()
|
||||||
|
if resolvedValue != defaultValue {
|
||||||
|
completion(.updated(resolvedValue))
|
||||||
|
} else {
|
||||||
|
completion(.unchanged)
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
} else {
|
||||||
|
dismissImpl?()
|
||||||
|
completion(.unchanged)
|
||||||
|
}
|
||||||
|
/*if let value = value, value != defaultValue {
|
||||||
|
if peerId.namespace == Namespaces.Peer.CloudGroup {
|
||||||
|
let signal = convertGroupToSupergroup(account: context.account, peerId: peerId)
|
||||||
|
|> mapToSignal { upgradedPeerId -> Signal<PeerId?, ConvertGroupToSupergroupError> in
|
||||||
|
return updateChannelHistoryAvailabilitySettingsInteractively(postbox: context.account.postbox, network: context.account.network, accountStateManager: context.account.stateManager, peerId: upgradedPeerId, historyAvailableForNewMembers: value)
|
||||||
|
|> `catch` { _ -> Signal<Void, NoError> in
|
||||||
|
return .complete()
|
||||||
|
}
|
||||||
|
|> mapToSignal { _ -> Signal<PeerId?, NoError> in
|
||||||
|
return .complete()
|
||||||
|
}
|
||||||
|
|> then(.single(upgradedPeerId))
|
||||||
|
|> castError(ConvertGroupToSupergroupError.self)
|
||||||
|
}
|
||||||
|
|> deliverOnMainQueue
|
||||||
|
applyDisposable.set((signal
|
||||||
|
|> deliverOnMainQueue).start(next: { upgradedPeerId in
|
||||||
|
if let upgradedPeerId = upgradedPeerId {
|
||||||
|
upgradedToSupergroup(upgradedPeerId, {
|
||||||
|
dismissImpl?()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}, error: { error in
|
||||||
|
switch error {
|
||||||
|
case .tooManyChannels:
|
||||||
|
pushControllerImpl?(oldChannelsController(context: context, intent: .upgrade))
|
||||||
|
default:
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
} else {
|
||||||
|
applyDisposable.set((updateChannelHistoryAvailabilitySettingsInteractively(postbox: context.account.postbox, network: context.account.network, accountStateManager: context.account.stateManager, peerId: peerId, historyAvailableForNewMembers: value)
|
||||||
|
|> deliverOnMainQueue).start(completed: {
|
||||||
|
dismissImpl?()
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
dismissImpl?()
|
||||||
|
}*/
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO:localize
|
||||||
|
let controllerState = ItemListControllerState(presentationData: ItemListPresentationData(presentationData), title: .text("Auto-Deletion"), leftNavigationButton: leftNavigationButton, rightNavigationButton: rightNavigationButton, backNavigationButton: ItemListBackButton(title: presentationData.strings.Common_Back))
|
||||||
|
let listState = ItemListNodeState(presentationData: ItemListPresentationData(presentationData), entries: peerAutoremoveSetupEntries(peer: peer, presentationData: presentationData, defaultValue: defaultValue, defaultGlobalValue: defaultGlobalValue, state: state), style: .blocks)
|
||||||
|
|
||||||
|
return (controllerState, (listState, arguments))
|
||||||
|
}
|
||||||
|
|> afterDisposed {
|
||||||
|
actionsDisposable.dispose()
|
||||||
|
}
|
||||||
|
|
||||||
|
let controller = ItemListController(context: context, state: signal)
|
||||||
|
controller.navigationPresentation = .modal
|
||||||
|
dismissImpl = { [weak controller] in
|
||||||
|
controller?.view.endEditing(true)
|
||||||
|
controller?.dismiss()
|
||||||
|
}
|
||||||
|
pushControllerImpl = { [weak controller] c in
|
||||||
|
controller?.push(c)
|
||||||
|
}
|
||||||
|
return controller
|
||||||
|
}
|
324
submodules/PeerInfoUI/Sources/PeerAutoremoveTimeoutItem.swift
Normal file
324
submodules/PeerInfoUI/Sources/PeerAutoremoveTimeoutItem.swift
Normal file
@ -0,0 +1,324 @@
|
|||||||
|
import Foundation
|
||||||
|
import UIKit
|
||||||
|
import Display
|
||||||
|
import AsyncDisplayKit
|
||||||
|
import SwiftSignalKit
|
||||||
|
import TelegramCore
|
||||||
|
import SyncCore
|
||||||
|
import TelegramPresentationData
|
||||||
|
import TelegramUIPreferences
|
||||||
|
import LegacyComponents
|
||||||
|
import ItemListUI
|
||||||
|
import PresentationDataUtils
|
||||||
|
import AppBundle
|
||||||
|
|
||||||
|
class PeerRemoveTimeoutItem: ListViewItem, ItemListItem {
|
||||||
|
let theme: PresentationTheme
|
||||||
|
let value: Int32
|
||||||
|
let maxValue: Int32
|
||||||
|
let enabled: Bool
|
||||||
|
let sectionId: ItemListSectionId
|
||||||
|
let updated: (Int32) -> Void
|
||||||
|
let tag: ItemListItemTag?
|
||||||
|
|
||||||
|
init(theme: PresentationTheme, value: Int32, maxValue: Int32, enabled: Bool = true, sectionId: ItemListSectionId, updated: @escaping (Int32) -> Void, tag: ItemListItemTag? = nil) {
|
||||||
|
self.theme = theme
|
||||||
|
self.value = value
|
||||||
|
self.maxValue = maxValue
|
||||||
|
self.enabled = enabled
|
||||||
|
self.sectionId = sectionId
|
||||||
|
self.updated = updated
|
||||||
|
self.tag = tag
|
||||||
|
}
|
||||||
|
|
||||||
|
func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal<Void, NoError>?, (ListViewItemApply) -> Void)) -> Void) {
|
||||||
|
async {
|
||||||
|
let node = PeerRemoveTimeoutItemNode()
|
||||||
|
let (layout, apply) = node.asyncLayout()(self, params, itemListNeighbors(item: self, topItem: previousItem as? ItemListItem, bottomItem: nextItem as? ItemListItem))
|
||||||
|
|
||||||
|
node.contentSize = layout.contentSize
|
||||||
|
node.insets = layout.insets
|
||||||
|
|
||||||
|
Queue.mainQueue().async {
|
||||||
|
completion(node, {
|
||||||
|
return (nil, { _ in apply() })
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping (ListViewItemApply) -> Void) -> Void) {
|
||||||
|
Queue.mainQueue().async {
|
||||||
|
if let nodeValue = node() as? PeerRemoveTimeoutItemNode {
|
||||||
|
let makeLayout = nodeValue.asyncLayout()
|
||||||
|
|
||||||
|
async {
|
||||||
|
let (layout, apply) = makeLayout(self, params, itemListNeighbors(item: self, topItem: previousItem as? ItemListItem, bottomItem: nextItem as? ItemListItem))
|
||||||
|
Queue.mainQueue().async {
|
||||||
|
completion(layout, { _ in
|
||||||
|
apply()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private func generateKnobImage() -> UIImage? {
|
||||||
|
return generateImage(CGSize(width: 40.0, height: 40.0), rotatedContext: { size, context in
|
||||||
|
context.clear(CGRect(origin: CGPoint(), size: size))
|
||||||
|
context.setShadow(offset: CGSize(width: 0.0, height: -1.0), blur: 3.5, color: UIColor(white: 0.0, alpha: 0.25).cgColor)
|
||||||
|
context.setFillColor(UIColor.white.cgColor)
|
||||||
|
context.fillEllipse(in: CGRect(origin: CGPoint(x: 6.0, y: 6.0), size: CGSize(width: 28.0, height: 28.0)))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
class PeerRemoveTimeoutItemNode: ListViewItemNode, ItemListItemNode {
|
||||||
|
private let backgroundNode: ASDisplayNode
|
||||||
|
private let topStripeNode: ASDisplayNode
|
||||||
|
private let bottomStripeNode: ASDisplayNode
|
||||||
|
private let maskNode: ASImageNode
|
||||||
|
|
||||||
|
private var sliderView: TGPhotoEditorSliderView?
|
||||||
|
private let titleNodes: [TextNode]
|
||||||
|
private let disabledOverlayNode: ASDisplayNode
|
||||||
|
|
||||||
|
private var item: PeerRemoveTimeoutItem?
|
||||||
|
private var layoutParams: ListViewItemLayoutParams?
|
||||||
|
|
||||||
|
var tag: ItemListItemTag? {
|
||||||
|
return self.item?.tag
|
||||||
|
}
|
||||||
|
|
||||||
|
init() {
|
||||||
|
self.backgroundNode = ASDisplayNode()
|
||||||
|
self.backgroundNode.isLayerBacked = true
|
||||||
|
|
||||||
|
self.topStripeNode = ASDisplayNode()
|
||||||
|
self.topStripeNode.isLayerBacked = true
|
||||||
|
|
||||||
|
self.bottomStripeNode = ASDisplayNode()
|
||||||
|
self.bottomStripeNode.isLayerBacked = true
|
||||||
|
|
||||||
|
self.maskNode = ASImageNode()
|
||||||
|
|
||||||
|
self.disabledOverlayNode = ASDisplayNode()
|
||||||
|
|
||||||
|
self.titleNodes = (0 ..< 3).map { _ in
|
||||||
|
return TextNode()
|
||||||
|
}
|
||||||
|
|
||||||
|
super.init(layerBacked: false, dynamicBounce: false)
|
||||||
|
|
||||||
|
self.titleNodes.forEach(self.addSubnode)
|
||||||
|
|
||||||
|
self.addSubnode(self.disabledOverlayNode)
|
||||||
|
}
|
||||||
|
|
||||||
|
override func didLoad() {
|
||||||
|
super.didLoad()
|
||||||
|
|
||||||
|
let sliderView = TGPhotoEditorSliderView()
|
||||||
|
sliderView.enablePanHandling = true
|
||||||
|
sliderView.trackCornerRadius = 1.0
|
||||||
|
sliderView.lineSize = 2.0
|
||||||
|
sliderView.dotSize = 5.0
|
||||||
|
sliderView.minimumValue = 0.0
|
||||||
|
sliderView.maximumValue = 2.0
|
||||||
|
sliderView.startValue = 0.0
|
||||||
|
sliderView.positionsCount = 3
|
||||||
|
sliderView.useLinesForPositions = true
|
||||||
|
sliderView.minimumUndottedValue = 2
|
||||||
|
sliderView.disablesInteractiveTransitionGestureRecognizer = true
|
||||||
|
if let item = self.item, let params = self.layoutParams {
|
||||||
|
sliderView.isUserInteractionEnabled = item.enabled
|
||||||
|
|
||||||
|
let value: CGFloat
|
||||||
|
switch item.value {
|
||||||
|
case 24 * 60 * 60:
|
||||||
|
value = 0.0
|
||||||
|
case 7 * 24 * 60 * 60:
|
||||||
|
value = 1.0
|
||||||
|
default:
|
||||||
|
value = 2.0
|
||||||
|
}
|
||||||
|
sliderView.value = value
|
||||||
|
sliderView.backgroundColor = item.theme.list.itemBlocksBackgroundColor
|
||||||
|
sliderView.backColor = item.theme.list.disclosureArrowColor
|
||||||
|
sliderView.trackColor = item.enabled ? item.theme.list.itemAccentColor : item.theme.list.itemDisabledTextColor
|
||||||
|
sliderView.knobImage = generateKnobImage()
|
||||||
|
|
||||||
|
let sliderInset: CGFloat = params.leftInset + 16.0
|
||||||
|
|
||||||
|
sliderView.frame = CGRect(origin: CGPoint(x: params.leftInset + sliderInset, y: 38.0), size: CGSize(width: params.width - params.leftInset - params.rightInset - sliderInset * 2.0, height: 44.0))
|
||||||
|
}
|
||||||
|
self.view.insertSubview(sliderView, belowSubview: self.disabledOverlayNode.view)
|
||||||
|
sliderView.addTarget(self, action: #selector(self.sliderValueChanged), for: .valueChanged)
|
||||||
|
self.sliderView = sliderView
|
||||||
|
}
|
||||||
|
|
||||||
|
func asyncLayout() -> (_ item: PeerRemoveTimeoutItem, _ params: ListViewItemLayoutParams, _ neighbors: ItemListNeighbors) -> (ListViewItemNodeLayout, () -> Void) {
|
||||||
|
let currentItem = self.item
|
||||||
|
|
||||||
|
let makeTitleNodeLayouts = self.titleNodes.map(TextNode.asyncLayout)
|
||||||
|
|
||||||
|
return { item, params, neighbors in
|
||||||
|
var themeUpdated = false
|
||||||
|
if currentItem?.theme !== item.theme {
|
||||||
|
themeUpdated = true
|
||||||
|
}
|
||||||
|
|
||||||
|
let contentSize: CGSize
|
||||||
|
var insets: UIEdgeInsets
|
||||||
|
let separatorHeight = UIScreenPixel
|
||||||
|
|
||||||
|
let titleLayouts = zip(0 ..< makeTitleNodeLayouts.count, makeTitleNodeLayouts).map { index, makeLayout -> (TextNodeLayout, () -> TextNode) in
|
||||||
|
let text: String
|
||||||
|
//TODO:localize
|
||||||
|
switch index {
|
||||||
|
case 0:
|
||||||
|
text = "After 24 hours"
|
||||||
|
case 1:
|
||||||
|
text = "After 7 days"
|
||||||
|
default:
|
||||||
|
text = "Never"
|
||||||
|
}
|
||||||
|
return makeLayout(TextNodeLayoutArguments(attributedString: NSAttributedString(string: text, font: Font.regular(13.0), textColor: item.theme.list.itemSecondaryTextColor), maximumNumberOfLines: 1, truncationType: .end, constrainedSize: CGSize(width: 100.0, height: 100.0)))
|
||||||
|
}
|
||||||
|
|
||||||
|
contentSize = CGSize(width: params.width, height: 88.0)
|
||||||
|
insets = itemListNeighborsGroupedInsets(neighbors)
|
||||||
|
|
||||||
|
let layout = ListViewItemNodeLayout(contentSize: contentSize, insets: insets)
|
||||||
|
let layoutSize = layout.size
|
||||||
|
|
||||||
|
return (layout, { [weak self] in
|
||||||
|
if let strongSelf = self {
|
||||||
|
let firstTime = strongSelf.item == nil
|
||||||
|
strongSelf.item = item
|
||||||
|
strongSelf.layoutParams = params
|
||||||
|
|
||||||
|
let leftInset = 16.0 + params.leftInset
|
||||||
|
|
||||||
|
strongSelf.backgroundNode.backgroundColor = item.theme.list.itemBlocksBackgroundColor
|
||||||
|
strongSelf.topStripeNode.backgroundColor = item.theme.list.itemBlocksSeparatorColor
|
||||||
|
strongSelf.bottomStripeNode.backgroundColor = item.theme.list.itemBlocksSeparatorColor
|
||||||
|
|
||||||
|
strongSelf.disabledOverlayNode.backgroundColor = item.theme.list.itemBlocksBackgroundColor.withAlphaComponent(0.4)
|
||||||
|
strongSelf.disabledOverlayNode.isHidden = item.enabled
|
||||||
|
strongSelf.disabledOverlayNode.frame = CGRect(origin: CGPoint(x: params.leftInset, y: 8.0), size: CGSize(width: params.width - params.leftInset - params.rightInset, height: 44.0))
|
||||||
|
|
||||||
|
if strongSelf.backgroundNode.supernode == nil {
|
||||||
|
strongSelf.insertSubnode(strongSelf.backgroundNode, at: 0)
|
||||||
|
}
|
||||||
|
if strongSelf.topStripeNode.supernode == nil {
|
||||||
|
strongSelf.insertSubnode(strongSelf.topStripeNode, at: 1)
|
||||||
|
}
|
||||||
|
if strongSelf.bottomStripeNode.supernode == nil {
|
||||||
|
strongSelf.insertSubnode(strongSelf.bottomStripeNode, at: 2)
|
||||||
|
}
|
||||||
|
if strongSelf.maskNode.supernode == nil {
|
||||||
|
strongSelf.insertSubnode(strongSelf.maskNode, at: 3)
|
||||||
|
}
|
||||||
|
|
||||||
|
let hasCorners = itemListHasRoundedBlockLayout(params)
|
||||||
|
var hasTopCorners = false
|
||||||
|
var hasBottomCorners = false
|
||||||
|
switch neighbors.top {
|
||||||
|
case .sameSection(false):
|
||||||
|
strongSelf.topStripeNode.isHidden = true
|
||||||
|
default:
|
||||||
|
hasTopCorners = true
|
||||||
|
strongSelf.topStripeNode.isHidden = hasCorners
|
||||||
|
}
|
||||||
|
let bottomStripeInset: CGFloat
|
||||||
|
let bottomStripeOffset: CGFloat
|
||||||
|
switch neighbors.bottom {
|
||||||
|
case .sameSection(false):
|
||||||
|
bottomStripeInset = params.leftInset + 16.0
|
||||||
|
bottomStripeOffset = -separatorHeight
|
||||||
|
default:
|
||||||
|
bottomStripeInset = 0.0
|
||||||
|
bottomStripeOffset = 0.0
|
||||||
|
hasBottomCorners = true
|
||||||
|
strongSelf.bottomStripeNode.isHidden = hasCorners
|
||||||
|
}
|
||||||
|
|
||||||
|
strongSelf.maskNode.image = hasCorners ? PresentationResourcesItemList.cornersImage(item.theme, top: hasTopCorners, bottom: hasBottomCorners) : nil
|
||||||
|
|
||||||
|
strongSelf.backgroundNode.frame = CGRect(origin: CGPoint(x: 0.0, y: -min(insets.top, separatorHeight)), size: CGSize(width: params.width, height: contentSize.height + min(insets.top, separatorHeight) + min(insets.bottom, separatorHeight)))
|
||||||
|
strongSelf.maskNode.frame = strongSelf.backgroundNode.frame.insetBy(dx: params.leftInset, dy: 0.0)
|
||||||
|
strongSelf.topStripeNode.frame = CGRect(origin: CGPoint(x: 0.0, y: -min(insets.top, separatorHeight)), size: CGSize(width: layoutSize.width, height: separatorHeight))
|
||||||
|
strongSelf.bottomStripeNode.frame = CGRect(origin: CGPoint(x: bottomStripeInset, y: contentSize.height + bottomStripeOffset), size: CGSize(width: layoutSize.width - bottomStripeInset, height: separatorHeight))
|
||||||
|
|
||||||
|
zip(0 ..< titleLayouts.count, titleLayouts).forEach { index, layoutAndApply in
|
||||||
|
let textNode = layoutAndApply.1()
|
||||||
|
|
||||||
|
let size = layoutAndApply.0.size
|
||||||
|
switch index {
|
||||||
|
case 0:
|
||||||
|
textNode.frame = CGRect(origin: CGPoint(x: leftInset, y: 13.0), size: size)
|
||||||
|
case 1:
|
||||||
|
textNode.frame = CGRect(origin: CGPoint(x: floor((params.width - size.width) / 2.0), y: 13.0), size: size)
|
||||||
|
default:
|
||||||
|
textNode.frame = CGRect(origin: CGPoint(x: params.width - size.width - 16.0, y: 13.0), size: size)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if let sliderView = strongSelf.sliderView {
|
||||||
|
sliderView.isUserInteractionEnabled = item.enabled
|
||||||
|
sliderView.trackColor = item.enabled ? item.theme.list.itemAccentColor : item.theme.list.itemDisabledTextColor
|
||||||
|
|
||||||
|
if themeUpdated {
|
||||||
|
sliderView.backgroundColor = item.theme.list.itemBlocksBackgroundColor
|
||||||
|
sliderView.backColor = item.theme.list.disclosureArrowColor
|
||||||
|
sliderView.knobImage = generateKnobImage()
|
||||||
|
}
|
||||||
|
|
||||||
|
let value: CGFloat
|
||||||
|
switch item.value {
|
||||||
|
case 24 * 60 * 60:
|
||||||
|
value = 0.0
|
||||||
|
case 7 * 24 * 60 * 60:
|
||||||
|
value = 1.0
|
||||||
|
default:
|
||||||
|
value = 2.0
|
||||||
|
}
|
||||||
|
if firstTime {
|
||||||
|
sliderView.value = value
|
||||||
|
}
|
||||||
|
|
||||||
|
let sliderInset: CGFloat = leftInset
|
||||||
|
sliderView.frame = CGRect(origin: CGPoint(x: params.leftInset + sliderInset, y: 38.0), size: CGSize(width: params.width - params.leftInset - params.rightInset - sliderInset * 2.0, height: 44.0))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override func animateInsertion(_ currentTimestamp: Double, duration: Double, short: Bool) {
|
||||||
|
self.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.4)
|
||||||
|
}
|
||||||
|
|
||||||
|
override func animateRemoved(_ currentTimestamp: Double, duration: Double) {
|
||||||
|
self.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.15, removeOnCompletion: false)
|
||||||
|
}
|
||||||
|
|
||||||
|
@objc func sliderValueChanged() {
|
||||||
|
guard let sliderView = self.sliderView else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
let value: Int32
|
||||||
|
switch sliderView.value {
|
||||||
|
case 0.0:
|
||||||
|
value = 24 * 60 * 60
|
||||||
|
case 1.0:
|
||||||
|
value = 7 * 24 * 60 * 60
|
||||||
|
default:
|
||||||
|
value = Int32.max
|
||||||
|
}
|
||||||
|
self.item?.updated(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -429,15 +429,7 @@ public final class CachedChannelData: CachedPeerData {
|
|||||||
self.slowModeTimeout = decoder.decodeOptionalInt32ForKey("smt")
|
self.slowModeTimeout = decoder.decodeOptionalInt32ForKey("smt")
|
||||||
self.slowModeValidUntilTimestamp = decoder.decodeOptionalInt32ForKey("smv")
|
self.slowModeValidUntilTimestamp = decoder.decodeOptionalInt32ForKey("smv")
|
||||||
self.hasScheduledMessages = decoder.decodeBoolForKey("hsm", orElse: false)
|
self.hasScheduledMessages = decoder.decodeBoolForKey("hsm", orElse: false)
|
||||||
if let value = decoder.decodeOptionalInt32ForKey("art") {
|
self.autoremoveTimeout = decoder.decodeObjectForKey("artv", decoder: CachedPeerAutoremoveTimeout.init(decoder:)) as? CachedPeerAutoremoveTimeout ?? .unknown
|
||||||
if value == -1 {
|
|
||||||
self.autoremoveTimeout = .known(nil)
|
|
||||||
} else {
|
|
||||||
self.autoremoveTimeout = .known(value)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
self.autoremoveTimeout = .unknown
|
|
||||||
}
|
|
||||||
self.statsDatacenterId = decoder.decodeInt32ForKey("sdi", orElse: 0)
|
self.statsDatacenterId = decoder.decodeInt32ForKey("sdi", orElse: 0)
|
||||||
|
|
||||||
self.invitedBy = decoder.decodeOptionalInt64ForKey("invBy").flatMap(PeerId.init)
|
self.invitedBy = decoder.decodeOptionalInt64ForKey("invBy").flatMap(PeerId.init)
|
||||||
@ -545,16 +537,7 @@ public final class CachedChannelData: CachedPeerData {
|
|||||||
encoder.encodeNil(forKey: "smv")
|
encoder.encodeNil(forKey: "smv")
|
||||||
}
|
}
|
||||||
encoder.encodeBool(self.hasScheduledMessages, forKey: "hsm")
|
encoder.encodeBool(self.hasScheduledMessages, forKey: "hsm")
|
||||||
switch self.autoremoveTimeout {
|
encoder.encodeObject(self.autoremoveTimeout, forKey: "artv")
|
||||||
case let .known(value):
|
|
||||||
if let value = value {
|
|
||||||
encoder.encodeInt32(value, forKey: "art")
|
|
||||||
} else {
|
|
||||||
encoder.encodeInt32(-1, forKey: "art")
|
|
||||||
}
|
|
||||||
case .unknown:
|
|
||||||
encoder.encodeNil(forKey: "art")
|
|
||||||
}
|
|
||||||
encoder.encodeInt32(self.statsDatacenterId, forKey: "sdi")
|
encoder.encodeInt32(self.statsDatacenterId, forKey: "sdi")
|
||||||
|
|
||||||
if let invitedBy = self.invitedBy {
|
if let invitedBy = self.invitedBy {
|
||||||
|
@ -131,15 +131,7 @@ public final class CachedGroupData: CachedPeerData {
|
|||||||
self.about = decoder.decodeOptionalStringForKey("ab")
|
self.about = decoder.decodeOptionalStringForKey("ab")
|
||||||
self.flags = CachedGroupFlags(rawValue: decoder.decodeInt32ForKey("fl", orElse: 0))
|
self.flags = CachedGroupFlags(rawValue: decoder.decodeInt32ForKey("fl", orElse: 0))
|
||||||
self.hasScheduledMessages = decoder.decodeBoolForKey("hsm", orElse: false)
|
self.hasScheduledMessages = decoder.decodeBoolForKey("hsm", orElse: false)
|
||||||
if let value = decoder.decodeOptionalInt32ForKey("art") {
|
self.autoremoveTimeout = decoder.decodeObjectForKey("artv", decoder: CachedPeerAutoremoveTimeout.init(decoder:)) as? CachedPeerAutoremoveTimeout ?? .unknown
|
||||||
if value == -1 {
|
|
||||||
self.autoremoveTimeout = .known(nil)
|
|
||||||
} else {
|
|
||||||
self.autoremoveTimeout = .known(value)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
self.autoremoveTimeout = .unknown
|
|
||||||
}
|
|
||||||
|
|
||||||
self.invitedBy = decoder.decodeOptionalInt64ForKey("invBy").flatMap(PeerId.init)
|
self.invitedBy = decoder.decodeOptionalInt64ForKey("invBy").flatMap(PeerId.init)
|
||||||
|
|
||||||
@ -207,16 +199,7 @@ public final class CachedGroupData: CachedPeerData {
|
|||||||
}
|
}
|
||||||
encoder.encodeInt32(self.flags.rawValue, forKey: "fl")
|
encoder.encodeInt32(self.flags.rawValue, forKey: "fl")
|
||||||
encoder.encodeBool(self.hasScheduledMessages, forKey: "hsm")
|
encoder.encodeBool(self.hasScheduledMessages, forKey: "hsm")
|
||||||
switch self.autoremoveTimeout {
|
encoder.encodeObject(self.autoremoveTimeout, forKey: "artv")
|
||||||
case let .known(value):
|
|
||||||
if let value = value {
|
|
||||||
encoder.encodeInt32(value, forKey: "art")
|
|
||||||
} else {
|
|
||||||
encoder.encodeInt32(-1, forKey: "art")
|
|
||||||
}
|
|
||||||
case .unknown:
|
|
||||||
encoder.encodeNil(forKey: "art")
|
|
||||||
}
|
|
||||||
|
|
||||||
if let invitedBy = self.invitedBy {
|
if let invitedBy = self.invitedBy {
|
||||||
encoder.encodeInt64(invitedBy.toInt64(), forKey: "invBy")
|
encoder.encodeInt64(invitedBy.toInt64(), forKey: "invBy")
|
||||||
|
@ -1,9 +1,56 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
import Postbox
|
import Postbox
|
||||||
|
|
||||||
public enum CachedPeerAutoremoveTimeout: Equatable {
|
public enum CachedPeerAutoremoveTimeout: Equatable, PostboxCoding {
|
||||||
|
public struct Value: Equatable, PostboxCoding {
|
||||||
|
public var myValue: Int32
|
||||||
|
public var peerValue: Int32
|
||||||
|
public var isGlobal: Bool
|
||||||
|
|
||||||
|
public init(myValue: Int32, peerValue: Int32, isGlobal: Bool) {
|
||||||
|
self.myValue = myValue
|
||||||
|
self.peerValue = peerValue
|
||||||
|
self.isGlobal = isGlobal
|
||||||
|
}
|
||||||
|
|
||||||
|
public init(decoder: PostboxDecoder) {
|
||||||
|
self.myValue = decoder.decodeInt32ForKey("myValue", orElse: 7 * 60 * 60)
|
||||||
|
self.peerValue = decoder.decodeInt32ForKey("peerValue", orElse: 7 * 60 * 60)
|
||||||
|
self.isGlobal = decoder.decodeInt32ForKey("isGlobal", orElse: 1) != 0
|
||||||
|
}
|
||||||
|
|
||||||
|
public func encode(_ encoder: PostboxEncoder) {
|
||||||
|
encoder.encodeInt32(self.myValue, forKey: "myValue")
|
||||||
|
encoder.encodeInt32(self.peerValue, forKey: "peerValue")
|
||||||
|
encoder.encodeInt32(self.isGlobal ? 1 : 0, forKey: "isGlobal")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
case unknown
|
case unknown
|
||||||
case known(Int32?)
|
case known(Value?)
|
||||||
|
|
||||||
|
public init(decoder: PostboxDecoder) {
|
||||||
|
switch decoder.decodeInt32ForKey("_v", orElse: 0) {
|
||||||
|
case 1:
|
||||||
|
self = .known(decoder.decodeObjectForKey("v", decoder: Value.init(decoder:)) as? Value)
|
||||||
|
default:
|
||||||
|
self = .unknown
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public func encode(_ encoder: PostboxEncoder) {
|
||||||
|
switch self {
|
||||||
|
case .unknown:
|
||||||
|
encoder.encodeInt32(0, forKey: "_v")
|
||||||
|
case let .known(value):
|
||||||
|
encoder.encodeInt32(1, forKey: "_v")
|
||||||
|
if let value = value {
|
||||||
|
encoder.encodeObject(value, forKey: "v")
|
||||||
|
} else {
|
||||||
|
encoder.encodeNil(forKey: "v")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public final class CachedUserData: CachedPeerData {
|
public final class CachedUserData: CachedPeerData {
|
||||||
@ -82,15 +129,7 @@ public final class CachedUserData: CachedPeerData {
|
|||||||
self.callsPrivate = decoder.decodeInt32ForKey("cp", orElse: 0) != 0
|
self.callsPrivate = decoder.decodeInt32ForKey("cp", orElse: 0) != 0
|
||||||
self.canPinMessages = decoder.decodeInt32ForKey("cpm", orElse: 0) != 0
|
self.canPinMessages = decoder.decodeInt32ForKey("cpm", orElse: 0) != 0
|
||||||
self.hasScheduledMessages = decoder.decodeBoolForKey("hsm", orElse: false)
|
self.hasScheduledMessages = decoder.decodeBoolForKey("hsm", orElse: false)
|
||||||
if let value = decoder.decodeOptionalInt32ForKey("art") {
|
self.autoremoveTimeout = decoder.decodeObjectForKey("artv", decoder: CachedPeerAutoremoveTimeout.init(decoder:)) as? CachedPeerAutoremoveTimeout ?? .unknown
|
||||||
if value == -1 {
|
|
||||||
self.autoremoveTimeout = .known(nil)
|
|
||||||
} else {
|
|
||||||
self.autoremoveTimeout = .known(value)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
self.autoremoveTimeout = .unknown
|
|
||||||
}
|
|
||||||
|
|
||||||
var messageIds = Set<MessageId>()
|
var messageIds = Set<MessageId>()
|
||||||
if let pinnedMessageId = self.pinnedMessageId {
|
if let pinnedMessageId = self.pinnedMessageId {
|
||||||
@ -131,16 +170,7 @@ public final class CachedUserData: CachedPeerData {
|
|||||||
encoder.encodeInt32(self.callsPrivate ? 1 : 0, forKey: "cp")
|
encoder.encodeInt32(self.callsPrivate ? 1 : 0, forKey: "cp")
|
||||||
encoder.encodeInt32(self.canPinMessages ? 1 : 0, forKey: "cpm")
|
encoder.encodeInt32(self.canPinMessages ? 1 : 0, forKey: "cpm")
|
||||||
encoder.encodeBool(self.hasScheduledMessages, forKey: "hsm")
|
encoder.encodeBool(self.hasScheduledMessages, forKey: "hsm")
|
||||||
switch self.autoremoveTimeout {
|
encoder.encodeObject(self.autoremoveTimeout, forKey: "artv")
|
||||||
case let .known(value):
|
|
||||||
if let value = value {
|
|
||||||
encoder.encodeInt32(value, forKey: "art")
|
|
||||||
} else {
|
|
||||||
encoder.encodeInt32(-1, forKey: "art")
|
|
||||||
}
|
|
||||||
case .unknown:
|
|
||||||
encoder.encodeNil(forKey: "art")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public func isEqual(to: CachedPeerData) -> Bool {
|
public func isEqual(to: CachedPeerData) -> Bool {
|
||||||
|
@ -11,8 +11,8 @@ 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[-1415563086] = { return Api.ChatFull.parse_channelFull($0) }
|
dict[-66811386] = { return Api.ChatFull.parse_channelFull($0) }
|
||||||
dict[-261341160] = { 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) }
|
||||||
dict[-636267638] = { return Api.ChatParticipant.parse_chatParticipantCreator($0) }
|
dict[-636267638] = { return Api.ChatParticipant.parse_chatParticipantCreator($0) }
|
||||||
@ -106,7 +106,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
|
|||||||
dict[483104362] = { return Api.RichText.parse_textPhone($0) }
|
dict[483104362] = { return Api.RichText.parse_textPhone($0) }
|
||||||
dict[136105807] = { return Api.RichText.parse_textImage($0) }
|
dict[136105807] = { return Api.RichText.parse_textImage($0) }
|
||||||
dict[894777186] = { return Api.RichText.parse_textAnchor($0) }
|
dict[894777186] = { return Api.RichText.parse_textAnchor($0) }
|
||||||
dict[328899191] = { return Api.UserFull.parse_userFull($0) }
|
dict[-1522240089] = { return Api.UserFull.parse_userFull($0) }
|
||||||
dict[-292807034] = { return Api.InputChannel.parse_inputChannelEmpty($0) }
|
dict[-292807034] = { return Api.InputChannel.parse_inputChannelEmpty($0) }
|
||||||
dict[-1343524562] = { return Api.InputChannel.parse_inputChannel($0) }
|
dict[-1343524562] = { return Api.InputChannel.parse_inputChannel($0) }
|
||||||
dict[707290417] = { return Api.InputChannel.parse_inputChannelFromMessage($0) }
|
dict[707290417] = { return Api.InputChannel.parse_inputChannelFromMessage($0) }
|
||||||
@ -118,6 +118,8 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
|
|||||||
dict[-1000708810] = { return Api.help.AppUpdate.parse_noAppUpdate($0) }
|
dict[-1000708810] = { return Api.help.AppUpdate.parse_noAppUpdate($0) }
|
||||||
dict[497489295] = { return Api.help.AppUpdate.parse_appUpdate($0) }
|
dict[497489295] = { return Api.help.AppUpdate.parse_appUpdate($0) }
|
||||||
dict[-209337866] = { return Api.LangPackDifference.parse_langPackDifference($0) }
|
dict[-209337866] = { return Api.LangPackDifference.parse_langPackDifference($0) }
|
||||||
|
dict[-815649386] = { return Api.PeerHistoryTTL.parse_peerHistoryTTLPM($0) }
|
||||||
|
dict[1041354473] = { return Api.PeerHistoryTTL.parse_peerHistoryTTL($0) }
|
||||||
dict[84438264] = { return Api.WallPaperSettings.parse_wallPaperSettings($0) }
|
dict[84438264] = { return Api.WallPaperSettings.parse_wallPaperSettings($0) }
|
||||||
dict[-1519029347] = { return Api.EmojiURL.parse_emojiURL($0) }
|
dict[-1519029347] = { return Api.EmojiURL.parse_emojiURL($0) }
|
||||||
dict[1611985938] = { return Api.StatsGroupTopAdmin.parse_statsGroupTopAdmin($0) }
|
dict[1611985938] = { return Api.StatsGroupTopAdmin.parse_statsGroupTopAdmin($0) }
|
||||||
@ -273,6 +275,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
|
|||||||
dict[-219423922] = { return Api.Update.parse_updateGroupCallParticipants($0) }
|
dict[-219423922] = { return Api.Update.parse_updateGroupCallParticipants($0) }
|
||||||
dict[-1537295973] = { return Api.Update.parse_updateGroupCall($0) }
|
dict[-1537295973] = { return Api.Update.parse_updateGroupCall($0) }
|
||||||
dict[1059076315] = { return Api.Update.parse_updateBotInlineQuery($0) }
|
dict[1059076315] = { return Api.Update.parse_updateBotInlineQuery($0) }
|
||||||
|
dict[19291112] = { return Api.Update.parse_updatePeerHistoryTTL($0) }
|
||||||
dict[136574537] = { return Api.messages.VotesList.parse_votesList($0) }
|
dict[136574537] = { return Api.messages.VotesList.parse_votesList($0) }
|
||||||
dict[1558266229] = { return Api.PopularContact.parse_popularContact($0) }
|
dict[1558266229] = { return Api.PopularContact.parse_popularContact($0) }
|
||||||
dict[-373643672] = { return Api.FolderPeer.parse_folderPeer($0) }
|
dict[-373643672] = { return Api.FolderPeer.parse_folderPeer($0) }
|
||||||
@ -1015,6 +1018,8 @@ public struct Api {
|
|||||||
_1.serialize(buffer, boxed)
|
_1.serialize(buffer, boxed)
|
||||||
case let _1 as Api.LangPackDifference:
|
case let _1 as Api.LangPackDifference:
|
||||||
_1.serialize(buffer, boxed)
|
_1.serialize(buffer, boxed)
|
||||||
|
case let _1 as Api.PeerHistoryTTL:
|
||||||
|
_1.serialize(buffer, boxed)
|
||||||
case let _1 as Api.WallPaperSettings:
|
case let _1 as Api.WallPaperSettings:
|
||||||
_1.serialize(buffer, boxed)
|
_1.serialize(buffer, boxed)
|
||||||
case let _1 as Api.EmojiURL:
|
case let _1 as Api.EmojiURL:
|
||||||
|
@ -2380,14 +2380,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?, ttlPeriod: Int32?)
|
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 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?, ttlPeriod: Int32?)
|
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 ttlPeriod):
|
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):
|
||||||
if boxed {
|
if boxed {
|
||||||
buffer.appendInt32(-1415563086)
|
buffer.appendInt32(-66811386)
|
||||||
}
|
}
|
||||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||||
serializeInt32(id, buffer: buffer, boxed: false)
|
serializeInt32(id, buffer: buffer, boxed: false)
|
||||||
@ -2421,11 +2421,11 @@ public extension Api {
|
|||||||
if Int(flags) & Int(1 << 12) != 0 {serializeInt32(statsDc!, buffer: buffer, boxed: false)}
|
if Int(flags) & Int(1 << 12) != 0 {serializeInt32(statsDc!, buffer: buffer, boxed: false)}
|
||||||
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 << 22) != 0 {serializeInt32(ttlPeriod!, buffer: buffer, boxed: false)}
|
if Int(flags) & Int(1 << 24) != 0 {ttl!.serialize(buffer, true)}
|
||||||
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 ttlPeriod):
|
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 {
|
||||||
buffer.appendInt32(-261341160)
|
buffer.appendInt32(-500874592)
|
||||||
}
|
}
|
||||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||||
serializeInt32(id, buffer: buffer, boxed: false)
|
serializeInt32(id, buffer: buffer, boxed: false)
|
||||||
@ -2442,17 +2442,17 @@ public extension Api {
|
|||||||
if Int(flags) & Int(1 << 6) != 0 {serializeInt32(pinnedMsgId!, buffer: buffer, boxed: false)}
|
if Int(flags) & Int(1 << 6) != 0 {serializeInt32(pinnedMsgId!, buffer: buffer, boxed: false)}
|
||||||
if Int(flags) & Int(1 << 11) != 0 {serializeInt32(folderId!, buffer: buffer, boxed: false)}
|
if Int(flags) & Int(1 << 11) != 0 {serializeInt32(folderId!, buffer: buffer, boxed: false)}
|
||||||
if Int(flags) & Int(1 << 12) != 0 {call!.serialize(buffer, true)}
|
if Int(flags) & Int(1 << 12) != 0 {call!.serialize(buffer, true)}
|
||||||
if Int(flags) & Int(1 << 14) != 0 {serializeInt32(ttlPeriod!, buffer: buffer, boxed: false)}
|
if Int(flags) & Int(1 << 14) != 0 {ttl!.serialize(buffer, true)}
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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 ttlPeriod):
|
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):
|
||||||
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), ("ttlPeriod", ttlPeriod)])
|
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)])
|
||||||
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 ttlPeriod):
|
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), ("ttlPeriod", ttlPeriod)])
|
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)])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2527,8 +2527,10 @@ public extension Api {
|
|||||||
if Int(_1!) & Int(1 << 21) != 0 {if let signature = reader.readInt32() {
|
if Int(_1!) & Int(1 << 21) != 0 {if let signature = reader.readInt32() {
|
||||||
_28 = Api.parse(reader, signature: signature) as? Api.InputGroupCall
|
_28 = Api.parse(reader, signature: signature) as? Api.InputGroupCall
|
||||||
} }
|
} }
|
||||||
var _29: Int32?
|
var _29: Api.PeerHistoryTTL?
|
||||||
if Int(_1!) & Int(1 << 22) != 0 {_29 = reader.readInt32() }
|
if Int(_1!) & Int(1 << 24) != 0 {if let signature = reader.readInt32() {
|
||||||
|
_29 = Api.parse(reader, signature: signature) as? Api.PeerHistoryTTL
|
||||||
|
} }
|
||||||
let _c1 = _1 != nil
|
let _c1 = _1 != nil
|
||||||
let _c2 = _2 != nil
|
let _c2 = _2 != nil
|
||||||
let _c3 = _3 != nil
|
let _c3 = _3 != nil
|
||||||
@ -2557,9 +2559,9 @@ public extension Api {
|
|||||||
let _c26 = (Int(_1!) & Int(1 << 12) == 0) || _26 != nil
|
let _c26 = (Int(_1!) & Int(1 << 12) == 0) || _26 != nil
|
||||||
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 << 22) == 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 {
|
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 {
|
||||||
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, ttlPeriod: _29)
|
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)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return nil
|
return nil
|
||||||
@ -2600,8 +2602,10 @@ public extension Api {
|
|||||||
if Int(_1!) & Int(1 << 12) != 0 {if let signature = reader.readInt32() {
|
if Int(_1!) & Int(1 << 12) != 0 {if let signature = reader.readInt32() {
|
||||||
_11 = Api.parse(reader, signature: signature) as? Api.InputGroupCall
|
_11 = Api.parse(reader, signature: signature) as? Api.InputGroupCall
|
||||||
} }
|
} }
|
||||||
var _12: Int32?
|
var _12: Api.PeerHistoryTTL?
|
||||||
if Int(_1!) & Int(1 << 14) != 0 {_12 = reader.readInt32() }
|
if Int(_1!) & Int(1 << 14) != 0 {if let signature = reader.readInt32() {
|
||||||
|
_12 = Api.parse(reader, signature: signature) as? Api.PeerHistoryTTL
|
||||||
|
} }
|
||||||
let _c1 = _1 != nil
|
let _c1 = _1 != nil
|
||||||
let _c2 = _2 != nil
|
let _c2 = _2 != nil
|
||||||
let _c3 = _3 != nil
|
let _c3 = _3 != nil
|
||||||
@ -2615,7 +2619,7 @@ public extension Api {
|
|||||||
let _c11 = (Int(_1!) & Int(1 << 12) == 0) || _11 != nil
|
let _c11 = (Int(_1!) & Int(1 << 12) == 0) || _11 != nil
|
||||||
let _c12 = (Int(_1!) & Int(1 << 14) == 0) || _12 != nil
|
let _c12 = (Int(_1!) & Int(1 << 14) == 0) || _12 != nil
|
||||||
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 && _c9 && _c10 && _c11 && _c12 {
|
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 && _c9 && _c10 && _c11 && _c12 {
|
||||||
return Api.ChatFull.chatFull(flags: _1!, id: _2!, about: _3!, participants: _4!, chatPhoto: _5, notifySettings: _6!, exportedInvite: _7, botInfo: _8, pinnedMsgId: _9, folderId: _10, call: _11, ttlPeriod: _12)
|
return Api.ChatFull.chatFull(flags: _1!, id: _2!, about: _3!, participants: _4!, chatPhoto: _5, notifySettings: _6!, exportedInvite: _7, botInfo: _8, pinnedMsgId: _9, folderId: _10, call: _11, ttl: _12)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return nil
|
return nil
|
||||||
@ -5080,13 +5084,13 @@ public extension Api {
|
|||||||
|
|
||||||
}
|
}
|
||||||
public enum UserFull: TypeConstructorDescription {
|
public enum UserFull: TypeConstructorDescription {
|
||||||
case userFull(flags: Int32, user: Api.User, about: String?, settings: Api.PeerSettings, profilePhoto: Api.Photo?, notifySettings: Api.PeerNotifySettings, botInfo: Api.BotInfo?, pinnedMsgId: Int32?, commonChatsCount: Int32, folderId: Int32?, ttlPeriod: Int32?)
|
case userFull(flags: Int32, user: Api.User, about: String?, settings: Api.PeerSettings, profilePhoto: Api.Photo?, notifySettings: Api.PeerNotifySettings, botInfo: Api.BotInfo?, pinnedMsgId: Int32?, commonChatsCount: Int32, folderId: Int32?, ttl: Api.PeerHistoryTTL?)
|
||||||
|
|
||||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||||
switch self {
|
switch self {
|
||||||
case .userFull(let flags, let user, let about, let settings, let profilePhoto, let notifySettings, let botInfo, let pinnedMsgId, let commonChatsCount, let folderId, let ttlPeriod):
|
case .userFull(let flags, let user, let about, let settings, let profilePhoto, let notifySettings, let botInfo, let pinnedMsgId, let commonChatsCount, let folderId, let ttl):
|
||||||
if boxed {
|
if boxed {
|
||||||
buffer.appendInt32(328899191)
|
buffer.appendInt32(-1522240089)
|
||||||
}
|
}
|
||||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||||
user.serialize(buffer, true)
|
user.serialize(buffer, true)
|
||||||
@ -5098,15 +5102,15 @@ public extension Api {
|
|||||||
if Int(flags) & Int(1 << 6) != 0 {serializeInt32(pinnedMsgId!, buffer: buffer, boxed: false)}
|
if Int(flags) & Int(1 << 6) != 0 {serializeInt32(pinnedMsgId!, buffer: buffer, boxed: false)}
|
||||||
serializeInt32(commonChatsCount, buffer: buffer, boxed: false)
|
serializeInt32(commonChatsCount, buffer: buffer, boxed: false)
|
||||||
if Int(flags) & Int(1 << 11) != 0 {serializeInt32(folderId!, buffer: buffer, boxed: false)}
|
if Int(flags) & Int(1 << 11) != 0 {serializeInt32(folderId!, buffer: buffer, boxed: false)}
|
||||||
if Int(flags) & Int(1 << 14) != 0 {serializeInt32(ttlPeriod!, buffer: buffer, boxed: false)}
|
if Int(flags) & Int(1 << 14) != 0 {ttl!.serialize(buffer, true)}
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||||
switch self {
|
switch self {
|
||||||
case .userFull(let flags, let user, let about, let settings, let profilePhoto, let notifySettings, let botInfo, let pinnedMsgId, let commonChatsCount, let folderId, let ttlPeriod):
|
case .userFull(let flags, let user, let about, let settings, let profilePhoto, let notifySettings, let botInfo, let pinnedMsgId, let commonChatsCount, let folderId, let ttl):
|
||||||
return ("userFull", [("flags", flags), ("user", user), ("about", about), ("settings", settings), ("profilePhoto", profilePhoto), ("notifySettings", notifySettings), ("botInfo", botInfo), ("pinnedMsgId", pinnedMsgId), ("commonChatsCount", commonChatsCount), ("folderId", folderId), ("ttlPeriod", ttlPeriod)])
|
return ("userFull", [("flags", flags), ("user", user), ("about", about), ("settings", settings), ("profilePhoto", profilePhoto), ("notifySettings", notifySettings), ("botInfo", botInfo), ("pinnedMsgId", pinnedMsgId), ("commonChatsCount", commonChatsCount), ("folderId", folderId), ("ttl", ttl)])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5141,8 +5145,10 @@ public extension Api {
|
|||||||
_9 = reader.readInt32()
|
_9 = reader.readInt32()
|
||||||
var _10: Int32?
|
var _10: Int32?
|
||||||
if Int(_1!) & Int(1 << 11) != 0 {_10 = reader.readInt32() }
|
if Int(_1!) & Int(1 << 11) != 0 {_10 = reader.readInt32() }
|
||||||
var _11: Int32?
|
var _11: Api.PeerHistoryTTL?
|
||||||
if Int(_1!) & Int(1 << 14) != 0 {_11 = reader.readInt32() }
|
if Int(_1!) & Int(1 << 14) != 0 {if let signature = reader.readInt32() {
|
||||||
|
_11 = Api.parse(reader, signature: signature) as? Api.PeerHistoryTTL
|
||||||
|
} }
|
||||||
let _c1 = _1 != nil
|
let _c1 = _1 != nil
|
||||||
let _c2 = _2 != nil
|
let _c2 = _2 != nil
|
||||||
let _c3 = (Int(_1!) & Int(1 << 1) == 0) || _3 != nil
|
let _c3 = (Int(_1!) & Int(1 << 1) == 0) || _3 != nil
|
||||||
@ -5155,7 +5161,7 @@ public extension Api {
|
|||||||
let _c10 = (Int(_1!) & Int(1 << 11) == 0) || _10 != nil
|
let _c10 = (Int(_1!) & Int(1 << 11) == 0) || _10 != nil
|
||||||
let _c11 = (Int(_1!) & Int(1 << 14) == 0) || _11 != nil
|
let _c11 = (Int(_1!) & Int(1 << 14) == 0) || _11 != nil
|
||||||
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 && _c9 && _c10 && _c11 {
|
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 && _c9 && _c10 && _c11 {
|
||||||
return Api.UserFull.userFull(flags: _1!, user: _2!, about: _3, settings: _4!, profilePhoto: _5, notifySettings: _6!, botInfo: _7, pinnedMsgId: _8, commonChatsCount: _9!, folderId: _10, ttlPeriod: _11)
|
return Api.UserFull.userFull(flags: _1!, user: _2!, about: _3, settings: _4!, profilePhoto: _5, notifySettings: _6!, botInfo: _7, pinnedMsgId: _8, commonChatsCount: _9!, folderId: _10, ttl: _11)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return nil
|
return nil
|
||||||
@ -5512,6 +5518,68 @@ public extension Api {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
public enum PeerHistoryTTL: TypeConstructorDescription {
|
||||||
|
case peerHistoryTTLPM(flags: Int32, myTtlPeriod: Int32?, peerTtlPeriod: Int32?)
|
||||||
|
case peerHistoryTTL(ttlPeriod: Int32)
|
||||||
|
|
||||||
|
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||||
|
switch self {
|
||||||
|
case .peerHistoryTTLPM(let flags, let myTtlPeriod, let peerTtlPeriod):
|
||||||
|
if boxed {
|
||||||
|
buffer.appendInt32(-815649386)
|
||||||
|
}
|
||||||
|
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||||
|
if Int(flags) & Int(1 << 1) != 0 {serializeInt32(myTtlPeriod!, buffer: buffer, boxed: false)}
|
||||||
|
if Int(flags) & Int(1 << 2) != 0 {serializeInt32(peerTtlPeriod!, buffer: buffer, boxed: false)}
|
||||||
|
break
|
||||||
|
case .peerHistoryTTL(let ttlPeriod):
|
||||||
|
if boxed {
|
||||||
|
buffer.appendInt32(1041354473)
|
||||||
|
}
|
||||||
|
serializeInt32(ttlPeriod, buffer: buffer, boxed: false)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||||
|
switch self {
|
||||||
|
case .peerHistoryTTLPM(let flags, let myTtlPeriod, let peerTtlPeriod):
|
||||||
|
return ("peerHistoryTTLPM", [("flags", flags), ("myTtlPeriod", myTtlPeriod), ("peerTtlPeriod", peerTtlPeriod)])
|
||||||
|
case .peerHistoryTTL(let ttlPeriod):
|
||||||
|
return ("peerHistoryTTL", [("ttlPeriod", ttlPeriod)])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static func parse_peerHistoryTTLPM(_ reader: BufferReader) -> PeerHistoryTTL? {
|
||||||
|
var _1: Int32?
|
||||||
|
_1 = reader.readInt32()
|
||||||
|
var _2: Int32?
|
||||||
|
if Int(_1!) & Int(1 << 1) != 0 {_2 = reader.readInt32() }
|
||||||
|
var _3: Int32?
|
||||||
|
if Int(_1!) & Int(1 << 2) != 0 {_3 = reader.readInt32() }
|
||||||
|
let _c1 = _1 != nil
|
||||||
|
let _c2 = (Int(_1!) & Int(1 << 1) == 0) || _2 != nil
|
||||||
|
let _c3 = (Int(_1!) & Int(1 << 2) == 0) || _3 != nil
|
||||||
|
if _c1 && _c2 && _c3 {
|
||||||
|
return Api.PeerHistoryTTL.peerHistoryTTLPM(flags: _1!, myTtlPeriod: _2, peerTtlPeriod: _3)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public static func parse_peerHistoryTTL(_ reader: BufferReader) -> PeerHistoryTTL? {
|
||||||
|
var _1: Int32?
|
||||||
|
_1 = reader.readInt32()
|
||||||
|
let _c1 = _1 != nil
|
||||||
|
if _c1 {
|
||||||
|
return Api.PeerHistoryTTL.peerHistoryTTL(ttlPeriod: _1!)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
public enum WallPaperSettings: TypeConstructorDescription {
|
public enum WallPaperSettings: TypeConstructorDescription {
|
||||||
case wallPaperSettings(flags: Int32, backgroundColor: Int32?, secondBackgroundColor: Int32?, intensity: Int32?, rotation: Int32?)
|
case wallPaperSettings(flags: Int32, backgroundColor: Int32?, secondBackgroundColor: Int32?, intensity: Int32?, rotation: Int32?)
|
||||||
@ -6822,6 +6890,7 @@ public extension Api {
|
|||||||
case updateGroupCallParticipants(call: Api.InputGroupCall, participants: [Api.GroupCallParticipant], version: Int32)
|
case updateGroupCallParticipants(call: Api.InputGroupCall, participants: [Api.GroupCallParticipant], version: Int32)
|
||||||
case updateGroupCall(chatId: Int32, call: Api.GroupCall)
|
case updateGroupCall(chatId: Int32, call: Api.GroupCall)
|
||||||
case updateBotInlineQuery(flags: Int32, queryId: Int64, userId: Int32, query: String, geo: Api.GeoPoint?, peerType: Api.InlineQueryPeerType?, offset: String)
|
case updateBotInlineQuery(flags: Int32, queryId: Int64, userId: Int32, query: String, geo: Api.GeoPoint?, peerType: Api.InlineQueryPeerType?, offset: String)
|
||||||
|
case updatePeerHistoryTTL(flags: Int32, peer: Api.Peer, ttl: Api.PeerHistoryTTL?)
|
||||||
|
|
||||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||||
switch self {
|
switch self {
|
||||||
@ -7583,6 +7652,14 @@ public extension Api {
|
|||||||
if Int(flags) & Int(1 << 1) != 0 {peerType!.serialize(buffer, true)}
|
if Int(flags) & Int(1 << 1) != 0 {peerType!.serialize(buffer, true)}
|
||||||
serializeString(offset, buffer: buffer, boxed: false)
|
serializeString(offset, buffer: buffer, boxed: false)
|
||||||
break
|
break
|
||||||
|
case .updatePeerHistoryTTL(let flags, let peer, let ttl):
|
||||||
|
if boxed {
|
||||||
|
buffer.appendInt32(19291112)
|
||||||
|
}
|
||||||
|
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||||
|
peer.serialize(buffer, true)
|
||||||
|
if Int(flags) & Int(1 << 0) != 0 {ttl!.serialize(buffer, true)}
|
||||||
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -7764,6 +7841,8 @@ public extension Api {
|
|||||||
return ("updateGroupCall", [("chatId", chatId), ("call", call)])
|
return ("updateGroupCall", [("chatId", chatId), ("call", call)])
|
||||||
case .updateBotInlineQuery(let flags, let queryId, let userId, let query, let geo, let peerType, let offset):
|
case .updateBotInlineQuery(let flags, let queryId, let userId, let query, let geo, let peerType, let offset):
|
||||||
return ("updateBotInlineQuery", [("flags", flags), ("queryId", queryId), ("userId", userId), ("query", query), ("geo", geo), ("peerType", peerType), ("offset", offset)])
|
return ("updateBotInlineQuery", [("flags", flags), ("queryId", queryId), ("userId", userId), ("query", query), ("geo", geo), ("peerType", peerType), ("offset", offset)])
|
||||||
|
case .updatePeerHistoryTTL(let flags, let peer, let ttl):
|
||||||
|
return ("updatePeerHistoryTTL", [("flags", flags), ("peer", peer), ("ttl", ttl)])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -9289,6 +9368,27 @@ public extension Api {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
public static func parse_updatePeerHistoryTTL(_ reader: BufferReader) -> Update? {
|
||||||
|
var _1: Int32?
|
||||||
|
_1 = reader.readInt32()
|
||||||
|
var _2: Api.Peer?
|
||||||
|
if let signature = reader.readInt32() {
|
||||||
|
_2 = Api.parse(reader, signature: signature) as? Api.Peer
|
||||||
|
}
|
||||||
|
var _3: Api.PeerHistoryTTL?
|
||||||
|
if Int(_1!) & Int(1 << 0) != 0 {if let signature = reader.readInt32() {
|
||||||
|
_3 = Api.parse(reader, signature: signature) as? Api.PeerHistoryTTL
|
||||||
|
} }
|
||||||
|
let _c1 = _1 != nil
|
||||||
|
let _c2 = _2 != nil
|
||||||
|
let _c3 = (Int(_1!) & Int(1 << 0) == 0) || _3 != nil
|
||||||
|
if _c1 && _c2 && _c3 {
|
||||||
|
return Api.Update.updatePeerHistoryTTL(flags: _1!, peer: _2!, ttl: _3)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
public enum PopularContact: TypeConstructorDescription {
|
public enum PopularContact: TypeConstructorDescription {
|
||||||
|
@ -3995,6 +3995,22 @@ public extension Api {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static func setHistoryTTL(flags: Int32, peer: Api.InputPeer, period: Int32) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Updates>) {
|
||||||
|
let buffer = Buffer()
|
||||||
|
buffer.appendInt32(-859093215)
|
||||||
|
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||||
|
peer.serialize(buffer, true)
|
||||||
|
serializeInt32(period, buffer: buffer, boxed: false)
|
||||||
|
return (FunctionDescription(name: "messages.setHistoryTTL", parameters: [("flags", flags), ("peer", peer), ("period", period)]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.Updates? in
|
||||||
|
let reader = BufferReader(buffer)
|
||||||
|
var result: Api.Updates?
|
||||||
|
if let signature = reader.readInt32() {
|
||||||
|
result = Api.parse(reader, signature: signature) as? Api.Updates
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
public static func exportChatInvite(flags: Int32, peer: Api.InputPeer, expireDate: Int32?, usageLimit: Int32?) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.ExportedChatInvite>) {
|
public static func exportChatInvite(flags: Int32, peer: Api.InputPeer, expireDate: Int32?, usageLimit: Int32?) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.ExportedChatInvite>) {
|
||||||
let buffer = Buffer()
|
let buffer = Buffer()
|
||||||
buffer.appendInt32(347716823)
|
buffer.appendInt32(347716823)
|
||||||
@ -4109,21 +4125,6 @@ public extension Api {
|
|||||||
return result
|
return result
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
public static func setPeerMessagesTTL(peer: Api.InputPeer, period: Int32) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Bool>) {
|
|
||||||
let buffer = Buffer()
|
|
||||||
buffer.appendInt32(-56903344)
|
|
||||||
peer.serialize(buffer, true)
|
|
||||||
serializeInt32(period, buffer: buffer, boxed: false)
|
|
||||||
return (FunctionDescription(name: "messages.setPeerMessagesTTL", parameters: [("peer", peer), ("period", period)]), 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 channels {
|
public struct channels {
|
||||||
public static func readHistory(channel: Api.InputChannel, maxId: Int32) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Bool>) {
|
public static func readHistory(channel: Api.InputChannel, maxId: Int32) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Bool>) {
|
||||||
|
@ -112,6 +112,7 @@ enum AccountStateMutationOperation {
|
|||||||
case UpdateReadThread(threadMessageId: MessageId, readMaxId: Int32, isIncoming: Bool, mainChannelMessage: MessageId?)
|
case UpdateReadThread(threadMessageId: MessageId, readMaxId: Int32, isIncoming: Bool, mainChannelMessage: MessageId?)
|
||||||
case UpdateGroupCallParticipants(id: Int64, accessHash: Int64, participants: [Api.GroupCallParticipant], version: Int32)
|
case UpdateGroupCallParticipants(id: Int64, accessHash: Int64, participants: [Api.GroupCallParticipant], version: Int32)
|
||||||
case UpdateGroupCall(peerId: PeerId, call: Api.GroupCall)
|
case UpdateGroupCall(peerId: PeerId, call: Api.GroupCall)
|
||||||
|
case UpdateAutoremoveTimeout(peer: Api.Peer, value: CachedPeerAutoremoveTimeout.Value?)
|
||||||
}
|
}
|
||||||
|
|
||||||
struct HoleFromPreviousState {
|
struct HoleFromPreviousState {
|
||||||
@ -286,6 +287,10 @@ struct AccountMutableState {
|
|||||||
self.addOperation(.UpdateGroupCall(peerId: peerId, call: call))
|
self.addOperation(.UpdateGroupCall(peerId: peerId, call: call))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mutating func updateAutoremoveTimeout(peer: Api.Peer, value: CachedPeerAutoremoveTimeout.Value?) {
|
||||||
|
self.addOperation(.UpdateAutoremoveTimeout(peer: peer, value: value))
|
||||||
|
}
|
||||||
|
|
||||||
mutating func readGroupFeedInbox(groupId: PeerGroupId, index: MessageIndex) {
|
mutating func readGroupFeedInbox(groupId: PeerGroupId, index: MessageIndex) {
|
||||||
self.addOperation(.ReadGroupFeedInbox(groupId, index))
|
self.addOperation(.ReadGroupFeedInbox(groupId, index))
|
||||||
}
|
}
|
||||||
@ -494,7 +499,7 @@ struct AccountMutableState {
|
|||||||
|
|
||||||
mutating func addOperation(_ operation: AccountStateMutationOperation) {
|
mutating func addOperation(_ operation: AccountStateMutationOperation) {
|
||||||
switch operation {
|
switch operation {
|
||||||
case .DeleteMessages, .DeleteMessagesWithGlobalIds, .EditMessage, .UpdateMessagePoll/*, .UpdateMessageReactions*/, .UpdateMedia, .ReadOutbox, .ReadGroupFeedInbox, .MergePeerPresences, .UpdateSecretChat, .AddSecretMessages, .ReadSecretOutbox, .AddPeerInputActivity, .UpdateCachedPeerData, .UpdatePinnedItemIds, .ReadMessageContents, .UpdateMessageImpressionCount, .UpdateMessageForwardsCount, .UpdateInstalledStickerPacks, .UpdateRecentGifs, .UpdateChatInputState, .UpdateCall, .AddCallSignalingData, .UpdateLangPack, .UpdateMinAvailableMessage, .UpdatePeerChatUnreadMark, .UpdateIsContact, .UpdatePeerChatInclusion, .UpdatePeersNearby, .UpdateTheme, .SyncChatListFilters, .UpdateChatListFilterOrder, .UpdateChatListFilter, .UpdateReadThread, .UpdateGroupCallParticipants, .UpdateGroupCall, .UpdateMessagesPinned:
|
case .DeleteMessages, .DeleteMessagesWithGlobalIds, .EditMessage, .UpdateMessagePoll/*, .UpdateMessageReactions*/, .UpdateMedia, .ReadOutbox, .ReadGroupFeedInbox, .MergePeerPresences, .UpdateSecretChat, .AddSecretMessages, .ReadSecretOutbox, .AddPeerInputActivity, .UpdateCachedPeerData, .UpdatePinnedItemIds, .ReadMessageContents, .UpdateMessageImpressionCount, .UpdateMessageForwardsCount, .UpdateInstalledStickerPacks, .UpdateRecentGifs, .UpdateChatInputState, .UpdateCall, .AddCallSignalingData, .UpdateLangPack, .UpdateMinAvailableMessage, .UpdatePeerChatUnreadMark, .UpdateIsContact, .UpdatePeerChatInclusion, .UpdatePeersNearby, .UpdateTheme, .SyncChatListFilters, .UpdateChatListFilterOrder, .UpdateChatListFilter, .UpdateReadThread, .UpdateGroupCallParticipants, .UpdateGroupCall, .UpdateMessagesPinned, .UpdateAutoremoveTimeout:
|
||||||
break
|
break
|
||||||
case let .AddMessages(messages, location):
|
case let .AddMessages(messages, location):
|
||||||
for message in messages {
|
for message in messages {
|
||||||
|
@ -1358,6 +1358,8 @@ private func finalStateWithUpdatesAndServerTime(postbox: Postbox, network: Netwo
|
|||||||
case let .updateGroupCall(channelId, call):
|
case let .updateGroupCall(channelId, call):
|
||||||
updatedState.updateGroupCall(peerId: PeerId(namespace: Namespaces.Peer.CloudChannel, id: channelId), call: call)
|
updatedState.updateGroupCall(peerId: PeerId(namespace: Namespaces.Peer.CloudChannel, id: channelId), call: call)
|
||||||
updatedState.updateGroupCall(peerId: PeerId(namespace: Namespaces.Peer.CloudGroup, id: channelId), call: call)
|
updatedState.updateGroupCall(peerId: PeerId(namespace: Namespaces.Peer.CloudGroup, id: channelId), call: call)
|
||||||
|
case let .updatePeerHistoryTTL(_, peer, ttl):
|
||||||
|
updatedState.updateAutoremoveTimeout(peer: peer, value: CachedPeerAutoremoveTimeout.Value(ttl))
|
||||||
case let .updateLangPackTooLong(langCode):
|
case let .updateLangPackTooLong(langCode):
|
||||||
updatedState.updateLangPack(langCode: langCode, difference: nil)
|
updatedState.updateLangPack(langCode: langCode, difference: nil)
|
||||||
case let .updateLangPack(difference):
|
case let .updateLangPack(difference):
|
||||||
@ -2148,7 +2150,7 @@ private func optimizedOperations(_ operations: [AccountStateMutationOperation])
|
|||||||
var currentAddScheduledMessages: OptimizeAddMessagesState?
|
var currentAddScheduledMessages: OptimizeAddMessagesState?
|
||||||
for operation in operations {
|
for operation in operations {
|
||||||
switch operation {
|
switch operation {
|
||||||
case .DeleteMessages, .DeleteMessagesWithGlobalIds, .EditMessage, .UpdateMessagePoll/*, .UpdateMessageReactions*/, .UpdateMedia, .MergeApiChats, .MergeApiUsers, .MergePeerPresences, .UpdatePeer, .ReadInbox, .ReadOutbox, .ReadGroupFeedInbox, .ResetReadState, .ResetIncomingReadState, .UpdatePeerChatUnreadMark, .ResetMessageTagSummary, .UpdateNotificationSettings, .UpdateGlobalNotificationSettings, .UpdateSecretChat, .AddSecretMessages, .ReadSecretOutbox, .AddPeerInputActivity, .UpdateCachedPeerData, .UpdatePinnedItemIds, .ReadMessageContents, .UpdateMessageImpressionCount, .UpdateMessageForwardsCount, .UpdateInstalledStickerPacks, .UpdateRecentGifs, .UpdateChatInputState, .UpdateCall, .AddCallSignalingData, .UpdateLangPack, .UpdateMinAvailableMessage, .UpdateIsContact, .UpdatePeerChatInclusion, .UpdatePeersNearby, .UpdateTheme, .SyncChatListFilters, .UpdateChatListFilter, .UpdateChatListFilterOrder, .UpdateReadThread, .UpdateMessagesPinned, .UpdateGroupCallParticipants, .UpdateGroupCall:
|
case .DeleteMessages, .DeleteMessagesWithGlobalIds, .EditMessage, .UpdateMessagePoll/*, .UpdateMessageReactions*/, .UpdateMedia, .MergeApiChats, .MergeApiUsers, .MergePeerPresences, .UpdatePeer, .ReadInbox, .ReadOutbox, .ReadGroupFeedInbox, .ResetReadState, .ResetIncomingReadState, .UpdatePeerChatUnreadMark, .ResetMessageTagSummary, .UpdateNotificationSettings, .UpdateGlobalNotificationSettings, .UpdateSecretChat, .AddSecretMessages, .ReadSecretOutbox, .AddPeerInputActivity, .UpdateCachedPeerData, .UpdatePinnedItemIds, .ReadMessageContents, .UpdateMessageImpressionCount, .UpdateMessageForwardsCount, .UpdateInstalledStickerPacks, .UpdateRecentGifs, .UpdateChatInputState, .UpdateCall, .AddCallSignalingData, .UpdateLangPack, .UpdateMinAvailableMessage, .UpdateIsContact, .UpdatePeerChatInclusion, .UpdatePeersNearby, .UpdateTheme, .SyncChatListFilters, .UpdateChatListFilter, .UpdateChatListFilterOrder, .UpdateReadThread, .UpdateMessagesPinned, .UpdateGroupCallParticipants, .UpdateGroupCall, .UpdateAutoremoveTimeout:
|
||||||
if let currentAddMessages = currentAddMessages, !currentAddMessages.messages.isEmpty {
|
if let currentAddMessages = currentAddMessages, !currentAddMessages.messages.isEmpty {
|
||||||
result.append(.AddMessages(currentAddMessages.messages, currentAddMessages.location))
|
result.append(.AddMessages(currentAddMessages.messages, currentAddMessages.location))
|
||||||
}
|
}
|
||||||
@ -3021,6 +3023,18 @@ func replayFinalState(accountManager: AccountManager, postbox: Postbox, accountP
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
case let .UpdateAutoremoveTimeout(peer, value):
|
||||||
|
transaction.updatePeerCachedData(peerIds: Set([peer.peerId]), update: { _, current in
|
||||||
|
if let current = current as? CachedUserData {
|
||||||
|
return current.withUpdatedAutoremoveTimeout(.known(value))
|
||||||
|
} else if let current = current as? CachedGroupData {
|
||||||
|
return current.withUpdatedAutoremoveTimeout(.known(value))
|
||||||
|
} else if let current = current as? CachedChannelData {
|
||||||
|
return current.withUpdatedAutoremoveTimeout(.known(value))
|
||||||
|
} else {
|
||||||
|
return current
|
||||||
|
}
|
||||||
|
})
|
||||||
case let .UpdateLangPack(langCode, difference):
|
case let .UpdateLangPack(langCode, difference):
|
||||||
if let difference = difference {
|
if let difference = difference {
|
||||||
if langPackDifferences[langCode] == nil {
|
if langPackDifferences[langCode] == nil {
|
||||||
|
@ -146,64 +146,72 @@ public enum SetChatMessageAutoremoveTimeoutError {
|
|||||||
case generic
|
case generic
|
||||||
}
|
}
|
||||||
|
|
||||||
public func setChatMessageAutoremoveTimeoutInteractively(account: Account, peerId: PeerId, timeout: Int32?) -> Signal<Never, SetChatMessageAutoremoveTimeoutError> {
|
public func setChatMessageAutoremoveTimeoutInteractively(account: Account, peerId: PeerId, timeout: Int32?, isGlobal: Bool) -> Signal<Never, SetChatMessageAutoremoveTimeoutError> {
|
||||||
return account.postbox.transaction { transaction -> (Api.InputPeer?, CachedPeerAutoremoveTimeout) in
|
return account.postbox.transaction { transaction -> Api.InputPeer? in
|
||||||
var currentValue: CachedPeerAutoremoveTimeout = .unknown
|
return transaction.getPeer(peerId).flatMap(apiInputPeer)
|
||||||
|
|
||||||
transaction.updatePeerCachedData(peerIds: [peerId], update: { _, current in
|
|
||||||
if let current = current as? CachedUserData {
|
|
||||||
currentValue = current.autoremoveTimeout
|
|
||||||
return current.withUpdatedAutoremoveTimeout(.known(timeout))
|
|
||||||
} else if let current = current as? CachedGroupData {
|
|
||||||
currentValue = current.autoremoveTimeout
|
|
||||||
return current.withUpdatedAutoremoveTimeout(.known(timeout))
|
|
||||||
} else if let current = current as? CachedChannelData {
|
|
||||||
currentValue = current.autoremoveTimeout
|
|
||||||
return current.withUpdatedAutoremoveTimeout(.known(timeout))
|
|
||||||
} else {
|
|
||||||
return current
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
return (transaction.getPeer(peerId).flatMap(apiInputPeer), currentValue)
|
|
||||||
}
|
}
|
||||||
|> castError(SetChatMessageAutoremoveTimeoutError.self)
|
|> castError(SetChatMessageAutoremoveTimeoutError.self)
|
||||||
|> mapToSignal { (inputPeer, previousValue) -> Signal<Never, SetChatMessageAutoremoveTimeoutError> in
|
|> mapToSignal { inputPeer -> Signal<Never, SetChatMessageAutoremoveTimeoutError> in
|
||||||
guard let inputPeer = inputPeer else {
|
guard let inputPeer = inputPeer else {
|
||||||
return .fail(.generic)
|
return .fail(.generic)
|
||||||
}
|
}
|
||||||
return account.network.request(Api.functions.messages.setPeerMessagesTTL(peer: inputPeer, period: timeout ?? 0))
|
var flags: Int32 = 0
|
||||||
|> `catch` { _ -> Signal<Api.Bool, NoError> in
|
if !isGlobal {
|
||||||
return .single(.boolFalse)
|
flags |= 1 << 0
|
||||||
|
}
|
||||||
|
return account.network.request(Api.functions.messages.setHistoryTTL(flags: flags, peer: inputPeer, period: timeout ?? 0))
|
||||||
|
|> map(Optional.init)
|
||||||
|
|> `catch` { _ -> Signal<Api.Updates?, NoError> in
|
||||||
|
return .single(nil)
|
||||||
}
|
}
|
||||||
|> castError(SetChatMessageAutoremoveTimeoutError.self)
|
|> castError(SetChatMessageAutoremoveTimeoutError.self)
|
||||||
|> mapToSignal { result -> Signal<Never, SetChatMessageAutoremoveTimeoutError> in
|
|> mapToSignal { result -> Signal<Never, SetChatMessageAutoremoveTimeoutError> in
|
||||||
if case .boolTrue = result {
|
if let result = result {
|
||||||
return .complete()
|
account.stateManager.addUpdates(result)
|
||||||
|
|
||||||
|
return account.postbox.transaction { transaction -> Void in
|
||||||
|
transaction.updatePeerCachedData(peerIds: [peerId], update: { _, current in
|
||||||
|
var currentPeerValue: Int32?
|
||||||
|
if let current = current as? CachedUserData {
|
||||||
|
if case let .known(value?) = current.autoremoveTimeout {
|
||||||
|
currentPeerValue = value.peerValue
|
||||||
|
}
|
||||||
|
} else if let current = current as? CachedGroupData {
|
||||||
|
if case let .known(value?) = current.autoremoveTimeout {
|
||||||
|
currentPeerValue = value.peerValue
|
||||||
|
}
|
||||||
|
} else if let current = current as? CachedChannelData {
|
||||||
|
if case let .known(value?) = current.autoremoveTimeout {
|
||||||
|
currentPeerValue = value.peerValue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let updatedTimeout: CachedPeerAutoremoveTimeout
|
||||||
|
if let timeout = timeout {
|
||||||
|
updatedTimeout = .known(CachedPeerAutoremoveTimeout.Value(myValue: timeout, peerValue: currentPeerValue ?? timeout, isGlobal: isGlobal))
|
||||||
|
} else {
|
||||||
|
updatedTimeout = .known(nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
if let current = current as? CachedUserData {
|
||||||
|
return current.withUpdatedAutoremoveTimeout(updatedTimeout)
|
||||||
|
} else if let current = current as? CachedGroupData {
|
||||||
|
return current.withUpdatedAutoremoveTimeout(updatedTimeout)
|
||||||
|
} else if let current = current as? CachedChannelData {
|
||||||
|
return current.withUpdatedAutoremoveTimeout(updatedTimeout)
|
||||||
|
} else {
|
||||||
|
return current
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|> castError(SetChatMessageAutoremoveTimeoutError.self)
|
||||||
|
|> ignoreValues
|
||||||
} else {
|
} else {
|
||||||
return .fail(.generic)
|
return .fail(.generic)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|> `catch` { _ -> Signal<Never, SetChatMessageAutoremoveTimeoutError> in
|
|> `catch` { _ -> Signal<Never, SetChatMessageAutoremoveTimeoutError> in
|
||||||
return account.postbox.transaction { transaction -> Void in
|
return .complete()
|
||||||
transaction.updatePeerCachedData(peerIds: [peerId], update: { _, current in
|
|
||||||
transaction.updatePeerCachedData(peerIds: [peerId], update: { _, current in
|
|
||||||
if let current = current as? CachedUserData {
|
|
||||||
return current.withUpdatedAutoremoveTimeout(previousValue)
|
|
||||||
} else if let current = current as? CachedGroupData {
|
|
||||||
return current.withUpdatedAutoremoveTimeout(previousValue)
|
|
||||||
} else if let current = current as? CachedChannelData {
|
|
||||||
return current.withUpdatedAutoremoveTimeout(previousValue)
|
|
||||||
} else {
|
|
||||||
return current
|
|
||||||
}
|
|
||||||
})
|
|
||||||
return current
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|> castError(SetChatMessageAutoremoveTimeoutError.self)
|
|
||||||
|> ignoreValues
|
|
||||||
|> then(.fail(.generic))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -332,6 +332,25 @@ 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) {
|
||||||
|
var messageAutoremoveTimeout: Int32?
|
||||||
|
if let cachedData = cachedData as? CachedUserData {
|
||||||
|
if case let .known(value) = cachedData.autoremoveTimeout {
|
||||||
|
messageAutoremoveTimeout = value?.peerValue
|
||||||
|
}
|
||||||
|
} else if let cachedData = cachedData as? CachedGroupData {
|
||||||
|
if case let .known(value) = cachedData.autoremoveTimeout {
|
||||||
|
messageAutoremoveTimeout = value?.peerValue
|
||||||
|
}
|
||||||
|
} else if let cachedData = cachedData as? CachedChannelData {
|
||||||
|
if case let .known(value) = cachedData.autoremoveTimeout {
|
||||||
|
messageAutoremoveTimeout = value?.peerValue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if let messageAutoremoveTimeout = messageAutoremoveTimeout {
|
||||||
|
attributes.append(AutoremoveTimeoutMessageAttribute(timeout: messageAutoremoveTimeout, countdownBeginTime: nil))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
attributes.append(contentsOf: filterMessageAttributesForOutgoingMessage(requestedAttributes))
|
attributes.append(contentsOf: filterMessageAttributesForOutgoingMessage(requestedAttributes))
|
||||||
|
@ -207,7 +207,7 @@ func fetchAndUpdateCachedPeerData(accountPeerId: PeerId, peerId rawPeerId: PeerI
|
|||||||
|
|
||||||
let hasScheduledMessages = (userFull.flags & 1 << 12) != 0
|
let hasScheduledMessages = (userFull.flags & 1 << 12) != 0
|
||||||
|
|
||||||
let autoremoveTimeout: CachedPeerAutoremoveTimeout = .known(userFull.ttlPeriod)
|
let autoremoveTimeout: CachedPeerAutoremoveTimeout = .known(CachedPeerAutoremoveTimeout.Value(userFull.ttl))
|
||||||
|
|
||||||
return previous.withUpdatedAbout(userFull.about).withUpdatedBotInfo(botInfo).withUpdatedCommonGroupCount(userFull.commonChatsCount).withUpdatedIsBlocked(isBlocked).withUpdatedVoiceCallsAvailable(voiceCallsAvailable).withUpdatedVideoCallsAvailable(videoCallsAvailable).withUpdatedCallsPrivate(callsPrivate).withUpdatedCanPinMessages(canPinMessages).withUpdatedPeerStatusSettings(peerStatusSettings).withUpdatedPinnedMessageId(pinnedMessageId).withUpdatedHasScheduledMessages(hasScheduledMessages)
|
return previous.withUpdatedAbout(userFull.about).withUpdatedBotInfo(botInfo).withUpdatedCommonGroupCount(userFull.commonChatsCount).withUpdatedIsBlocked(isBlocked).withUpdatedVoiceCallsAvailable(voiceCallsAvailable).withUpdatedVideoCallsAvailable(videoCallsAvailable).withUpdatedCallsPrivate(callsPrivate).withUpdatedCanPinMessages(canPinMessages).withUpdatedPeerStatusSettings(peerStatusSettings).withUpdatedPinnedMessageId(pinnedMessageId).withUpdatedHasScheduledMessages(hasScheduledMessages)
|
||||||
.withUpdatedAutoremoveTimeout(autoremoveTimeout)
|
.withUpdatedAutoremoveTimeout(autoremoveTimeout)
|
||||||
@ -300,7 +300,7 @@ func fetchAndUpdateCachedPeerData(accountPeerId: PeerId, peerId rawPeerId: PeerI
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let autoremoveTimeout: CachedPeerAutoremoveTimeout = .known(chatFull.ttlPeriod)
|
let autoremoveTimeout: CachedPeerAutoremoveTimeout = .known(CachedPeerAutoremoveTimeout.Value(chatFull.ttl))
|
||||||
|
|
||||||
transaction.updatePeerCachedData(peerIds: [peerId], update: { _, current in
|
transaction.updatePeerCachedData(peerIds: [peerId], update: { _, current in
|
||||||
let previous: CachedGroupData
|
let previous: CachedGroupData
|
||||||
@ -513,7 +513,7 @@ func fetchAndUpdateCachedPeerData(accountPeerId: PeerId, peerId rawPeerId: PeerI
|
|||||||
|
|
||||||
minAvailableMessageIdUpdated = previous.minAvailableMessageId != minAvailableMessageId
|
minAvailableMessageIdUpdated = previous.minAvailableMessageId != minAvailableMessageId
|
||||||
|
|
||||||
let autoremoveTimeout: CachedPeerAutoremoveTimeout = .known(ttlPeriod)
|
let autoremoveTimeout: CachedPeerAutoremoveTimeout = .known(CachedPeerAutoremoveTimeout.Value(ttlPeriod))
|
||||||
|
|
||||||
return previous.withUpdatedFlags(channelFlags)
|
return previous.withUpdatedFlags(channelFlags)
|
||||||
.withUpdatedAbout(about)
|
.withUpdatedAbout(about)
|
||||||
@ -565,3 +565,22 @@ func fetchAndUpdateCachedPeerData(accountPeerId: PeerId, peerId rawPeerId: PeerI
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extension CachedPeerAutoremoveTimeout.Value {
|
||||||
|
init?(_ apiValue: Api.PeerHistoryTTL?) {
|
||||||
|
if let apiValue = apiValue {
|
||||||
|
switch apiValue {
|
||||||
|
case let .peerHistoryTTLPM(flags, ttlPeriodMy, ttlPeriodPeer):
|
||||||
|
guard let ttlPeriodPeer = ttlPeriodPeer else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
let pmOneSide = flags & (1 << 0) != 0
|
||||||
|
self.init(myValue: ttlPeriodMy ?? ttlPeriodPeer, peerValue: ttlPeriodPeer, isGlobal: !pmOneSide)
|
||||||
|
case let .peerHistoryTTL(ttlPeriodPeer):
|
||||||
|
self.init(myValue: ttlPeriodPeer, peerValue: ttlPeriodPeer, isGlobal: true)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
BIN
submodules/TelegramUI/Resources/Animations/MessageAutoRemove.tgs
Normal file
BIN
submodules/TelegramUI/Resources/Animations/MessageAutoRemove.tgs
Normal file
Binary file not shown.
@ -2876,7 +2876,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
|||||||
hasBots = true
|
hasBots = true
|
||||||
}
|
}
|
||||||
if case let .known(value) = cachedGroupData.autoremoveTimeout {
|
if case let .known(value) = cachedGroupData.autoremoveTimeout {
|
||||||
autoremoveTimeout = value
|
autoremoveTimeout = value?.peerValue
|
||||||
}
|
}
|
||||||
} else if let cachedChannelData = peerView.cachedData as? CachedChannelData {
|
} else if let cachedChannelData = peerView.cachedData as? CachedChannelData {
|
||||||
if let channel = peer as? TelegramChannel, case .group = channel.info {
|
if let channel = peer as? TelegramChannel, case .group = channel.info {
|
||||||
@ -2885,11 +2885,11 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if case let .known(value) = cachedChannelData.autoremoveTimeout {
|
if case let .known(value) = cachedChannelData.autoremoveTimeout {
|
||||||
autoremoveTimeout = value
|
autoremoveTimeout = value?.peerValue
|
||||||
}
|
}
|
||||||
} else if let cachedUserData = peerView.cachedData as? CachedUserData {
|
} else if let cachedUserData = peerView.cachedData as? CachedUserData {
|
||||||
if case let .known(value) = cachedUserData.autoremoveTimeout {
|
if case let .known(value) = cachedUserData.autoremoveTimeout {
|
||||||
autoremoveTimeout = value
|
autoremoveTimeout = value?.peerValue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -5436,10 +5436,13 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
|||||||
guard let strongSelf = self, case let .peer(peerId) = strongSelf.chatLocation else {
|
guard let strongSelf = self, case let .peer(peerId) = strongSelf.chatLocation else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
guard let peer = strongSelf.presentationInterfaceState.renderedPeer?.peer else {
|
||||||
|
return
|
||||||
|
}
|
||||||
if peerId.namespace == Namespaces.Peer.SecretChat {
|
if peerId.namespace == Namespaces.Peer.SecretChat {
|
||||||
strongSelf.chatDisplayNode.dismissInput()
|
strongSelf.chatDisplayNode.dismissInput()
|
||||||
|
|
||||||
if let peer = strongSelf.presentationInterfaceState.renderedPeer?.peer as? TelegramSecretChat {
|
if let peer = peer as? TelegramSecretChat {
|
||||||
let controller = ChatSecretAutoremoveTimerActionSheetController(context: strongSelf.context, currentValue: peer.messageAutoremoveTimeout == nil ? 0 : peer.messageAutoremoveTimeout!, applyValue: { value in
|
let controller = ChatSecretAutoremoveTimerActionSheetController(context: strongSelf.context, currentValue: peer.messageAutoremoveTimeout == nil ? 0 : peer.messageAutoremoveTimeout!, applyValue: { value in
|
||||||
if let strongSelf = self {
|
if let strongSelf = self {
|
||||||
let _ = setSecretChatMessageAutoremoveTimeoutInteractively(account: strongSelf.context.account, peerId: peer.id, timeout: value == 0 ? nil : value).start()
|
let _ = setSecretChatMessageAutoremoveTimeoutInteractively(account: strongSelf.context.account, peerId: peer.id, timeout: value == 0 ? nil : value).start()
|
||||||
@ -5448,24 +5451,60 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
|||||||
strongSelf.present(controller, in: .window(.root))
|
strongSelf.present(controller, in: .window(.root))
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
strongSelf.chatDisplayNode.dismissInput()
|
var currentAutoremoveTimeout: Int32? = strongSelf.presentationInterfaceState.autoremoveTimeout
|
||||||
|
var canSetupAutoremoveTimeout = false
|
||||||
|
|
||||||
if let peer = strongSelf.presentationInterfaceState.renderedPeer?.peer {
|
if let secretChat = peer as? TelegramSecretChat {
|
||||||
var availableValues: [Int32] = [
|
currentAutoremoveTimeout = secretChat.messageAutoremoveTimeout
|
||||||
60,
|
canSetupAutoremoveTimeout = true
|
||||||
300,
|
} else if let group = peer as? TelegramGroup {
|
||||||
86400,
|
if case .creator = group.role {
|
||||||
604800
|
canSetupAutoremoveTimeout = true
|
||||||
]
|
} else if case let .admin(rights, _) = group.role {
|
||||||
#if DEBUG
|
if rights.flags.contains(.canChangeInfo) {
|
||||||
availableValues.insert(5, at: 0)
|
canSetupAutoremoveTimeout = true
|
||||||
#endif
|
|
||||||
let controller = ChatSecretAutoremoveTimerActionSheetController(context: strongSelf.context, currentValue: strongSelf.presentationInterfaceState.autoremoveTimeout ?? 0, availableValues: availableValues, applyValue: { value in
|
|
||||||
if let strongSelf = self {
|
|
||||||
let _ = setChatMessageAutoremoveTimeoutInteractively(account: strongSelf.context.account, peerId: peer.id, timeout: value == 0 ? nil : value).start()
|
|
||||||
}
|
}
|
||||||
})
|
} else if let defaultBannedRights = group.defaultBannedRights {
|
||||||
strongSelf.present(controller, in: .window(.root))
|
if !defaultBannedRights.flags.contains(.banChangeInfo) {
|
||||||
|
canSetupAutoremoveTimeout = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if let _ = peer as? TelegramUser {
|
||||||
|
canSetupAutoremoveTimeout = true
|
||||||
|
} else if let channel = peer as? TelegramChannel {
|
||||||
|
if channel.hasPermission(.changeInfo) {
|
||||||
|
canSetupAutoremoveTimeout = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if canSetupAutoremoveTimeout {
|
||||||
|
strongSelf.chatDisplayNode.dismissInput()
|
||||||
|
|
||||||
|
let controller = peerAutoremoveSetupScreen(context: strongSelf.context, peerId: peerId)
|
||||||
|
strongSelf.push(controller)
|
||||||
|
} else if let currentAutoremoveTimeout = currentAutoremoveTimeout, let rect = strongSelf.chatDisplayNode.frameForInputPanelAccessoryButton(.messageAutoremoveTimeout(currentAutoremoveTimeout)) {
|
||||||
|
|
||||||
|
//TODO:localize
|
||||||
|
let intervalText = timeIntervalString(strings: strongSelf.presentationData.strings, value: currentAutoremoveTimeout)
|
||||||
|
let text: String = "Messages in this chat are automatically\ndeleted \(intervalText) after they have been sent."
|
||||||
|
|
||||||
|
if let tooltipController = strongSelf.silentPostTooltipController {
|
||||||
|
tooltipController.updateContent(.text(text), animated: true, extendTimer: true)
|
||||||
|
} else {
|
||||||
|
let tooltipController = TooltipController(content: .text(text), baseFontSize: strongSelf.presentationData.listsFontSize.baseDisplaySize)
|
||||||
|
strongSelf.silentPostTooltipController = tooltipController
|
||||||
|
tooltipController.dismissed = { [weak tooltipController] _ in
|
||||||
|
if let strongSelf = self, let tooltipController = tooltipController, strongSelf.silentPostTooltipController === tooltipController {
|
||||||
|
strongSelf.silentPostTooltipController = nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
strongSelf.present(tooltipController, in: .window(.root), with: TooltipControllerPresentationArguments(sourceNodeAndRect: {
|
||||||
|
if let strongSelf = self {
|
||||||
|
return (strongSelf.chatDisplayNode, rect)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, sendSticker: { [weak self] file, sourceNode, sourceRect in
|
}, sendSticker: { [weak self] file, sourceNode, sourceRect in
|
||||||
@ -7544,6 +7583,10 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
|||||||
}))
|
}))
|
||||||
} else if canRemoveGlobally {
|
} else if canRemoveGlobally {
|
||||||
items.append(DeleteChatPeerActionSheetItem(context: self.context, peer: mainPeer, chatPeer: chatPeer, action: .clearHistory, strings: self.presentationData.strings, nameDisplayOrder: self.presentationData.nameDisplayOrder))
|
items.append(DeleteChatPeerActionSheetItem(context: self.context, peer: mainPeer, chatPeer: chatPeer, action: .clearHistory, strings: self.presentationData.strings, nameDisplayOrder: self.presentationData.nameDisplayOrder))
|
||||||
|
items.append(ActionSheetButtonItem(title: self.presentationData.strings.ChatList_DeleteForCurrentUser, color: .destructive, action: { [weak actionSheet] in
|
||||||
|
actionSheet?.dismissAnimated()
|
||||||
|
beginClear(.forLocalPeer)
|
||||||
|
}))
|
||||||
items.append(ActionSheetButtonItem(title: self.presentationData.strings.ChatList_DeleteForEveryone(mainPeer.compactDisplayTitle).0, color: .destructive, action: { [weak self, weak actionSheet] in
|
items.append(ActionSheetButtonItem(title: self.presentationData.strings.ChatList_DeleteForEveryone(mainPeer.compactDisplayTitle).0, color: .destructive, action: { [weak self, weak actionSheet] in
|
||||||
actionSheet?.dismissAnimated()
|
actionSheet?.dismissAnimated()
|
||||||
|
|
||||||
@ -7559,10 +7602,6 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
|||||||
})
|
})
|
||||||
], parseMarkdown: true), in: .window(.root))
|
], parseMarkdown: true), in: .window(.root))
|
||||||
}))
|
}))
|
||||||
items.append(ActionSheetButtonItem(title: self.presentationData.strings.ChatList_DeleteForCurrentUser, color: .destructive, action: { [weak actionSheet] in
|
|
||||||
actionSheet?.dismissAnimated()
|
|
||||||
beginClear(.forLocalPeer)
|
|
||||||
}))
|
|
||||||
} else {
|
} else {
|
||||||
items.append(ActionSheetTextItem(title: text))
|
items.append(ActionSheetTextItem(title: text))
|
||||||
items.append(ActionSheetButtonItem(title: self.presentationData.strings.Conversation_ClearAll, color: .destructive, action: { [weak self, weak actionSheet] in
|
items.append(ActionSheetButtonItem(title: self.presentationData.strings.Conversation_ClearAll, color: .destructive, action: { [weak self, weak actionSheet] in
|
||||||
@ -7581,6 +7620,58 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
|||||||
], parseMarkdown: true), in: .window(.root))
|
], parseMarkdown: true), in: .window(.root))
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let peer = self.presentationInterfaceState.renderedPeer?.peer {
|
||||||
|
var currentAutoremoveTimeout: Int32? = self.presentationInterfaceState.autoremoveTimeout
|
||||||
|
var canSetupAutoremoveTimeout = false
|
||||||
|
|
||||||
|
if let secretChat = peer as? TelegramSecretChat {
|
||||||
|
currentAutoremoveTimeout = secretChat.messageAutoremoveTimeout
|
||||||
|
canSetupAutoremoveTimeout = true
|
||||||
|
} else if let group = peer as? TelegramGroup {
|
||||||
|
if case .creator = group.role {
|
||||||
|
canSetupAutoremoveTimeout = true
|
||||||
|
} else if case let .admin(rights, _) = group.role {
|
||||||
|
if rights.flags.contains(.canChangeInfo) {
|
||||||
|
canSetupAutoremoveTimeout = true
|
||||||
|
}
|
||||||
|
} else if let defaultBannedRights = group.defaultBannedRights {
|
||||||
|
if !defaultBannedRights.flags.contains(.banChangeInfo) {
|
||||||
|
canSetupAutoremoveTimeout = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if let _ = self.presentationInterfaceState.renderedPeer?.peer as? TelegramUser {
|
||||||
|
canSetupAutoremoveTimeout = true
|
||||||
|
} else if let channel = self.presentationInterfaceState.renderedPeer?.peer as? TelegramChannel {
|
||||||
|
if channel.hasPermission(.changeInfo) {
|
||||||
|
canSetupAutoremoveTimeout = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if canSetupAutoremoveTimeout {
|
||||||
|
//TODO:localize
|
||||||
|
items.append(ActionSheetButtonItem(title: currentAutoremoveTimeout == nil ? "Enable Auto-Delete" : "Edit Auto-Delete Settings", color: .accent, action: { [weak self, weak actionSheet] in
|
||||||
|
guard let actionSheet = actionSheet else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
actionSheet.dismissAnimated()
|
||||||
|
|
||||||
|
guard let strongSelf = self else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
let controller = peerAutoremoveSetupScreen(context: strongSelf.context, peerId: peer.id, completion: { updatedValue in
|
||||||
|
if case .updated = updatedValue {
|
||||||
|
if currentAutoremoveTimeout == nil {
|
||||||
|
self?.navigationButtonAction(.clearHistory)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
strongSelf.chatDisplayNode.dismissInput()
|
||||||
|
strongSelf.push(controller)
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
actionSheet.setItemGroups([ActionSheetItemGroup(items: items), ActionSheetItemGroup(items: [
|
actionSheet.setItemGroups([ActionSheetItemGroup(items: items), ActionSheetItemGroup(items: [
|
||||||
ActionSheetButtonItem(title: self.presentationData.strings.Common_Cancel, color: .accent, font: .bold, action: { [weak actionSheet] in
|
ActionSheetButtonItem(title: self.presentationData.strings.Common_Cancel, color: .accent, font: .bold, action: { [weak actionSheet] in
|
||||||
|
@ -259,7 +259,9 @@ func inputTextPanelStateForChatPresentationInterfaceState(_ chatPresentationInte
|
|||||||
}
|
}
|
||||||
|
|
||||||
if canSetupAutoremoveTimeout {
|
if canSetupAutoremoveTimeout {
|
||||||
accessoryItems.append(.messageAutoremoveTimeout(currentAutoremoveTimeout))
|
if currentAutoremoveTimeout != nil || chatPresentationInterfaceState.renderedPeer?.peer is TelegramSecretChat {
|
||||||
|
accessoryItems.append(.messageAutoremoveTimeout(currentAutoremoveTimeout))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
switch chatPresentationInterfaceState.inputMode {
|
switch chatPresentationInterfaceState.inputMode {
|
||||||
@ -283,7 +285,7 @@ func inputTextPanelStateForChatPresentationInterfaceState(_ chatPresentationInte
|
|||||||
if !extendedSearchLayout {
|
if !extendedSearchLayout {
|
||||||
if let peer = chatPresentationInterfaceState.renderedPeer?.peer as? TelegramSecretChat {
|
if let peer = chatPresentationInterfaceState.renderedPeer?.peer as? TelegramSecretChat {
|
||||||
accessoryItems.append(.messageAutoremoveTimeout(peer.messageAutoremoveTimeout))
|
accessoryItems.append(.messageAutoremoveTimeout(peer.messageAutoremoveTimeout))
|
||||||
} else if canSetupAutoremoveTimeout {
|
} else if currentAutoremoveTimeout != nil {
|
||||||
accessoryItems.append(.messageAutoremoveTimeout(currentAutoremoveTimeout))
|
accessoryItems.append(.messageAutoremoveTimeout(currentAutoremoveTimeout))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1235,7 +1235,7 @@ private func editingItems(data: PeerInfoScreenData?, context: AccountContext, pr
|
|||||||
if channel.hasPermission(.changeInfo) {
|
if channel.hasPermission(.changeInfo) {
|
||||||
let timeoutString: String
|
let timeoutString: String
|
||||||
if case let .known(value) = (data.cachedData as? CachedChannelData)?.autoremoveTimeout {
|
if case let .known(value) = (data.cachedData as? CachedChannelData)?.autoremoveTimeout {
|
||||||
if let value = value {
|
if let value = value?.peerValue {
|
||||||
timeoutString = timeIntervalString(strings: presentationData.strings, value: value)
|
timeoutString = timeIntervalString(strings: presentationData.strings, value: value)
|
||||||
} else {
|
} else {
|
||||||
timeoutString = presentationData.strings.PeerInfo_AutoremoveMessagesDisabled
|
timeoutString = presentationData.strings.PeerInfo_AutoremoveMessagesDisabled
|
||||||
@ -1350,10 +1350,10 @@ private func editingItems(data: PeerInfoScreenData?, context: AccountContext, pr
|
|||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
if channel.hasPermission(.changeInfo) {
|
/*if channel.hasPermission(.changeInfo) {
|
||||||
let timeoutString: String
|
let timeoutString: String
|
||||||
if case let .known(value) = cachedData.autoremoveTimeout {
|
if case let .known(value) = cachedData.autoremoveTimeout {
|
||||||
if let value = value {
|
if let value = value?.peerValue {
|
||||||
timeoutString = timeIntervalString(strings: presentationData.strings, value: value)
|
timeoutString = timeIntervalString(strings: presentationData.strings, value: value)
|
||||||
} else {
|
} else {
|
||||||
timeoutString = presentationData.strings.PeerInfo_AutoremoveMessagesDisabled
|
timeoutString = presentationData.strings.PeerInfo_AutoremoveMessagesDisabled
|
||||||
@ -1365,7 +1365,7 @@ private func editingItems(data: PeerInfoScreenData?, context: AccountContext, pr
|
|||||||
items[.peerPublicSettings]!.append(PeerInfoScreenDisclosureItem(id: ItemAutoremove, label: .text(timeoutString), text: presentationData.strings.PeerInfo_AutoremoveMessages, action: {
|
items[.peerPublicSettings]!.append(PeerInfoScreenDisclosureItem(id: ItemAutoremove, label: .text(timeoutString), text: presentationData.strings.PeerInfo_AutoremoveMessages, action: {
|
||||||
interaction.editingOpenAutoremoveMesages()
|
interaction.editingOpenAutoremoveMesages()
|
||||||
}))
|
}))
|
||||||
}
|
}*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1436,11 +1436,11 @@ private func editingItems(data: PeerInfoScreenData?, context: AccountContext, pr
|
|||||||
interaction.editingOpenPreHistorySetup()
|
interaction.editingOpenPreHistorySetup()
|
||||||
}))
|
}))
|
||||||
|
|
||||||
let canChangeInfo = true
|
/*let canChangeInfo = true
|
||||||
if canChangeInfo {
|
if canChangeInfo {
|
||||||
let timeoutString: String
|
let timeoutString: String
|
||||||
if case let .known(value) = (data.cachedData as? CachedGroupData)?.autoremoveTimeout {
|
if case let .known(value) = (data.cachedData as? CachedGroupData)?.autoremoveTimeout {
|
||||||
if let value = value {
|
if let value = value?.value {
|
||||||
timeoutString = timeIntervalString(strings: presentationData.strings, value: value)
|
timeoutString = timeIntervalString(strings: presentationData.strings, value: value)
|
||||||
} else {
|
} else {
|
||||||
timeoutString = presentationData.strings.PeerInfo_AutoremoveMessagesDisabled
|
timeoutString = presentationData.strings.PeerInfo_AutoremoveMessagesDisabled
|
||||||
@ -1452,7 +1452,7 @@ private func editingItems(data: PeerInfoScreenData?, context: AccountContext, pr
|
|||||||
items[.peerPublicSettings]!.append(PeerInfoScreenDisclosureItem(id: ItemAutoremove, label: .text(timeoutString), text: presentationData.strings.PeerInfo_AutoremoveMessages, action: {
|
items[.peerPublicSettings]!.append(PeerInfoScreenDisclosureItem(id: ItemAutoremove, label: .text(timeoutString), text: presentationData.strings.PeerInfo_AutoremoveMessages, action: {
|
||||||
interaction.editingOpenAutoremoveMesages()
|
interaction.editingOpenAutoremoveMesages()
|
||||||
}))
|
}))
|
||||||
}
|
}*/
|
||||||
|
|
||||||
var activePermissionCount: Int?
|
var activePermissionCount: Int?
|
||||||
if let defaultBannedRights = group.defaultBannedRights {
|
if let defaultBannedRights = group.defaultBannedRights {
|
||||||
@ -3859,7 +3859,12 @@ private final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewD
|
|||||||
}
|
}
|
||||||
|
|
||||||
private func editingOpenAutoremoveMesages() {
|
private func editingOpenAutoremoveMesages() {
|
||||||
|
guard let data = self.data, let peer = data.peer else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
let controller = peerAutoremoveSetupScreen(context: self.context, peerId: peer.id)
|
||||||
|
self.controller?.push(controller)
|
||||||
}
|
}
|
||||||
|
|
||||||
private func openPermissions() {
|
private func openPermissions() {
|
||||||
|
@ -192,7 +192,7 @@ final class WidgetDataContext {
|
|||||||
return WidgetDataPeer(id: peer.id.toInt64(), name: name, lastName: lastName, letters: peer.displayLetters, avatarPath: smallestImageRepresentation(peer.profileImageRepresentations).flatMap { representation in
|
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)
|
return account.postbox.mediaBox.resourcePath(representation.resource)
|
||||||
}, badge: badge, message: message)
|
}, badge: badge, message: message)
|
||||||
})))
|
}, updateTimestamp: Int32(Date().timeIntervalSince1970))))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|> distinctUntilChanged
|
|> distinctUntilChanged
|
||||||
@ -282,7 +282,7 @@ final class WidgetDataContext {
|
|||||||
return WidgetDataPeer(id: peer.id.toInt64(), name: name, lastName: lastName, letters: peer.displayLetters, avatarPath: smallestImageRepresentation(peer.profileImageRepresentations).flatMap { representation in
|
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)
|
return account.postbox.mediaBox.resourcePath(representation.resource)
|
||||||
}, badge: badge, message: message)
|
}, badge: badge, message: message)
|
||||||
})))
|
}, updateTimestamp: Int32(Date().timeIntervalSince1970))))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|> distinctUntilChanged
|
|> distinctUntilChanged
|
||||||
|
@ -238,10 +238,12 @@ public struct WidgetDataPeer: Codable, Equatable {
|
|||||||
public struct WidgetDataPeers: Codable, Equatable {
|
public struct WidgetDataPeers: Codable, Equatable {
|
||||||
public var accountPeerId: Int64
|
public var accountPeerId: Int64
|
||||||
public var peers: [WidgetDataPeer]
|
public var peers: [WidgetDataPeer]
|
||||||
|
public var updateTimestamp: Int32
|
||||||
|
|
||||||
public init(accountPeerId: Int64, peers: [WidgetDataPeer]) {
|
public init(accountPeerId: Int64, peers: [WidgetDataPeer], updateTimestamp: Int32) {
|
||||||
self.accountPeerId = accountPeerId
|
self.accountPeerId = accountPeerId
|
||||||
self.peers = peers
|
self.peers = peers
|
||||||
|
self.updateTimestamp = updateTimestamp
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user