mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
Merge branch 'master' into experimental-2
This commit is contained in:
commit
f590511158
@ -1578,7 +1578,7 @@ ios_application(
|
||||
":NotificationContentExtension",
|
||||
":NotificationServiceExtension",
|
||||
":IntentsExtension",
|
||||
# ":WidgetExtension",
|
||||
":WidgetExtension",
|
||||
],
|
||||
}),
|
||||
watch_application = select({
|
||||
|
@ -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
|
||||
|
@ -146,7 +146,7 @@
|
||||
</dict>
|
||||
<dict>
|
||||
<key>INIntentParameterArraySizeSize</key>
|
||||
<integer>8</integer>
|
||||
<integer>2</integer>
|
||||
<key>INIntentParameterArraySizeSizeClass</key>
|
||||
<string>Medium</string>
|
||||
</dict>
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
||||
|
@ -13,6 +13,7 @@
|
||||
|
||||
@property (nonatomic, assign) CGFloat startValue;
|
||||
@property (nonatomic, assign) CGFloat value;
|
||||
@property (nonatomic, assign) int minimumUndottedValue;
|
||||
|
||||
@property (nonatomic, assign) CGFloat markValue;
|
||||
|
||||
|
@ -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)
|
||||
{
|
||||
|
319
submodules/PeerInfoUI/Sources/PeerAutoremoveSetupScreen.swift
Normal file
319
submodules/PeerInfoUI/Sources/PeerAutoremoveSetupScreen.swift
Normal file
@ -0,0 +1,319 @@
|
||||
import Foundation
|
||||
import UIKit
|
||||
import Display
|
||||
import SwiftSignalKit
|
||||
import Postbox
|
||||
import TelegramCore
|
||||
import SyncCore
|
||||
import TelegramPresentationData
|
||||
import ItemListUI
|
||||
import PresentationDataUtils
|
||||
import AccountContext
|
||||
import ChatListFilterSettingsHeaderItem
|
||||
|
||||
private final class PeerAutoremoveSetupArguments {
|
||||
let toggleGlobal: (Bool) -> Void
|
||||
let updateValue: (Int32) -> Void
|
||||
|
||||
init(toggleGlobal: @escaping (Bool) -> Void, updateValue: @escaping (Int32) -> Void) {
|
||||
self.toggleGlobal = toggleGlobal
|
||||
self.updateValue = updateValue
|
||||
}
|
||||
}
|
||||
|
||||
private enum PeerAutoremoveSetupSection: Int32 {
|
||||
case header
|
||||
case time
|
||||
case global
|
||||
}
|
||||
|
||||
private enum PeerAutoremoveSetupEntry: ItemListNodeEntry {
|
||||
case header
|
||||
case timeHeader(String)
|
||||
case timeValue(Int32)
|
||||
case timeComment(String)
|
||||
case globalSwitch(String, Bool)
|
||||
|
||||
var section: ItemListSectionId {
|
||||
switch self {
|
||||
case .header:
|
||||
return PeerAutoremoveSetupSection.header.rawValue
|
||||
case .timeHeader, .timeValue, .timeComment:
|
||||
return PeerAutoremoveSetupSection.time.rawValue
|
||||
case .globalSwitch:
|
||||
return PeerAutoremoveSetupSection.global.rawValue
|
||||
}
|
||||
}
|
||||
|
||||
var stableId: Int32 {
|
||||
switch self {
|
||||
case .header:
|
||||
return 0
|
||||
case .timeHeader:
|
||||
return 1
|
||||
case .timeValue:
|
||||
return 2
|
||||
case .timeComment:
|
||||
return 3
|
||||
case .globalSwitch:
|
||||
return 4
|
||||
}
|
||||
}
|
||||
|
||||
static func ==(lhs: PeerAutoremoveSetupEntry, rhs: PeerAutoremoveSetupEntry) -> Bool {
|
||||
switch lhs {
|
||||
case .header:
|
||||
if case .header = rhs {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
case let .timeHeader(lhsText):
|
||||
if case let .timeHeader(rhsText) = rhs, lhsText == rhsText {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
case let .timeValue(lhsValue):
|
||||
if case let .timeValue(rhsValue) = rhs, lhsValue == rhsValue {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
case let .timeComment(lhsText):
|
||||
if case let .timeComment(rhsText) = rhs, lhsText == rhsText {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
case let .globalSwitch(lhsText, lhsValue):
|
||||
if case let .globalSwitch(rhsText, rhsValue) = rhs, lhsText == rhsText, lhsValue == rhsValue {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static func <(lhs: PeerAutoremoveSetupEntry, rhs: PeerAutoremoveSetupEntry) -> Bool {
|
||||
return lhs.stableId < rhs.stableId
|
||||
}
|
||||
|
||||
func item(presentationData: ItemListPresentationData, arguments: Any) -> ListViewItem {
|
||||
let arguments = arguments as! PeerAutoremoveSetupArguments
|
||||
switch self {
|
||||
case .header:
|
||||
return ChatListFilterSettingsHeaderItem(theme: presentationData.theme, text: "", animation: .autoRemove, sectionId: self.section)
|
||||
case let .timeHeader(text):
|
||||
return ItemListSectionHeaderItem(presentationData: presentationData, text: text, sectionId: self.section)
|
||||
case let .timeValue(value):
|
||||
return PeerRemoveTimeoutItem(theme: presentationData.theme, value: value, maxValue: Int32.max, enabled: true, sectionId: self.section, updated: { value in
|
||||
arguments.updateValue(value)
|
||||
}, tag: nil)
|
||||
case let .timeComment(text):
|
||||
return ItemListTextItem(presentationData: presentationData, text: .plain(text), sectionId: self.section)
|
||||
case let .globalSwitch(text, value):
|
||||
return ItemListSwitchItem(presentationData: presentationData, title: text, value: value, sectionId: self.section, style: .blocks, updated: { value in
|
||||
arguments.toggleGlobal(value)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private struct PeerAutoremoveSetupState: Equatable {
|
||||
var changedValue: Int32?
|
||||
var changedGlobalValue: Bool?
|
||||
var applyingSetting: Bool = false
|
||||
}
|
||||
|
||||
private func peerAutoremoveSetupEntries(peer: Peer?, presentationData: PresentationData, defaultValue: Int32?, defaultGlobalValue: Bool, state: PeerAutoremoveSetupState) -> [PeerAutoremoveSetupEntry] {
|
||||
var entries: [PeerAutoremoveSetupEntry] = []
|
||||
let value = state.changedValue ?? defaultValue
|
||||
let globalValue = state.changedGlobalValue ?? defaultGlobalValue
|
||||
|
||||
//TODO:localize
|
||||
entries.append(.header)
|
||||
entries.append(.timeHeader("AUTO-DELETE MESSAGES"))
|
||||
entries.append(.timeValue(value ?? Int32.max))
|
||||
if let channel = peer as? TelegramChannel, case .broadcast = channel.info {
|
||||
entries.append(.timeComment("Automatically delete messages sent in this channel after a certain period of time."))
|
||||
} else {
|
||||
entries.append(.timeComment("Automatically delete messages sent in this chat after a certain period of time."))
|
||||
}
|
||||
if let user = peer as? TelegramUser {
|
||||
entries.append(.globalSwitch("Also auto-delete for \(user.compactDisplayTitle)", globalValue))
|
||||
}
|
||||
|
||||
return entries
|
||||
}
|
||||
|
||||
public enum PeerAutoremoveSetupScreenResult {
|
||||
case unchanged
|
||||
case updated(Int32?)
|
||||
}
|
||||
|
||||
public func peerAutoremoveSetupScreen(context: AccountContext, peerId: PeerId, completion: @escaping (PeerAutoremoveSetupScreenResult) -> Void = { _ in }) -> ViewController {
|
||||
let statePromise = ValuePromise(PeerAutoremoveSetupState(), ignoreRepeated: true)
|
||||
let stateValue = Atomic(value: PeerAutoremoveSetupState())
|
||||
let updateState: ((PeerAutoremoveSetupState) -> PeerAutoremoveSetupState) -> Void = { f in
|
||||
statePromise.set(stateValue.modify { f($0) })
|
||||
}
|
||||
|
||||
var pushControllerImpl: ((ViewController) -> Void)?
|
||||
var dismissImpl: (() -> Void)?
|
||||
|
||||
let actionsDisposable = DisposableSet()
|
||||
|
||||
let applyDisposable = MetaDisposable()
|
||||
actionsDisposable.add(applyDisposable)
|
||||
|
||||
let arguments = PeerAutoremoveSetupArguments(toggleGlobal: { value in
|
||||
updateState { state in
|
||||
var state = state
|
||||
state.changedGlobalValue = value
|
||||
return state
|
||||
}
|
||||
}, updateValue: { value in
|
||||
updateState { state in
|
||||
var state = state
|
||||
state.changedValue = value
|
||||
return state
|
||||
}
|
||||
})
|
||||
|
||||
let signal = combineLatest(context.sharedContext.presentationData, statePromise.get(), context.account.viewTracker.peerView(peerId))
|
||||
|> deliverOnMainQueue
|
||||
|> map { presentationData, state, view -> (ItemListControllerState, (ItemListNodeState, Any)) in
|
||||
var defaultValue: Int32 = Int32.max
|
||||
var maxValue: Int32 = Int32.max
|
||||
var defaultGlobalValue = true
|
||||
if let cachedData = view.cachedData as? CachedChannelData {
|
||||
if case let .known(value) = cachedData.autoremoveTimeout {
|
||||
defaultValue = value?.myValue ?? Int32.max
|
||||
maxValue = value?.peerValue ?? Int32.max
|
||||
defaultGlobalValue = value?.isGlobal ?? true
|
||||
}
|
||||
} else if let cachedData = view.cachedData as? CachedGroupData {
|
||||
if case let .known(value) = cachedData.autoremoveTimeout {
|
||||
defaultValue = value?.myValue ?? Int32.max
|
||||
maxValue = value?.peerValue ?? Int32.max
|
||||
defaultGlobalValue = value?.isGlobal ?? true
|
||||
}
|
||||
} else if let cachedData = view.cachedData as? CachedUserData {
|
||||
if case let .known(value) = cachedData.autoremoveTimeout {
|
||||
defaultValue = value?.myValue ?? Int32.max
|
||||
maxValue = value?.peerValue ?? Int32.max
|
||||
defaultGlobalValue = value?.isGlobal ?? true
|
||||
}
|
||||
}
|
||||
|
||||
let peer = view.peers[view.peerId]
|
||||
|
||||
let leftNavigationButton = ItemListNavigationButton(content: .text(presentationData.strings.Common_Cancel), style: .regular, enabled: true, action: {
|
||||
dismissImpl?()
|
||||
})
|
||||
var rightNavigationButton: ItemListNavigationButton?
|
||||
if state.applyingSetting {
|
||||
rightNavigationButton = ItemListNavigationButton(content: .none, style: .activity, enabled: true, action: {})
|
||||
} else {
|
||||
rightNavigationButton = ItemListNavigationButton(content: .text(presentationData.strings.Common_Done), style: .bold, enabled: true, action: {
|
||||
var value: Int32?
|
||||
var globalValue: Bool?
|
||||
updateState { state in
|
||||
var state = state
|
||||
state.applyingSetting = true
|
||||
value = state.changedValue
|
||||
globalValue = state.changedGlobalValue
|
||||
return state
|
||||
}
|
||||
var updated = false
|
||||
if let value = value, value != defaultValue {
|
||||
updated = true
|
||||
}
|
||||
if let globalValue = globalValue, globalValue != defaultGlobalValue {
|
||||
updated = true
|
||||
}
|
||||
if updated {
|
||||
let resolvedValue = value ?? defaultValue
|
||||
let resolvedGlobalValue = globalValue ?? defaultGlobalValue
|
||||
|
||||
let signal = setChatMessageAutoremoveTimeoutInteractively(account: context.account, peerId: peerId, timeout: resolvedValue == Int32.max ? nil : resolvedValue, isGlobal: resolvedGlobalValue)
|
||||
|> deliverOnMainQueue
|
||||
|
||||
applyDisposable.set((signal
|
||||
|> deliverOnMainQueue).start(error: { _ in
|
||||
}, completed: {
|
||||
dismissImpl?()
|
||||
if resolvedValue != defaultValue {
|
||||
completion(.updated(resolvedValue))
|
||||
} else {
|
||||
completion(.unchanged)
|
||||
}
|
||||
}))
|
||||
} else {
|
||||
dismissImpl?()
|
||||
completion(.unchanged)
|
||||
}
|
||||
/*if let value = value, value != defaultValue {
|
||||
if peerId.namespace == Namespaces.Peer.CloudGroup {
|
||||
let signal = convertGroupToSupergroup(account: context.account, peerId: peerId)
|
||||
|> mapToSignal { upgradedPeerId -> Signal<PeerId?, ConvertGroupToSupergroupError> in
|
||||
return updateChannelHistoryAvailabilitySettingsInteractively(postbox: context.account.postbox, network: context.account.network, accountStateManager: context.account.stateManager, peerId: upgradedPeerId, historyAvailableForNewMembers: value)
|
||||
|> `catch` { _ -> Signal<Void, NoError> in
|
||||
return .complete()
|
||||
}
|
||||
|> mapToSignal { _ -> Signal<PeerId?, NoError> in
|
||||
return .complete()
|
||||
}
|
||||
|> then(.single(upgradedPeerId))
|
||||
|> castError(ConvertGroupToSupergroupError.self)
|
||||
}
|
||||
|> deliverOnMainQueue
|
||||
applyDisposable.set((signal
|
||||
|> deliverOnMainQueue).start(next: { upgradedPeerId in
|
||||
if let upgradedPeerId = upgradedPeerId {
|
||||
upgradedToSupergroup(upgradedPeerId, {
|
||||
dismissImpl?()
|
||||
})
|
||||
}
|
||||
}, error: { error in
|
||||
switch error {
|
||||
case .tooManyChannels:
|
||||
pushControllerImpl?(oldChannelsController(context: context, intent: .upgrade))
|
||||
default:
|
||||
break
|
||||
}
|
||||
}))
|
||||
} else {
|
||||
applyDisposable.set((updateChannelHistoryAvailabilitySettingsInteractively(postbox: context.account.postbox, network: context.account.network, accountStateManager: context.account.stateManager, peerId: peerId, historyAvailableForNewMembers: value)
|
||||
|> deliverOnMainQueue).start(completed: {
|
||||
dismissImpl?()
|
||||
}))
|
||||
}
|
||||
} else {
|
||||
dismissImpl?()
|
||||
}*/
|
||||
})
|
||||
}
|
||||
|
||||
//TODO:localize
|
||||
let controllerState = ItemListControllerState(presentationData: ItemListPresentationData(presentationData), title: .text("Auto-Deletion"), leftNavigationButton: leftNavigationButton, rightNavigationButton: rightNavigationButton, backNavigationButton: ItemListBackButton(title: presentationData.strings.Common_Back))
|
||||
let listState = ItemListNodeState(presentationData: ItemListPresentationData(presentationData), entries: peerAutoremoveSetupEntries(peer: peer, presentationData: presentationData, defaultValue: defaultValue, defaultGlobalValue: defaultGlobalValue, state: state), style: .blocks)
|
||||
|
||||
return (controllerState, (listState, arguments))
|
||||
}
|
||||
|> afterDisposed {
|
||||
actionsDisposable.dispose()
|
||||
}
|
||||
|
||||
let controller = ItemListController(context: context, state: signal)
|
||||
controller.navigationPresentation = .modal
|
||||
dismissImpl = { [weak controller] in
|
||||
controller?.view.endEditing(true)
|
||||
controller?.dismiss()
|
||||
}
|
||||
pushControllerImpl = { [weak controller] c in
|
||||
controller?.push(c)
|
||||
}
|
||||
return controller
|
||||
}
|
324
submodules/PeerInfoUI/Sources/PeerAutoremoveTimeoutItem.swift
Normal file
324
submodules/PeerInfoUI/Sources/PeerAutoremoveTimeoutItem.swift
Normal file
@ -0,0 +1,324 @@
|
||||
import Foundation
|
||||
import UIKit
|
||||
import Display
|
||||
import AsyncDisplayKit
|
||||
import SwiftSignalKit
|
||||
import TelegramCore
|
||||
import SyncCore
|
||||
import TelegramPresentationData
|
||||
import TelegramUIPreferences
|
||||
import LegacyComponents
|
||||
import ItemListUI
|
||||
import PresentationDataUtils
|
||||
import AppBundle
|
||||
|
||||
class PeerRemoveTimeoutItem: ListViewItem, ItemListItem {
|
||||
let theme: PresentationTheme
|
||||
let value: Int32
|
||||
let maxValue: Int32
|
||||
let enabled: Bool
|
||||
let sectionId: ItemListSectionId
|
||||
let updated: (Int32) -> Void
|
||||
let tag: ItemListItemTag?
|
||||
|
||||
init(theme: PresentationTheme, value: Int32, maxValue: Int32, enabled: Bool = true, sectionId: ItemListSectionId, updated: @escaping (Int32) -> Void, tag: ItemListItemTag? = nil) {
|
||||
self.theme = theme
|
||||
self.value = value
|
||||
self.maxValue = maxValue
|
||||
self.enabled = enabled
|
||||
self.sectionId = sectionId
|
||||
self.updated = updated
|
||||
self.tag = tag
|
||||
}
|
||||
|
||||
func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal<Void, NoError>?, (ListViewItemApply) -> Void)) -> Void) {
|
||||
async {
|
||||
let node = PeerRemoveTimeoutItemNode()
|
||||
let (layout, apply) = node.asyncLayout()(self, params, itemListNeighbors(item: self, topItem: previousItem as? ItemListItem, bottomItem: nextItem as? ItemListItem))
|
||||
|
||||
node.contentSize = layout.contentSize
|
||||
node.insets = layout.insets
|
||||
|
||||
Queue.mainQueue().async {
|
||||
completion(node, {
|
||||
return (nil, { _ in apply() })
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping (ListViewItemApply) -> Void) -> Void) {
|
||||
Queue.mainQueue().async {
|
||||
if let nodeValue = node() as? PeerRemoveTimeoutItemNode {
|
||||
let makeLayout = nodeValue.asyncLayout()
|
||||
|
||||
async {
|
||||
let (layout, apply) = makeLayout(self, params, itemListNeighbors(item: self, topItem: previousItem as? ItemListItem, bottomItem: nextItem as? ItemListItem))
|
||||
Queue.mainQueue().async {
|
||||
completion(layout, { _ in
|
||||
apply()
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func generateKnobImage() -> UIImage? {
|
||||
return generateImage(CGSize(width: 40.0, height: 40.0), rotatedContext: { size, context in
|
||||
context.clear(CGRect(origin: CGPoint(), size: size))
|
||||
context.setShadow(offset: CGSize(width: 0.0, height: -1.0), blur: 3.5, color: UIColor(white: 0.0, alpha: 0.25).cgColor)
|
||||
context.setFillColor(UIColor.white.cgColor)
|
||||
context.fillEllipse(in: CGRect(origin: CGPoint(x: 6.0, y: 6.0), size: CGSize(width: 28.0, height: 28.0)))
|
||||
})
|
||||
}
|
||||
|
||||
class PeerRemoveTimeoutItemNode: ListViewItemNode, ItemListItemNode {
|
||||
private let backgroundNode: ASDisplayNode
|
||||
private let topStripeNode: ASDisplayNode
|
||||
private let bottomStripeNode: ASDisplayNode
|
||||
private let maskNode: ASImageNode
|
||||
|
||||
private var sliderView: TGPhotoEditorSliderView?
|
||||
private let titleNodes: [TextNode]
|
||||
private let disabledOverlayNode: ASDisplayNode
|
||||
|
||||
private var item: PeerRemoveTimeoutItem?
|
||||
private var layoutParams: ListViewItemLayoutParams?
|
||||
|
||||
var tag: ItemListItemTag? {
|
||||
return self.item?.tag
|
||||
}
|
||||
|
||||
init() {
|
||||
self.backgroundNode = ASDisplayNode()
|
||||
self.backgroundNode.isLayerBacked = true
|
||||
|
||||
self.topStripeNode = ASDisplayNode()
|
||||
self.topStripeNode.isLayerBacked = true
|
||||
|
||||
self.bottomStripeNode = ASDisplayNode()
|
||||
self.bottomStripeNode.isLayerBacked = true
|
||||
|
||||
self.maskNode = ASImageNode()
|
||||
|
||||
self.disabledOverlayNode = ASDisplayNode()
|
||||
|
||||
self.titleNodes = (0 ..< 3).map { _ in
|
||||
return TextNode()
|
||||
}
|
||||
|
||||
super.init(layerBacked: false, dynamicBounce: false)
|
||||
|
||||
self.titleNodes.forEach(self.addSubnode)
|
||||
|
||||
self.addSubnode(self.disabledOverlayNode)
|
||||
}
|
||||
|
||||
override func didLoad() {
|
||||
super.didLoad()
|
||||
|
||||
let sliderView = TGPhotoEditorSliderView()
|
||||
sliderView.enablePanHandling = true
|
||||
sliderView.trackCornerRadius = 1.0
|
||||
sliderView.lineSize = 2.0
|
||||
sliderView.dotSize = 5.0
|
||||
sliderView.minimumValue = 0.0
|
||||
sliderView.maximumValue = 2.0
|
||||
sliderView.startValue = 0.0
|
||||
sliderView.positionsCount = 3
|
||||
sliderView.useLinesForPositions = true
|
||||
sliderView.minimumUndottedValue = 2
|
||||
sliderView.disablesInteractiveTransitionGestureRecognizer = true
|
||||
if let item = self.item, let params = self.layoutParams {
|
||||
sliderView.isUserInteractionEnabled = item.enabled
|
||||
|
||||
let value: CGFloat
|
||||
switch item.value {
|
||||
case 24 * 60 * 60:
|
||||
value = 0.0
|
||||
case 7 * 24 * 60 * 60:
|
||||
value = 1.0
|
||||
default:
|
||||
value = 2.0
|
||||
}
|
||||
sliderView.value = value
|
||||
sliderView.backgroundColor = item.theme.list.itemBlocksBackgroundColor
|
||||
sliderView.backColor = item.theme.list.disclosureArrowColor
|
||||
sliderView.trackColor = item.enabled ? item.theme.list.itemAccentColor : item.theme.list.itemDisabledTextColor
|
||||
sliderView.knobImage = generateKnobImage()
|
||||
|
||||
let sliderInset: CGFloat = params.leftInset + 16.0
|
||||
|
||||
sliderView.frame = CGRect(origin: CGPoint(x: params.leftInset + sliderInset, y: 38.0), size: CGSize(width: params.width - params.leftInset - params.rightInset - sliderInset * 2.0, height: 44.0))
|
||||
}
|
||||
self.view.insertSubview(sliderView, belowSubview: self.disabledOverlayNode.view)
|
||||
sliderView.addTarget(self, action: #selector(self.sliderValueChanged), for: .valueChanged)
|
||||
self.sliderView = sliderView
|
||||
}
|
||||
|
||||
func asyncLayout() -> (_ item: PeerRemoveTimeoutItem, _ params: ListViewItemLayoutParams, _ neighbors: ItemListNeighbors) -> (ListViewItemNodeLayout, () -> Void) {
|
||||
let currentItem = self.item
|
||||
|
||||
let makeTitleNodeLayouts = self.titleNodes.map(TextNode.asyncLayout)
|
||||
|
||||
return { item, params, neighbors in
|
||||
var themeUpdated = false
|
||||
if currentItem?.theme !== item.theme {
|
||||
themeUpdated = true
|
||||
}
|
||||
|
||||
let contentSize: CGSize
|
||||
var insets: UIEdgeInsets
|
||||
let separatorHeight = UIScreenPixel
|
||||
|
||||
let titleLayouts = zip(0 ..< makeTitleNodeLayouts.count, makeTitleNodeLayouts).map { index, makeLayout -> (TextNodeLayout, () -> TextNode) in
|
||||
let text: String
|
||||
//TODO:localize
|
||||
switch index {
|
||||
case 0:
|
||||
text = "After 24 hours"
|
||||
case 1:
|
||||
text = "After 7 days"
|
||||
default:
|
||||
text = "Never"
|
||||
}
|
||||
return makeLayout(TextNodeLayoutArguments(attributedString: NSAttributedString(string: text, font: Font.regular(13.0), textColor: item.theme.list.itemSecondaryTextColor), maximumNumberOfLines: 1, truncationType: .end, constrainedSize: CGSize(width: 100.0, height: 100.0)))
|
||||
}
|
||||
|
||||
contentSize = CGSize(width: params.width, height: 88.0)
|
||||
insets = itemListNeighborsGroupedInsets(neighbors)
|
||||
|
||||
let layout = ListViewItemNodeLayout(contentSize: contentSize, insets: insets)
|
||||
let layoutSize = layout.size
|
||||
|
||||
return (layout, { [weak self] in
|
||||
if let strongSelf = self {
|
||||
let firstTime = strongSelf.item == nil
|
||||
strongSelf.item = item
|
||||
strongSelf.layoutParams = params
|
||||
|
||||
let leftInset = 16.0 + params.leftInset
|
||||
|
||||
strongSelf.backgroundNode.backgroundColor = item.theme.list.itemBlocksBackgroundColor
|
||||
strongSelf.topStripeNode.backgroundColor = item.theme.list.itemBlocksSeparatorColor
|
||||
strongSelf.bottomStripeNode.backgroundColor = item.theme.list.itemBlocksSeparatorColor
|
||||
|
||||
strongSelf.disabledOverlayNode.backgroundColor = item.theme.list.itemBlocksBackgroundColor.withAlphaComponent(0.4)
|
||||
strongSelf.disabledOverlayNode.isHidden = item.enabled
|
||||
strongSelf.disabledOverlayNode.frame = CGRect(origin: CGPoint(x: params.leftInset, y: 8.0), size: CGSize(width: params.width - params.leftInset - params.rightInset, height: 44.0))
|
||||
|
||||
if strongSelf.backgroundNode.supernode == nil {
|
||||
strongSelf.insertSubnode(strongSelf.backgroundNode, at: 0)
|
||||
}
|
||||
if strongSelf.topStripeNode.supernode == nil {
|
||||
strongSelf.insertSubnode(strongSelf.topStripeNode, at: 1)
|
||||
}
|
||||
if strongSelf.bottomStripeNode.supernode == nil {
|
||||
strongSelf.insertSubnode(strongSelf.bottomStripeNode, at: 2)
|
||||
}
|
||||
if strongSelf.maskNode.supernode == nil {
|
||||
strongSelf.insertSubnode(strongSelf.maskNode, at: 3)
|
||||
}
|
||||
|
||||
let hasCorners = itemListHasRoundedBlockLayout(params)
|
||||
var hasTopCorners = false
|
||||
var hasBottomCorners = false
|
||||
switch neighbors.top {
|
||||
case .sameSection(false):
|
||||
strongSelf.topStripeNode.isHidden = true
|
||||
default:
|
||||
hasTopCorners = true
|
||||
strongSelf.topStripeNode.isHidden = hasCorners
|
||||
}
|
||||
let bottomStripeInset: CGFloat
|
||||
let bottomStripeOffset: CGFloat
|
||||
switch neighbors.bottom {
|
||||
case .sameSection(false):
|
||||
bottomStripeInset = params.leftInset + 16.0
|
||||
bottomStripeOffset = -separatorHeight
|
||||
default:
|
||||
bottomStripeInset = 0.0
|
||||
bottomStripeOffset = 0.0
|
||||
hasBottomCorners = true
|
||||
strongSelf.bottomStripeNode.isHidden = hasCorners
|
||||
}
|
||||
|
||||
strongSelf.maskNode.image = hasCorners ? PresentationResourcesItemList.cornersImage(item.theme, top: hasTopCorners, bottom: hasBottomCorners) : nil
|
||||
|
||||
strongSelf.backgroundNode.frame = CGRect(origin: CGPoint(x: 0.0, y: -min(insets.top, separatorHeight)), size: CGSize(width: params.width, height: contentSize.height + min(insets.top, separatorHeight) + min(insets.bottom, separatorHeight)))
|
||||
strongSelf.maskNode.frame = strongSelf.backgroundNode.frame.insetBy(dx: params.leftInset, dy: 0.0)
|
||||
strongSelf.topStripeNode.frame = CGRect(origin: CGPoint(x: 0.0, y: -min(insets.top, separatorHeight)), size: CGSize(width: layoutSize.width, height: separatorHeight))
|
||||
strongSelf.bottomStripeNode.frame = CGRect(origin: CGPoint(x: bottomStripeInset, y: contentSize.height + bottomStripeOffset), size: CGSize(width: layoutSize.width - bottomStripeInset, height: separatorHeight))
|
||||
|
||||
zip(0 ..< titleLayouts.count, titleLayouts).forEach { index, layoutAndApply in
|
||||
let textNode = layoutAndApply.1()
|
||||
|
||||
let size = layoutAndApply.0.size
|
||||
switch index {
|
||||
case 0:
|
||||
textNode.frame = CGRect(origin: CGPoint(x: leftInset, y: 13.0), size: size)
|
||||
case 1:
|
||||
textNode.frame = CGRect(origin: CGPoint(x: floor((params.width - size.width) / 2.0), y: 13.0), size: size)
|
||||
default:
|
||||
textNode.frame = CGRect(origin: CGPoint(x: params.width - size.width - 16.0, y: 13.0), size: size)
|
||||
}
|
||||
}
|
||||
|
||||
if let sliderView = strongSelf.sliderView {
|
||||
sliderView.isUserInteractionEnabled = item.enabled
|
||||
sliderView.trackColor = item.enabled ? item.theme.list.itemAccentColor : item.theme.list.itemDisabledTextColor
|
||||
|
||||
if themeUpdated {
|
||||
sliderView.backgroundColor = item.theme.list.itemBlocksBackgroundColor
|
||||
sliderView.backColor = item.theme.list.disclosureArrowColor
|
||||
sliderView.knobImage = generateKnobImage()
|
||||
}
|
||||
|
||||
let value: CGFloat
|
||||
switch item.value {
|
||||
case 24 * 60 * 60:
|
||||
value = 0.0
|
||||
case 7 * 24 * 60 * 60:
|
||||
value = 1.0
|
||||
default:
|
||||
value = 2.0
|
||||
}
|
||||
if firstTime {
|
||||
sliderView.value = value
|
||||
}
|
||||
|
||||
let sliderInset: CGFloat = leftInset
|
||||
sliderView.frame = CGRect(origin: CGPoint(x: params.leftInset + sliderInset, y: 38.0), size: CGSize(width: params.width - params.leftInset - params.rightInset - sliderInset * 2.0, height: 44.0))
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
override func animateInsertion(_ currentTimestamp: Double, duration: Double, short: Bool) {
|
||||
self.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.4)
|
||||
}
|
||||
|
||||
override func animateRemoved(_ currentTimestamp: Double, duration: Double) {
|
||||
self.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.15, removeOnCompletion: false)
|
||||
}
|
||||
|
||||
@objc func sliderValueChanged() {
|
||||
guard let sliderView = self.sliderView else {
|
||||
return
|
||||
}
|
||||
let value: Int32
|
||||
switch sliderView.value {
|
||||
case 0.0:
|
||||
value = 24 * 60 * 60
|
||||
case 1.0:
|
||||
value = 7 * 24 * 60 * 60
|
||||
default:
|
||||
value = Int32.max
|
||||
}
|
||||
self.item?.updated(value)
|
||||
}
|
||||
}
|
||||
|
@ -429,15 +429,7 @@ public final class CachedChannelData: CachedPeerData {
|
||||
self.slowModeTimeout = decoder.decodeOptionalInt32ForKey("smt")
|
||||
self.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 {
|
||||
|
@ -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")
|
||||
|
@ -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 {
|
||||
|
@ -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:
|
||||
|
@ -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 {
|
||||
|
@ -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>) {
|
||||
|
@ -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 {
|
||||
|
@ -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 {
|
||||
|
@ -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()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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))
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
BIN
submodules/TelegramUI/Resources/Animations/MessageAutoRemove.tgs
Normal file
BIN
submodules/TelegramUI/Resources/Animations/MessageAutoRemove.tgs
Normal file
Binary file not shown.
@ -2876,7 +2876,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
hasBots = true
|
||||
}
|
||||
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
|
||||
|
@ -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))
|
||||
}
|
||||
}
|
||||
|
@ -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() {
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user