Merge branch 'master' into experimental-2

This commit is contained in:
Ali 2021-02-06 00:10:08 +04:00
commit f590511158
26 changed files with 1251 additions and 218 deletions

View File

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

View File

@ -701,7 +701,7 @@ class IntentHandler: INExtension, INSendMessageIntentHandling, INSearchForMessag
}
@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()
|> take(1)
|> mapToSignal { account -> Signal<[Friend], NoError> in

View File

@ -146,7 +146,7 @@
</dict>
<dict>
<key>INIntentParameterArraySizeSize</key>
<integer>8</integer>
<integer>2</integer>
<key>INIntentParameterArraySizeSizeClass</key>
<string>Medium</string>
</dict>

View File

@ -171,7 +171,7 @@ struct Provider: IntentTimelineProvider {
}, 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
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
switch data {
case let .peers(peersValue):
@ -454,16 +454,57 @@ struct WidgetView: View {
return AnyView(Spacer())
}
let itemHeight = (size.height - 22.0) / 2.0
return AnyView(
Link(destination: URL(string: linkForPeer(id: peers.peers[index].id))!, label: {
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))
})
})
}).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 {
switch colorScheme {
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 {
GeometryReader(content: { geometry in
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(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)
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)
return ZStack {
chatContentView(0, size: geometry.size)
chatContentView(1, size: geometry.size)
chatSeparatorView(size: geometry.size)
chatsUpdateBackgroundView(size: geometry.size)
chatsUpdateTimestampView(size: geometry.size)
}
})
.padding(0.0)

View File

@ -13,6 +13,7 @@ public enum ChatListFilterSettingsHeaderAnimation {
case folders
case newFolder
case discussionGroupSetup
case autoRemove
}
public class ChatListFilterSettingsHeaderItem: ListViewItem, ItemListItem {
@ -106,7 +107,26 @@ class ChatListFilterSettingsHeaderItemNode: ListViewItemNode {
return { item, params, neighbors in
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 (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
if let strongSelf = self {
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") {
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
}
}
@ -137,7 +148,7 @@ class ChatListFilterSettingsHeaderItemNode: ListViewItemNode {
strongSelf.item = item
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.updateLayout(size: iconSize)

View File

@ -13,6 +13,7 @@
@property (nonatomic, assign) CGFloat startValue;
@property (nonatomic, assign) CGFloat value;
@property (nonatomic, assign) int minimumUndottedValue;
@property (nonatomic, assign) CGFloat markValue;

View File

@ -174,13 +174,59 @@ const CGFloat TGPhotoEditorSliderViewInternalMargin = 7.0f;
CGContextSetBlendMode(context, kCGBlendModeCopy);
}
CGContextSetFillColorWithColor(context, _backColor.CGColor);
[self drawRectangle:backFrame cornerRadius:self.trackCornerRadius context:context];
if (_minimumUndottedValue > 0 && self.positionsCount > 1) {
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);
CGContextSetFillColorWithColor(context, _trackColor.CGColor);
[self drawRectangle:trackFrame cornerRadius:self.trackCornerRadius context:context];
if (_minimumUndottedValue > 0) {
} else {
CGContextSetFillColorWithColor(context, _trackColor.CGColor);
[self drawRectangle:trackFrame cornerRadius:self.trackCornerRadius context:context];
}
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.slowModeValidUntilTimestamp = decoder.decodeOptionalInt32ForKey("smv")
self.hasScheduledMessages = decoder.decodeBoolForKey("hsm", orElse: false)
if let value = decoder.decodeOptionalInt32ForKey("art") {
if value == -1 {
self.autoremoveTimeout = .known(nil)
} else {
self.autoremoveTimeout = .known(value)
}
} else {
self.autoremoveTimeout = .unknown
}
self.autoremoveTimeout = decoder.decodeObjectForKey("artv", decoder: CachedPeerAutoremoveTimeout.init(decoder:)) as? CachedPeerAutoremoveTimeout ?? .unknown
self.statsDatacenterId = decoder.decodeInt32ForKey("sdi", orElse: 0)
self.invitedBy = decoder.decodeOptionalInt64ForKey("invBy").flatMap(PeerId.init)
@ -545,16 +537,7 @@ public final class CachedChannelData: CachedPeerData {
encoder.encodeNil(forKey: "smv")
}
encoder.encodeBool(self.hasScheduledMessages, forKey: "hsm")
switch self.autoremoveTimeout {
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.encodeObject(self.autoremoveTimeout, forKey: "artv")
encoder.encodeInt32(self.statsDatacenterId, forKey: "sdi")
if let invitedBy = self.invitedBy {

View File

@ -131,15 +131,7 @@ public final class CachedGroupData: CachedPeerData {
self.about = decoder.decodeOptionalStringForKey("ab")
self.flags = CachedGroupFlags(rawValue: decoder.decodeInt32ForKey("fl", orElse: 0))
self.hasScheduledMessages = decoder.decodeBoolForKey("hsm", orElse: false)
if let value = decoder.decodeOptionalInt32ForKey("art") {
if value == -1 {
self.autoremoveTimeout = .known(nil)
} else {
self.autoremoveTimeout = .known(value)
}
} else {
self.autoremoveTimeout = .unknown
}
self.autoremoveTimeout = decoder.decodeObjectForKey("artv", decoder: CachedPeerAutoremoveTimeout.init(decoder:)) as? CachedPeerAutoremoveTimeout ?? .unknown
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.encodeBool(self.hasScheduledMessages, forKey: "hsm")
switch self.autoremoveTimeout {
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.encodeObject(self.autoremoveTimeout, forKey: "artv")
if let invitedBy = self.invitedBy {
encoder.encodeInt64(invitedBy.toInt64(), forKey: "invBy")

View File

@ -1,9 +1,56 @@
import Foundation
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 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 {
@ -82,15 +129,7 @@ public final class CachedUserData: CachedPeerData {
self.callsPrivate = decoder.decodeInt32ForKey("cp", orElse: 0) != 0
self.canPinMessages = decoder.decodeInt32ForKey("cpm", orElse: 0) != 0
self.hasScheduledMessages = decoder.decodeBoolForKey("hsm", orElse: false)
if let value = decoder.decodeOptionalInt32ForKey("art") {
if value == -1 {
self.autoremoveTimeout = .known(nil)
} else {
self.autoremoveTimeout = .known(value)
}
} else {
self.autoremoveTimeout = .unknown
}
self.autoremoveTimeout = decoder.decodeObjectForKey("artv", decoder: CachedPeerAutoremoveTimeout.init(decoder:)) as? CachedPeerAutoremoveTimeout ?? .unknown
var messageIds = Set<MessageId>()
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.canPinMessages ? 1 : 0, forKey: "cpm")
encoder.encodeBool(self.hasScheduledMessages, forKey: "hsm")
switch self.autoremoveTimeout {
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.encodeObject(self.autoremoveTimeout, forKey: "artv")
}
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[1210199983] = { return Api.InputGeoPoint.parse_inputGeoPoint($0) }
dict[-784000893] = { return Api.payments.ValidatedRequestedInfo.parse_validatedRequestedInfo($0) }
dict[-1415563086] = { return Api.ChatFull.parse_channelFull($0) }
dict[-261341160] = { return Api.ChatFull.parse_chatFull($0) }
dict[-66811386] = { return Api.ChatFull.parse_channelFull($0) }
dict[-500874592] = { return Api.ChatFull.parse_chatFull($0) }
dict[-1159937629] = { return Api.PollResults.parse_pollResults($0) }
dict[-925415106] = { return Api.ChatParticipant.parse_chatParticipant($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[136105807] = { return Api.RichText.parse_textImage($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[-1343524562] = { return Api.InputChannel.parse_inputChannel($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[497489295] = { return Api.help.AppUpdate.parse_appUpdate($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[-1519029347] = { return Api.EmojiURL.parse_emojiURL($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[-1537295973] = { return Api.Update.parse_updateGroupCall($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[1558266229] = { return Api.PopularContact.parse_popularContact($0) }
dict[-373643672] = { return Api.FolderPeer.parse_folderPeer($0) }
@ -1015,6 +1018,8 @@ public struct Api {
_1.serialize(buffer, boxed)
case let _1 as Api.LangPackDifference:
_1.serialize(buffer, boxed)
case let _1 as Api.PeerHistoryTTL:
_1.serialize(buffer, boxed)
case let _1 as Api.WallPaperSettings:
_1.serialize(buffer, boxed)
case let _1 as Api.EmojiURL:

View File

@ -2380,14 +2380,14 @@ public extension Api {
}
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 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 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?, ttl: Api.PeerHistoryTTL?)
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
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 {
buffer.appendInt32(-1415563086)
buffer.appendInt32(-66811386)
}
serializeInt32(flags, 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)}
serializeInt32(pts, buffer: buffer, boxed: false)
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
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 {
buffer.appendInt32(-261341160)
buffer.appendInt32(-500874592)
}
serializeInt32(flags, 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 << 11) != 0 {serializeInt32(folderId!, buffer: buffer, boxed: false)}
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
}
}
public func descriptionFields() -> (String, [(String, Any)]) {
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):
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)])
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):
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)])
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), ("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 ttl):
return ("chatFull", [("flags", flags), ("id", id), ("about", about), ("participants", participants), ("chatPhoto", chatPhoto), ("notifySettings", notifySettings), ("exportedInvite", exportedInvite), ("botInfo", botInfo), ("pinnedMsgId", pinnedMsgId), ("folderId", folderId), ("call", call), ("ttl", ttl)])
}
}
@ -2527,8 +2527,10 @@ public extension Api {
if Int(_1!) & Int(1 << 21) != 0 {if let signature = reader.readInt32() {
_28 = Api.parse(reader, signature: signature) as? Api.InputGroupCall
} }
var _29: Int32?
if Int(_1!) & Int(1 << 22) != 0 {_29 = reader.readInt32() }
var _29: Api.PeerHistoryTTL?
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 _c2 = _2 != nil
let _c3 = _3 != nil
@ -2557,9 +2559,9 @@ public extension Api {
let _c26 = (Int(_1!) & Int(1 << 12) == 0) || _26 != nil
let _c27 = _27 != 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 {
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 {
return nil
@ -2600,8 +2602,10 @@ public extension Api {
if Int(_1!) & Int(1 << 12) != 0 {if let signature = reader.readInt32() {
_11 = Api.parse(reader, signature: signature) as? Api.InputGroupCall
} }
var _12: Int32?
if Int(_1!) & Int(1 << 14) != 0 {_12 = reader.readInt32() }
var _12: Api.PeerHistoryTTL?
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 _c2 = _2 != nil
let _c3 = _3 != nil
@ -2615,7 +2619,7 @@ public extension Api {
let _c11 = (Int(_1!) & Int(1 << 12) == 0) || _11 != nil
let _c12 = (Int(_1!) & Int(1 << 14) == 0) || _12 != nil
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 {
return nil
@ -5080,13 +5084,13 @@ public extension Api {
}
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) {
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 {
buffer.appendInt32(328899191)
buffer.appendInt32(-1522240089)
}
serializeInt32(flags, buffer: buffer, boxed: false)
user.serialize(buffer, true)
@ -5098,15 +5102,15 @@ public extension Api {
if Int(flags) & Int(1 << 6) != 0 {serializeInt32(pinnedMsgId!, 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 << 14) != 0 {serializeInt32(ttlPeriod!, buffer: buffer, boxed: false)}
if Int(flags) & Int(1 << 14) != 0 {ttl!.serialize(buffer, true)}
break
}
}
public func descriptionFields() -> (String, [(String, Any)]) {
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):
return ("userFull", [("flags", flags), ("user", user), ("about", about), ("settings", settings), ("profilePhoto", profilePhoto), ("notifySettings", notifySettings), ("botInfo", botInfo), ("pinnedMsgId", pinnedMsgId), ("commonChatsCount", commonChatsCount), ("folderId", folderId), ("ttlPeriod", 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), ("ttl", ttl)])
}
}
@ -5141,8 +5145,10 @@ public extension Api {
_9 = reader.readInt32()
var _10: Int32?
if Int(_1!) & Int(1 << 11) != 0 {_10 = reader.readInt32() }
var _11: Int32?
if Int(_1!) & Int(1 << 14) != 0 {_11 = reader.readInt32() }
var _11: Api.PeerHistoryTTL?
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 _c2 = _2 != 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 _c11 = (Int(_1!) & Int(1 << 14) == 0) || _11 != nil
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 {
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 {
case wallPaperSettings(flags: Int32, backgroundColor: Int32?, secondBackgroundColor: Int32?, intensity: Int32?, rotation: Int32?)
@ -6828,6 +6896,7 @@ public extension Api {
case updateGroupCallParticipants(call: Api.InputGroupCall, participants: [Api.GroupCallParticipant], version: Int32)
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 updatePeerHistoryTTL(flags: Int32, peer: Api.Peer, ttl: Api.PeerHistoryTTL?)
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
switch self {
@ -7589,6 +7658,14 @@ public extension Api {
if Int(flags) & Int(1 << 1) != 0 {peerType!.serialize(buffer, true)}
serializeString(offset, buffer: buffer, boxed: false)
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
}
}
@ -7770,6 +7847,8 @@ public extension Api {
return ("updateGroupCall", [("chatId", chatId), ("call", call)])
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)])
case .updatePeerHistoryTTL(let flags, let peer, let ttl):
return ("updatePeerHistoryTTL", [("flags", flags), ("peer", peer), ("ttl", ttl)])
}
}
@ -9295,6 +9374,27 @@ public extension Api {
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 {

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>) {
let buffer = Buffer()
buffer.appendInt32(347716823)
@ -4109,21 +4125,6 @@ public extension Api {
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 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 UpdateGroupCallParticipants(id: Int64, accessHash: Int64, participants: [Api.GroupCallParticipant], version: Int32)
case UpdateGroupCall(peerId: PeerId, call: Api.GroupCall)
case UpdateAutoremoveTimeout(peer: Api.Peer, value: CachedPeerAutoremoveTimeout.Value?)
}
struct HoleFromPreviousState {
@ -286,6 +287,10 @@ struct AccountMutableState {
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) {
self.addOperation(.ReadGroupFeedInbox(groupId, index))
}
@ -494,7 +499,7 @@ struct AccountMutableState {
mutating func addOperation(_ operation: AccountStateMutationOperation) {
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
case let .AddMessages(messages, location):
for message in messages {

View File

@ -1358,6 +1358,8 @@ private func finalStateWithUpdatesAndServerTime(postbox: Postbox, network: Netwo
case let .updateGroupCall(channelId, 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)
case let .updatePeerHistoryTTL(_, peer, ttl):
updatedState.updateAutoremoveTimeout(peer: peer, value: CachedPeerAutoremoveTimeout.Value(ttl))
case let .updateLangPackTooLong(langCode):
updatedState.updateLangPack(langCode: langCode, difference: nil)
case let .updateLangPack(difference):
@ -2148,7 +2150,7 @@ private func optimizedOperations(_ operations: [AccountStateMutationOperation])
var currentAddScheduledMessages: OptimizeAddMessagesState?
for operation in operations {
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 {
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):
if let difference = difference {
if langPackDifferences[langCode] == nil {

View File

@ -146,64 +146,72 @@ public enum SetChatMessageAutoremoveTimeoutError {
case generic
}
public func setChatMessageAutoremoveTimeoutInteractively(account: Account, peerId: PeerId, timeout: Int32?) -> Signal<Never, SetChatMessageAutoremoveTimeoutError> {
return account.postbox.transaction { transaction -> (Api.InputPeer?, CachedPeerAutoremoveTimeout) in
var currentValue: CachedPeerAutoremoveTimeout = .unknown
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)
public func setChatMessageAutoremoveTimeoutInteractively(account: Account, peerId: PeerId, timeout: Int32?, isGlobal: Bool) -> Signal<Never, SetChatMessageAutoremoveTimeoutError> {
return account.postbox.transaction { transaction -> Api.InputPeer? in
return transaction.getPeer(peerId).flatMap(apiInputPeer)
}
|> castError(SetChatMessageAutoremoveTimeoutError.self)
|> mapToSignal { (inputPeer, previousValue) -> Signal<Never, SetChatMessageAutoremoveTimeoutError> in
|> mapToSignal { inputPeer -> Signal<Never, SetChatMessageAutoremoveTimeoutError> in
guard let inputPeer = inputPeer else {
return .fail(.generic)
}
return account.network.request(Api.functions.messages.setPeerMessagesTTL(peer: inputPeer, period: timeout ?? 0))
|> `catch` { _ -> Signal<Api.Bool, NoError> in
return .single(.boolFalse)
var flags: Int32 = 0
if !isGlobal {
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)
|> mapToSignal { result -> Signal<Never, SetChatMessageAutoremoveTimeoutError> in
if case .boolTrue = result {
return .complete()
if let result = result {
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 {
return .fail(.generic)
}
}
|> `catch` { _ -> Signal<Never, SetChatMessageAutoremoveTimeoutError> in
return account.postbox.transaction { transaction -> Void in
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))
return .complete()
}
}
}

View File

@ -332,6 +332,25 @@ func enqueueMessages(transaction: Transaction, account: Account, peerId: PeerId,
if !disableAutoremove, let messageAutoremoveTimeout = peer.messageAutoremoveTimeout, !isAction {
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))

View File

@ -207,7 +207,7 @@ func fetchAndUpdateCachedPeerData(accountPeerId: PeerId, peerId rawPeerId: PeerI
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)
.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
let previous: CachedGroupData
@ -513,7 +513,7 @@ func fetchAndUpdateCachedPeerData(accountPeerId: PeerId, peerId rawPeerId: PeerI
minAvailableMessageIdUpdated = previous.minAvailableMessageId != minAvailableMessageId
let autoremoveTimeout: CachedPeerAutoremoveTimeout = .known(ttlPeriod)
let autoremoveTimeout: CachedPeerAutoremoveTimeout = .known(CachedPeerAutoremoveTimeout.Value(ttlPeriod))
return previous.withUpdatedFlags(channelFlags)
.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
}
if case let .known(value) = cachedGroupData.autoremoveTimeout {
autoremoveTimeout = value
autoremoveTimeout = value?.peerValue
}
} else if let cachedChannelData = peerView.cachedData as? CachedChannelData {
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 {
autoremoveTimeout = value
autoremoveTimeout = value?.peerValue
}
} else if let cachedUserData = peerView.cachedData as? CachedUserData {
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 {
return
}
guard let peer = strongSelf.presentationInterfaceState.renderedPeer?.peer else {
return
}
if peerId.namespace == Namespaces.Peer.SecretChat {
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
if let strongSelf = self {
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))
}
} else {
strongSelf.chatDisplayNode.dismissInput()
var currentAutoremoveTimeout: Int32? = strongSelf.presentationInterfaceState.autoremoveTimeout
var canSetupAutoremoveTimeout = false
if let peer = strongSelf.presentationInterfaceState.renderedPeer?.peer {
var availableValues: [Int32] = [
60,
300,
86400,
604800
]
#if DEBUG
availableValues.insert(5, at: 0)
#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()
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
}
})
strongSelf.present(controller, in: .window(.root))
} else if let defaultBannedRights = group.defaultBannedRights {
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
@ -7544,6 +7583,10 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
}))
} 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(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
actionSheet?.dismissAnimated()
@ -7559,10 +7602,6 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
})
], 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 {
items.append(ActionSheetTextItem(title: text))
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))
}))
}
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: [
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 {
accessoryItems.append(.messageAutoremoveTimeout(currentAutoremoveTimeout))
if currentAutoremoveTimeout != nil || chatPresentationInterfaceState.renderedPeer?.peer is TelegramSecretChat {
accessoryItems.append(.messageAutoremoveTimeout(currentAutoremoveTimeout))
}
}
switch chatPresentationInterfaceState.inputMode {
@ -283,7 +285,7 @@ func inputTextPanelStateForChatPresentationInterfaceState(_ chatPresentationInte
if !extendedSearchLayout {
if let peer = chatPresentationInterfaceState.renderedPeer?.peer as? TelegramSecretChat {
accessoryItems.append(.messageAutoremoveTimeout(peer.messageAutoremoveTimeout))
} else if canSetupAutoremoveTimeout {
} else if currentAutoremoveTimeout != nil {
accessoryItems.append(.messageAutoremoveTimeout(currentAutoremoveTimeout))
}
}

View File

@ -1235,7 +1235,7 @@ private func editingItems(data: PeerInfoScreenData?, context: AccountContext, pr
if channel.hasPermission(.changeInfo) {
let timeoutString: String
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)
} else {
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
if case let .known(value) = cachedData.autoremoveTimeout {
if let value = value {
if let value = value?.peerValue {
timeoutString = timeIntervalString(strings: presentationData.strings, value: value)
} else {
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: {
interaction.editingOpenAutoremoveMesages()
}))
}
}*/
}
}
@ -1436,11 +1436,11 @@ private func editingItems(data: PeerInfoScreenData?, context: AccountContext, pr
interaction.editingOpenPreHistorySetup()
}))
let canChangeInfo = true
/*let canChangeInfo = true
if canChangeInfo {
let timeoutString: String
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)
} else {
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: {
interaction.editingOpenAutoremoveMesages()
}))
}
}*/
var activePermissionCount: Int?
if let defaultBannedRights = group.defaultBannedRights {
@ -3859,7 +3859,12 @@ private final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewD
}
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() {

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 account.postbox.mediaBox.resourcePath(representation.resource)
}, badge: badge, message: message)
})))
}, updateTimestamp: Int32(Date().timeIntervalSince1970))))
}
}
|> 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 account.postbox.mediaBox.resourcePath(representation.resource)
}, badge: badge, message: message)
})))
}, updateTimestamp: Int32(Date().timeIntervalSince1970))))
}
}
|> distinctUntilChanged

View File

@ -238,10 +238,12 @@ public struct WidgetDataPeer: Codable, Equatable {
public struct WidgetDataPeers: Codable, Equatable {
public var accountPeerId: Int64
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.peers = peers
self.updateTimestamp = updateTimestamp
}
}