[WIP] Autoremove timer

This commit is contained in:
Ali 2021-02-06 00:09:51 +04:00
parent e80c198605
commit 4cd27e7864
26 changed files with 1251 additions and 218 deletions

View File

@ -1578,7 +1578,7 @@ ios_application(
":NotificationContentExtension", ":NotificationContentExtension",
":NotificationServiceExtension", ":NotificationServiceExtension",
":IntentsExtension", ":IntentsExtension",
# ":WidgetExtension", ":WidgetExtension",
], ],
}), }),
watch_application = select({ watch_application = select({

View File

@ -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

View File

@ -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>

View File

@ -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)

View File

@ -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)

View File

@ -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;

View File

@ -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)
{ {

View 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
}

View 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)
}
}

View File

@ -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 {

View File

@ -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")

View File

@ -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 {

View File

@ -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:

View File

@ -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 {

View File

@ -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>) {

View File

@ -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 {

View File

@ -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 {

View File

@ -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))
} }
} }
} }

View File

@ -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))

View File

@ -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
}
}
}

View File

@ -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

View File

@ -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))
} }
} }

View File

@ -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() {

View File

@ -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

View File

@ -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
} }
} }