mirror of
https://github.com/TelegramMessenger/Telegram-iOS.git
synced 2026-07-05 19:28:46 +02:00
Peer sound and message removal update
This commit is contained in:
parent
0e55dd7db7
commit
235302c7c4
63 changed files with 3906 additions and 1934 deletions
|
|
@ -7419,3 +7419,9 @@ Sorry for the inconvenience.";
|
|||
|
||||
"WebApp.MessagePreview" = "Message Preview";
|
||||
"WebApp.Send" = "Send";
|
||||
|
||||
"Notifications.SystemTones" = "SYSTEM TONES";
|
||||
"Notifications.TelegramTones" = "TELEGRAM TONES";
|
||||
|
||||
"Notifications.UploadSound" = "Upload Sound";
|
||||
"Notifications.MessageSoundInfo" = "Long tap on any short voice note or mp3 file in chat\nand select \"Save for Notifications\". It will appear here.";
|
||||
|
|
|
|||
|
|
@ -464,6 +464,8 @@ final class AttachmentPanel: ASDisplayNode, UIScrollViewDelegate {
|
|||
}, openSendAsPeer: { _, _ in
|
||||
}, presentChatRequestAdminInfo: {
|
||||
}, displayCopyProtectionTip: { _, _ in
|
||||
}, chatController: {
|
||||
return nil
|
||||
}, statuses: nil)
|
||||
|
||||
self.presentationDataDisposable = ((updatedPresentationData?.signal ?? context.sharedContext.presentationData)
|
||||
|
|
|
|||
|
|
@ -142,6 +142,7 @@ public final class ChatPanelInterfaceInteraction {
|
|||
public let openSendAsPeer: (ASDisplayNode, ContextGesture?) -> Void
|
||||
public let presentChatRequestAdminInfo: () -> Void
|
||||
public let displayCopyProtectionTip: (ASDisplayNode, Bool) -> Void
|
||||
public let chatController: () -> ViewController?
|
||||
public let statuses: ChatPanelInterfaceInteractionStatuses?
|
||||
|
||||
public init(
|
||||
|
|
@ -233,6 +234,7 @@ public final class ChatPanelInterfaceInteraction {
|
|||
openSendAsPeer: @escaping (ASDisplayNode, ContextGesture?) -> Void,
|
||||
presentChatRequestAdminInfo: @escaping () -> Void,
|
||||
displayCopyProtectionTip: @escaping (ASDisplayNode, Bool) -> Void,
|
||||
chatController: @escaping () -> ViewController?,
|
||||
statuses: ChatPanelInterfaceInteractionStatuses?
|
||||
) {
|
||||
self.setupReplyMessage = setupReplyMessage
|
||||
|
|
@ -323,6 +325,7 @@ public final class ChatPanelInterfaceInteraction {
|
|||
self.openSendAsPeer = openSendAsPeer
|
||||
self.presentChatRequestAdminInfo = presentChatRequestAdminInfo
|
||||
self.displayCopyProtectionTip = displayCopyProtectionTip
|
||||
self.chatController = chatController
|
||||
self.statuses = statuses
|
||||
}
|
||||
|
||||
|
|
@ -420,6 +423,8 @@ public final class ChatPanelInterfaceInteraction {
|
|||
}, openSendAsPeer: { _, _ in
|
||||
}, presentChatRequestAdminInfo: {
|
||||
}, displayCopyProtectionTip: { _, _ in
|
||||
}, chatController: {
|
||||
return nil
|
||||
}, statuses: nil)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -94,6 +94,8 @@ private final class ContextControllerActionsListActionItemNode: HighlightTrackin
|
|||
self.addSubnode(self.subtitleNode)
|
||||
self.addSubnode(self.iconNode)
|
||||
|
||||
self.isEnabled = self.canBeHighlighted()
|
||||
|
||||
self.highligthedChanged = { [weak self] highlighted in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
|
|
@ -135,7 +137,7 @@ private final class ContextControllerActionsListActionItemNode: HighlightTrackin
|
|||
}
|
||||
|
||||
func canBeHighlighted() -> Bool {
|
||||
return true
|
||||
return self.item.action != nil
|
||||
}
|
||||
|
||||
func updateIsHighlighted(isHighlighted: Bool) {
|
||||
|
|
|
|||
|
|
@ -225,7 +225,12 @@ final class ContextControllerExtractedPresentationNode: ASDisplayNode, ContextCo
|
|||
}
|
||||
|
||||
private func getActionsStackPositionLock() -> CGFloat? {
|
||||
return self.actionsStackNode.view.convert(CGPoint(), to: self.view).y
|
||||
switch self.source {
|
||||
case .reference:
|
||||
return nil
|
||||
case .extracted:
|
||||
return self.actionsStackNode.view.convert(CGPoint(), to: self.view).y
|
||||
}
|
||||
}
|
||||
|
||||
func update(
|
||||
|
|
|
|||
|
|
@ -16,9 +16,15 @@ public enum ItemListCheckboxItemColor {
|
|||
}
|
||||
|
||||
public class ItemListCheckboxItem: ListViewItem, ItemListItem {
|
||||
public enum IconPlacement {
|
||||
case `default`
|
||||
case check
|
||||
}
|
||||
|
||||
let presentationData: ItemListPresentationData
|
||||
let icon: UIImage?
|
||||
let iconSize: CGSize?
|
||||
let iconPlacement: IconPlacement
|
||||
let title: String
|
||||
let style: ItemListCheckboxItemStyle
|
||||
let color: ItemListCheckboxItemColor
|
||||
|
|
@ -27,10 +33,11 @@ public class ItemListCheckboxItem: ListViewItem, ItemListItem {
|
|||
public let sectionId: ItemListSectionId
|
||||
let action: () -> Void
|
||||
|
||||
public init(presentationData: ItemListPresentationData, icon: UIImage? = nil, iconSize: CGSize? = nil, title: String, style: ItemListCheckboxItemStyle, color: ItemListCheckboxItemColor = .accent, checked: Bool, zeroSeparatorInsets: Bool, sectionId: ItemListSectionId, action: @escaping () -> Void) {
|
||||
public init(presentationData: ItemListPresentationData, icon: UIImage? = nil, iconSize: CGSize? = nil, iconPlacement: IconPlacement = .default, title: String, style: ItemListCheckboxItemStyle, color: ItemListCheckboxItemColor = .accent, checked: Bool, zeroSeparatorInsets: Bool, sectionId: ItemListSectionId, action: @escaping () -> Void) {
|
||||
self.presentationData = presentationData
|
||||
self.icon = icon
|
||||
self.iconSize = iconSize
|
||||
self.iconPlacement = iconPlacement
|
||||
self.title = title
|
||||
self.style = style
|
||||
self.color = color
|
||||
|
|
@ -158,7 +165,12 @@ public class ItemListCheckboxItemNode: ListViewItemNode {
|
|||
|
||||
let iconInset: CGFloat = 44.0
|
||||
if item.icon != nil {
|
||||
leftInset += iconInset
|
||||
switch item.iconPlacement {
|
||||
case .default:
|
||||
leftInset += iconInset
|
||||
case .check:
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
let titleFont = Font.regular(item.presentationData.fontSize.itemListBaseFontSize)
|
||||
|
|
@ -273,7 +285,15 @@ public class ItemListCheckboxItemNode: ListViewItemNode {
|
|||
if let icon = item.icon {
|
||||
let iconSize = item.iconSize ?? icon.size
|
||||
strongSelf.imageNode.image = icon
|
||||
strongSelf.imageNode.frame = CGRect(origin: CGPoint(x: params.leftInset + floor((leftInset - params.leftInset - iconSize.width) / 2.0), y: floor((layout.contentSize.height - iconSize.height) / 2.0)), size: iconSize)
|
||||
|
||||
let iconFrame: CGRect
|
||||
switch item.iconPlacement {
|
||||
case .default:
|
||||
iconFrame = CGRect(origin: CGPoint(x: params.leftInset + floor((leftInset - params.leftInset - iconSize.width) / 2.0), y: floor((layout.contentSize.height - iconSize.height) / 2.0)), size: iconSize)
|
||||
case .check:
|
||||
iconFrame = CGRect(origin: CGPoint(x: params.leftInset + floor((leftInset - params.leftInset - iconSize.width) / 2.0), y: floor((contentSize.height - iconSize.height) / 2.0)), size: iconSize)
|
||||
}
|
||||
strongSelf.imageNode.frame = iconFrame
|
||||
}
|
||||
|
||||
strongSelf.highlightedBackgroundNode.frame = CGRect(origin: CGPoint(x: 0.0, y: -UIScreenPixel), size: CGSize(width: params.width, height: strongSelf.backgroundNode.frame.height + UIScreenPixel + UIScreenPixel))
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ public struct NotificationSoundSettings {
|
|||
}
|
||||
}
|
||||
|
||||
public func notificationMuteSettingsController(presentationData: PresentationData, notificationSettings: MessageNotificationSettings, soundSettings: NotificationSoundSettings?, openSoundSettings: @escaping () -> Void, updateSettings: @escaping (Int32?) -> Void) -> ViewController {
|
||||
public func notificationMuteSettingsController(presentationData: PresentationData, notificationSoundList: NotificationSoundList?, notificationSettings: MessageNotificationSettings, soundSettings: NotificationSoundSettings?, openSoundSettings: @escaping () -> Void, updateSettings: @escaping (Int32?) -> Void) -> ViewController {
|
||||
let controller = ActionSheetController(presentationData: presentationData)
|
||||
let dismissAction: () -> Void = { [weak controller] in
|
||||
controller?.dismissAnimated()
|
||||
|
|
@ -81,7 +81,7 @@ public func notificationMuteSettingsController(presentationData: PresentationDat
|
|||
items.append(item)
|
||||
}
|
||||
if let soundSettings = soundSettings {
|
||||
items.append(ActionSheetButtonItem(title: soundSettings.value.flatMap({ presentationData.strings.Notification_Exceptions_Sound(localizedPeerNotificationSoundString(strings: presentationData.strings, sound: $0)).string }) ?? presentationData.strings.GroupInfo_SetSound, action: {
|
||||
items.append(ActionSheetButtonItem(title: soundSettings.value.flatMap({ presentationData.strings.Notification_Exceptions_Sound(localizedPeerNotificationSoundString(strings: presentationData.strings, notificationSoundList: notificationSoundList, sound: $0)).string }) ?? presentationData.strings.GroupInfo_SetSound, action: {
|
||||
dismissAction()
|
||||
openSoundSettings()
|
||||
}))
|
||||
|
|
|
|||
|
|
@ -19,6 +19,8 @@ swift_library(
|
|||
"//submodules/AccountContext:AccountContext",
|
||||
"//submodules/TelegramStringFormatting:TelegramStringFormatting",
|
||||
"//submodules/PresentationDataUtils:PresentationDataUtils",
|
||||
"//submodules/LegacyMediaPickerUI:LegacyMediaPickerUI",
|
||||
"//submodules/UndoUI:UndoUI",
|
||||
],
|
||||
visibility = [
|
||||
"//visibility:public",
|
||||
|
|
|
|||
|
|
@ -10,6 +10,9 @@ import PresentationDataUtils
|
|||
import AccountContext
|
||||
import TelegramStringFormatting
|
||||
import AppBundle
|
||||
import LegacyMediaPickerUI
|
||||
import AVFoundation
|
||||
import UndoUI
|
||||
|
||||
private struct NotificationSoundSelectionArguments {
|
||||
let account: Account
|
||||
|
|
@ -17,22 +20,24 @@ private struct NotificationSoundSelectionArguments {
|
|||
let selectSound: (PeerMessageSound) -> Void
|
||||
let complete: () -> Void
|
||||
let cancel: () -> Void
|
||||
let upload: () -> Void
|
||||
}
|
||||
|
||||
private enum NotificationSoundSelectionSection: Int32 {
|
||||
case cloud
|
||||
case modern
|
||||
case classic
|
||||
}
|
||||
|
||||
private struct NotificationSoundSelectionState: Equatable {
|
||||
let selectedSound: PeerMessageSound
|
||||
|
||||
static func ==(lhs: NotificationSoundSelectionState, rhs: NotificationSoundSelectionState) -> Bool {
|
||||
return lhs.selectedSound == rhs.selectedSound
|
||||
}
|
||||
var selectedSound: PeerMessageSound
|
||||
}
|
||||
|
||||
private enum NotificationSoundSelectionEntry: ItemListNodeEntry {
|
||||
case cloudHeader(String)
|
||||
case uploadSound(String)
|
||||
case cloudInfo(String)
|
||||
|
||||
case modernHeader(PresentationTheme, String)
|
||||
case classicHeader(PresentationTheme, String)
|
||||
case none(section: NotificationSoundSelectionSection, theme: PresentationTheme, text: String, selected: Bool)
|
||||
|
|
@ -41,6 +46,8 @@ private enum NotificationSoundSelectionEntry: ItemListNodeEntry {
|
|||
|
||||
var section: ItemListSectionId {
|
||||
switch self {
|
||||
case .cloudHeader, .uploadSound, .cloudInfo:
|
||||
return NotificationSoundSelectionSection.cloud.rawValue
|
||||
case .modernHeader:
|
||||
return NotificationSoundSelectionSection.modern.rawValue
|
||||
case .classicHeader:
|
||||
|
|
@ -54,68 +61,102 @@ private enum NotificationSoundSelectionEntry: ItemListNodeEntry {
|
|||
}
|
||||
}
|
||||
|
||||
var stableId: Int32 {
|
||||
var sortId: Int32 {
|
||||
switch self {
|
||||
case .modernHeader:
|
||||
return 0
|
||||
case .classicHeader:
|
||||
return 1000
|
||||
case let .none(section, _, _, _):
|
||||
switch section {
|
||||
case .modern:
|
||||
return 2
|
||||
case .classic:
|
||||
return 1001
|
||||
}
|
||||
case let .default(section, _, _, _):
|
||||
switch section {
|
||||
case .modern:
|
||||
return 1
|
||||
case .classic:
|
||||
return 1002
|
||||
}
|
||||
case let .sound(section, index, _, _, _, _):
|
||||
switch section {
|
||||
case .modern:
|
||||
return 3 + index
|
||||
case .classic:
|
||||
return 1003 + index
|
||||
}
|
||||
case .cloudHeader:
|
||||
return 0
|
||||
case .uploadSound:
|
||||
return 998
|
||||
case .cloudInfo:
|
||||
return 999
|
||||
case .modernHeader:
|
||||
return 1000
|
||||
case .classicHeader:
|
||||
return 2000
|
||||
case let .none(section, _, _, _):
|
||||
switch section {
|
||||
case .cloud:
|
||||
return 1
|
||||
case .modern:
|
||||
return 1001
|
||||
case .classic:
|
||||
return 2001
|
||||
}
|
||||
case let .default(section, _, _, _):
|
||||
switch section {
|
||||
case .cloud:
|
||||
return 2
|
||||
case .modern:
|
||||
return 1002
|
||||
case .classic:
|
||||
return 2002
|
||||
}
|
||||
case let .sound(section, index, _, _, _, _):
|
||||
switch section {
|
||||
case .cloud:
|
||||
return 3 + index
|
||||
case .modern:
|
||||
return 1003 + index
|
||||
case .classic:
|
||||
return 2003 + index
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var stableId: Int32 {
|
||||
return self.sortId
|
||||
}
|
||||
|
||||
static func ==(lhs: NotificationSoundSelectionEntry, rhs: NotificationSoundSelectionEntry) -> Bool {
|
||||
switch lhs {
|
||||
case let .modernHeader(lhsTheme, lhsText):
|
||||
if case let .modernHeader(rhsTheme, rhsText) = rhs, lhsTheme === rhsTheme, lhsText == rhsText {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
case let .classicHeader(lhsTheme, lhsText):
|
||||
if case let .classicHeader(rhsTheme, rhsText) = rhs, lhsTheme === rhsTheme, lhsText == rhsText {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
case let .none(lhsSection, lhsTheme, lhsText, lhsSelected):
|
||||
if case let .none(rhsSection, rhsTheme, rhsText, rhsSelected) = rhs, lhsSection == rhsSection, lhsTheme === rhsTheme, lhsText == rhsText, lhsSelected == rhsSelected {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
case let .default(lhsSection, lhsTheme, lhsText, lhsSelected):
|
||||
if case let .default(rhsSection, rhsTheme, rhsText, rhsSelected) = rhs, lhsSection == rhsSection, lhsTheme === rhsTheme, lhsText == rhsText, lhsSelected == rhsSelected {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
case let .sound(lhsSection, lhsIndex, lhsTheme, lhsText, lhsSound, lhsSelected):
|
||||
if case let .sound(rhsSection, rhsIndex, rhsTheme, rhsText, rhsSound, rhsSelected) = rhs, lhsSection == rhsSection, lhsIndex == rhsIndex, lhsTheme === rhsTheme, lhsText == rhsText, lhsSound == rhsSound, lhsSelected == rhsSelected {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
case let .cloudHeader(text):
|
||||
if case .cloudHeader(text) = rhs {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
case let .cloudInfo(text):
|
||||
if case .cloudInfo(text) = rhs {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
case let .uploadSound(text):
|
||||
if case .uploadSound(text) = rhs {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
case let .modernHeader(lhsTheme, lhsText):
|
||||
if case let .modernHeader(rhsTheme, rhsText) = rhs, lhsTheme === rhsTheme, lhsText == rhsText {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
case let .classicHeader(lhsTheme, lhsText):
|
||||
if case let .classicHeader(rhsTheme, rhsText) = rhs, lhsTheme === rhsTheme, lhsText == rhsText {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
case let .none(lhsSection, lhsTheme, lhsText, lhsSelected):
|
||||
if case let .none(rhsSection, rhsTheme, rhsText, rhsSelected) = rhs, lhsSection == rhsSection, lhsTheme === rhsTheme, lhsText == rhsText, lhsSelected == rhsSelected {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
case let .default(lhsSection, lhsTheme, lhsText, lhsSelected):
|
||||
if case let .default(rhsSection, rhsTheme, rhsText, rhsSelected) = rhs, lhsSection == rhsSection, lhsTheme === rhsTheme, lhsText == rhsText, lhsSelected == rhsSelected {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
case let .sound(lhsSection, lhsIndex, lhsTheme, lhsText, lhsSound, lhsSelected):
|
||||
if case let .sound(rhsSection, rhsIndex, rhsTheme, rhsText, rhsSound, rhsSelected) = rhs, lhsSection == rhsSection, lhsIndex == rhsIndex, lhsTheme === rhsTheme, lhsText == rhsText, lhsSound == rhsSound, lhsSelected == rhsSelected {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -126,43 +167,63 @@ private enum NotificationSoundSelectionEntry: ItemListNodeEntry {
|
|||
func item(presentationData: ItemListPresentationData, arguments: Any) -> ListViewItem {
|
||||
let arguments = arguments as! NotificationSoundSelectionArguments
|
||||
switch self {
|
||||
case let.modernHeader(_, text):
|
||||
return ItemListSectionHeaderItem(presentationData: presentationData, text: text, sectionId: self.section)
|
||||
case let .classicHeader(_, text):
|
||||
return ItemListSectionHeaderItem(presentationData: presentationData, text: text, sectionId: self.section)
|
||||
case let .none(_, _, text, selected):
|
||||
return ItemListCheckboxItem(presentationData: presentationData, title: text, style: .left, checked: selected, zeroSeparatorInsets: true, sectionId: self.section, action: {
|
||||
arguments.selectSound(.none)
|
||||
})
|
||||
case let .default(_, _, text, selected):
|
||||
return ItemListCheckboxItem(presentationData: presentationData, title: text, style: .left, checked: selected, zeroSeparatorInsets: false, sectionId: self.section, action: {
|
||||
arguments.selectSound(.default)
|
||||
})
|
||||
case let .sound(_, _, _, text, sound, selected):
|
||||
return ItemListCheckboxItem(presentationData: presentationData, title: text, style: .left, checked: selected, zeroSeparatorInsets: false, sectionId: self.section, action: {
|
||||
arguments.selectSound(sound)
|
||||
})
|
||||
case let .cloudHeader(text):
|
||||
return ItemListSectionHeaderItem(presentationData: presentationData, text: text, sectionId: self.section)
|
||||
case let .uploadSound(text):
|
||||
let icon = PresentationResourcesItemList.uploadToneIcon(presentationData.theme)
|
||||
return ItemListCheckboxItem(presentationData: presentationData, icon: icon, iconSize: nil, iconPlacement: .check, title: text, style: .left, checked: false, zeroSeparatorInsets: false, sectionId: self.section, action: {
|
||||
arguments.upload()
|
||||
})
|
||||
case let .cloudInfo(text):
|
||||
return ItemListTextItem(presentationData: presentationData, text: .plain(text), sectionId: self.section)
|
||||
case let .modernHeader(_, text):
|
||||
return ItemListSectionHeaderItem(presentationData: presentationData, text: text, sectionId: self.section)
|
||||
case let .classicHeader(_, text):
|
||||
return ItemListSectionHeaderItem(presentationData: presentationData, text: text, sectionId: self.section)
|
||||
case let .none(_, _, text, selected):
|
||||
return ItemListCheckboxItem(presentationData: presentationData, title: text, style: .left, checked: selected, zeroSeparatorInsets: true, sectionId: self.section, action: {
|
||||
arguments.selectSound(.none)
|
||||
})
|
||||
case let .default(_, _, text, selected):
|
||||
return ItemListCheckboxItem(presentationData: presentationData, title: text, style: .left, checked: selected, zeroSeparatorInsets: false, sectionId: self.section, action: {
|
||||
arguments.selectSound(.default)
|
||||
})
|
||||
case let .sound(_, _, _, text, sound, selected):
|
||||
return ItemListCheckboxItem(presentationData: presentationData, title: text, style: .left, checked: selected, zeroSeparatorInsets: false, sectionId: self.section, action: {
|
||||
arguments.selectSound(sound)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func notificationsAndSoundsEntries(presentationData: PresentationData, defaultSound: PeerMessageSound?, state: NotificationSoundSelectionState) -> [NotificationSoundSelectionEntry] {
|
||||
private func notificationsAndSoundsEntries(presentationData: PresentationData, defaultSound: PeerMessageSound?, state: NotificationSoundSelectionState, notificationSoundList: NotificationSoundList?) -> [NotificationSoundSelectionEntry] {
|
||||
var entries: [NotificationSoundSelectionEntry] = []
|
||||
|
||||
entries.append(.cloudHeader(presentationData.strings.Notifications_TelegramTones))
|
||||
//entries.append(.none(section: .cloud, theme: presentationData.theme, text: localizedPeerNotificationSoundString(strings: presentationData.strings, notificationSoundList: notificationSoundList, sound: .none), selected: state.selectedSound == .none))
|
||||
if let notificationSoundList = notificationSoundList {
|
||||
for listSound in notificationSoundList.sounds {
|
||||
let sound: PeerMessageSound = .cloud(fileId: listSound.file.fileId.id)
|
||||
entries.append(.sound(section: .cloud, index: Int32(entries.count), theme: presentationData.theme, text: localizedPeerNotificationSoundString(strings: presentationData.strings, notificationSoundList: notificationSoundList, sound: sound), sound: sound, selected: state.selectedSound.id == sound.id))
|
||||
}
|
||||
}
|
||||
entries.append(.uploadSound(presentationData.strings.Notifications_UploadSound))
|
||||
entries.append(.cloudInfo(presentationData.strings.Notifications_MessageSoundInfo))
|
||||
|
||||
entries.append(.modernHeader(presentationData.theme, presentationData.strings.Notifications_AlertTones))
|
||||
if let defaultSound = defaultSound {
|
||||
entries.append(.default(section: .modern, theme: presentationData.theme, text: localizedPeerNotificationSoundString(strings: presentationData.strings, sound: .default, default: defaultSound), selected: state.selectedSound == .default))
|
||||
entries.append(.default(section: .modern, theme: presentationData.theme, text: localizedPeerNotificationSoundString(strings: presentationData.strings, notificationSoundList: notificationSoundList, sound: .default, default: defaultSound), selected: state.selectedSound.id == .default))
|
||||
}
|
||||
entries.append(.none(section: .modern, theme: presentationData.theme, text: localizedPeerNotificationSoundString(strings: presentationData.strings, sound: .none), selected: state.selectedSound == .none))
|
||||
entries.append(.none(section: .modern, theme: presentationData.theme, text: localizedPeerNotificationSoundString(strings: presentationData.strings, notificationSoundList: notificationSoundList, sound: .none), selected: state.selectedSound.id == .none))
|
||||
for i in 0 ..< 12 {
|
||||
let sound: PeerMessageSound = .bundledModern(id: Int32(i))
|
||||
entries.append(.sound(section: .modern, index: Int32(i), theme: presentationData.theme, text: localizedPeerNotificationSoundString(strings: presentationData.strings, sound: sound), sound: sound, selected: sound == state.selectedSound))
|
||||
entries.append(.sound(section: .modern, index: Int32(i), theme: presentationData.theme, text: localizedPeerNotificationSoundString(strings: presentationData.strings, notificationSoundList: notificationSoundList, sound: sound), sound: sound, selected: sound.id == state.selectedSound.id))
|
||||
}
|
||||
|
||||
entries.append(.classicHeader(presentationData.theme, presentationData.strings.Notifications_ClassicTones))
|
||||
for i in 0 ..< 8 {
|
||||
let sound: PeerMessageSound = .bundledClassic(id: Int32(i))
|
||||
entries.append(.sound(section: .classic, index: Int32(i), theme: presentationData.theme, text: localizedPeerNotificationSoundString(strings: presentationData.strings, sound: sound), sound: sound, selected: sound == state.selectedSound))
|
||||
entries.append(.sound(section: .classic, index: Int32(i), theme: presentationData.theme, text: localizedPeerNotificationSoundString(strings: presentationData.strings, notificationSoundList: notificationSoundList, sound: sound), sound: sound, selected: sound.id == state.selectedSound.id))
|
||||
}
|
||||
|
||||
return entries
|
||||
|
|
@ -195,28 +256,40 @@ private final class AudioPlayerWrapper: NSObject, AVAudioPlayerDelegate {
|
|||
}
|
||||
}
|
||||
|
||||
public func fileNameForNotificationSound(_ sound: PeerMessageSound, defaultSound: PeerMessageSound?) -> String {
|
||||
public func fileNameForNotificationSound(account: Account, notificationSoundList: NotificationSoundList?, sound: PeerMessageSound, defaultSound: PeerMessageSound?) -> String {
|
||||
switch sound {
|
||||
case .none:
|
||||
return ""
|
||||
case .default:
|
||||
if let defaultSound = defaultSound {
|
||||
if case .default = defaultSound {
|
||||
return "\(100)"
|
||||
} else {
|
||||
return fileNameForNotificationSound(defaultSound, defaultSound: nil)
|
||||
}
|
||||
} else {
|
||||
case .none:
|
||||
return ""
|
||||
case .default:
|
||||
if let defaultSound = defaultSound {
|
||||
if case .default = defaultSound {
|
||||
return "\(100)"
|
||||
} else {
|
||||
return fileNameForNotificationSound(account: account, notificationSoundList: notificationSoundList, sound: defaultSound, defaultSound: nil)
|
||||
}
|
||||
case let .bundledModern(id):
|
||||
return "\(id + 100)"
|
||||
case let .bundledClassic(id):
|
||||
return "\(id + 2)"
|
||||
} else {
|
||||
return "\(100)"
|
||||
}
|
||||
case let .bundledModern(id):
|
||||
return "\(id + 100)"
|
||||
case let .bundledClassic(id):
|
||||
return "\(id + 2)"
|
||||
case let .cloud(fileId):
|
||||
guard let notificationSoundList = notificationSoundList else {
|
||||
return ""
|
||||
}
|
||||
for sound in notificationSoundList.sounds {
|
||||
if sound.file.fileId.id == fileId {
|
||||
if let path = account.postbox.mediaBox.completedResourcePath(sound.file.resource, pathExtension: "mp3") {
|
||||
return path
|
||||
}
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
}
|
||||
|
||||
public func playSound(context: AccountContext, sound: PeerMessageSound, defaultSound: PeerMessageSound?) -> Signal<Void, NoError> {
|
||||
public func playSound(context: AccountContext, notificationSoundList: NotificationSoundList?, sound: PeerMessageSound, defaultSound: PeerMessageSound?) -> Signal<Void, NoError> {
|
||||
if case .none = sound {
|
||||
return .complete()
|
||||
} else {
|
||||
|
|
@ -225,11 +298,20 @@ public func playSound(context: AccountContext, sound: PeerMessageSound, defaultS
|
|||
var deactivateImpl: (() -> Void)?
|
||||
let session = context.sharedContext.mediaManager.audioSession.push(audioSessionType: .play, activate: { _ in
|
||||
Queue.mainQueue().async {
|
||||
if let url = getAppBundle().url(forResource: fileNameForNotificationSound(sound, defaultSound: defaultSound), withExtension: "m4a") {
|
||||
currentPlayer = AudioPlayerWrapper(url: url, completed: {
|
||||
let filePath = fileNameForNotificationSound(account: context.account, notificationSoundList: notificationSoundList, sound: sound, defaultSound: defaultSound)
|
||||
|
||||
if filePath.contains("/") {
|
||||
currentPlayer = AudioPlayerWrapper(url: URL(fileURLWithPath: filePath), completed: {
|
||||
deactivateImpl?()
|
||||
})
|
||||
currentPlayer?.play()
|
||||
} else {
|
||||
if let url = getAppBundle().url(forResource: filePath, withExtension: "m4a") {
|
||||
currentPlayer = AudioPlayerWrapper(url: url, completed: {
|
||||
deactivateImpl?()
|
||||
})
|
||||
currentPlayer?.play()
|
||||
}
|
||||
}
|
||||
}
|
||||
}, deactivate: { _ in
|
||||
|
|
@ -266,25 +348,32 @@ public func notificationSoundSelectionController(context: AccountContext, update
|
|||
|
||||
var completeImpl: (() -> Void)?
|
||||
var cancelImpl: (() -> Void)?
|
||||
var presentFilePicker: (() -> Void)?
|
||||
|
||||
let playSoundDisposable = MetaDisposable()
|
||||
let soundActionDisposable = MetaDisposable()
|
||||
|
||||
let arguments = NotificationSoundSelectionArguments(account: context.account, selectSound: { sound in
|
||||
updateState { state in
|
||||
return NotificationSoundSelectionState(selectedSound: sound)
|
||||
}
|
||||
|
||||
playSoundDisposable.set(playSound(context: context, sound: sound, defaultSound: defaultSound).start())
|
||||
let _ = (context.engine.peers.notificationSoundList()
|
||||
|> take(1)
|
||||
|> deliverOnMainQueue).start(next: { notificationSoundList in
|
||||
playSoundDisposable.set(playSound(context: context, notificationSoundList: notificationSoundList, sound: sound, defaultSound: defaultSound).start())
|
||||
})
|
||||
}, complete: {
|
||||
completeImpl?()
|
||||
}, cancel: {
|
||||
cancelImpl?()
|
||||
}, upload: {
|
||||
presentFilePicker?()
|
||||
})
|
||||
|
||||
let presentationData = updatedPresentationData?.signal ?? context.sharedContext.presentationData
|
||||
let signal = combineLatest(presentationData, statePromise.get())
|
||||
|> map { presentationData, state -> (ItemListControllerState, (ItemListNodeState, Any)) in
|
||||
|
||||
let signal = combineLatest(presentationData, statePromise.get(), context.engine.peers.notificationSoundList())
|
||||
|> map { presentationData, state, notificationSoundList -> (ItemListControllerState, (ItemListNodeState, Any)) in
|
||||
let leftNavigationButton = ItemListNavigationButton(content: .text(presentationData.strings.Common_Cancel), style: .regular, enabled: true, action: {
|
||||
arguments.cancel()
|
||||
})
|
||||
|
|
@ -294,13 +383,14 @@ public func notificationSoundSelectionController(context: AccountContext, update
|
|||
})
|
||||
|
||||
let controllerState = ItemListControllerState(presentationData: ItemListPresentationData(presentationData), title: .text(presentationData.strings.Notifications_TextTone), leftNavigationButton: leftNavigationButton, rightNavigationButton: rightNavigationButton, backNavigationButton: ItemListBackButton(title: presentationData.strings.Common_Back))
|
||||
let listState = ItemListNodeState(presentationData: ItemListPresentationData(presentationData), entries: notificationsAndSoundsEntries(presentationData: presentationData, defaultSound: defaultSound, state: state), style: .blocks)
|
||||
let listState = ItemListNodeState(presentationData: ItemListPresentationData(presentationData), entries: notificationsAndSoundsEntries(presentationData: presentationData, defaultSound: defaultSound, state: state, notificationSoundList: notificationSoundList), style: .blocks)
|
||||
|
||||
return (controllerState, (listState, arguments))
|
||||
}
|
||||
|
||||
let controller = ItemListController(context: context, state: signal |> afterDisposed {
|
||||
playSoundDisposable.dispose()
|
||||
soundActionDisposable.dispose()
|
||||
})
|
||||
controller.enableInteractiveDismiss = true
|
||||
if isModal {
|
||||
|
|
@ -319,5 +409,57 @@ public func notificationSoundSelectionController(context: AccountContext, update
|
|||
controller?.dismiss()
|
||||
}
|
||||
|
||||
var presentUndo: ((UndoOverlayContent) -> Void)?
|
||||
|
||||
|
||||
presentFilePicker = { [weak controller] in
|
||||
guard let controller = controller else {
|
||||
return
|
||||
}
|
||||
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||
controller.present(legacyICloudFilePicker(theme: presentationData.theme, documentTypes: ["public.mp3"], completion: { urls in
|
||||
guard !urls.isEmpty, let url = urls.first else {
|
||||
return
|
||||
}
|
||||
|
||||
let coordinator = NSFileCoordinator(filePresenter: nil)
|
||||
var error: NSError?
|
||||
coordinator.coordinate(readingItemAt: url, options: .forUploading, error: &error, byAccessor: { url in
|
||||
Queue.mainQueue().async {
|
||||
let asset = AVAsset(url: url)
|
||||
|
||||
guard let data = try? Data(contentsOf: url) else {
|
||||
return
|
||||
}
|
||||
if data.count > 200 * 1024 {
|
||||
presentUndo?(.info(title: "Audio is too large", text: "The file is larger than 200 KB."))
|
||||
return
|
||||
}
|
||||
|
||||
asset.loadValuesAsynchronously(forKeys: ["duration"], completionHandler: {
|
||||
let duration = asset.duration.seconds
|
||||
if duration > 5.0 {
|
||||
//TODO:localize
|
||||
presentUndo?(.info(title: "Audio is too long", text: "The duration is longer than 5 seconds."))
|
||||
} else {
|
||||
soundActionDisposable.set((context.engine.peers.uploadNotificationSound(title: url.lastPathComponent, data: data)
|
||||
|> deliverOnMainQueue).start(next: { _ in
|
||||
}, error: { _ in
|
||||
}))
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
}), in: .window(.root))
|
||||
}
|
||||
|
||||
presentUndo = { [weak controller] content in
|
||||
guard let controller = controller else {
|
||||
return
|
||||
}
|
||||
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||
controller.present(UndoOverlayController(presentationData: presentationData, content: content, elevatedLayout: false, animateInAsReplacement: true, action: { _ in return false }), in: .current)
|
||||
}
|
||||
|
||||
return controller
|
||||
}
|
||||
|
|
|
|||
|
|
@ -287,7 +287,7 @@ public enum NotificationExceptionMode : Equatable {
|
|||
}
|
||||
}
|
||||
|
||||
private func notificationsExceptionEntries(presentationData: PresentationData, state: NotificationExceptionState, query: String? = nil, foundPeers: [RenderedPeer] = []) -> [NotificationExceptionEntry] {
|
||||
private func notificationsExceptionEntries(presentationData: PresentationData, notificationSoundList: NotificationSoundList?, state: NotificationExceptionState, query: String? = nil, foundPeers: [RenderedPeer] = []) -> [NotificationExceptionEntry] {
|
||||
var entries: [NotificationExceptionEntry] = []
|
||||
|
||||
if !state.isSearchMode {
|
||||
|
|
@ -361,7 +361,7 @@ private func notificationsExceptionEntries(presentationData: PresentationData, s
|
|||
case .default:
|
||||
break
|
||||
default:
|
||||
let soundName = localizedPeerNotificationSoundString(strings: presentationData.strings, sound: value.settings.messageSound)
|
||||
let soundName = localizedPeerNotificationSoundString(strings: presentationData.strings, notificationSoundList: notificationSoundList, sound: value.settings.messageSound)
|
||||
title += (title.isEmpty ? presentationData.strings.Notification_Exceptions_Sound(soundName).string : ", \(presentationData.strings.Notification_Exceptions_Sound(soundName).string)")
|
||||
}
|
||||
switch value.settings.displayPreviews {
|
||||
|
|
@ -975,8 +975,8 @@ final class NotificationExceptionsControllerNode: ViewControllerTracingNode {
|
|||
|
||||
let previousEntriesHolder = Atomic<([NotificationExceptionEntry], PresentationTheme, PresentationStrings)?>(value: nil)
|
||||
|
||||
self.listDisposable = (combineLatest(context.sharedContext.presentationData, statePromise.get(), preferences) |> deliverOnMainQueue).start(next: { [weak self] (presentationData, state, prefs) in
|
||||
let entries = notificationsExceptionEntries(presentationData: presentationData, state: state)
|
||||
self.listDisposable = (combineLatest(context.sharedContext.presentationData, statePromise.get(), preferences, context.engine.peers.notificationSoundList()) |> deliverOnMainQueue).start(next: { [weak self] presentationData, state, prefs, notificationSoundList in
|
||||
let entries = notificationsExceptionEntries(presentationData: presentationData, notificationSoundList: notificationSoundList, state: state)
|
||||
let previousEntriesAndPresentationData = previousEntriesHolder.swap((entries, presentationData.theme, presentationData.strings))
|
||||
|
||||
updateCanStartEditing(state.mode.peerIds.isEmpty ? nil : state.editing)
|
||||
|
|
@ -1233,16 +1233,16 @@ private final class NotificationExceptionsSearchContainerNode: SearchDisplayCont
|
|||
|> distinctUntilChanged
|
||||
|
||||
let searchSignal = stateQuery
|
||||
|> mapToSignal { query -> Signal<(PresentationData, (NotificationExceptionState, String?), PreferencesView, [RenderedPeer]), NoError> in
|
||||
|> mapToSignal { query -> Signal<(PresentationData, NotificationSoundList?, (NotificationExceptionState, String?), PreferencesView, [RenderedPeer]), NoError> in
|
||||
var contactsSignal: Signal<[RenderedPeer], NoError> = .single([])
|
||||
if let query = query {
|
||||
contactsSignal = context.account.postbox.searchPeers(query: query)
|
||||
}
|
||||
return combineLatest(context.sharedContext.presentationData, stateAndPeers, preferences, contactsSignal)
|
||||
return combineLatest(context.sharedContext.presentationData, context.engine.peers.notificationSoundList(), stateAndPeers, preferences, contactsSignal)
|
||||
}
|
||||
self.searchDisposable.set((searchSignal
|
||||
|> deliverOnMainQueue).start(next: { [weak self] (presentationData, state, prefs, foundPeers) in
|
||||
let entries = notificationsExceptionEntries(presentationData: presentationData, state: state.0, query: state.1, foundPeers: foundPeers)
|
||||
|> deliverOnMainQueue).start(next: { [weak self] presentationData, notificationSoundList, state, prefs, foundPeers in
|
||||
let entries = notificationsExceptionEntries(presentationData: presentationData, notificationSoundList: notificationSoundList, state: state.0, query: state.1, foundPeers: foundPeers)
|
||||
let previousEntriesAndPresentationData = previousEntriesHolder.swap((entries, presentationData.theme, presentationData.strings))
|
||||
|
||||
let transition = preparedNotificationExceptionsSearchContainerTransition(presentationData: ItemListPresentationData(presentationData), from: previousEntriesAndPresentationData?.0 ?? [], to: entries, arguments: arguments, isSearching: state.1 != nil && !state.1!.isEmpty, forceUpdate: previousEntriesAndPresentationData?.1 !== presentationData.theme || previousEntriesAndPresentationData?.2 !== presentationData.strings)
|
||||
|
|
|
|||
|
|
@ -209,7 +209,7 @@ private enum NotificationPeerExceptionEntry: ItemListNodeEntry {
|
|||
}
|
||||
|
||||
|
||||
private func notificationPeerExceptionEntries(presentationData: PresentationData, state: NotificationExceptionPeerState) -> [NotificationPeerExceptionEntry] {
|
||||
private func notificationPeerExceptionEntries(presentationData: PresentationData, notificationSoundList: NotificationSoundList?, state: NotificationExceptionPeerState) -> [NotificationPeerExceptionEntry] {
|
||||
var entries:[NotificationPeerExceptionEntry] = []
|
||||
|
||||
var index: Int32 = 0
|
||||
|
|
@ -239,15 +239,15 @@ private func notificationPeerExceptionEntries(presentationData: PresentationData
|
|||
entries.append(.soundModernHeader(index: index, theme: presentationData.theme, title: presentationData.strings.Notifications_AlertTones))
|
||||
index += 1
|
||||
|
||||
entries.append(.default(index: index, section: .soundModern, theme: presentationData.theme, text: localizedPeerNotificationSoundString(strings: presentationData.strings, sound: .default, default: state.defaultSound), selected: state.selectedSound == .default))
|
||||
entries.append(.default(index: index, section: .soundModern, theme: presentationData.theme, text: localizedPeerNotificationSoundString(strings: presentationData.strings, notificationSoundList: notificationSoundList, sound: .default, default: state.defaultSound), selected: state.selectedSound == .default))
|
||||
index += 1
|
||||
|
||||
entries.append(.none(index: index, section: .soundModern, theme: presentationData.theme, text: localizedPeerNotificationSoundString(strings: presentationData.strings, sound: .none), selected: state.selectedSound == .none))
|
||||
entries.append(.none(index: index, section: .soundModern, theme: presentationData.theme, text: localizedPeerNotificationSoundString(strings: presentationData.strings, notificationSoundList: notificationSoundList, sound: .none), selected: state.selectedSound == .none))
|
||||
index += 1
|
||||
|
||||
for i in 0 ..< 12 {
|
||||
let sound: PeerMessageSound = .bundledModern(id: Int32(i))
|
||||
entries.append(.sound(index: index, section: .soundModern, theme: presentationData.theme, text: localizedPeerNotificationSoundString(strings: presentationData.strings, sound: sound), sound: sound, selected: sound == state.selectedSound))
|
||||
entries.append(.sound(index: index, section: .soundModern, theme: presentationData.theme, text: localizedPeerNotificationSoundString(strings: presentationData.strings, notificationSoundList: notificationSoundList, sound: sound), sound: sound, selected: sound == state.selectedSound))
|
||||
index += 1
|
||||
}
|
||||
|
||||
|
|
@ -256,7 +256,7 @@ private func notificationPeerExceptionEntries(presentationData: PresentationData
|
|||
|
||||
for i in 0 ..< 8 {
|
||||
let sound: PeerMessageSound = .bundledClassic(id: Int32(i))
|
||||
entries.append(.sound(index: index, section: .soundClassic, theme: presentationData.theme, text: localizedPeerNotificationSoundString(strings: presentationData.strings, sound: sound), sound: sound, selected: sound == state.selectedSound))
|
||||
entries.append(.sound(index: index, section: .soundClassic, theme: presentationData.theme, text: localizedPeerNotificationSoundString(strings: presentationData.strings, notificationSoundList: notificationSoundList, sound: sound), sound: sound, selected: sound == state.selectedSound))
|
||||
index += 1
|
||||
}
|
||||
}
|
||||
|
|
@ -330,7 +330,12 @@ public func notificationPeerExceptionController(context: AccountContext, updated
|
|||
|
||||
let arguments = NotificationPeerExceptionArguments(account: context.account, selectSound: { sound in
|
||||
updateState { state in
|
||||
playSoundDisposable.set(playSound(context: context, sound: sound, defaultSound: state.defaultSound).start())
|
||||
let _ = (context.engine.peers.notificationSoundList()
|
||||
|> take(1)
|
||||
|> deliverOnMainQueue).start(next: { notificationSoundList in
|
||||
playSoundDisposable.set(playSound(context: context, notificationSoundList: notificationSoundList, sound: sound, defaultSound: state.defaultSound).start())
|
||||
})
|
||||
|
||||
return state.withUpdatedSound(sound)
|
||||
}
|
||||
}, selectMode: { mode in
|
||||
|
|
@ -365,8 +370,8 @@ public func notificationPeerExceptionController(context: AccountContext, updated
|
|||
})
|
||||
|
||||
|
||||
let signal = combineLatest(queue: .mainQueue(), (updatedPresentationData?.signal ?? context.sharedContext.presentationData), statePromise.get() |> distinctUntilChanged)
|
||||
|> map { presentationData, state -> (ItemListControllerState, (ItemListNodeState, Any)) in
|
||||
let signal = combineLatest(queue: .mainQueue(), (updatedPresentationData?.signal ?? context.sharedContext.presentationData), context.engine.peers.notificationSoundList(), statePromise.get() |> distinctUntilChanged)
|
||||
|> map { presentationData, notificationSoundList, state -> (ItemListControllerState, (ItemListNodeState, Any)) in
|
||||
let leftNavigationButton = ItemListNavigationButton(content: .text(presentationData.strings.Common_Cancel), style: .regular, enabled: true, action: {
|
||||
arguments.cancel()
|
||||
})
|
||||
|
|
@ -376,7 +381,7 @@ public func notificationPeerExceptionController(context: AccountContext, updated
|
|||
})
|
||||
|
||||
let controllerState = ItemListControllerState(presentationData: ItemListPresentationData(presentationData), title: .text(EnginePeer(peer).displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)), leftNavigationButton: leftNavigationButton, rightNavigationButton: rightNavigationButton, backNavigationButton: ItemListBackButton(title: presentationData.strings.Common_Back))
|
||||
let listState = ItemListNodeState(presentationData: ItemListPresentationData(presentationData), entries: notificationPeerExceptionEntries(presentationData: presentationData, state: state), style: .blocks, animateChanges: false)
|
||||
let listState = ItemListNodeState(presentationData: ItemListPresentationData(presentationData), entries: notificationPeerExceptionEntries(presentationData: presentationData, notificationSoundList: notificationSoundList, state: state), style: .blocks, animateChanges: false)
|
||||
|
||||
return (controllerState, (listState, arguments))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -249,7 +249,7 @@ private func filteredGlobalSound(_ sound: PeerMessageSound) -> PeerMessageSound
|
|||
}
|
||||
}
|
||||
|
||||
private func notificationsPeerCategoryEntries(category: NotificationsPeerCategory, globalSettings: GlobalNotificationSettingsSet, state: NotificationExceptionState, presentationData: PresentationData) -> [NotificationsPeerCategoryEntry] {
|
||||
private func notificationsPeerCategoryEntries(category: NotificationsPeerCategory, globalSettings: GlobalNotificationSettingsSet, state: NotificationExceptionState, presentationData: PresentationData, notificationSoundList: NotificationSoundList?) -> [NotificationsPeerCategoryEntry] {
|
||||
var entries: [NotificationsPeerCategoryEntry] = []
|
||||
|
||||
let notificationSettings: MessageNotificationSettings
|
||||
|
|
@ -268,7 +268,7 @@ private func notificationsPeerCategoryEntries(category: NotificationsPeerCategor
|
|||
if notificationSettings.enabled || !notificationExceptions.isEmpty {
|
||||
entries.append(.optionsHeader(presentationData.theme, presentationData.strings.Notifications_Options.uppercased()))
|
||||
entries.append(.previews(presentationData.theme, presentationData.strings.Notifications_MessageNotificationsPreview, notificationSettings.displayPreviews))
|
||||
entries.append(.sound(presentationData.theme, presentationData.strings.Notifications_MessageNotificationsSound, localizedPeerNotificationSoundString(strings: presentationData.strings, sound: filteredGlobalSound(notificationSettings.sound)), filteredGlobalSound(notificationSettings.sound)))
|
||||
entries.append(.sound(presentationData.theme, presentationData.strings.Notifications_MessageNotificationsSound, localizedPeerNotificationSoundString(strings: presentationData.strings, notificationSoundList: notificationSoundList, sound: filteredGlobalSound(notificationSettings.sound)), filteredGlobalSound(notificationSettings.sound)))
|
||||
}
|
||||
|
||||
entries.append(.exceptionsHeader(presentationData.theme, presentationData.strings.Notifications_MessageNotificationsExceptions.uppercased()))
|
||||
|
|
@ -338,7 +338,7 @@ private func notificationsPeerCategoryEntries(category: NotificationsPeerCategor
|
|||
case .default:
|
||||
break
|
||||
default:
|
||||
let soundName = localizedPeerNotificationSoundString(strings: presentationData.strings, sound: value.settings.messageSound)
|
||||
let soundName = localizedPeerNotificationSoundString(strings: presentationData.strings, notificationSoundList: notificationSoundList, sound: value.settings.messageSound)
|
||||
title += (title.isEmpty ? presentationData.strings.Notification_Exceptions_Sound(soundName).string : ", \(presentationData.strings.Notification_Exceptions_Sound(soundName).string)")
|
||||
}
|
||||
switch value.settings.displayPreviews {
|
||||
|
|
@ -687,8 +687,8 @@ public func notificationsPeerCategoryController(context: AccountContext, categor
|
|||
let sharedData = context.sharedContext.accountManager.sharedData(keys: [ApplicationSpecificSharedDataKeys.inAppNotificationSettings])
|
||||
let preferences = context.account.postbox.preferencesView(keys: [PreferencesKeys.globalNotifications])
|
||||
|
||||
let signal = combineLatest(context.sharedContext.presentationData, sharedData, preferences, statePromise.get())
|
||||
|> map { presentationData, sharedData, view, state -> (ItemListControllerState, (ItemListNodeState, Any)) in
|
||||
let signal = combineLatest(context.sharedContext.presentationData, context.engine.peers.notificationSoundList(), sharedData, preferences, statePromise.get())
|
||||
|> map { presentationData, notificationSoundList, sharedData, view, state -> (ItemListControllerState, (ItemListNodeState, Any)) in
|
||||
let viewSettings: GlobalNotificationSettingsSet
|
||||
if let settings = view.values[PreferencesKeys.globalNotifications]?.get(GlobalNotificationSettings.self) {
|
||||
viewSettings = settings.effective
|
||||
|
|
@ -696,7 +696,7 @@ public func notificationsPeerCategoryController(context: AccountContext, categor
|
|||
viewSettings = GlobalNotificationSettingsSet.defaultSettings
|
||||
}
|
||||
|
||||
let entries = notificationsPeerCategoryEntries(category: category, globalSettings: viewSettings, state: state, presentationData: presentationData)
|
||||
let entries = notificationsPeerCategoryEntries(category: category, globalSettings: viewSettings, state: state, presentationData: presentationData, notificationSoundList: notificationSoundList)
|
||||
|
||||
var index = 0
|
||||
var scrollToItem: ListViewScrollToItem?
|
||||
|
|
|
|||
|
|
@ -303,7 +303,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
|
|||
dict[2107670217] = { return Api.InputPeer.parse_inputPeerSelf($0) }
|
||||
dict[-571955892] = { return Api.InputPeer.parse_inputPeerUser($0) }
|
||||
dict[-1468331492] = { return Api.InputPeer.parse_inputPeerUserFromMessage($0) }
|
||||
dict[-1673717362] = { return Api.InputPeerNotifySettings.parse_inputPeerNotifySettings($0) }
|
||||
dict[-551616469] = { return Api.InputPeerNotifySettings.parse_inputPeerNotifySettings($0) }
|
||||
dict[506920429] = { return Api.InputPhoneCall.parse_inputPhoneCall($0) }
|
||||
dict[1001634122] = { return Api.InputPhoto.parse_inputPhoto($0) }
|
||||
dict[483901197] = { return Api.InputPhoto.parse_inputPhotoEmpty($0) }
|
||||
|
|
@ -477,6 +477,10 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
|
|||
dict[-1614803355] = { return Api.MessagesFilter.parse_inputMessagesFilterVideo($0) }
|
||||
dict[1358283666] = { return Api.MessagesFilter.parse_inputMessagesFilterVoice($0) }
|
||||
dict[-1910892683] = { return Api.NearestDc.parse_nearestDc($0) }
|
||||
dict[-1746354498] = { return Api.NotificationSound.parse_notificationSoundDefault($0) }
|
||||
dict[-2096391452] = { return Api.NotificationSound.parse_notificationSoundLocal($0) }
|
||||
dict[1863070943] = { return Api.NotificationSound.parse_notificationSoundNone($0) }
|
||||
dict[-9666487] = { return Api.NotificationSound.parse_notificationSoundRingtone($0) }
|
||||
dict[-703403793] = { return Api.NotifyPeer.parse_notifyBroadcasts($0) }
|
||||
dict[-1073230141] = { return Api.NotifyPeer.parse_notifyChats($0) }
|
||||
dict[-1613493288] = { return Api.NotifyPeer.parse_notifyPeer($0) }
|
||||
|
|
@ -530,7 +534,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
|
|||
dict[-386039788] = { return Api.PeerBlocked.parse_peerBlocked($0) }
|
||||
dict[-901375139] = { return Api.PeerLocated.parse_peerLocated($0) }
|
||||
dict[-118740917] = { return Api.PeerLocated.parse_peerSelfLocated($0) }
|
||||
dict[-1353671392] = { return Api.PeerNotifySettings.parse_peerNotifySettings($0) }
|
||||
dict[-1472527322] = { return Api.PeerNotifySettings.parse_peerNotifySettings($0) }
|
||||
dict[-1525149427] = { return Api.PeerSettings.parse_peerSettings($0) }
|
||||
dict[-1770029977] = { return Api.PhoneCall.parse_phoneCall($0) }
|
||||
dict[912311057] = { return Api.PhoneCall.parse_phoneCallAccepted($0) }
|
||||
|
|
@ -787,6 +791,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
|
|||
dict[1757493555] = { return Api.Update.parse_updateReadMessagesContents($0) }
|
||||
dict[-1706939360] = { return Api.Update.parse_updateRecentStickers($0) }
|
||||
dict[-1821035490] = { return Api.Update.parse_updateSavedGifs($0) }
|
||||
dict[1960361625] = { return Api.Update.parse_updateSavedRingtones($0) }
|
||||
dict[-337352679] = { return Api.Update.parse_updateServiceNotification($0) }
|
||||
dict[1135492588] = { return Api.Update.parse_updateStickerSets($0) }
|
||||
dict[196268545] = { return Api.Update.parse_updateStickerSetsOrder($0) }
|
||||
|
|
@ -845,6 +850,8 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
|
|||
dict[-478701471] = { return Api.account.ResetPasswordResult.parse_resetPasswordFailedWait($0) }
|
||||
dict[-383330754] = { return Api.account.ResetPasswordResult.parse_resetPasswordOk($0) }
|
||||
dict[-370148227] = { return Api.account.ResetPasswordResult.parse_resetPasswordRequestedWait($0) }
|
||||
dict[-1041683259] = { return Api.account.SavedRingtones.parse_savedRingtones($0) }
|
||||
dict[-67704655] = { return Api.account.SavedRingtones.parse_savedRingtonesNotModified($0) }
|
||||
dict[-2128640689] = { return Api.account.SentEmailCode.parse_sentEmailCode($0) }
|
||||
dict[1304052993] = { return Api.account.Takeout.parse_takeout($0) }
|
||||
dict[-1707242387] = { return Api.account.Themes.parse_themes($0) }
|
||||
|
|
@ -1354,6 +1361,8 @@ public extension Api {
|
|||
_1.serialize(buffer, boxed)
|
||||
case let _1 as Api.NearestDc:
|
||||
_1.serialize(buffer, boxed)
|
||||
case let _1 as Api.NotificationSound:
|
||||
_1.serialize(buffer, boxed)
|
||||
case let _1 as Api.NotifyPeer:
|
||||
_1.serialize(buffer, boxed)
|
||||
case let _1 as Api.Page:
|
||||
|
|
@ -1550,6 +1559,8 @@ public extension Api {
|
|||
_1.serialize(buffer, boxed)
|
||||
case let _1 as Api.account.ResetPasswordResult:
|
||||
_1.serialize(buffer, boxed)
|
||||
case let _1 as Api.account.SavedRingtones:
|
||||
_1.serialize(buffer, boxed)
|
||||
case let _1 as Api.account.SentEmailCode:
|
||||
_1.serialize(buffer, boxed)
|
||||
case let _1 as Api.account.Takeout:
|
||||
|
|
|
|||
|
|
@ -680,6 +680,90 @@ public extension Api {
|
|||
|
||||
}
|
||||
}
|
||||
public extension Api {
|
||||
enum NotificationSound: TypeConstructorDescription {
|
||||
case notificationSoundDefault
|
||||
case notificationSoundLocal(title: String, data: String)
|
||||
case notificationSoundNone
|
||||
case notificationSoundRingtone(id: Int64)
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .notificationSoundDefault:
|
||||
if boxed {
|
||||
buffer.appendInt32(-1746354498)
|
||||
}
|
||||
|
||||
break
|
||||
case .notificationSoundLocal(let title, let data):
|
||||
if boxed {
|
||||
buffer.appendInt32(-2096391452)
|
||||
}
|
||||
serializeString(title, buffer: buffer, boxed: false)
|
||||
serializeString(data, buffer: buffer, boxed: false)
|
||||
break
|
||||
case .notificationSoundNone:
|
||||
if boxed {
|
||||
buffer.appendInt32(1863070943)
|
||||
}
|
||||
|
||||
break
|
||||
case .notificationSoundRingtone(let id):
|
||||
if boxed {
|
||||
buffer.appendInt32(-9666487)
|
||||
}
|
||||
serializeInt64(id, buffer: buffer, boxed: false)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .notificationSoundDefault:
|
||||
return ("notificationSoundDefault", [])
|
||||
case .notificationSoundLocal(let title, let data):
|
||||
return ("notificationSoundLocal", [("title", String(describing: title)), ("data", String(describing: data))])
|
||||
case .notificationSoundNone:
|
||||
return ("notificationSoundNone", [])
|
||||
case .notificationSoundRingtone(let id):
|
||||
return ("notificationSoundRingtone", [("id", String(describing: id))])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_notificationSoundDefault(_ reader: BufferReader) -> NotificationSound? {
|
||||
return Api.NotificationSound.notificationSoundDefault
|
||||
}
|
||||
public static func parse_notificationSoundLocal(_ reader: BufferReader) -> NotificationSound? {
|
||||
var _1: String?
|
||||
_1 = parseString(reader)
|
||||
var _2: String?
|
||||
_2 = parseString(reader)
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
if _c1 && _c2 {
|
||||
return Api.NotificationSound.notificationSoundLocal(title: _1!, data: _2!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
public static func parse_notificationSoundNone(_ reader: BufferReader) -> NotificationSound? {
|
||||
return Api.NotificationSound.notificationSoundNone
|
||||
}
|
||||
public static func parse_notificationSoundRingtone(_ reader: BufferReader) -> NotificationSound? {
|
||||
var _1: Int64?
|
||||
_1 = reader.readInt64()
|
||||
let _c1 = _1 != nil
|
||||
if _c1 {
|
||||
return Api.NotificationSound.notificationSoundRingtone(id: _1!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api {
|
||||
enum NotifyPeer: TypeConstructorDescription {
|
||||
case notifyBroadcasts
|
||||
|
|
@ -754,77 +838,3 @@ public extension Api {
|
|||
|
||||
}
|
||||
}
|
||||
public extension Api {
|
||||
enum Page: TypeConstructorDescription {
|
||||
case page(flags: Int32, url: String, blocks: [Api.PageBlock], photos: [Api.Photo], documents: [Api.Document], views: Int32?)
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .page(let flags, let url, let blocks, let photos, let documents, let views):
|
||||
if boxed {
|
||||
buffer.appendInt32(-1738178803)
|
||||
}
|
||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||
serializeString(url, buffer: buffer, boxed: false)
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(blocks.count))
|
||||
for item in blocks {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(photos.count))
|
||||
for item in photos {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(documents.count))
|
||||
for item in documents {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
if Int(flags) & Int(1 << 3) != 0 {serializeInt32(views!, buffer: buffer, boxed: false)}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .page(let flags, let url, let blocks, let photos, let documents, let views):
|
||||
return ("page", [("flags", String(describing: flags)), ("url", String(describing: url)), ("blocks", String(describing: blocks)), ("photos", String(describing: photos)), ("documents", String(describing: documents)), ("views", String(describing: views))])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_page(_ reader: BufferReader) -> Page? {
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
var _2: String?
|
||||
_2 = parseString(reader)
|
||||
var _3: [Api.PageBlock]?
|
||||
if let _ = reader.readInt32() {
|
||||
_3 = Api.parseVector(reader, elementSignature: 0, elementType: Api.PageBlock.self)
|
||||
}
|
||||
var _4: [Api.Photo]?
|
||||
if let _ = reader.readInt32() {
|
||||
_4 = Api.parseVector(reader, elementSignature: 0, elementType: Api.Photo.self)
|
||||
}
|
||||
var _5: [Api.Document]?
|
||||
if let _ = reader.readInt32() {
|
||||
_5 = Api.parseVector(reader, elementSignature: 0, elementType: Api.Document.self)
|
||||
}
|
||||
var _6: Int32?
|
||||
if Int(_1!) & Int(1 << 3) != 0 {_6 = reader.readInt32() }
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
let _c3 = _3 != nil
|
||||
let _c4 = _4 != nil
|
||||
let _c5 = _5 != nil
|
||||
let _c6 = (Int(_1!) & Int(1 << 3) == 0) || _6 != nil
|
||||
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 {
|
||||
return Api.Page.page(flags: _1!, url: _2!, blocks: _3!, photos: _4!, documents: _5!, views: _6)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,77 @@
|
|||
public extension Api {
|
||||
enum Page: TypeConstructorDescription {
|
||||
case page(flags: Int32, url: String, blocks: [Api.PageBlock], photos: [Api.Photo], documents: [Api.Document], views: Int32?)
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .page(let flags, let url, let blocks, let photos, let documents, let views):
|
||||
if boxed {
|
||||
buffer.appendInt32(-1738178803)
|
||||
}
|
||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||
serializeString(url, buffer: buffer, boxed: false)
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(blocks.count))
|
||||
for item in blocks {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(photos.count))
|
||||
for item in photos {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(documents.count))
|
||||
for item in documents {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
if Int(flags) & Int(1 << 3) != 0 {serializeInt32(views!, buffer: buffer, boxed: false)}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .page(let flags, let url, let blocks, let photos, let documents, let views):
|
||||
return ("page", [("flags", String(describing: flags)), ("url", String(describing: url)), ("blocks", String(describing: blocks)), ("photos", String(describing: photos)), ("documents", String(describing: documents)), ("views", String(describing: views))])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_page(_ reader: BufferReader) -> Page? {
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
var _2: String?
|
||||
_2 = parseString(reader)
|
||||
var _3: [Api.PageBlock]?
|
||||
if let _ = reader.readInt32() {
|
||||
_3 = Api.parseVector(reader, elementSignature: 0, elementType: Api.PageBlock.self)
|
||||
}
|
||||
var _4: [Api.Photo]?
|
||||
if let _ = reader.readInt32() {
|
||||
_4 = Api.parseVector(reader, elementSignature: 0, elementType: Api.Photo.self)
|
||||
}
|
||||
var _5: [Api.Document]?
|
||||
if let _ = reader.readInt32() {
|
||||
_5 = Api.parseVector(reader, elementSignature: 0, elementType: Api.Document.self)
|
||||
}
|
||||
var _6: Int32?
|
||||
if Int(_1!) & Int(1 << 3) != 0 {_6 = reader.readInt32() }
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
let _c3 = _3 != nil
|
||||
let _c4 = _4 != nil
|
||||
let _c5 = _5 != nil
|
||||
let _c6 = (Int(_1!) & Int(1 << 3) == 0) || _6 != nil
|
||||
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 {
|
||||
return Api.Page.page(flags: _1!, url: _2!, blocks: _3!, photos: _4!, documents: _5!, views: _6)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api {
|
||||
indirect enum PageBlock: TypeConstructorDescription {
|
||||
case pageBlockAnchor(name: String)
|
||||
|
|
|
|||
|
|
@ -606,27 +606,29 @@ public extension Api {
|
|||
}
|
||||
public extension Api {
|
||||
enum PeerNotifySettings: TypeConstructorDescription {
|
||||
case peerNotifySettings(flags: Int32, showPreviews: Api.Bool?, silent: Api.Bool?, muteUntil: Int32?, sound: String?)
|
||||
case peerNotifySettings(flags: Int32, showPreviews: Api.Bool?, silent: Api.Bool?, muteUntil: Int32?, iosSound: Api.NotificationSound?, androidSound: Api.NotificationSound?, otherSound: Api.NotificationSound?)
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .peerNotifySettings(let flags, let showPreviews, let silent, let muteUntil, let sound):
|
||||
case .peerNotifySettings(let flags, let showPreviews, let silent, let muteUntil, let iosSound, let androidSound, let otherSound):
|
||||
if boxed {
|
||||
buffer.appendInt32(-1353671392)
|
||||
buffer.appendInt32(-1472527322)
|
||||
}
|
||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||
if Int(flags) & Int(1 << 0) != 0 {showPreviews!.serialize(buffer, true)}
|
||||
if Int(flags) & Int(1 << 1) != 0 {silent!.serialize(buffer, true)}
|
||||
if Int(flags) & Int(1 << 2) != 0 {serializeInt32(muteUntil!, buffer: buffer, boxed: false)}
|
||||
if Int(flags) & Int(1 << 3) != 0 {serializeString(sound!, buffer: buffer, boxed: false)}
|
||||
if Int(flags) & Int(1 << 3) != 0 {iosSound!.serialize(buffer, true)}
|
||||
if Int(flags) & Int(1 << 4) != 0 {androidSound!.serialize(buffer, true)}
|
||||
if Int(flags) & Int(1 << 5) != 0 {otherSound!.serialize(buffer, true)}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .peerNotifySettings(let flags, let showPreviews, let silent, let muteUntil, let sound):
|
||||
return ("peerNotifySettings", [("flags", String(describing: flags)), ("showPreviews", String(describing: showPreviews)), ("silent", String(describing: silent)), ("muteUntil", String(describing: muteUntil)), ("sound", String(describing: sound))])
|
||||
case .peerNotifySettings(let flags, let showPreviews, let silent, let muteUntil, let iosSound, let androidSound, let otherSound):
|
||||
return ("peerNotifySettings", [("flags", String(describing: flags)), ("showPreviews", String(describing: showPreviews)), ("silent", String(describing: silent)), ("muteUntil", String(describing: muteUntil)), ("iosSound", String(describing: iosSound)), ("androidSound", String(describing: androidSound)), ("otherSound", String(describing: otherSound))])
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -643,15 +645,27 @@ public extension Api {
|
|||
} }
|
||||
var _4: Int32?
|
||||
if Int(_1!) & Int(1 << 2) != 0 {_4 = reader.readInt32() }
|
||||
var _5: String?
|
||||
if Int(_1!) & Int(1 << 3) != 0 {_5 = parseString(reader) }
|
||||
var _5: Api.NotificationSound?
|
||||
if Int(_1!) & Int(1 << 3) != 0 {if let signature = reader.readInt32() {
|
||||
_5 = Api.parse(reader, signature: signature) as? Api.NotificationSound
|
||||
} }
|
||||
var _6: Api.NotificationSound?
|
||||
if Int(_1!) & Int(1 << 4) != 0 {if let signature = reader.readInt32() {
|
||||
_6 = Api.parse(reader, signature: signature) as? Api.NotificationSound
|
||||
} }
|
||||
var _7: Api.NotificationSound?
|
||||
if Int(_1!) & Int(1 << 5) != 0 {if let signature = reader.readInt32() {
|
||||
_7 = Api.parse(reader, signature: signature) as? Api.NotificationSound
|
||||
} }
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = (Int(_1!) & Int(1 << 0) == 0) || _2 != nil
|
||||
let _c3 = (Int(_1!) & Int(1 << 1) == 0) || _3 != nil
|
||||
let _c4 = (Int(_1!) & Int(1 << 2) == 0) || _4 != nil
|
||||
let _c5 = (Int(_1!) & Int(1 << 3) == 0) || _5 != nil
|
||||
if _c1 && _c2 && _c3 && _c4 && _c5 {
|
||||
return Api.PeerNotifySettings.peerNotifySettings(flags: _1!, showPreviews: _2, silent: _3, muteUntil: _4, sound: _5)
|
||||
let _c6 = (Int(_1!) & Int(1 << 4) == 0) || _6 != nil
|
||||
let _c7 = (Int(_1!) & Int(1 << 5) == 0) || _7 != nil
|
||||
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 {
|
||||
return Api.PeerNotifySettings.peerNotifySettings(flags: _1!, showPreviews: _2, silent: _3, muteUntil: _4, iosSound: _5, androidSound: _6, otherSound: _7)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
|
|
|
|||
|
|
@ -594,6 +594,7 @@ public extension Api {
|
|||
case updateReadMessagesContents(messages: [Int32], pts: Int32, ptsCount: Int32)
|
||||
case updateRecentStickers
|
||||
case updateSavedGifs
|
||||
case updateSavedRingtones
|
||||
case updateServiceNotification(flags: Int32, inboxDate: Int32?, type: String, message: String, media: Api.MessageMedia, entities: [Api.MessageEntity])
|
||||
case updateStickerSets
|
||||
case updateStickerSetsOrder(flags: Int32, order: [Int64])
|
||||
|
|
@ -1380,6 +1381,12 @@ public extension Api {
|
|||
buffer.appendInt32(-1821035490)
|
||||
}
|
||||
|
||||
break
|
||||
case .updateSavedRingtones:
|
||||
if boxed {
|
||||
buffer.appendInt32(1960361625)
|
||||
}
|
||||
|
||||
break
|
||||
case .updateServiceNotification(let flags, let inboxDate, let type, let message, let media, let entities):
|
||||
if boxed {
|
||||
|
|
@ -1655,6 +1662,8 @@ public extension Api {
|
|||
return ("updateRecentStickers", [])
|
||||
case .updateSavedGifs:
|
||||
return ("updateSavedGifs", [])
|
||||
case .updateSavedRingtones:
|
||||
return ("updateSavedRingtones", [])
|
||||
case .updateServiceNotification(let flags, let inboxDate, let type, let message, let media, let entities):
|
||||
return ("updateServiceNotification", [("flags", String(describing: flags)), ("inboxDate", String(describing: inboxDate)), ("type", String(describing: type)), ("message", String(describing: message)), ("media", String(describing: media)), ("entities", String(describing: entities))])
|
||||
case .updateStickerSets:
|
||||
|
|
@ -3265,6 +3274,9 @@ public extension Api {
|
|||
public static func parse_updateSavedGifs(_ reader: BufferReader) -> Update? {
|
||||
return Api.Update.updateSavedGifs
|
||||
}
|
||||
public static func parse_updateSavedRingtones(_ reader: BufferReader) -> Update? {
|
||||
return Api.Update.updateSavedRingtones
|
||||
}
|
||||
public static func parse_updateServiceNotification(_ reader: BufferReader) -> Update? {
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
|
|
|
|||
|
|
@ -690,6 +690,64 @@ public extension Api.account {
|
|||
|
||||
}
|
||||
}
|
||||
public extension Api.account {
|
||||
enum SavedRingtones: TypeConstructorDescription {
|
||||
case savedRingtones(hash: Int64, ringtones: [Api.Document])
|
||||
case savedRingtonesNotModified
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .savedRingtones(let hash, let ringtones):
|
||||
if boxed {
|
||||
buffer.appendInt32(-1041683259)
|
||||
}
|
||||
serializeInt64(hash, buffer: buffer, boxed: false)
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(ringtones.count))
|
||||
for item in ringtones {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
break
|
||||
case .savedRingtonesNotModified:
|
||||
if boxed {
|
||||
buffer.appendInt32(-67704655)
|
||||
}
|
||||
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .savedRingtones(let hash, let ringtones):
|
||||
return ("savedRingtones", [("hash", String(describing: hash)), ("ringtones", String(describing: ringtones))])
|
||||
case .savedRingtonesNotModified:
|
||||
return ("savedRingtonesNotModified", [])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_savedRingtones(_ reader: BufferReader) -> SavedRingtones? {
|
||||
var _1: Int64?
|
||||
_1 = reader.readInt64()
|
||||
var _2: [Api.Document]?
|
||||
if let _ = reader.readInt32() {
|
||||
_2 = Api.parseVector(reader, elementSignature: 0, elementType: Api.Document.self)
|
||||
}
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
if _c1 && _c2 {
|
||||
return Api.account.SavedRingtones.savedRingtones(hash: _1!, ringtones: _2!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
public static func parse_savedRingtonesNotModified(_ reader: BufferReader) -> SavedRingtones? {
|
||||
return Api.account.SavedRingtones.savedRingtonesNotModified
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api.account {
|
||||
enum SentEmailCode: TypeConstructorDescription {
|
||||
case sentEmailCode(emailPattern: String, length: Int32)
|
||||
|
|
@ -1154,129 +1212,3 @@ public extension Api.auth {
|
|||
|
||||
}
|
||||
}
|
||||
public extension Api.auth {
|
||||
enum LoggedOut: TypeConstructorDescription {
|
||||
case loggedOut(flags: Int32, futureAuthToken: Buffer?)
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .loggedOut(let flags, let futureAuthToken):
|
||||
if boxed {
|
||||
buffer.appendInt32(-1012759713)
|
||||
}
|
||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||
if Int(flags) & Int(1 << 0) != 0 {serializeBytes(futureAuthToken!, buffer: buffer, boxed: false)}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .loggedOut(let flags, let futureAuthToken):
|
||||
return ("loggedOut", [("flags", String(describing: flags)), ("futureAuthToken", String(describing: futureAuthToken))])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_loggedOut(_ reader: BufferReader) -> LoggedOut? {
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
var _2: Buffer?
|
||||
if Int(_1!) & Int(1 << 0) != 0 {_2 = parseBytes(reader) }
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = (Int(_1!) & Int(1 << 0) == 0) || _2 != nil
|
||||
if _c1 && _c2 {
|
||||
return Api.auth.LoggedOut.loggedOut(flags: _1!, futureAuthToken: _2)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api.auth {
|
||||
enum LoginToken: TypeConstructorDescription {
|
||||
case loginToken(expires: Int32, token: Buffer)
|
||||
case loginTokenMigrateTo(dcId: Int32, token: Buffer)
|
||||
case loginTokenSuccess(authorization: Api.auth.Authorization)
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .loginToken(let expires, let token):
|
||||
if boxed {
|
||||
buffer.appendInt32(1654593920)
|
||||
}
|
||||
serializeInt32(expires, buffer: buffer, boxed: false)
|
||||
serializeBytes(token, buffer: buffer, boxed: false)
|
||||
break
|
||||
case .loginTokenMigrateTo(let dcId, let token):
|
||||
if boxed {
|
||||
buffer.appendInt32(110008598)
|
||||
}
|
||||
serializeInt32(dcId, buffer: buffer, boxed: false)
|
||||
serializeBytes(token, buffer: buffer, boxed: false)
|
||||
break
|
||||
case .loginTokenSuccess(let authorization):
|
||||
if boxed {
|
||||
buffer.appendInt32(957176926)
|
||||
}
|
||||
authorization.serialize(buffer, true)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .loginToken(let expires, let token):
|
||||
return ("loginToken", [("expires", String(describing: expires)), ("token", String(describing: token))])
|
||||
case .loginTokenMigrateTo(let dcId, let token):
|
||||
return ("loginTokenMigrateTo", [("dcId", String(describing: dcId)), ("token", String(describing: token))])
|
||||
case .loginTokenSuccess(let authorization):
|
||||
return ("loginTokenSuccess", [("authorization", String(describing: authorization))])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_loginToken(_ reader: BufferReader) -> LoginToken? {
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
var _2: Buffer?
|
||||
_2 = parseBytes(reader)
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
if _c1 && _c2 {
|
||||
return Api.auth.LoginToken.loginToken(expires: _1!, token: _2!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
public static func parse_loginTokenMigrateTo(_ reader: BufferReader) -> LoginToken? {
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
var _2: Buffer?
|
||||
_2 = parseBytes(reader)
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
if _c1 && _c2 {
|
||||
return Api.auth.LoginToken.loginTokenMigrateTo(dcId: _1!, token: _2!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
public static func parse_loginTokenSuccess(_ reader: BufferReader) -> LoginToken? {
|
||||
var _1: Api.auth.Authorization?
|
||||
if let signature = reader.readInt32() {
|
||||
_1 = Api.parse(reader, signature: signature) as? Api.auth.Authorization
|
||||
}
|
||||
let _c1 = _1 != nil
|
||||
if _c1 {
|
||||
return Api.auth.LoginToken.loginTokenSuccess(authorization: _1!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,129 @@
|
|||
public extension Api.auth {
|
||||
enum LoggedOut: TypeConstructorDescription {
|
||||
case loggedOut(flags: Int32, futureAuthToken: Buffer?)
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .loggedOut(let flags, let futureAuthToken):
|
||||
if boxed {
|
||||
buffer.appendInt32(-1012759713)
|
||||
}
|
||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||
if Int(flags) & Int(1 << 0) != 0 {serializeBytes(futureAuthToken!, buffer: buffer, boxed: false)}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .loggedOut(let flags, let futureAuthToken):
|
||||
return ("loggedOut", [("flags", String(describing: flags)), ("futureAuthToken", String(describing: futureAuthToken))])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_loggedOut(_ reader: BufferReader) -> LoggedOut? {
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
var _2: Buffer?
|
||||
if Int(_1!) & Int(1 << 0) != 0 {_2 = parseBytes(reader) }
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = (Int(_1!) & Int(1 << 0) == 0) || _2 != nil
|
||||
if _c1 && _c2 {
|
||||
return Api.auth.LoggedOut.loggedOut(flags: _1!, futureAuthToken: _2)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api.auth {
|
||||
enum LoginToken: TypeConstructorDescription {
|
||||
case loginToken(expires: Int32, token: Buffer)
|
||||
case loginTokenMigrateTo(dcId: Int32, token: Buffer)
|
||||
case loginTokenSuccess(authorization: Api.auth.Authorization)
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .loginToken(let expires, let token):
|
||||
if boxed {
|
||||
buffer.appendInt32(1654593920)
|
||||
}
|
||||
serializeInt32(expires, buffer: buffer, boxed: false)
|
||||
serializeBytes(token, buffer: buffer, boxed: false)
|
||||
break
|
||||
case .loginTokenMigrateTo(let dcId, let token):
|
||||
if boxed {
|
||||
buffer.appendInt32(110008598)
|
||||
}
|
||||
serializeInt32(dcId, buffer: buffer, boxed: false)
|
||||
serializeBytes(token, buffer: buffer, boxed: false)
|
||||
break
|
||||
case .loginTokenSuccess(let authorization):
|
||||
if boxed {
|
||||
buffer.appendInt32(957176926)
|
||||
}
|
||||
authorization.serialize(buffer, true)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .loginToken(let expires, let token):
|
||||
return ("loginToken", [("expires", String(describing: expires)), ("token", String(describing: token))])
|
||||
case .loginTokenMigrateTo(let dcId, let token):
|
||||
return ("loginTokenMigrateTo", [("dcId", String(describing: dcId)), ("token", String(describing: token))])
|
||||
case .loginTokenSuccess(let authorization):
|
||||
return ("loginTokenSuccess", [("authorization", String(describing: authorization))])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_loginToken(_ reader: BufferReader) -> LoginToken? {
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
var _2: Buffer?
|
||||
_2 = parseBytes(reader)
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
if _c1 && _c2 {
|
||||
return Api.auth.LoginToken.loginToken(expires: _1!, token: _2!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
public static func parse_loginTokenMigrateTo(_ reader: BufferReader) -> LoginToken? {
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
var _2: Buffer?
|
||||
_2 = parseBytes(reader)
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
if _c1 && _c2 {
|
||||
return Api.auth.LoginToken.loginTokenMigrateTo(dcId: _1!, token: _2!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
public static func parse_loginTokenSuccess(_ reader: BufferReader) -> LoginToken? {
|
||||
var _1: Api.auth.Authorization?
|
||||
if let signature = reader.readInt32() {
|
||||
_1 = Api.parse(reader, signature: signature) as? Api.auth.Authorization
|
||||
}
|
||||
let _c1 = _1 != nil
|
||||
if _c1 {
|
||||
return Api.auth.LoginToken.loginTokenSuccess(authorization: _1!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api.auth {
|
||||
enum PasswordRecovery: TypeConstructorDescription {
|
||||
case passwordRecovery(emailPattern: String)
|
||||
|
|
@ -1178,183 +1304,3 @@ public extension Api.help {
|
|||
|
||||
}
|
||||
}
|
||||
public extension Api.help {
|
||||
enum Country: TypeConstructorDescription {
|
||||
case country(flags: Int32, iso2: String, defaultName: String, name: String?, countryCodes: [Api.help.CountryCode])
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .country(let flags, let iso2, let defaultName, let name, let countryCodes):
|
||||
if boxed {
|
||||
buffer.appendInt32(-1014526429)
|
||||
}
|
||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||
serializeString(iso2, buffer: buffer, boxed: false)
|
||||
serializeString(defaultName, buffer: buffer, boxed: false)
|
||||
if Int(flags) & Int(1 << 1) != 0 {serializeString(name!, buffer: buffer, boxed: false)}
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(countryCodes.count))
|
||||
for item in countryCodes {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .country(let flags, let iso2, let defaultName, let name, let countryCodes):
|
||||
return ("country", [("flags", String(describing: flags)), ("iso2", String(describing: iso2)), ("defaultName", String(describing: defaultName)), ("name", String(describing: name)), ("countryCodes", String(describing: countryCodes))])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_country(_ reader: BufferReader) -> Country? {
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
var _2: String?
|
||||
_2 = parseString(reader)
|
||||
var _3: String?
|
||||
_3 = parseString(reader)
|
||||
var _4: String?
|
||||
if Int(_1!) & Int(1 << 1) != 0 {_4 = parseString(reader) }
|
||||
var _5: [Api.help.CountryCode]?
|
||||
if let _ = reader.readInt32() {
|
||||
_5 = Api.parseVector(reader, elementSignature: 0, elementType: Api.help.CountryCode.self)
|
||||
}
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
let _c3 = _3 != nil
|
||||
let _c4 = (Int(_1!) & Int(1 << 1) == 0) || _4 != nil
|
||||
let _c5 = _5 != nil
|
||||
if _c1 && _c2 && _c3 && _c4 && _c5 {
|
||||
return Api.help.Country.country(flags: _1!, iso2: _2!, defaultName: _3!, name: _4, countryCodes: _5!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api.help {
|
||||
enum CountryCode: TypeConstructorDescription {
|
||||
case countryCode(flags: Int32, countryCode: String, prefixes: [String]?, patterns: [String]?)
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .countryCode(let flags, let countryCode, let prefixes, let patterns):
|
||||
if boxed {
|
||||
buffer.appendInt32(1107543535)
|
||||
}
|
||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||
serializeString(countryCode, buffer: buffer, boxed: false)
|
||||
if Int(flags) & Int(1 << 0) != 0 {buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(prefixes!.count))
|
||||
for item in prefixes! {
|
||||
serializeString(item, buffer: buffer, boxed: false)
|
||||
}}
|
||||
if Int(flags) & Int(1 << 1) != 0 {buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(patterns!.count))
|
||||
for item in patterns! {
|
||||
serializeString(item, buffer: buffer, boxed: false)
|
||||
}}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .countryCode(let flags, let countryCode, let prefixes, let patterns):
|
||||
return ("countryCode", [("flags", String(describing: flags)), ("countryCode", String(describing: countryCode)), ("prefixes", String(describing: prefixes)), ("patterns", String(describing: patterns))])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_countryCode(_ reader: BufferReader) -> CountryCode? {
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
var _2: String?
|
||||
_2 = parseString(reader)
|
||||
var _3: [String]?
|
||||
if Int(_1!) & Int(1 << 0) != 0 {if let _ = reader.readInt32() {
|
||||
_3 = Api.parseVector(reader, elementSignature: -1255641564, elementType: String.self)
|
||||
} }
|
||||
var _4: [String]?
|
||||
if Int(_1!) & Int(1 << 1) != 0 {if let _ = reader.readInt32() {
|
||||
_4 = Api.parseVector(reader, elementSignature: -1255641564, elementType: String.self)
|
||||
} }
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
let _c3 = (Int(_1!) & Int(1 << 0) == 0) || _3 != nil
|
||||
let _c4 = (Int(_1!) & Int(1 << 1) == 0) || _4 != nil
|
||||
if _c1 && _c2 && _c3 && _c4 {
|
||||
return Api.help.CountryCode.countryCode(flags: _1!, countryCode: _2!, prefixes: _3, patterns: _4)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api.help {
|
||||
enum DeepLinkInfo: TypeConstructorDescription {
|
||||
case deepLinkInfo(flags: Int32, message: String, entities: [Api.MessageEntity]?)
|
||||
case deepLinkInfoEmpty
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .deepLinkInfo(let flags, let message, let entities):
|
||||
if boxed {
|
||||
buffer.appendInt32(1783556146)
|
||||
}
|
||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||
serializeString(message, buffer: buffer, boxed: false)
|
||||
if Int(flags) & Int(1 << 1) != 0 {buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(entities!.count))
|
||||
for item in entities! {
|
||||
item.serialize(buffer, true)
|
||||
}}
|
||||
break
|
||||
case .deepLinkInfoEmpty:
|
||||
if boxed {
|
||||
buffer.appendInt32(1722786150)
|
||||
}
|
||||
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .deepLinkInfo(let flags, let message, let entities):
|
||||
return ("deepLinkInfo", [("flags", String(describing: flags)), ("message", String(describing: message)), ("entities", String(describing: entities))])
|
||||
case .deepLinkInfoEmpty:
|
||||
return ("deepLinkInfoEmpty", [])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_deepLinkInfo(_ reader: BufferReader) -> DeepLinkInfo? {
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
var _2: String?
|
||||
_2 = parseString(reader)
|
||||
var _3: [Api.MessageEntity]?
|
||||
if Int(_1!) & Int(1 << 1) != 0 {if let _ = reader.readInt32() {
|
||||
_3 = Api.parseVector(reader, elementSignature: 0, elementType: Api.MessageEntity.self)
|
||||
} }
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
let _c3 = (Int(_1!) & Int(1 << 1) == 0) || _3 != nil
|
||||
if _c1 && _c2 && _c3 {
|
||||
return Api.help.DeepLinkInfo.deepLinkInfo(flags: _1!, message: _2!, entities: _3)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
public static func parse_deepLinkInfoEmpty(_ reader: BufferReader) -> DeepLinkInfo? {
|
||||
return Api.help.DeepLinkInfo.deepLinkInfoEmpty
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,183 @@
|
|||
public extension Api.help {
|
||||
enum Country: TypeConstructorDescription {
|
||||
case country(flags: Int32, iso2: String, defaultName: String, name: String?, countryCodes: [Api.help.CountryCode])
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .country(let flags, let iso2, let defaultName, let name, let countryCodes):
|
||||
if boxed {
|
||||
buffer.appendInt32(-1014526429)
|
||||
}
|
||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||
serializeString(iso2, buffer: buffer, boxed: false)
|
||||
serializeString(defaultName, buffer: buffer, boxed: false)
|
||||
if Int(flags) & Int(1 << 1) != 0 {serializeString(name!, buffer: buffer, boxed: false)}
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(countryCodes.count))
|
||||
for item in countryCodes {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .country(let flags, let iso2, let defaultName, let name, let countryCodes):
|
||||
return ("country", [("flags", String(describing: flags)), ("iso2", String(describing: iso2)), ("defaultName", String(describing: defaultName)), ("name", String(describing: name)), ("countryCodes", String(describing: countryCodes))])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_country(_ reader: BufferReader) -> Country? {
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
var _2: String?
|
||||
_2 = parseString(reader)
|
||||
var _3: String?
|
||||
_3 = parseString(reader)
|
||||
var _4: String?
|
||||
if Int(_1!) & Int(1 << 1) != 0 {_4 = parseString(reader) }
|
||||
var _5: [Api.help.CountryCode]?
|
||||
if let _ = reader.readInt32() {
|
||||
_5 = Api.parseVector(reader, elementSignature: 0, elementType: Api.help.CountryCode.self)
|
||||
}
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
let _c3 = _3 != nil
|
||||
let _c4 = (Int(_1!) & Int(1 << 1) == 0) || _4 != nil
|
||||
let _c5 = _5 != nil
|
||||
if _c1 && _c2 && _c3 && _c4 && _c5 {
|
||||
return Api.help.Country.country(flags: _1!, iso2: _2!, defaultName: _3!, name: _4, countryCodes: _5!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api.help {
|
||||
enum CountryCode: TypeConstructorDescription {
|
||||
case countryCode(flags: Int32, countryCode: String, prefixes: [String]?, patterns: [String]?)
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .countryCode(let flags, let countryCode, let prefixes, let patterns):
|
||||
if boxed {
|
||||
buffer.appendInt32(1107543535)
|
||||
}
|
||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||
serializeString(countryCode, buffer: buffer, boxed: false)
|
||||
if Int(flags) & Int(1 << 0) != 0 {buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(prefixes!.count))
|
||||
for item in prefixes! {
|
||||
serializeString(item, buffer: buffer, boxed: false)
|
||||
}}
|
||||
if Int(flags) & Int(1 << 1) != 0 {buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(patterns!.count))
|
||||
for item in patterns! {
|
||||
serializeString(item, buffer: buffer, boxed: false)
|
||||
}}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .countryCode(let flags, let countryCode, let prefixes, let patterns):
|
||||
return ("countryCode", [("flags", String(describing: flags)), ("countryCode", String(describing: countryCode)), ("prefixes", String(describing: prefixes)), ("patterns", String(describing: patterns))])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_countryCode(_ reader: BufferReader) -> CountryCode? {
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
var _2: String?
|
||||
_2 = parseString(reader)
|
||||
var _3: [String]?
|
||||
if Int(_1!) & Int(1 << 0) != 0 {if let _ = reader.readInt32() {
|
||||
_3 = Api.parseVector(reader, elementSignature: -1255641564, elementType: String.self)
|
||||
} }
|
||||
var _4: [String]?
|
||||
if Int(_1!) & Int(1 << 1) != 0 {if let _ = reader.readInt32() {
|
||||
_4 = Api.parseVector(reader, elementSignature: -1255641564, elementType: String.self)
|
||||
} }
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
let _c3 = (Int(_1!) & Int(1 << 0) == 0) || _3 != nil
|
||||
let _c4 = (Int(_1!) & Int(1 << 1) == 0) || _4 != nil
|
||||
if _c1 && _c2 && _c3 && _c4 {
|
||||
return Api.help.CountryCode.countryCode(flags: _1!, countryCode: _2!, prefixes: _3, patterns: _4)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api.help {
|
||||
enum DeepLinkInfo: TypeConstructorDescription {
|
||||
case deepLinkInfo(flags: Int32, message: String, entities: [Api.MessageEntity]?)
|
||||
case deepLinkInfoEmpty
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .deepLinkInfo(let flags, let message, let entities):
|
||||
if boxed {
|
||||
buffer.appendInt32(1783556146)
|
||||
}
|
||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||
serializeString(message, buffer: buffer, boxed: false)
|
||||
if Int(flags) & Int(1 << 1) != 0 {buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(entities!.count))
|
||||
for item in entities! {
|
||||
item.serialize(buffer, true)
|
||||
}}
|
||||
break
|
||||
case .deepLinkInfoEmpty:
|
||||
if boxed {
|
||||
buffer.appendInt32(1722786150)
|
||||
}
|
||||
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .deepLinkInfo(let flags, let message, let entities):
|
||||
return ("deepLinkInfo", [("flags", String(describing: flags)), ("message", String(describing: message)), ("entities", String(describing: entities))])
|
||||
case .deepLinkInfoEmpty:
|
||||
return ("deepLinkInfoEmpty", [])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_deepLinkInfo(_ reader: BufferReader) -> DeepLinkInfo? {
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
var _2: String?
|
||||
_2 = parseString(reader)
|
||||
var _3: [Api.MessageEntity]?
|
||||
if Int(_1!) & Int(1 << 1) != 0 {if let _ = reader.readInt32() {
|
||||
_3 = Api.parseVector(reader, elementSignature: 0, elementType: Api.MessageEntity.self)
|
||||
} }
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
let _c3 = (Int(_1!) & Int(1 << 1) == 0) || _3 != nil
|
||||
if _c1 && _c2 && _c3 {
|
||||
return Api.help.DeepLinkInfo.deepLinkInfo(flags: _1!, message: _2!, entities: _3)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
public static func parse_deepLinkInfoEmpty(_ reader: BufferReader) -> DeepLinkInfo? {
|
||||
return Api.help.DeepLinkInfo.deepLinkInfoEmpty
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api.help {
|
||||
enum InviteText: TypeConstructorDescription {
|
||||
case inviteText(message: String)
|
||||
|
|
@ -1170,259 +1350,3 @@ public extension Api.messages {
|
|||
|
||||
}
|
||||
}
|
||||
public extension Api.messages {
|
||||
enum CheckedHistoryImportPeer: TypeConstructorDescription {
|
||||
case checkedHistoryImportPeer(confirmText: String)
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .checkedHistoryImportPeer(let confirmText):
|
||||
if boxed {
|
||||
buffer.appendInt32(-1571952873)
|
||||
}
|
||||
serializeString(confirmText, buffer: buffer, boxed: false)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .checkedHistoryImportPeer(let confirmText):
|
||||
return ("checkedHistoryImportPeer", [("confirmText", String(describing: confirmText))])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_checkedHistoryImportPeer(_ reader: BufferReader) -> CheckedHistoryImportPeer? {
|
||||
var _1: String?
|
||||
_1 = parseString(reader)
|
||||
let _c1 = _1 != nil
|
||||
if _c1 {
|
||||
return Api.messages.CheckedHistoryImportPeer.checkedHistoryImportPeer(confirmText: _1!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api.messages {
|
||||
enum DhConfig: TypeConstructorDescription {
|
||||
case dhConfig(g: Int32, p: Buffer, version: Int32, random: Buffer)
|
||||
case dhConfigNotModified(random: Buffer)
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .dhConfig(let g, let p, let version, let random):
|
||||
if boxed {
|
||||
buffer.appendInt32(740433629)
|
||||
}
|
||||
serializeInt32(g, buffer: buffer, boxed: false)
|
||||
serializeBytes(p, buffer: buffer, boxed: false)
|
||||
serializeInt32(version, buffer: buffer, boxed: false)
|
||||
serializeBytes(random, buffer: buffer, boxed: false)
|
||||
break
|
||||
case .dhConfigNotModified(let random):
|
||||
if boxed {
|
||||
buffer.appendInt32(-1058912715)
|
||||
}
|
||||
serializeBytes(random, buffer: buffer, boxed: false)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .dhConfig(let g, let p, let version, let random):
|
||||
return ("dhConfig", [("g", String(describing: g)), ("p", String(describing: p)), ("version", String(describing: version)), ("random", String(describing: random))])
|
||||
case .dhConfigNotModified(let random):
|
||||
return ("dhConfigNotModified", [("random", String(describing: random))])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_dhConfig(_ reader: BufferReader) -> DhConfig? {
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
var _2: Buffer?
|
||||
_2 = parseBytes(reader)
|
||||
var _3: Int32?
|
||||
_3 = reader.readInt32()
|
||||
var _4: Buffer?
|
||||
_4 = parseBytes(reader)
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
let _c3 = _3 != nil
|
||||
let _c4 = _4 != nil
|
||||
if _c1 && _c2 && _c3 && _c4 {
|
||||
return Api.messages.DhConfig.dhConfig(g: _1!, p: _2!, version: _3!, random: _4!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
public static func parse_dhConfigNotModified(_ reader: BufferReader) -> DhConfig? {
|
||||
var _1: Buffer?
|
||||
_1 = parseBytes(reader)
|
||||
let _c1 = _1 != nil
|
||||
if _c1 {
|
||||
return Api.messages.DhConfig.dhConfigNotModified(random: _1!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api.messages {
|
||||
enum Dialogs: TypeConstructorDescription {
|
||||
case dialogs(dialogs: [Api.Dialog], messages: [Api.Message], chats: [Api.Chat], users: [Api.User])
|
||||
case dialogsNotModified(count: Int32)
|
||||
case dialogsSlice(count: Int32, dialogs: [Api.Dialog], messages: [Api.Message], chats: [Api.Chat], users: [Api.User])
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .dialogs(let dialogs, let messages, let chats, let users):
|
||||
if boxed {
|
||||
buffer.appendInt32(364538944)
|
||||
}
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(dialogs.count))
|
||||
for item in dialogs {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(messages.count))
|
||||
for item in messages {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(chats.count))
|
||||
for item in chats {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(users.count))
|
||||
for item in users {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
break
|
||||
case .dialogsNotModified(let count):
|
||||
if boxed {
|
||||
buffer.appendInt32(-253500010)
|
||||
}
|
||||
serializeInt32(count, buffer: buffer, boxed: false)
|
||||
break
|
||||
case .dialogsSlice(let count, let dialogs, let messages, let chats, let users):
|
||||
if boxed {
|
||||
buffer.appendInt32(1910543603)
|
||||
}
|
||||
serializeInt32(count, buffer: buffer, boxed: false)
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(dialogs.count))
|
||||
for item in dialogs {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(messages.count))
|
||||
for item in messages {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(chats.count))
|
||||
for item in chats {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(users.count))
|
||||
for item in users {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .dialogs(let dialogs, let messages, let chats, let users):
|
||||
return ("dialogs", [("dialogs", String(describing: dialogs)), ("messages", String(describing: messages)), ("chats", String(describing: chats)), ("users", String(describing: users))])
|
||||
case .dialogsNotModified(let count):
|
||||
return ("dialogsNotModified", [("count", String(describing: count))])
|
||||
case .dialogsSlice(let count, let dialogs, let messages, let chats, let users):
|
||||
return ("dialogsSlice", [("count", String(describing: count)), ("dialogs", String(describing: dialogs)), ("messages", String(describing: messages)), ("chats", String(describing: chats)), ("users", String(describing: users))])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_dialogs(_ reader: BufferReader) -> Dialogs? {
|
||||
var _1: [Api.Dialog]?
|
||||
if let _ = reader.readInt32() {
|
||||
_1 = Api.parseVector(reader, elementSignature: 0, elementType: Api.Dialog.self)
|
||||
}
|
||||
var _2: [Api.Message]?
|
||||
if let _ = reader.readInt32() {
|
||||
_2 = Api.parseVector(reader, elementSignature: 0, elementType: Api.Message.self)
|
||||
}
|
||||
var _3: [Api.Chat]?
|
||||
if let _ = reader.readInt32() {
|
||||
_3 = Api.parseVector(reader, elementSignature: 0, elementType: Api.Chat.self)
|
||||
}
|
||||
var _4: [Api.User]?
|
||||
if let _ = reader.readInt32() {
|
||||
_4 = Api.parseVector(reader, elementSignature: 0, elementType: Api.User.self)
|
||||
}
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
let _c3 = _3 != nil
|
||||
let _c4 = _4 != nil
|
||||
if _c1 && _c2 && _c3 && _c4 {
|
||||
return Api.messages.Dialogs.dialogs(dialogs: _1!, messages: _2!, chats: _3!, users: _4!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
public static func parse_dialogsNotModified(_ reader: BufferReader) -> Dialogs? {
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
let _c1 = _1 != nil
|
||||
if _c1 {
|
||||
return Api.messages.Dialogs.dialogsNotModified(count: _1!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
public static func parse_dialogsSlice(_ reader: BufferReader) -> Dialogs? {
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
var _2: [Api.Dialog]?
|
||||
if let _ = reader.readInt32() {
|
||||
_2 = Api.parseVector(reader, elementSignature: 0, elementType: Api.Dialog.self)
|
||||
}
|
||||
var _3: [Api.Message]?
|
||||
if let _ = reader.readInt32() {
|
||||
_3 = Api.parseVector(reader, elementSignature: 0, elementType: Api.Message.self)
|
||||
}
|
||||
var _4: [Api.Chat]?
|
||||
if let _ = reader.readInt32() {
|
||||
_4 = Api.parseVector(reader, elementSignature: 0, elementType: Api.Chat.self)
|
||||
}
|
||||
var _5: [Api.User]?
|
||||
if let _ = reader.readInt32() {
|
||||
_5 = Api.parseVector(reader, elementSignature: 0, elementType: Api.User.self)
|
||||
}
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
let _c3 = _3 != nil
|
||||
let _c4 = _4 != nil
|
||||
let _c5 = _5 != nil
|
||||
if _c1 && _c2 && _c3 && _c4 && _c5 {
|
||||
return Api.messages.Dialogs.dialogsSlice(count: _1!, dialogs: _2!, messages: _3!, chats: _4!, users: _5!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,259 @@
|
|||
public extension Api.messages {
|
||||
enum CheckedHistoryImportPeer: TypeConstructorDescription {
|
||||
case checkedHistoryImportPeer(confirmText: String)
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .checkedHistoryImportPeer(let confirmText):
|
||||
if boxed {
|
||||
buffer.appendInt32(-1571952873)
|
||||
}
|
||||
serializeString(confirmText, buffer: buffer, boxed: false)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .checkedHistoryImportPeer(let confirmText):
|
||||
return ("checkedHistoryImportPeer", [("confirmText", String(describing: confirmText))])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_checkedHistoryImportPeer(_ reader: BufferReader) -> CheckedHistoryImportPeer? {
|
||||
var _1: String?
|
||||
_1 = parseString(reader)
|
||||
let _c1 = _1 != nil
|
||||
if _c1 {
|
||||
return Api.messages.CheckedHistoryImportPeer.checkedHistoryImportPeer(confirmText: _1!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api.messages {
|
||||
enum DhConfig: TypeConstructorDescription {
|
||||
case dhConfig(g: Int32, p: Buffer, version: Int32, random: Buffer)
|
||||
case dhConfigNotModified(random: Buffer)
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .dhConfig(let g, let p, let version, let random):
|
||||
if boxed {
|
||||
buffer.appendInt32(740433629)
|
||||
}
|
||||
serializeInt32(g, buffer: buffer, boxed: false)
|
||||
serializeBytes(p, buffer: buffer, boxed: false)
|
||||
serializeInt32(version, buffer: buffer, boxed: false)
|
||||
serializeBytes(random, buffer: buffer, boxed: false)
|
||||
break
|
||||
case .dhConfigNotModified(let random):
|
||||
if boxed {
|
||||
buffer.appendInt32(-1058912715)
|
||||
}
|
||||
serializeBytes(random, buffer: buffer, boxed: false)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .dhConfig(let g, let p, let version, let random):
|
||||
return ("dhConfig", [("g", String(describing: g)), ("p", String(describing: p)), ("version", String(describing: version)), ("random", String(describing: random))])
|
||||
case .dhConfigNotModified(let random):
|
||||
return ("dhConfigNotModified", [("random", String(describing: random))])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_dhConfig(_ reader: BufferReader) -> DhConfig? {
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
var _2: Buffer?
|
||||
_2 = parseBytes(reader)
|
||||
var _3: Int32?
|
||||
_3 = reader.readInt32()
|
||||
var _4: Buffer?
|
||||
_4 = parseBytes(reader)
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
let _c3 = _3 != nil
|
||||
let _c4 = _4 != nil
|
||||
if _c1 && _c2 && _c3 && _c4 {
|
||||
return Api.messages.DhConfig.dhConfig(g: _1!, p: _2!, version: _3!, random: _4!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
public static func parse_dhConfigNotModified(_ reader: BufferReader) -> DhConfig? {
|
||||
var _1: Buffer?
|
||||
_1 = parseBytes(reader)
|
||||
let _c1 = _1 != nil
|
||||
if _c1 {
|
||||
return Api.messages.DhConfig.dhConfigNotModified(random: _1!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api.messages {
|
||||
enum Dialogs: TypeConstructorDescription {
|
||||
case dialogs(dialogs: [Api.Dialog], messages: [Api.Message], chats: [Api.Chat], users: [Api.User])
|
||||
case dialogsNotModified(count: Int32)
|
||||
case dialogsSlice(count: Int32, dialogs: [Api.Dialog], messages: [Api.Message], chats: [Api.Chat], users: [Api.User])
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .dialogs(let dialogs, let messages, let chats, let users):
|
||||
if boxed {
|
||||
buffer.appendInt32(364538944)
|
||||
}
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(dialogs.count))
|
||||
for item in dialogs {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(messages.count))
|
||||
for item in messages {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(chats.count))
|
||||
for item in chats {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(users.count))
|
||||
for item in users {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
break
|
||||
case .dialogsNotModified(let count):
|
||||
if boxed {
|
||||
buffer.appendInt32(-253500010)
|
||||
}
|
||||
serializeInt32(count, buffer: buffer, boxed: false)
|
||||
break
|
||||
case .dialogsSlice(let count, let dialogs, let messages, let chats, let users):
|
||||
if boxed {
|
||||
buffer.appendInt32(1910543603)
|
||||
}
|
||||
serializeInt32(count, buffer: buffer, boxed: false)
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(dialogs.count))
|
||||
for item in dialogs {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(messages.count))
|
||||
for item in messages {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(chats.count))
|
||||
for item in chats {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(users.count))
|
||||
for item in users {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .dialogs(let dialogs, let messages, let chats, let users):
|
||||
return ("dialogs", [("dialogs", String(describing: dialogs)), ("messages", String(describing: messages)), ("chats", String(describing: chats)), ("users", String(describing: users))])
|
||||
case .dialogsNotModified(let count):
|
||||
return ("dialogsNotModified", [("count", String(describing: count))])
|
||||
case .dialogsSlice(let count, let dialogs, let messages, let chats, let users):
|
||||
return ("dialogsSlice", [("count", String(describing: count)), ("dialogs", String(describing: dialogs)), ("messages", String(describing: messages)), ("chats", String(describing: chats)), ("users", String(describing: users))])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_dialogs(_ reader: BufferReader) -> Dialogs? {
|
||||
var _1: [Api.Dialog]?
|
||||
if let _ = reader.readInt32() {
|
||||
_1 = Api.parseVector(reader, elementSignature: 0, elementType: Api.Dialog.self)
|
||||
}
|
||||
var _2: [Api.Message]?
|
||||
if let _ = reader.readInt32() {
|
||||
_2 = Api.parseVector(reader, elementSignature: 0, elementType: Api.Message.self)
|
||||
}
|
||||
var _3: [Api.Chat]?
|
||||
if let _ = reader.readInt32() {
|
||||
_3 = Api.parseVector(reader, elementSignature: 0, elementType: Api.Chat.self)
|
||||
}
|
||||
var _4: [Api.User]?
|
||||
if let _ = reader.readInt32() {
|
||||
_4 = Api.parseVector(reader, elementSignature: 0, elementType: Api.User.self)
|
||||
}
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
let _c3 = _3 != nil
|
||||
let _c4 = _4 != nil
|
||||
if _c1 && _c2 && _c3 && _c4 {
|
||||
return Api.messages.Dialogs.dialogs(dialogs: _1!, messages: _2!, chats: _3!, users: _4!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
public static func parse_dialogsNotModified(_ reader: BufferReader) -> Dialogs? {
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
let _c1 = _1 != nil
|
||||
if _c1 {
|
||||
return Api.messages.Dialogs.dialogsNotModified(count: _1!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
public static func parse_dialogsSlice(_ reader: BufferReader) -> Dialogs? {
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
var _2: [Api.Dialog]?
|
||||
if let _ = reader.readInt32() {
|
||||
_2 = Api.parseVector(reader, elementSignature: 0, elementType: Api.Dialog.self)
|
||||
}
|
||||
var _3: [Api.Message]?
|
||||
if let _ = reader.readInt32() {
|
||||
_3 = Api.parseVector(reader, elementSignature: 0, elementType: Api.Message.self)
|
||||
}
|
||||
var _4: [Api.Chat]?
|
||||
if let _ = reader.readInt32() {
|
||||
_4 = Api.parseVector(reader, elementSignature: 0, elementType: Api.Chat.self)
|
||||
}
|
||||
var _5: [Api.User]?
|
||||
if let _ = reader.readInt32() {
|
||||
_5 = Api.parseVector(reader, elementSignature: 0, elementType: Api.User.self)
|
||||
}
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
let _c3 = _3 != nil
|
||||
let _c4 = _4 != nil
|
||||
let _c5 = _5 != nil
|
||||
if _c1 && _c2 && _c3 && _c4 && _c5 {
|
||||
return Api.messages.Dialogs.dialogsSlice(count: _1!, dialogs: _2!, messages: _3!, chats: _4!, users: _5!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api.messages {
|
||||
enum DiscussionMessage: TypeConstructorDescription {
|
||||
case discussionMessage(flags: Int32, messages: [Api.Message], maxId: Int32?, readInboxMaxId: Int32?, readOutboxMaxId: Int32?, unreadCount: Int32, chats: [Api.Chat], users: [Api.User])
|
||||
|
|
@ -1268,249 +1524,3 @@ public extension Api.messages {
|
|||
|
||||
}
|
||||
}
|
||||
public extension Api.messages {
|
||||
enum SearchCounter: TypeConstructorDescription {
|
||||
case searchCounter(flags: Int32, filter: Api.MessagesFilter, count: Int32)
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .searchCounter(let flags, let filter, let count):
|
||||
if boxed {
|
||||
buffer.appendInt32(-398136321)
|
||||
}
|
||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||
filter.serialize(buffer, true)
|
||||
serializeInt32(count, buffer: buffer, boxed: false)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .searchCounter(let flags, let filter, let count):
|
||||
return ("searchCounter", [("flags", String(describing: flags)), ("filter", String(describing: filter)), ("count", String(describing: count))])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_searchCounter(_ reader: BufferReader) -> SearchCounter? {
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
var _2: Api.MessagesFilter?
|
||||
if let signature = reader.readInt32() {
|
||||
_2 = Api.parse(reader, signature: signature) as? Api.MessagesFilter
|
||||
}
|
||||
var _3: Int32?
|
||||
_3 = reader.readInt32()
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
let _c3 = _3 != nil
|
||||
if _c1 && _c2 && _c3 {
|
||||
return Api.messages.SearchCounter.searchCounter(flags: _1!, filter: _2!, count: _3!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api.messages {
|
||||
enum SearchResultsCalendar: TypeConstructorDescription {
|
||||
case searchResultsCalendar(flags: Int32, count: Int32, minDate: Int32, minMsgId: Int32, offsetIdOffset: Int32?, periods: [Api.SearchResultsCalendarPeriod], messages: [Api.Message], chats: [Api.Chat], users: [Api.User])
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .searchResultsCalendar(let flags, let count, let minDate, let minMsgId, let offsetIdOffset, let periods, let messages, let chats, let users):
|
||||
if boxed {
|
||||
buffer.appendInt32(343859772)
|
||||
}
|
||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||
serializeInt32(count, buffer: buffer, boxed: false)
|
||||
serializeInt32(minDate, buffer: buffer, boxed: false)
|
||||
serializeInt32(minMsgId, buffer: buffer, boxed: false)
|
||||
if Int(flags) & Int(1 << 1) != 0 {serializeInt32(offsetIdOffset!, buffer: buffer, boxed: false)}
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(periods.count))
|
||||
for item in periods {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(messages.count))
|
||||
for item in messages {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(chats.count))
|
||||
for item in chats {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(users.count))
|
||||
for item in users {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .searchResultsCalendar(let flags, let count, let minDate, let minMsgId, let offsetIdOffset, let periods, let messages, let chats, let users):
|
||||
return ("searchResultsCalendar", [("flags", String(describing: flags)), ("count", String(describing: count)), ("minDate", String(describing: minDate)), ("minMsgId", String(describing: minMsgId)), ("offsetIdOffset", String(describing: offsetIdOffset)), ("periods", String(describing: periods)), ("messages", String(describing: messages)), ("chats", String(describing: chats)), ("users", String(describing: users))])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_searchResultsCalendar(_ reader: BufferReader) -> SearchResultsCalendar? {
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
var _2: Int32?
|
||||
_2 = reader.readInt32()
|
||||
var _3: Int32?
|
||||
_3 = reader.readInt32()
|
||||
var _4: Int32?
|
||||
_4 = reader.readInt32()
|
||||
var _5: Int32?
|
||||
if Int(_1!) & Int(1 << 1) != 0 {_5 = reader.readInt32() }
|
||||
var _6: [Api.SearchResultsCalendarPeriod]?
|
||||
if let _ = reader.readInt32() {
|
||||
_6 = Api.parseVector(reader, elementSignature: 0, elementType: Api.SearchResultsCalendarPeriod.self)
|
||||
}
|
||||
var _7: [Api.Message]?
|
||||
if let _ = reader.readInt32() {
|
||||
_7 = Api.parseVector(reader, elementSignature: 0, elementType: Api.Message.self)
|
||||
}
|
||||
var _8: [Api.Chat]?
|
||||
if let _ = reader.readInt32() {
|
||||
_8 = Api.parseVector(reader, elementSignature: 0, elementType: Api.Chat.self)
|
||||
}
|
||||
var _9: [Api.User]?
|
||||
if let _ = reader.readInt32() {
|
||||
_9 = Api.parseVector(reader, elementSignature: 0, elementType: Api.User.self)
|
||||
}
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
let _c3 = _3 != nil
|
||||
let _c4 = _4 != nil
|
||||
let _c5 = (Int(_1!) & Int(1 << 1) == 0) || _5 != nil
|
||||
let _c6 = _6 != nil
|
||||
let _c7 = _7 != nil
|
||||
let _c8 = _8 != nil
|
||||
let _c9 = _9 != nil
|
||||
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 && _c9 {
|
||||
return Api.messages.SearchResultsCalendar.searchResultsCalendar(flags: _1!, count: _2!, minDate: _3!, minMsgId: _4!, offsetIdOffset: _5, periods: _6!, messages: _7!, chats: _8!, users: _9!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api.messages {
|
||||
enum SearchResultsPositions: TypeConstructorDescription {
|
||||
case searchResultsPositions(count: Int32, positions: [Api.SearchResultsPosition])
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .searchResultsPositions(let count, let positions):
|
||||
if boxed {
|
||||
buffer.appendInt32(1404185519)
|
||||
}
|
||||
serializeInt32(count, buffer: buffer, boxed: false)
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(positions.count))
|
||||
for item in positions {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .searchResultsPositions(let count, let positions):
|
||||
return ("searchResultsPositions", [("count", String(describing: count)), ("positions", String(describing: positions))])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_searchResultsPositions(_ reader: BufferReader) -> SearchResultsPositions? {
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
var _2: [Api.SearchResultsPosition]?
|
||||
if let _ = reader.readInt32() {
|
||||
_2 = Api.parseVector(reader, elementSignature: 0, elementType: Api.SearchResultsPosition.self)
|
||||
}
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
if _c1 && _c2 {
|
||||
return Api.messages.SearchResultsPositions.searchResultsPositions(count: _1!, positions: _2!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api.messages {
|
||||
enum SentEncryptedMessage: TypeConstructorDescription {
|
||||
case sentEncryptedFile(date: Int32, file: Api.EncryptedFile)
|
||||
case sentEncryptedMessage(date: Int32)
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .sentEncryptedFile(let date, let file):
|
||||
if boxed {
|
||||
buffer.appendInt32(-1802240206)
|
||||
}
|
||||
serializeInt32(date, buffer: buffer, boxed: false)
|
||||
file.serialize(buffer, true)
|
||||
break
|
||||
case .sentEncryptedMessage(let date):
|
||||
if boxed {
|
||||
buffer.appendInt32(1443858741)
|
||||
}
|
||||
serializeInt32(date, buffer: buffer, boxed: false)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .sentEncryptedFile(let date, let file):
|
||||
return ("sentEncryptedFile", [("date", String(describing: date)), ("file", String(describing: file))])
|
||||
case .sentEncryptedMessage(let date):
|
||||
return ("sentEncryptedMessage", [("date", String(describing: date))])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_sentEncryptedFile(_ reader: BufferReader) -> SentEncryptedMessage? {
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
var _2: Api.EncryptedFile?
|
||||
if let signature = reader.readInt32() {
|
||||
_2 = Api.parse(reader, signature: signature) as? Api.EncryptedFile
|
||||
}
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
if _c1 && _c2 {
|
||||
return Api.messages.SentEncryptedMessage.sentEncryptedFile(date: _1!, file: _2!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
public static func parse_sentEncryptedMessage(_ reader: BufferReader) -> SentEncryptedMessage? {
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
let _c1 = _1 != nil
|
||||
if _c1 {
|
||||
return Api.messages.SentEncryptedMessage.sentEncryptedMessage(date: _1!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,249 @@
|
|||
public extension Api.messages {
|
||||
enum SearchCounter: TypeConstructorDescription {
|
||||
case searchCounter(flags: Int32, filter: Api.MessagesFilter, count: Int32)
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .searchCounter(let flags, let filter, let count):
|
||||
if boxed {
|
||||
buffer.appendInt32(-398136321)
|
||||
}
|
||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||
filter.serialize(buffer, true)
|
||||
serializeInt32(count, buffer: buffer, boxed: false)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .searchCounter(let flags, let filter, let count):
|
||||
return ("searchCounter", [("flags", String(describing: flags)), ("filter", String(describing: filter)), ("count", String(describing: count))])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_searchCounter(_ reader: BufferReader) -> SearchCounter? {
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
var _2: Api.MessagesFilter?
|
||||
if let signature = reader.readInt32() {
|
||||
_2 = Api.parse(reader, signature: signature) as? Api.MessagesFilter
|
||||
}
|
||||
var _3: Int32?
|
||||
_3 = reader.readInt32()
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
let _c3 = _3 != nil
|
||||
if _c1 && _c2 && _c3 {
|
||||
return Api.messages.SearchCounter.searchCounter(flags: _1!, filter: _2!, count: _3!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api.messages {
|
||||
enum SearchResultsCalendar: TypeConstructorDescription {
|
||||
case searchResultsCalendar(flags: Int32, count: Int32, minDate: Int32, minMsgId: Int32, offsetIdOffset: Int32?, periods: [Api.SearchResultsCalendarPeriod], messages: [Api.Message], chats: [Api.Chat], users: [Api.User])
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .searchResultsCalendar(let flags, let count, let minDate, let minMsgId, let offsetIdOffset, let periods, let messages, let chats, let users):
|
||||
if boxed {
|
||||
buffer.appendInt32(343859772)
|
||||
}
|
||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||
serializeInt32(count, buffer: buffer, boxed: false)
|
||||
serializeInt32(minDate, buffer: buffer, boxed: false)
|
||||
serializeInt32(minMsgId, buffer: buffer, boxed: false)
|
||||
if Int(flags) & Int(1 << 1) != 0 {serializeInt32(offsetIdOffset!, buffer: buffer, boxed: false)}
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(periods.count))
|
||||
for item in periods {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(messages.count))
|
||||
for item in messages {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(chats.count))
|
||||
for item in chats {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(users.count))
|
||||
for item in users {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .searchResultsCalendar(let flags, let count, let minDate, let minMsgId, let offsetIdOffset, let periods, let messages, let chats, let users):
|
||||
return ("searchResultsCalendar", [("flags", String(describing: flags)), ("count", String(describing: count)), ("minDate", String(describing: minDate)), ("minMsgId", String(describing: minMsgId)), ("offsetIdOffset", String(describing: offsetIdOffset)), ("periods", String(describing: periods)), ("messages", String(describing: messages)), ("chats", String(describing: chats)), ("users", String(describing: users))])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_searchResultsCalendar(_ reader: BufferReader) -> SearchResultsCalendar? {
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
var _2: Int32?
|
||||
_2 = reader.readInt32()
|
||||
var _3: Int32?
|
||||
_3 = reader.readInt32()
|
||||
var _4: Int32?
|
||||
_4 = reader.readInt32()
|
||||
var _5: Int32?
|
||||
if Int(_1!) & Int(1 << 1) != 0 {_5 = reader.readInt32() }
|
||||
var _6: [Api.SearchResultsCalendarPeriod]?
|
||||
if let _ = reader.readInt32() {
|
||||
_6 = Api.parseVector(reader, elementSignature: 0, elementType: Api.SearchResultsCalendarPeriod.self)
|
||||
}
|
||||
var _7: [Api.Message]?
|
||||
if let _ = reader.readInt32() {
|
||||
_7 = Api.parseVector(reader, elementSignature: 0, elementType: Api.Message.self)
|
||||
}
|
||||
var _8: [Api.Chat]?
|
||||
if let _ = reader.readInt32() {
|
||||
_8 = Api.parseVector(reader, elementSignature: 0, elementType: Api.Chat.self)
|
||||
}
|
||||
var _9: [Api.User]?
|
||||
if let _ = reader.readInt32() {
|
||||
_9 = Api.parseVector(reader, elementSignature: 0, elementType: Api.User.self)
|
||||
}
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
let _c3 = _3 != nil
|
||||
let _c4 = _4 != nil
|
||||
let _c5 = (Int(_1!) & Int(1 << 1) == 0) || _5 != nil
|
||||
let _c6 = _6 != nil
|
||||
let _c7 = _7 != nil
|
||||
let _c8 = _8 != nil
|
||||
let _c9 = _9 != nil
|
||||
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 && _c9 {
|
||||
return Api.messages.SearchResultsCalendar.searchResultsCalendar(flags: _1!, count: _2!, minDate: _3!, minMsgId: _4!, offsetIdOffset: _5, periods: _6!, messages: _7!, chats: _8!, users: _9!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api.messages {
|
||||
enum SearchResultsPositions: TypeConstructorDescription {
|
||||
case searchResultsPositions(count: Int32, positions: [Api.SearchResultsPosition])
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .searchResultsPositions(let count, let positions):
|
||||
if boxed {
|
||||
buffer.appendInt32(1404185519)
|
||||
}
|
||||
serializeInt32(count, buffer: buffer, boxed: false)
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(positions.count))
|
||||
for item in positions {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .searchResultsPositions(let count, let positions):
|
||||
return ("searchResultsPositions", [("count", String(describing: count)), ("positions", String(describing: positions))])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_searchResultsPositions(_ reader: BufferReader) -> SearchResultsPositions? {
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
var _2: [Api.SearchResultsPosition]?
|
||||
if let _ = reader.readInt32() {
|
||||
_2 = Api.parseVector(reader, elementSignature: 0, elementType: Api.SearchResultsPosition.self)
|
||||
}
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
if _c1 && _c2 {
|
||||
return Api.messages.SearchResultsPositions.searchResultsPositions(count: _1!, positions: _2!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api.messages {
|
||||
enum SentEncryptedMessage: TypeConstructorDescription {
|
||||
case sentEncryptedFile(date: Int32, file: Api.EncryptedFile)
|
||||
case sentEncryptedMessage(date: Int32)
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .sentEncryptedFile(let date, let file):
|
||||
if boxed {
|
||||
buffer.appendInt32(-1802240206)
|
||||
}
|
||||
serializeInt32(date, buffer: buffer, boxed: false)
|
||||
file.serialize(buffer, true)
|
||||
break
|
||||
case .sentEncryptedMessage(let date):
|
||||
if boxed {
|
||||
buffer.appendInt32(1443858741)
|
||||
}
|
||||
serializeInt32(date, buffer: buffer, boxed: false)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .sentEncryptedFile(let date, let file):
|
||||
return ("sentEncryptedFile", [("date", String(describing: date)), ("file", String(describing: file))])
|
||||
case .sentEncryptedMessage(let date):
|
||||
return ("sentEncryptedMessage", [("date", String(describing: date))])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_sentEncryptedFile(_ reader: BufferReader) -> SentEncryptedMessage? {
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
var _2: Api.EncryptedFile?
|
||||
if let signature = reader.readInt32() {
|
||||
_2 = Api.parse(reader, signature: signature) as? Api.EncryptedFile
|
||||
}
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
if _c1 && _c2 {
|
||||
return Api.messages.SentEncryptedMessage.sentEncryptedFile(date: _1!, file: _2!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
public static func parse_sentEncryptedMessage(_ reader: BufferReader) -> SentEncryptedMessage? {
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
let _c1 = _1 != nil
|
||||
if _c1 {
|
||||
return Api.messages.SentEncryptedMessage.sentEncryptedMessage(date: _1!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api.messages {
|
||||
enum SponsoredMessages: TypeConstructorDescription {
|
||||
case sponsoredMessages(messages: [Api.SponsoredMessage], chats: [Api.Chat], users: [Api.User])
|
||||
|
|
@ -1260,489 +1506,3 @@ public extension Api.photos {
|
|||
|
||||
}
|
||||
}
|
||||
public extension Api.stats {
|
||||
enum BroadcastStats: TypeConstructorDescription {
|
||||
case broadcastStats(period: Api.StatsDateRangeDays, followers: Api.StatsAbsValueAndPrev, viewsPerPost: Api.StatsAbsValueAndPrev, sharesPerPost: Api.StatsAbsValueAndPrev, enabledNotifications: Api.StatsPercentValue, growthGraph: Api.StatsGraph, followersGraph: Api.StatsGraph, muteGraph: Api.StatsGraph, topHoursGraph: Api.StatsGraph, interactionsGraph: Api.StatsGraph, ivInteractionsGraph: Api.StatsGraph, viewsBySourceGraph: Api.StatsGraph, newFollowersBySourceGraph: Api.StatsGraph, languagesGraph: Api.StatsGraph, recentMessageInteractions: [Api.MessageInteractionCounters])
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .broadcastStats(let period, let followers, let viewsPerPost, let sharesPerPost, let enabledNotifications, let growthGraph, let followersGraph, let muteGraph, let topHoursGraph, let interactionsGraph, let ivInteractionsGraph, let viewsBySourceGraph, let newFollowersBySourceGraph, let languagesGraph, let recentMessageInteractions):
|
||||
if boxed {
|
||||
buffer.appendInt32(-1107852396)
|
||||
}
|
||||
period.serialize(buffer, true)
|
||||
followers.serialize(buffer, true)
|
||||
viewsPerPost.serialize(buffer, true)
|
||||
sharesPerPost.serialize(buffer, true)
|
||||
enabledNotifications.serialize(buffer, true)
|
||||
growthGraph.serialize(buffer, true)
|
||||
followersGraph.serialize(buffer, true)
|
||||
muteGraph.serialize(buffer, true)
|
||||
topHoursGraph.serialize(buffer, true)
|
||||
interactionsGraph.serialize(buffer, true)
|
||||
ivInteractionsGraph.serialize(buffer, true)
|
||||
viewsBySourceGraph.serialize(buffer, true)
|
||||
newFollowersBySourceGraph.serialize(buffer, true)
|
||||
languagesGraph.serialize(buffer, true)
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(recentMessageInteractions.count))
|
||||
for item in recentMessageInteractions {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .broadcastStats(let period, let followers, let viewsPerPost, let sharesPerPost, let enabledNotifications, let growthGraph, let followersGraph, let muteGraph, let topHoursGraph, let interactionsGraph, let ivInteractionsGraph, let viewsBySourceGraph, let newFollowersBySourceGraph, let languagesGraph, let recentMessageInteractions):
|
||||
return ("broadcastStats", [("period", String(describing: period)), ("followers", String(describing: followers)), ("viewsPerPost", String(describing: viewsPerPost)), ("sharesPerPost", String(describing: sharesPerPost)), ("enabledNotifications", String(describing: enabledNotifications)), ("growthGraph", String(describing: growthGraph)), ("followersGraph", String(describing: followersGraph)), ("muteGraph", String(describing: muteGraph)), ("topHoursGraph", String(describing: topHoursGraph)), ("interactionsGraph", String(describing: interactionsGraph)), ("ivInteractionsGraph", String(describing: ivInteractionsGraph)), ("viewsBySourceGraph", String(describing: viewsBySourceGraph)), ("newFollowersBySourceGraph", String(describing: newFollowersBySourceGraph)), ("languagesGraph", String(describing: languagesGraph)), ("recentMessageInteractions", String(describing: recentMessageInteractions))])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_broadcastStats(_ reader: BufferReader) -> BroadcastStats? {
|
||||
var _1: Api.StatsDateRangeDays?
|
||||
if let signature = reader.readInt32() {
|
||||
_1 = Api.parse(reader, signature: signature) as? Api.StatsDateRangeDays
|
||||
}
|
||||
var _2: Api.StatsAbsValueAndPrev?
|
||||
if let signature = reader.readInt32() {
|
||||
_2 = Api.parse(reader, signature: signature) as? Api.StatsAbsValueAndPrev
|
||||
}
|
||||
var _3: Api.StatsAbsValueAndPrev?
|
||||
if let signature = reader.readInt32() {
|
||||
_3 = Api.parse(reader, signature: signature) as? Api.StatsAbsValueAndPrev
|
||||
}
|
||||
var _4: Api.StatsAbsValueAndPrev?
|
||||
if let signature = reader.readInt32() {
|
||||
_4 = Api.parse(reader, signature: signature) as? Api.StatsAbsValueAndPrev
|
||||
}
|
||||
var _5: Api.StatsPercentValue?
|
||||
if let signature = reader.readInt32() {
|
||||
_5 = Api.parse(reader, signature: signature) as? Api.StatsPercentValue
|
||||
}
|
||||
var _6: Api.StatsGraph?
|
||||
if let signature = reader.readInt32() {
|
||||
_6 = Api.parse(reader, signature: signature) as? Api.StatsGraph
|
||||
}
|
||||
var _7: Api.StatsGraph?
|
||||
if let signature = reader.readInt32() {
|
||||
_7 = Api.parse(reader, signature: signature) as? Api.StatsGraph
|
||||
}
|
||||
var _8: Api.StatsGraph?
|
||||
if let signature = reader.readInt32() {
|
||||
_8 = Api.parse(reader, signature: signature) as? Api.StatsGraph
|
||||
}
|
||||
var _9: Api.StatsGraph?
|
||||
if let signature = reader.readInt32() {
|
||||
_9 = Api.parse(reader, signature: signature) as? Api.StatsGraph
|
||||
}
|
||||
var _10: Api.StatsGraph?
|
||||
if let signature = reader.readInt32() {
|
||||
_10 = Api.parse(reader, signature: signature) as? Api.StatsGraph
|
||||
}
|
||||
var _11: Api.StatsGraph?
|
||||
if let signature = reader.readInt32() {
|
||||
_11 = Api.parse(reader, signature: signature) as? Api.StatsGraph
|
||||
}
|
||||
var _12: Api.StatsGraph?
|
||||
if let signature = reader.readInt32() {
|
||||
_12 = Api.parse(reader, signature: signature) as? Api.StatsGraph
|
||||
}
|
||||
var _13: Api.StatsGraph?
|
||||
if let signature = reader.readInt32() {
|
||||
_13 = Api.parse(reader, signature: signature) as? Api.StatsGraph
|
||||
}
|
||||
var _14: Api.StatsGraph?
|
||||
if let signature = reader.readInt32() {
|
||||
_14 = Api.parse(reader, signature: signature) as? Api.StatsGraph
|
||||
}
|
||||
var _15: [Api.MessageInteractionCounters]?
|
||||
if let _ = reader.readInt32() {
|
||||
_15 = Api.parseVector(reader, elementSignature: 0, elementType: Api.MessageInteractionCounters.self)
|
||||
}
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
let _c3 = _3 != nil
|
||||
let _c4 = _4 != nil
|
||||
let _c5 = _5 != nil
|
||||
let _c6 = _6 != nil
|
||||
let _c7 = _7 != nil
|
||||
let _c8 = _8 != nil
|
||||
let _c9 = _9 != nil
|
||||
let _c10 = _10 != nil
|
||||
let _c11 = _11 != nil
|
||||
let _c12 = _12 != nil
|
||||
let _c13 = _13 != nil
|
||||
let _c14 = _14 != nil
|
||||
let _c15 = _15 != nil
|
||||
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 && _c9 && _c10 && _c11 && _c12 && _c13 && _c14 && _c15 {
|
||||
return Api.stats.BroadcastStats.broadcastStats(period: _1!, followers: _2!, viewsPerPost: _3!, sharesPerPost: _4!, enabledNotifications: _5!, growthGraph: _6!, followersGraph: _7!, muteGraph: _8!, topHoursGraph: _9!, interactionsGraph: _10!, ivInteractionsGraph: _11!, viewsBySourceGraph: _12!, newFollowersBySourceGraph: _13!, languagesGraph: _14!, recentMessageInteractions: _15!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api.stats {
|
||||
enum MegagroupStats: TypeConstructorDescription {
|
||||
case megagroupStats(period: Api.StatsDateRangeDays, members: Api.StatsAbsValueAndPrev, messages: Api.StatsAbsValueAndPrev, viewers: Api.StatsAbsValueAndPrev, posters: Api.StatsAbsValueAndPrev, growthGraph: Api.StatsGraph, membersGraph: Api.StatsGraph, newMembersBySourceGraph: Api.StatsGraph, languagesGraph: Api.StatsGraph, messagesGraph: Api.StatsGraph, actionsGraph: Api.StatsGraph, topHoursGraph: Api.StatsGraph, weekdaysGraph: Api.StatsGraph, topPosters: [Api.StatsGroupTopPoster], topAdmins: [Api.StatsGroupTopAdmin], topInviters: [Api.StatsGroupTopInviter], users: [Api.User])
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .megagroupStats(let period, let members, let messages, let viewers, let posters, let growthGraph, let membersGraph, let newMembersBySourceGraph, let languagesGraph, let messagesGraph, let actionsGraph, let topHoursGraph, let weekdaysGraph, let topPosters, let topAdmins, let topInviters, let users):
|
||||
if boxed {
|
||||
buffer.appendInt32(-276825834)
|
||||
}
|
||||
period.serialize(buffer, true)
|
||||
members.serialize(buffer, true)
|
||||
messages.serialize(buffer, true)
|
||||
viewers.serialize(buffer, true)
|
||||
posters.serialize(buffer, true)
|
||||
growthGraph.serialize(buffer, true)
|
||||
membersGraph.serialize(buffer, true)
|
||||
newMembersBySourceGraph.serialize(buffer, true)
|
||||
languagesGraph.serialize(buffer, true)
|
||||
messagesGraph.serialize(buffer, true)
|
||||
actionsGraph.serialize(buffer, true)
|
||||
topHoursGraph.serialize(buffer, true)
|
||||
weekdaysGraph.serialize(buffer, true)
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(topPosters.count))
|
||||
for item in topPosters {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(topAdmins.count))
|
||||
for item in topAdmins {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(topInviters.count))
|
||||
for item in topInviters {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(users.count))
|
||||
for item in users {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .megagroupStats(let period, let members, let messages, let viewers, let posters, let growthGraph, let membersGraph, let newMembersBySourceGraph, let languagesGraph, let messagesGraph, let actionsGraph, let topHoursGraph, let weekdaysGraph, let topPosters, let topAdmins, let topInviters, let users):
|
||||
return ("megagroupStats", [("period", String(describing: period)), ("members", String(describing: members)), ("messages", String(describing: messages)), ("viewers", String(describing: viewers)), ("posters", String(describing: posters)), ("growthGraph", String(describing: growthGraph)), ("membersGraph", String(describing: membersGraph)), ("newMembersBySourceGraph", String(describing: newMembersBySourceGraph)), ("languagesGraph", String(describing: languagesGraph)), ("messagesGraph", String(describing: messagesGraph)), ("actionsGraph", String(describing: actionsGraph)), ("topHoursGraph", String(describing: topHoursGraph)), ("weekdaysGraph", String(describing: weekdaysGraph)), ("topPosters", String(describing: topPosters)), ("topAdmins", String(describing: topAdmins)), ("topInviters", String(describing: topInviters)), ("users", String(describing: users))])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_megagroupStats(_ reader: BufferReader) -> MegagroupStats? {
|
||||
var _1: Api.StatsDateRangeDays?
|
||||
if let signature = reader.readInt32() {
|
||||
_1 = Api.parse(reader, signature: signature) as? Api.StatsDateRangeDays
|
||||
}
|
||||
var _2: Api.StatsAbsValueAndPrev?
|
||||
if let signature = reader.readInt32() {
|
||||
_2 = Api.parse(reader, signature: signature) as? Api.StatsAbsValueAndPrev
|
||||
}
|
||||
var _3: Api.StatsAbsValueAndPrev?
|
||||
if let signature = reader.readInt32() {
|
||||
_3 = Api.parse(reader, signature: signature) as? Api.StatsAbsValueAndPrev
|
||||
}
|
||||
var _4: Api.StatsAbsValueAndPrev?
|
||||
if let signature = reader.readInt32() {
|
||||
_4 = Api.parse(reader, signature: signature) as? Api.StatsAbsValueAndPrev
|
||||
}
|
||||
var _5: Api.StatsAbsValueAndPrev?
|
||||
if let signature = reader.readInt32() {
|
||||
_5 = Api.parse(reader, signature: signature) as? Api.StatsAbsValueAndPrev
|
||||
}
|
||||
var _6: Api.StatsGraph?
|
||||
if let signature = reader.readInt32() {
|
||||
_6 = Api.parse(reader, signature: signature) as? Api.StatsGraph
|
||||
}
|
||||
var _7: Api.StatsGraph?
|
||||
if let signature = reader.readInt32() {
|
||||
_7 = Api.parse(reader, signature: signature) as? Api.StatsGraph
|
||||
}
|
||||
var _8: Api.StatsGraph?
|
||||
if let signature = reader.readInt32() {
|
||||
_8 = Api.parse(reader, signature: signature) as? Api.StatsGraph
|
||||
}
|
||||
var _9: Api.StatsGraph?
|
||||
if let signature = reader.readInt32() {
|
||||
_9 = Api.parse(reader, signature: signature) as? Api.StatsGraph
|
||||
}
|
||||
var _10: Api.StatsGraph?
|
||||
if let signature = reader.readInt32() {
|
||||
_10 = Api.parse(reader, signature: signature) as? Api.StatsGraph
|
||||
}
|
||||
var _11: Api.StatsGraph?
|
||||
if let signature = reader.readInt32() {
|
||||
_11 = Api.parse(reader, signature: signature) as? Api.StatsGraph
|
||||
}
|
||||
var _12: Api.StatsGraph?
|
||||
if let signature = reader.readInt32() {
|
||||
_12 = Api.parse(reader, signature: signature) as? Api.StatsGraph
|
||||
}
|
||||
var _13: Api.StatsGraph?
|
||||
if let signature = reader.readInt32() {
|
||||
_13 = Api.parse(reader, signature: signature) as? Api.StatsGraph
|
||||
}
|
||||
var _14: [Api.StatsGroupTopPoster]?
|
||||
if let _ = reader.readInt32() {
|
||||
_14 = Api.parseVector(reader, elementSignature: 0, elementType: Api.StatsGroupTopPoster.self)
|
||||
}
|
||||
var _15: [Api.StatsGroupTopAdmin]?
|
||||
if let _ = reader.readInt32() {
|
||||
_15 = Api.parseVector(reader, elementSignature: 0, elementType: Api.StatsGroupTopAdmin.self)
|
||||
}
|
||||
var _16: [Api.StatsGroupTopInviter]?
|
||||
if let _ = reader.readInt32() {
|
||||
_16 = Api.parseVector(reader, elementSignature: 0, elementType: Api.StatsGroupTopInviter.self)
|
||||
}
|
||||
var _17: [Api.User]?
|
||||
if let _ = reader.readInt32() {
|
||||
_17 = Api.parseVector(reader, elementSignature: 0, elementType: Api.User.self)
|
||||
}
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
let _c3 = _3 != nil
|
||||
let _c4 = _4 != nil
|
||||
let _c5 = _5 != nil
|
||||
let _c6 = _6 != nil
|
||||
let _c7 = _7 != nil
|
||||
let _c8 = _8 != nil
|
||||
let _c9 = _9 != nil
|
||||
let _c10 = _10 != nil
|
||||
let _c11 = _11 != nil
|
||||
let _c12 = _12 != nil
|
||||
let _c13 = _13 != nil
|
||||
let _c14 = _14 != nil
|
||||
let _c15 = _15 != nil
|
||||
let _c16 = _16 != nil
|
||||
let _c17 = _17 != nil
|
||||
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 && _c9 && _c10 && _c11 && _c12 && _c13 && _c14 && _c15 && _c16 && _c17 {
|
||||
return Api.stats.MegagroupStats.megagroupStats(period: _1!, members: _2!, messages: _3!, viewers: _4!, posters: _5!, growthGraph: _6!, membersGraph: _7!, newMembersBySourceGraph: _8!, languagesGraph: _9!, messagesGraph: _10!, actionsGraph: _11!, topHoursGraph: _12!, weekdaysGraph: _13!, topPosters: _14!, topAdmins: _15!, topInviters: _16!, users: _17!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api.stats {
|
||||
enum MessageStats: TypeConstructorDescription {
|
||||
case messageStats(viewsGraph: Api.StatsGraph)
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .messageStats(let viewsGraph):
|
||||
if boxed {
|
||||
buffer.appendInt32(-1986399595)
|
||||
}
|
||||
viewsGraph.serialize(buffer, true)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .messageStats(let viewsGraph):
|
||||
return ("messageStats", [("viewsGraph", String(describing: viewsGraph))])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_messageStats(_ reader: BufferReader) -> MessageStats? {
|
||||
var _1: Api.StatsGraph?
|
||||
if let signature = reader.readInt32() {
|
||||
_1 = Api.parse(reader, signature: signature) as? Api.StatsGraph
|
||||
}
|
||||
let _c1 = _1 != nil
|
||||
if _c1 {
|
||||
return Api.stats.MessageStats.messageStats(viewsGraph: _1!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api.stickers {
|
||||
enum SuggestedShortName: TypeConstructorDescription {
|
||||
case suggestedShortName(shortName: String)
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .suggestedShortName(let shortName):
|
||||
if boxed {
|
||||
buffer.appendInt32(-2046910401)
|
||||
}
|
||||
serializeString(shortName, buffer: buffer, boxed: false)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .suggestedShortName(let shortName):
|
||||
return ("suggestedShortName", [("shortName", String(describing: shortName))])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_suggestedShortName(_ reader: BufferReader) -> SuggestedShortName? {
|
||||
var _1: String?
|
||||
_1 = parseString(reader)
|
||||
let _c1 = _1 != nil
|
||||
if _c1 {
|
||||
return Api.stickers.SuggestedShortName.suggestedShortName(shortName: _1!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api.storage {
|
||||
enum FileType: TypeConstructorDescription {
|
||||
case fileGif
|
||||
case fileJpeg
|
||||
case fileMov
|
||||
case fileMp3
|
||||
case fileMp4
|
||||
case filePartial
|
||||
case filePdf
|
||||
case filePng
|
||||
case fileUnknown
|
||||
case fileWebp
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .fileGif:
|
||||
if boxed {
|
||||
buffer.appendInt32(-891180321)
|
||||
}
|
||||
|
||||
break
|
||||
case .fileJpeg:
|
||||
if boxed {
|
||||
buffer.appendInt32(8322574)
|
||||
}
|
||||
|
||||
break
|
||||
case .fileMov:
|
||||
if boxed {
|
||||
buffer.appendInt32(1258941372)
|
||||
}
|
||||
|
||||
break
|
||||
case .fileMp3:
|
||||
if boxed {
|
||||
buffer.appendInt32(1384777335)
|
||||
}
|
||||
|
||||
break
|
||||
case .fileMp4:
|
||||
if boxed {
|
||||
buffer.appendInt32(-1278304028)
|
||||
}
|
||||
|
||||
break
|
||||
case .filePartial:
|
||||
if boxed {
|
||||
buffer.appendInt32(1086091090)
|
||||
}
|
||||
|
||||
break
|
||||
case .filePdf:
|
||||
if boxed {
|
||||
buffer.appendInt32(-1373745011)
|
||||
}
|
||||
|
||||
break
|
||||
case .filePng:
|
||||
if boxed {
|
||||
buffer.appendInt32(172975040)
|
||||
}
|
||||
|
||||
break
|
||||
case .fileUnknown:
|
||||
if boxed {
|
||||
buffer.appendInt32(-1432995067)
|
||||
}
|
||||
|
||||
break
|
||||
case .fileWebp:
|
||||
if boxed {
|
||||
buffer.appendInt32(276907596)
|
||||
}
|
||||
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .fileGif:
|
||||
return ("fileGif", [])
|
||||
case .fileJpeg:
|
||||
return ("fileJpeg", [])
|
||||
case .fileMov:
|
||||
return ("fileMov", [])
|
||||
case .fileMp3:
|
||||
return ("fileMp3", [])
|
||||
case .fileMp4:
|
||||
return ("fileMp4", [])
|
||||
case .filePartial:
|
||||
return ("filePartial", [])
|
||||
case .filePdf:
|
||||
return ("filePdf", [])
|
||||
case .filePng:
|
||||
return ("filePng", [])
|
||||
case .fileUnknown:
|
||||
return ("fileUnknown", [])
|
||||
case .fileWebp:
|
||||
return ("fileWebp", [])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_fileGif(_ reader: BufferReader) -> FileType? {
|
||||
return Api.storage.FileType.fileGif
|
||||
}
|
||||
public static func parse_fileJpeg(_ reader: BufferReader) -> FileType? {
|
||||
return Api.storage.FileType.fileJpeg
|
||||
}
|
||||
public static func parse_fileMov(_ reader: BufferReader) -> FileType? {
|
||||
return Api.storage.FileType.fileMov
|
||||
}
|
||||
public static func parse_fileMp3(_ reader: BufferReader) -> FileType? {
|
||||
return Api.storage.FileType.fileMp3
|
||||
}
|
||||
public static func parse_fileMp4(_ reader: BufferReader) -> FileType? {
|
||||
return Api.storage.FileType.fileMp4
|
||||
}
|
||||
public static func parse_filePartial(_ reader: BufferReader) -> FileType? {
|
||||
return Api.storage.FileType.filePartial
|
||||
}
|
||||
public static func parse_filePdf(_ reader: BufferReader) -> FileType? {
|
||||
return Api.storage.FileType.filePdf
|
||||
}
|
||||
public static func parse_filePng(_ reader: BufferReader) -> FileType? {
|
||||
return Api.storage.FileType.filePng
|
||||
}
|
||||
public static func parse_fileUnknown(_ reader: BufferReader) -> FileType? {
|
||||
return Api.storage.FileType.fileUnknown
|
||||
}
|
||||
public static func parse_fileWebp(_ reader: BufferReader) -> FileType? {
|
||||
return Api.storage.FileType.fileWebp
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,489 @@
|
|||
public extension Api.stats {
|
||||
enum BroadcastStats: TypeConstructorDescription {
|
||||
case broadcastStats(period: Api.StatsDateRangeDays, followers: Api.StatsAbsValueAndPrev, viewsPerPost: Api.StatsAbsValueAndPrev, sharesPerPost: Api.StatsAbsValueAndPrev, enabledNotifications: Api.StatsPercentValue, growthGraph: Api.StatsGraph, followersGraph: Api.StatsGraph, muteGraph: Api.StatsGraph, topHoursGraph: Api.StatsGraph, interactionsGraph: Api.StatsGraph, ivInteractionsGraph: Api.StatsGraph, viewsBySourceGraph: Api.StatsGraph, newFollowersBySourceGraph: Api.StatsGraph, languagesGraph: Api.StatsGraph, recentMessageInteractions: [Api.MessageInteractionCounters])
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .broadcastStats(let period, let followers, let viewsPerPost, let sharesPerPost, let enabledNotifications, let growthGraph, let followersGraph, let muteGraph, let topHoursGraph, let interactionsGraph, let ivInteractionsGraph, let viewsBySourceGraph, let newFollowersBySourceGraph, let languagesGraph, let recentMessageInteractions):
|
||||
if boxed {
|
||||
buffer.appendInt32(-1107852396)
|
||||
}
|
||||
period.serialize(buffer, true)
|
||||
followers.serialize(buffer, true)
|
||||
viewsPerPost.serialize(buffer, true)
|
||||
sharesPerPost.serialize(buffer, true)
|
||||
enabledNotifications.serialize(buffer, true)
|
||||
growthGraph.serialize(buffer, true)
|
||||
followersGraph.serialize(buffer, true)
|
||||
muteGraph.serialize(buffer, true)
|
||||
topHoursGraph.serialize(buffer, true)
|
||||
interactionsGraph.serialize(buffer, true)
|
||||
ivInteractionsGraph.serialize(buffer, true)
|
||||
viewsBySourceGraph.serialize(buffer, true)
|
||||
newFollowersBySourceGraph.serialize(buffer, true)
|
||||
languagesGraph.serialize(buffer, true)
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(recentMessageInteractions.count))
|
||||
for item in recentMessageInteractions {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .broadcastStats(let period, let followers, let viewsPerPost, let sharesPerPost, let enabledNotifications, let growthGraph, let followersGraph, let muteGraph, let topHoursGraph, let interactionsGraph, let ivInteractionsGraph, let viewsBySourceGraph, let newFollowersBySourceGraph, let languagesGraph, let recentMessageInteractions):
|
||||
return ("broadcastStats", [("period", String(describing: period)), ("followers", String(describing: followers)), ("viewsPerPost", String(describing: viewsPerPost)), ("sharesPerPost", String(describing: sharesPerPost)), ("enabledNotifications", String(describing: enabledNotifications)), ("growthGraph", String(describing: growthGraph)), ("followersGraph", String(describing: followersGraph)), ("muteGraph", String(describing: muteGraph)), ("topHoursGraph", String(describing: topHoursGraph)), ("interactionsGraph", String(describing: interactionsGraph)), ("ivInteractionsGraph", String(describing: ivInteractionsGraph)), ("viewsBySourceGraph", String(describing: viewsBySourceGraph)), ("newFollowersBySourceGraph", String(describing: newFollowersBySourceGraph)), ("languagesGraph", String(describing: languagesGraph)), ("recentMessageInteractions", String(describing: recentMessageInteractions))])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_broadcastStats(_ reader: BufferReader) -> BroadcastStats? {
|
||||
var _1: Api.StatsDateRangeDays?
|
||||
if let signature = reader.readInt32() {
|
||||
_1 = Api.parse(reader, signature: signature) as? Api.StatsDateRangeDays
|
||||
}
|
||||
var _2: Api.StatsAbsValueAndPrev?
|
||||
if let signature = reader.readInt32() {
|
||||
_2 = Api.parse(reader, signature: signature) as? Api.StatsAbsValueAndPrev
|
||||
}
|
||||
var _3: Api.StatsAbsValueAndPrev?
|
||||
if let signature = reader.readInt32() {
|
||||
_3 = Api.parse(reader, signature: signature) as? Api.StatsAbsValueAndPrev
|
||||
}
|
||||
var _4: Api.StatsAbsValueAndPrev?
|
||||
if let signature = reader.readInt32() {
|
||||
_4 = Api.parse(reader, signature: signature) as? Api.StatsAbsValueAndPrev
|
||||
}
|
||||
var _5: Api.StatsPercentValue?
|
||||
if let signature = reader.readInt32() {
|
||||
_5 = Api.parse(reader, signature: signature) as? Api.StatsPercentValue
|
||||
}
|
||||
var _6: Api.StatsGraph?
|
||||
if let signature = reader.readInt32() {
|
||||
_6 = Api.parse(reader, signature: signature) as? Api.StatsGraph
|
||||
}
|
||||
var _7: Api.StatsGraph?
|
||||
if let signature = reader.readInt32() {
|
||||
_7 = Api.parse(reader, signature: signature) as? Api.StatsGraph
|
||||
}
|
||||
var _8: Api.StatsGraph?
|
||||
if let signature = reader.readInt32() {
|
||||
_8 = Api.parse(reader, signature: signature) as? Api.StatsGraph
|
||||
}
|
||||
var _9: Api.StatsGraph?
|
||||
if let signature = reader.readInt32() {
|
||||
_9 = Api.parse(reader, signature: signature) as? Api.StatsGraph
|
||||
}
|
||||
var _10: Api.StatsGraph?
|
||||
if let signature = reader.readInt32() {
|
||||
_10 = Api.parse(reader, signature: signature) as? Api.StatsGraph
|
||||
}
|
||||
var _11: Api.StatsGraph?
|
||||
if let signature = reader.readInt32() {
|
||||
_11 = Api.parse(reader, signature: signature) as? Api.StatsGraph
|
||||
}
|
||||
var _12: Api.StatsGraph?
|
||||
if let signature = reader.readInt32() {
|
||||
_12 = Api.parse(reader, signature: signature) as? Api.StatsGraph
|
||||
}
|
||||
var _13: Api.StatsGraph?
|
||||
if let signature = reader.readInt32() {
|
||||
_13 = Api.parse(reader, signature: signature) as? Api.StatsGraph
|
||||
}
|
||||
var _14: Api.StatsGraph?
|
||||
if let signature = reader.readInt32() {
|
||||
_14 = Api.parse(reader, signature: signature) as? Api.StatsGraph
|
||||
}
|
||||
var _15: [Api.MessageInteractionCounters]?
|
||||
if let _ = reader.readInt32() {
|
||||
_15 = Api.parseVector(reader, elementSignature: 0, elementType: Api.MessageInteractionCounters.self)
|
||||
}
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
let _c3 = _3 != nil
|
||||
let _c4 = _4 != nil
|
||||
let _c5 = _5 != nil
|
||||
let _c6 = _6 != nil
|
||||
let _c7 = _7 != nil
|
||||
let _c8 = _8 != nil
|
||||
let _c9 = _9 != nil
|
||||
let _c10 = _10 != nil
|
||||
let _c11 = _11 != nil
|
||||
let _c12 = _12 != nil
|
||||
let _c13 = _13 != nil
|
||||
let _c14 = _14 != nil
|
||||
let _c15 = _15 != nil
|
||||
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 && _c9 && _c10 && _c11 && _c12 && _c13 && _c14 && _c15 {
|
||||
return Api.stats.BroadcastStats.broadcastStats(period: _1!, followers: _2!, viewsPerPost: _3!, sharesPerPost: _4!, enabledNotifications: _5!, growthGraph: _6!, followersGraph: _7!, muteGraph: _8!, topHoursGraph: _9!, interactionsGraph: _10!, ivInteractionsGraph: _11!, viewsBySourceGraph: _12!, newFollowersBySourceGraph: _13!, languagesGraph: _14!, recentMessageInteractions: _15!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api.stats {
|
||||
enum MegagroupStats: TypeConstructorDescription {
|
||||
case megagroupStats(period: Api.StatsDateRangeDays, members: Api.StatsAbsValueAndPrev, messages: Api.StatsAbsValueAndPrev, viewers: Api.StatsAbsValueAndPrev, posters: Api.StatsAbsValueAndPrev, growthGraph: Api.StatsGraph, membersGraph: Api.StatsGraph, newMembersBySourceGraph: Api.StatsGraph, languagesGraph: Api.StatsGraph, messagesGraph: Api.StatsGraph, actionsGraph: Api.StatsGraph, topHoursGraph: Api.StatsGraph, weekdaysGraph: Api.StatsGraph, topPosters: [Api.StatsGroupTopPoster], topAdmins: [Api.StatsGroupTopAdmin], topInviters: [Api.StatsGroupTopInviter], users: [Api.User])
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .megagroupStats(let period, let members, let messages, let viewers, let posters, let growthGraph, let membersGraph, let newMembersBySourceGraph, let languagesGraph, let messagesGraph, let actionsGraph, let topHoursGraph, let weekdaysGraph, let topPosters, let topAdmins, let topInviters, let users):
|
||||
if boxed {
|
||||
buffer.appendInt32(-276825834)
|
||||
}
|
||||
period.serialize(buffer, true)
|
||||
members.serialize(buffer, true)
|
||||
messages.serialize(buffer, true)
|
||||
viewers.serialize(buffer, true)
|
||||
posters.serialize(buffer, true)
|
||||
growthGraph.serialize(buffer, true)
|
||||
membersGraph.serialize(buffer, true)
|
||||
newMembersBySourceGraph.serialize(buffer, true)
|
||||
languagesGraph.serialize(buffer, true)
|
||||
messagesGraph.serialize(buffer, true)
|
||||
actionsGraph.serialize(buffer, true)
|
||||
topHoursGraph.serialize(buffer, true)
|
||||
weekdaysGraph.serialize(buffer, true)
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(topPosters.count))
|
||||
for item in topPosters {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(topAdmins.count))
|
||||
for item in topAdmins {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(topInviters.count))
|
||||
for item in topInviters {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(users.count))
|
||||
for item in users {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .megagroupStats(let period, let members, let messages, let viewers, let posters, let growthGraph, let membersGraph, let newMembersBySourceGraph, let languagesGraph, let messagesGraph, let actionsGraph, let topHoursGraph, let weekdaysGraph, let topPosters, let topAdmins, let topInviters, let users):
|
||||
return ("megagroupStats", [("period", String(describing: period)), ("members", String(describing: members)), ("messages", String(describing: messages)), ("viewers", String(describing: viewers)), ("posters", String(describing: posters)), ("growthGraph", String(describing: growthGraph)), ("membersGraph", String(describing: membersGraph)), ("newMembersBySourceGraph", String(describing: newMembersBySourceGraph)), ("languagesGraph", String(describing: languagesGraph)), ("messagesGraph", String(describing: messagesGraph)), ("actionsGraph", String(describing: actionsGraph)), ("topHoursGraph", String(describing: topHoursGraph)), ("weekdaysGraph", String(describing: weekdaysGraph)), ("topPosters", String(describing: topPosters)), ("topAdmins", String(describing: topAdmins)), ("topInviters", String(describing: topInviters)), ("users", String(describing: users))])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_megagroupStats(_ reader: BufferReader) -> MegagroupStats? {
|
||||
var _1: Api.StatsDateRangeDays?
|
||||
if let signature = reader.readInt32() {
|
||||
_1 = Api.parse(reader, signature: signature) as? Api.StatsDateRangeDays
|
||||
}
|
||||
var _2: Api.StatsAbsValueAndPrev?
|
||||
if let signature = reader.readInt32() {
|
||||
_2 = Api.parse(reader, signature: signature) as? Api.StatsAbsValueAndPrev
|
||||
}
|
||||
var _3: Api.StatsAbsValueAndPrev?
|
||||
if let signature = reader.readInt32() {
|
||||
_3 = Api.parse(reader, signature: signature) as? Api.StatsAbsValueAndPrev
|
||||
}
|
||||
var _4: Api.StatsAbsValueAndPrev?
|
||||
if let signature = reader.readInt32() {
|
||||
_4 = Api.parse(reader, signature: signature) as? Api.StatsAbsValueAndPrev
|
||||
}
|
||||
var _5: Api.StatsAbsValueAndPrev?
|
||||
if let signature = reader.readInt32() {
|
||||
_5 = Api.parse(reader, signature: signature) as? Api.StatsAbsValueAndPrev
|
||||
}
|
||||
var _6: Api.StatsGraph?
|
||||
if let signature = reader.readInt32() {
|
||||
_6 = Api.parse(reader, signature: signature) as? Api.StatsGraph
|
||||
}
|
||||
var _7: Api.StatsGraph?
|
||||
if let signature = reader.readInt32() {
|
||||
_7 = Api.parse(reader, signature: signature) as? Api.StatsGraph
|
||||
}
|
||||
var _8: Api.StatsGraph?
|
||||
if let signature = reader.readInt32() {
|
||||
_8 = Api.parse(reader, signature: signature) as? Api.StatsGraph
|
||||
}
|
||||
var _9: Api.StatsGraph?
|
||||
if let signature = reader.readInt32() {
|
||||
_9 = Api.parse(reader, signature: signature) as? Api.StatsGraph
|
||||
}
|
||||
var _10: Api.StatsGraph?
|
||||
if let signature = reader.readInt32() {
|
||||
_10 = Api.parse(reader, signature: signature) as? Api.StatsGraph
|
||||
}
|
||||
var _11: Api.StatsGraph?
|
||||
if let signature = reader.readInt32() {
|
||||
_11 = Api.parse(reader, signature: signature) as? Api.StatsGraph
|
||||
}
|
||||
var _12: Api.StatsGraph?
|
||||
if let signature = reader.readInt32() {
|
||||
_12 = Api.parse(reader, signature: signature) as? Api.StatsGraph
|
||||
}
|
||||
var _13: Api.StatsGraph?
|
||||
if let signature = reader.readInt32() {
|
||||
_13 = Api.parse(reader, signature: signature) as? Api.StatsGraph
|
||||
}
|
||||
var _14: [Api.StatsGroupTopPoster]?
|
||||
if let _ = reader.readInt32() {
|
||||
_14 = Api.parseVector(reader, elementSignature: 0, elementType: Api.StatsGroupTopPoster.self)
|
||||
}
|
||||
var _15: [Api.StatsGroupTopAdmin]?
|
||||
if let _ = reader.readInt32() {
|
||||
_15 = Api.parseVector(reader, elementSignature: 0, elementType: Api.StatsGroupTopAdmin.self)
|
||||
}
|
||||
var _16: [Api.StatsGroupTopInviter]?
|
||||
if let _ = reader.readInt32() {
|
||||
_16 = Api.parseVector(reader, elementSignature: 0, elementType: Api.StatsGroupTopInviter.self)
|
||||
}
|
||||
var _17: [Api.User]?
|
||||
if let _ = reader.readInt32() {
|
||||
_17 = Api.parseVector(reader, elementSignature: 0, elementType: Api.User.self)
|
||||
}
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
let _c3 = _3 != nil
|
||||
let _c4 = _4 != nil
|
||||
let _c5 = _5 != nil
|
||||
let _c6 = _6 != nil
|
||||
let _c7 = _7 != nil
|
||||
let _c8 = _8 != nil
|
||||
let _c9 = _9 != nil
|
||||
let _c10 = _10 != nil
|
||||
let _c11 = _11 != nil
|
||||
let _c12 = _12 != nil
|
||||
let _c13 = _13 != nil
|
||||
let _c14 = _14 != nil
|
||||
let _c15 = _15 != nil
|
||||
let _c16 = _16 != nil
|
||||
let _c17 = _17 != nil
|
||||
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 && _c9 && _c10 && _c11 && _c12 && _c13 && _c14 && _c15 && _c16 && _c17 {
|
||||
return Api.stats.MegagroupStats.megagroupStats(period: _1!, members: _2!, messages: _3!, viewers: _4!, posters: _5!, growthGraph: _6!, membersGraph: _7!, newMembersBySourceGraph: _8!, languagesGraph: _9!, messagesGraph: _10!, actionsGraph: _11!, topHoursGraph: _12!, weekdaysGraph: _13!, topPosters: _14!, topAdmins: _15!, topInviters: _16!, users: _17!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api.stats {
|
||||
enum MessageStats: TypeConstructorDescription {
|
||||
case messageStats(viewsGraph: Api.StatsGraph)
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .messageStats(let viewsGraph):
|
||||
if boxed {
|
||||
buffer.appendInt32(-1986399595)
|
||||
}
|
||||
viewsGraph.serialize(buffer, true)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .messageStats(let viewsGraph):
|
||||
return ("messageStats", [("viewsGraph", String(describing: viewsGraph))])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_messageStats(_ reader: BufferReader) -> MessageStats? {
|
||||
var _1: Api.StatsGraph?
|
||||
if let signature = reader.readInt32() {
|
||||
_1 = Api.parse(reader, signature: signature) as? Api.StatsGraph
|
||||
}
|
||||
let _c1 = _1 != nil
|
||||
if _c1 {
|
||||
return Api.stats.MessageStats.messageStats(viewsGraph: _1!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api.stickers {
|
||||
enum SuggestedShortName: TypeConstructorDescription {
|
||||
case suggestedShortName(shortName: String)
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .suggestedShortName(let shortName):
|
||||
if boxed {
|
||||
buffer.appendInt32(-2046910401)
|
||||
}
|
||||
serializeString(shortName, buffer: buffer, boxed: false)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .suggestedShortName(let shortName):
|
||||
return ("suggestedShortName", [("shortName", String(describing: shortName))])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_suggestedShortName(_ reader: BufferReader) -> SuggestedShortName? {
|
||||
var _1: String?
|
||||
_1 = parseString(reader)
|
||||
let _c1 = _1 != nil
|
||||
if _c1 {
|
||||
return Api.stickers.SuggestedShortName.suggestedShortName(shortName: _1!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api.storage {
|
||||
enum FileType: TypeConstructorDescription {
|
||||
case fileGif
|
||||
case fileJpeg
|
||||
case fileMov
|
||||
case fileMp3
|
||||
case fileMp4
|
||||
case filePartial
|
||||
case filePdf
|
||||
case filePng
|
||||
case fileUnknown
|
||||
case fileWebp
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .fileGif:
|
||||
if boxed {
|
||||
buffer.appendInt32(-891180321)
|
||||
}
|
||||
|
||||
break
|
||||
case .fileJpeg:
|
||||
if boxed {
|
||||
buffer.appendInt32(8322574)
|
||||
}
|
||||
|
||||
break
|
||||
case .fileMov:
|
||||
if boxed {
|
||||
buffer.appendInt32(1258941372)
|
||||
}
|
||||
|
||||
break
|
||||
case .fileMp3:
|
||||
if boxed {
|
||||
buffer.appendInt32(1384777335)
|
||||
}
|
||||
|
||||
break
|
||||
case .fileMp4:
|
||||
if boxed {
|
||||
buffer.appendInt32(-1278304028)
|
||||
}
|
||||
|
||||
break
|
||||
case .filePartial:
|
||||
if boxed {
|
||||
buffer.appendInt32(1086091090)
|
||||
}
|
||||
|
||||
break
|
||||
case .filePdf:
|
||||
if boxed {
|
||||
buffer.appendInt32(-1373745011)
|
||||
}
|
||||
|
||||
break
|
||||
case .filePng:
|
||||
if boxed {
|
||||
buffer.appendInt32(172975040)
|
||||
}
|
||||
|
||||
break
|
||||
case .fileUnknown:
|
||||
if boxed {
|
||||
buffer.appendInt32(-1432995067)
|
||||
}
|
||||
|
||||
break
|
||||
case .fileWebp:
|
||||
if boxed {
|
||||
buffer.appendInt32(276907596)
|
||||
}
|
||||
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .fileGif:
|
||||
return ("fileGif", [])
|
||||
case .fileJpeg:
|
||||
return ("fileJpeg", [])
|
||||
case .fileMov:
|
||||
return ("fileMov", [])
|
||||
case .fileMp3:
|
||||
return ("fileMp3", [])
|
||||
case .fileMp4:
|
||||
return ("fileMp4", [])
|
||||
case .filePartial:
|
||||
return ("filePartial", [])
|
||||
case .filePdf:
|
||||
return ("filePdf", [])
|
||||
case .filePng:
|
||||
return ("filePng", [])
|
||||
case .fileUnknown:
|
||||
return ("fileUnknown", [])
|
||||
case .fileWebp:
|
||||
return ("fileWebp", [])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_fileGif(_ reader: BufferReader) -> FileType? {
|
||||
return Api.storage.FileType.fileGif
|
||||
}
|
||||
public static func parse_fileJpeg(_ reader: BufferReader) -> FileType? {
|
||||
return Api.storage.FileType.fileJpeg
|
||||
}
|
||||
public static func parse_fileMov(_ reader: BufferReader) -> FileType? {
|
||||
return Api.storage.FileType.fileMov
|
||||
}
|
||||
public static func parse_fileMp3(_ reader: BufferReader) -> FileType? {
|
||||
return Api.storage.FileType.fileMp3
|
||||
}
|
||||
public static func parse_fileMp4(_ reader: BufferReader) -> FileType? {
|
||||
return Api.storage.FileType.fileMp4
|
||||
}
|
||||
public static func parse_filePartial(_ reader: BufferReader) -> FileType? {
|
||||
return Api.storage.FileType.filePartial
|
||||
}
|
||||
public static func parse_filePdf(_ reader: BufferReader) -> FileType? {
|
||||
return Api.storage.FileType.filePdf
|
||||
}
|
||||
public static func parse_filePng(_ reader: BufferReader) -> FileType? {
|
||||
return Api.storage.FileType.filePng
|
||||
}
|
||||
public static func parse_fileUnknown(_ reader: BufferReader) -> FileType? {
|
||||
return Api.storage.FileType.fileUnknown
|
||||
}
|
||||
public static func parse_fileWebp(_ reader: BufferReader) -> FileType? {
|
||||
return Api.storage.FileType.fileWebp
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api.updates {
|
||||
enum ChannelDifference: TypeConstructorDescription {
|
||||
case channelDifference(flags: Int32, pts: Int32, timeout: Int32?, newMessages: [Api.Message], otherUpdates: [Api.Update], chats: [Api.Chat], users: [Api.User])
|
||||
|
|
|
|||
|
|
@ -436,6 +436,21 @@ public extension Api.functions.account {
|
|||
})
|
||||
}
|
||||
}
|
||||
public extension Api.functions.account {
|
||||
static func getSavedRingtones(hash: Int64) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.account.SavedRingtones>) {
|
||||
let buffer = Buffer()
|
||||
buffer.appendInt32(-510647672)
|
||||
serializeInt64(hash, buffer: buffer, boxed: false)
|
||||
return (FunctionDescription(name: "account.getSavedRingtones", parameters: [("hash", String(describing: hash))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.account.SavedRingtones? in
|
||||
let reader = BufferReader(buffer)
|
||||
var result: Api.account.SavedRingtones?
|
||||
if let signature = reader.readInt32() {
|
||||
result = Api.parse(reader, signature: signature) as? Api.account.SavedRingtones
|
||||
}
|
||||
return result
|
||||
})
|
||||
}
|
||||
}
|
||||
public extension Api.functions.account {
|
||||
static func getSecureValue(types: [Api.SecureValueType]) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<[Api.SecureValue]>) {
|
||||
let buffer = Buffer()
|
||||
|
|
@ -779,6 +794,22 @@ public extension Api.functions.account {
|
|||
})
|
||||
}
|
||||
}
|
||||
public extension Api.functions.account {
|
||||
static func saveRingtone(id: Api.InputDocument, unsave: Api.Bool) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Bool>) {
|
||||
let buffer = Buffer()
|
||||
buffer.appendInt32(-369618141)
|
||||
id.serialize(buffer, true)
|
||||
unsave.serialize(buffer, true)
|
||||
return (FunctionDescription(name: "account.saveRingtone", parameters: [("id", String(describing: id)), ("unsave", String(describing: unsave))]), 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 extension Api.functions.account {
|
||||
static func saveSecureValue(value: Api.InputSecureValue, secureSecretId: Int64) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.SecureValue>) {
|
||||
let buffer = Buffer()
|
||||
|
|
@ -1127,6 +1158,23 @@ public extension Api.functions.account {
|
|||
})
|
||||
}
|
||||
}
|
||||
public extension Api.functions.account {
|
||||
static func uploadRingtone(file: Api.InputFile, fileName: String, mimeType: String) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Document>) {
|
||||
let buffer = Buffer()
|
||||
buffer.appendInt32(-2095414366)
|
||||
file.serialize(buffer, true)
|
||||
serializeString(fileName, buffer: buffer, boxed: false)
|
||||
serializeString(mimeType, buffer: buffer, boxed: false)
|
||||
return (FunctionDescription(name: "account.uploadRingtone", parameters: [("file", String(describing: file)), ("fileName", String(describing: fileName)), ("mimeType", String(describing: mimeType))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.Document? in
|
||||
let reader = BufferReader(buffer)
|
||||
var result: Api.Document?
|
||||
if let signature = reader.readInt32() {
|
||||
result = Api.parse(reader, signature: signature) as? Api.Document
|
||||
}
|
||||
return result
|
||||
})
|
||||
}
|
||||
}
|
||||
public extension Api.functions.account {
|
||||
static func uploadTheme(flags: Int32, file: Api.InputFile, thumb: Api.InputFile?, fileName: String, mimeType: String) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Document>) {
|
||||
let buffer = Buffer()
|
||||
|
|
|
|||
|
|
@ -444,19 +444,19 @@ public extension Api {
|
|||
}
|
||||
public extension Api {
|
||||
enum InputPeerNotifySettings: TypeConstructorDescription {
|
||||
case inputPeerNotifySettings(flags: Int32, showPreviews: Api.Bool?, silent: Api.Bool?, muteUntil: Int32?, sound: String?)
|
||||
case inputPeerNotifySettings(flags: Int32, showPreviews: Api.Bool?, silent: Api.Bool?, muteUntil: Int32?, sound: Api.NotificationSound?)
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .inputPeerNotifySettings(let flags, let showPreviews, let silent, let muteUntil, let sound):
|
||||
if boxed {
|
||||
buffer.appendInt32(-1673717362)
|
||||
buffer.appendInt32(-551616469)
|
||||
}
|
||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||
if Int(flags) & Int(1 << 0) != 0 {showPreviews!.serialize(buffer, true)}
|
||||
if Int(flags) & Int(1 << 1) != 0 {silent!.serialize(buffer, true)}
|
||||
if Int(flags) & Int(1 << 2) != 0 {serializeInt32(muteUntil!, buffer: buffer, boxed: false)}
|
||||
if Int(flags) & Int(1 << 3) != 0 {serializeString(sound!, buffer: buffer, boxed: false)}
|
||||
if Int(flags) & Int(1 << 3) != 0 {sound!.serialize(buffer, true)}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
|
@ -481,8 +481,10 @@ public extension Api {
|
|||
} }
|
||||
var _4: Int32?
|
||||
if Int(_1!) & Int(1 << 2) != 0 {_4 = reader.readInt32() }
|
||||
var _5: String?
|
||||
if Int(_1!) & Int(1 << 3) != 0 {_5 = parseString(reader) }
|
||||
var _5: Api.NotificationSound?
|
||||
if Int(_1!) & Int(1 << 3) != 0 {if let signature = reader.readInt32() {
|
||||
_5 = Api.parse(reader, signature: signature) as? Api.NotificationSound
|
||||
} }
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = (Int(_1!) & Int(1 << 0) == 0) || _2 != nil
|
||||
let _c3 = (Int(_1!) & Int(1 << 1) == 0) || _3 != nil
|
||||
|
|
|
|||
|
|
@ -207,6 +207,8 @@ public final class ManagedAudioSession {
|
|||
private let isActiveSubscribers = Bag<(Bool) -> Void>()
|
||||
private let isPlaybackActiveSubscribers = Bag<(Bool) -> Void>()
|
||||
|
||||
private var callKitAudioSessionIsActive: Bool = false
|
||||
|
||||
public init() {
|
||||
self.queue = Queue()
|
||||
|
||||
|
|
@ -899,18 +901,18 @@ public final class ManagedAudioSession {
|
|||
}
|
||||
|
||||
public func callKitActivatedAudioSession() {
|
||||
/*self.queue.async {
|
||||
managedAudioSessionLog("ManagedAudioSession callKitDeactivatedAudioSession")
|
||||
self.queue.async {
|
||||
managedAudioSessionLog("ManagedAudioSession callKitDeactivatedAudioSession")
|
||||
self.callKitAudioSessionIsActive = true
|
||||
self.updateHolders()
|
||||
}*/
|
||||
}
|
||||
}
|
||||
|
||||
public func callKitDeactivatedAudioSession() {
|
||||
/*self.queue.async {
|
||||
managedAudioSessionLog("ManagedAudioSession callKitDeactivatedAudioSession")
|
||||
self.queue.async {
|
||||
managedAudioSessionLog("ManagedAudioSession callKitDeactivatedAudioSession")
|
||||
self.callKitAudioSessionIsActive = false
|
||||
self.updateHolders()
|
||||
}*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1572,7 +1572,7 @@ public final class VoiceChatControllerImpl: ViewController, VoiceChatController
|
|||
}).start()
|
||||
}
|
||||
|
||||
strongSelf.presentUndoOverlay(content: .info(text: strongSelf.presentationData.strings.VoiceChat_EditBioSuccess), action: { _ in return false })
|
||||
strongSelf.presentUndoOverlay(content: .info(title: nil, text: strongSelf.presentationData.strings.VoiceChat_EditBioSuccess), action: { _ in return false })
|
||||
}
|
||||
})
|
||||
self?.controller?.present(controller, in: .window(.root))
|
||||
|
|
@ -1593,7 +1593,7 @@ public final class VoiceChatControllerImpl: ViewController, VoiceChatController
|
|||
if let strongSelf = self, let (firstName, lastName) = firstAndLastName {
|
||||
let _ = context.engine.accountData.updateAccountPeerName(firstName: firstName, lastName: lastName).start()
|
||||
|
||||
strongSelf.presentUndoOverlay(content: .info(text: strongSelf.presentationData.strings.VoiceChat_EditNameSuccess), action: { _ in return false })
|
||||
strongSelf.presentUndoOverlay(content: .info(title: nil, text: strongSelf.presentationData.strings.VoiceChat_EditNameSuccess), action: { _ in return false })
|
||||
}
|
||||
})
|
||||
self?.controller?.present(controller, in: .window(.root))
|
||||
|
|
|
|||
|
|
@ -1092,6 +1092,7 @@ public class Account {
|
|||
self.managedOperationsDisposable.add(managedApplyPendingScheduledMessagesActions(postbox: self.postbox, network: self.network, stateManager: self.stateManager).start())
|
||||
self.managedOperationsDisposable.add(managedSynchronizeAvailableReactions(postbox: self.postbox, network: self.network).start())
|
||||
self.managedOperationsDisposable.add(managedSynchronizeAttachMenuBots(postbox: self.postbox, network: self.network).start())
|
||||
self.managedOperationsDisposable.add(managedSynchronizeNotificationSoundList(postbox: self.postbox, network: self.network).start())
|
||||
|
||||
if !supplementary {
|
||||
self.managedOperationsDisposable.add(managedChatListFilters(postbox: self.postbox, network: self.network, accountPeerId: self.peerId).start())
|
||||
|
|
|
|||
|
|
@ -6,76 +6,91 @@ import TelegramApi
|
|||
extension TelegramPeerNotificationSettings {
|
||||
convenience init(apiSettings: Api.PeerNotifySettings) {
|
||||
switch apiSettings {
|
||||
case let .peerNotifySettings(_, showPreviews, _, muteUntil, sound):
|
||||
let muteState: PeerMuteState
|
||||
if let muteUntil = muteUntil {
|
||||
if muteUntil == 0 {
|
||||
muteState = .unmuted
|
||||
} else {
|
||||
muteState = .muted(until: muteUntil)
|
||||
}
|
||||
case let .peerNotifySettings(_, showPreviews, _, muteUntil, iosSound, _, desktopSound):
|
||||
let sound: Api.NotificationSound?
|
||||
#if os(iOS)
|
||||
sound = iosSound
|
||||
#elseif os(macOS)
|
||||
sound = desktopSound
|
||||
#endif
|
||||
|
||||
let muteState: PeerMuteState
|
||||
if let muteUntil = muteUntil {
|
||||
if muteUntil == 0 {
|
||||
muteState = .unmuted
|
||||
} else {
|
||||
muteState = .default
|
||||
muteState = .muted(until: muteUntil)
|
||||
}
|
||||
let displayPreviews: PeerNotificationDisplayPreviews
|
||||
if let showPreviews = showPreviews {
|
||||
if case .boolTrue = showPreviews {
|
||||
displayPreviews = .show
|
||||
} else {
|
||||
displayPreviews = .hide
|
||||
}
|
||||
} else {
|
||||
muteState = .default
|
||||
}
|
||||
let displayPreviews: PeerNotificationDisplayPreviews
|
||||
if let showPreviews = showPreviews {
|
||||
if case .boolTrue = showPreviews {
|
||||
displayPreviews = .show
|
||||
} else {
|
||||
displayPreviews = .default
|
||||
displayPreviews = .hide
|
||||
}
|
||||
self.init(muteState: muteState, messageSound: PeerMessageSound(apiSound: sound), displayPreviews: displayPreviews)
|
||||
} else {
|
||||
displayPreviews = .default
|
||||
}
|
||||
self.init(muteState: muteState, messageSound: PeerMessageSound(apiSound: sound ?? .notificationSoundDefault), displayPreviews: displayPreviews)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension PeerMessageSound {
|
||||
init(apiSound: String?) {
|
||||
guard let apiSound = apiSound else {
|
||||
init(apiSound: Api.NotificationSound) {
|
||||
switch apiSound {
|
||||
case .notificationSoundDefault:
|
||||
self = .default
|
||||
return
|
||||
}
|
||||
var rawApiSound = apiSound
|
||||
if let index = rawApiSound.firstIndex(of: ".") {
|
||||
rawApiSound = String(rawApiSound[..<index])
|
||||
}
|
||||
|
||||
let parsedSound: PeerMessageSound
|
||||
if rawApiSound == "default" {
|
||||
parsedSound = .default
|
||||
} else if rawApiSound == "" || rawApiSound == "0" {
|
||||
parsedSound = .none
|
||||
} else {
|
||||
let soundId: Int32
|
||||
if let id = Int32(rawApiSound) {
|
||||
soundId = id
|
||||
} else {
|
||||
soundId = 100
|
||||
case .notificationSoundNone:
|
||||
self = .none
|
||||
case let .notificationSoundLocal(_, data):
|
||||
var rawApiSound = data
|
||||
if let index = rawApiSound.firstIndex(of: ".") {
|
||||
rawApiSound = String(rawApiSound[..<index])
|
||||
}
|
||||
if soundId >= 100 && soundId <= 111 {
|
||||
parsedSound = .bundledModern(id: soundId - 100)
|
||||
} else if soundId >= 2 && soundId <= 9 {
|
||||
parsedSound = .bundledClassic(id: soundId - 2)
|
||||
let parsedSound: PeerMessageSound
|
||||
if rawApiSound == "default" {
|
||||
parsedSound = .default
|
||||
} else if rawApiSound == "" || rawApiSound == "0" {
|
||||
parsedSound = .none
|
||||
} else {
|
||||
parsedSound = .bundledModern(id: 0)
|
||||
let soundId: Int32
|
||||
if let id = Int32(rawApiSound) {
|
||||
soundId = id
|
||||
} else {
|
||||
soundId = 100
|
||||
}
|
||||
if soundId >= 100 && soundId <= 111 {
|
||||
parsedSound = .bundledModern(id: soundId - 100)
|
||||
} else if soundId >= 2 && soundId <= 9 {
|
||||
parsedSound = .bundledClassic(id: soundId - 2)
|
||||
} else {
|
||||
parsedSound = .bundledModern(id: 0)
|
||||
}
|
||||
}
|
||||
self = parsedSound
|
||||
case let .notificationSoundRingtone(id):
|
||||
self = .cloud(fileId: id)
|
||||
}
|
||||
self = parsedSound
|
||||
}
|
||||
|
||||
var apiSound: String? {
|
||||
var apiSound: Api.NotificationSound {
|
||||
switch self {
|
||||
case .none:
|
||||
return ""
|
||||
case .default:
|
||||
return nil
|
||||
case let .bundledModern(id):
|
||||
return "\(id + 100)"
|
||||
case let .bundledClassic(id):
|
||||
return "\(id + 2)"
|
||||
case .none:
|
||||
return .notificationSoundNone
|
||||
case .default:
|
||||
return .notificationSoundDefault
|
||||
case let .bundledModern(id):
|
||||
let string = "\(id + 100)"
|
||||
return .notificationSoundLocal(title: string, data: string)
|
||||
case let .bundledClassic(id):
|
||||
let string = "\(id + 2)"
|
||||
return .notificationSoundLocal(title: string, data: string)
|
||||
case let .cloud(fileId):
|
||||
return .notificationSoundRingtone(id: fileId)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,14 +6,20 @@ import TelegramApi
|
|||
extension MessageNotificationSettings {
|
||||
init(apiSettings: Api.PeerNotifySettings) {
|
||||
switch apiSettings {
|
||||
case let .peerNotifySettings(_, showPreviews, _, muteUntil, sound):
|
||||
let displayPreviews: Bool
|
||||
if let showPreviews = showPreviews, case .boolFalse = showPreviews {
|
||||
displayPreviews = false
|
||||
} else {
|
||||
displayPreviews = true
|
||||
}
|
||||
self = MessageNotificationSettings(enabled: muteUntil == 0, displayPreviews: displayPreviews, sound: PeerMessageSound(apiSound: sound ?? "2"))
|
||||
case let .peerNotifySettings(_, showPreviews, _, muteUntil, iosSound, _, desktopSound):
|
||||
let sound: Api.NotificationSound?
|
||||
#if os(iOS)
|
||||
sound = iosSound
|
||||
#elseif os(macOS)
|
||||
sound = desktopSound
|
||||
#endif
|
||||
let displayPreviews: Bool
|
||||
if let showPreviews = showPreviews, case .boolFalse = showPreviews {
|
||||
displayPreviews = false
|
||||
} else {
|
||||
displayPreviews = true
|
||||
}
|
||||
self = MessageNotificationSettings(enabled: muteUntil == 0, displayPreviews: displayPreviews, sound: PeerMessageSound(apiSound: sound ?? .notificationSoundDefault))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -395,7 +395,10 @@ private func _internal_clearHistory(transaction: Transaction, postbox: Postbox,
|
|||
if operation.minTimestamp != nil {
|
||||
return .complete()
|
||||
} else {
|
||||
let flags: Int32 = 0
|
||||
var flags: Int32 = 0
|
||||
if operation.type == .forEveryone {
|
||||
flags |= 1 << 0
|
||||
}
|
||||
return network.request(Api.functions.channels.deleteHistory(flags: flags, channel: inputChannel, maxId: operation.topMessageId.id))
|
||||
|> map(Optional.init)
|
||||
|> `catch` { _ -> Signal<Api.Updates?, NoError> in
|
||||
|
|
|
|||
|
|
@ -116,56 +116,77 @@ private func fetchedNotificationSettings(network: Network) -> Signal<GlobalNotif
|
|||
|> map { chats, users, channels, contactsJoinedMuted in
|
||||
let chatsSettings: MessageNotificationSettings
|
||||
switch chats {
|
||||
case let .peerNotifySettings(_, showPreviews, _, muteUntil, sound):
|
||||
let enabled: Bool
|
||||
if muteUntil != nil && muteUntil != 0 {
|
||||
enabled = false
|
||||
} else {
|
||||
enabled = true
|
||||
}
|
||||
let displayPreviews: Bool
|
||||
if let showPreviews = showPreviews, case .boolFalse = showPreviews {
|
||||
displayPreviews = false
|
||||
} else {
|
||||
displayPreviews = true
|
||||
}
|
||||
chatsSettings = MessageNotificationSettings(enabled: enabled, displayPreviews: displayPreviews, sound: PeerMessageSound(apiSound: sound))
|
||||
case let .peerNotifySettings(_, showPreviews, _, muteUntil, iosSound, _, desktopSound):
|
||||
let sound: Api.NotificationSound?
|
||||
#if os(iOS)
|
||||
sound = iosSound
|
||||
#elseif os(macOS)
|
||||
sound = desktopSound
|
||||
#endif
|
||||
|
||||
let enabled: Bool
|
||||
if muteUntil != nil && muteUntil != 0 {
|
||||
enabled = false
|
||||
} else {
|
||||
enabled = true
|
||||
}
|
||||
let displayPreviews: Bool
|
||||
if let showPreviews = showPreviews, case .boolFalse = showPreviews {
|
||||
displayPreviews = false
|
||||
} else {
|
||||
displayPreviews = true
|
||||
}
|
||||
chatsSettings = MessageNotificationSettings(enabled: enabled, displayPreviews: displayPreviews, sound: PeerMessageSound(apiSound: sound ?? .notificationSoundDefault))
|
||||
}
|
||||
|
||||
let userSettings: MessageNotificationSettings
|
||||
switch users {
|
||||
case let .peerNotifySettings(_, showPreviews, _, muteUntil, sound):
|
||||
let enabled: Bool
|
||||
if muteUntil != nil && muteUntil != 0 {
|
||||
enabled = false
|
||||
} else {
|
||||
enabled = true
|
||||
}
|
||||
let displayPreviews: Bool
|
||||
if let showPreviews = showPreviews, case .boolFalse = showPreviews {
|
||||
displayPreviews = false
|
||||
} else {
|
||||
displayPreviews = true
|
||||
}
|
||||
userSettings = MessageNotificationSettings(enabled: enabled, displayPreviews: displayPreviews, sound: PeerMessageSound(apiSound: sound))
|
||||
case let .peerNotifySettings(_, showPreviews, _, muteUntil, iosSound, _, desktopSound):
|
||||
let sound: Api.NotificationSound?
|
||||
#if os(iOS)
|
||||
sound = iosSound
|
||||
#elseif os(macOS)
|
||||
sound = desktopSound
|
||||
#endif
|
||||
|
||||
let enabled: Bool
|
||||
if muteUntil != nil && muteUntil != 0 {
|
||||
enabled = false
|
||||
} else {
|
||||
enabled = true
|
||||
}
|
||||
let displayPreviews: Bool
|
||||
if let showPreviews = showPreviews, case .boolFalse = showPreviews {
|
||||
displayPreviews = false
|
||||
} else {
|
||||
displayPreviews = true
|
||||
}
|
||||
userSettings = MessageNotificationSettings(enabled: enabled, displayPreviews: displayPreviews, sound: PeerMessageSound(apiSound: sound ?? .notificationSoundDefault))
|
||||
}
|
||||
|
||||
let channelSettings: MessageNotificationSettings
|
||||
switch channels {
|
||||
case let .peerNotifySettings(_, showPreviews, _, muteUntil, sound):
|
||||
let enabled: Bool
|
||||
if muteUntil != nil && muteUntil != 0 {
|
||||
enabled = false
|
||||
} else {
|
||||
enabled = true
|
||||
}
|
||||
let displayPreviews: Bool
|
||||
if let showPreviews = showPreviews, case .boolFalse = showPreviews {
|
||||
displayPreviews = false
|
||||
} else {
|
||||
displayPreviews = true
|
||||
}
|
||||
channelSettings = MessageNotificationSettings(enabled: enabled, displayPreviews: displayPreviews, sound: PeerMessageSound(apiSound: sound))
|
||||
case let .peerNotifySettings(_, showPreviews, _, muteUntil, iosSound, _, desktopSound):
|
||||
let sound: Api.NotificationSound?
|
||||
#if os(iOS)
|
||||
sound = iosSound
|
||||
#elseif os(macOS)
|
||||
sound = desktopSound
|
||||
#endif
|
||||
|
||||
let enabled: Bool
|
||||
if muteUntil != nil && muteUntil != 0 {
|
||||
enabled = false
|
||||
} else {
|
||||
enabled = true
|
||||
}
|
||||
let displayPreviews: Bool
|
||||
if let showPreviews = showPreviews, case .boolFalse = showPreviews {
|
||||
displayPreviews = false
|
||||
} else {
|
||||
displayPreviews = true
|
||||
}
|
||||
channelSettings = MessageNotificationSettings(enabled: enabled, displayPreviews: displayPreviews, sound: PeerMessageSound(apiSound: sound ?? .notificationSoundDefault))
|
||||
}
|
||||
|
||||
return GlobalNotificationSettingsSet(privateChats: userSettings, groupChats: chatsSettings, channels: channelSettings, contactsJoined: contactsJoinedMuted == .boolFalse)
|
||||
|
|
@ -179,7 +200,7 @@ private func apiInputPeerNotifySettings(_ settings: MessageNotificationSettings)
|
|||
} else {
|
||||
muteUntil = Int32.max
|
||||
}
|
||||
let sound: String? = settings.sound.apiSound
|
||||
let sound: Api.NotificationSound? = settings.sound.apiSound
|
||||
var flags: Int32 = 0
|
||||
flags |= (1 << 0)
|
||||
if muteUntil != nil {
|
||||
|
|
|
|||
|
|
@ -116,7 +116,7 @@ private func pushPeerNotificationSettings(postbox: Postbox, network: Network, pe
|
|||
case .default:
|
||||
muteUntil = nil
|
||||
}
|
||||
let sound: String? = settings.messageSound.apiSound
|
||||
let sound: Api.NotificationSound? = settings.messageSound.apiSound
|
||||
var flags: Int32 = 0
|
||||
if showPreviews != nil {
|
||||
flags |= (1 << 0)
|
||||
|
|
|
|||
|
|
@ -84,6 +84,7 @@ public struct Namespaces {
|
|||
public static let availableReactions: Int8 = 19
|
||||
public static let resolvedByPhonePeers: Int8 = 20
|
||||
public static let attachMenuBots: Int8 = 21
|
||||
public static let notificationSoundList: Int8 = 22
|
||||
}
|
||||
|
||||
public struct UnorderedItemList {
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
import Foundation
|
||||
import Postbox
|
||||
|
||||
public enum PeerMuteState: Equatable {
|
||||
|
|
@ -36,102 +37,147 @@ private enum PeerMessageSoundValue: Int32 {
|
|||
case bundledModern
|
||||
case bundledClassic
|
||||
case `default`
|
||||
case cloud
|
||||
}
|
||||
|
||||
public enum PeerMessageSound: Equatable {
|
||||
public enum Id: Hashable {
|
||||
case none
|
||||
case `default`
|
||||
case bundledModern(id: Int32)
|
||||
case bundledClassic(id: Int32)
|
||||
case cloud(fileId: Int64)
|
||||
}
|
||||
|
||||
case none
|
||||
case `default`
|
||||
case bundledModern(id: Int32)
|
||||
case bundledClassic(id: Int32)
|
||||
case cloud(fileId: Int64)
|
||||
|
||||
public var id: Id {
|
||||
switch self {
|
||||
case .none:
|
||||
return .none
|
||||
case .default:
|
||||
return .default
|
||||
case let .bundledModern(id):
|
||||
return .bundledModern(id: id)
|
||||
case let .bundledClassic(id):
|
||||
return .bundledClassic(id: id)
|
||||
case let .cloud(fileId):
|
||||
return .cloud(fileId: fileId)
|
||||
}
|
||||
}
|
||||
|
||||
static func decodeInline(_ container: KeyedDecodingContainer<StringCodingKey>) throws -> PeerMessageSound {
|
||||
switch try container.decode(Int32.self, forKey: "s.v") {
|
||||
case PeerMessageSoundValue.none.rawValue:
|
||||
return .none
|
||||
case PeerMessageSoundValue.bundledModern.rawValue:
|
||||
return .bundledModern(id: (try? container.decode(Int32.self, forKey: "s.i")) ?? 0)
|
||||
case PeerMessageSoundValue.bundledClassic.rawValue:
|
||||
return .bundledClassic(id: (try? container.decode(Int32.self, forKey: "s.i")) ?? 0)
|
||||
case PeerMessageSoundValue.default.rawValue:
|
||||
case PeerMessageSoundValue.none.rawValue:
|
||||
return .none
|
||||
case PeerMessageSoundValue.bundledModern.rawValue:
|
||||
return .bundledModern(id: (try? container.decode(Int32.self, forKey: "s.i")) ?? 0)
|
||||
case PeerMessageSoundValue.bundledClassic.rawValue:
|
||||
return .bundledClassic(id: (try? container.decode(Int32.self, forKey: "s.i")) ?? 0)
|
||||
case PeerMessageSoundValue.default.rawValue:
|
||||
return .default
|
||||
case PeerMessageSoundValue.cloud.rawValue:
|
||||
do {
|
||||
return .cloud(fileId: try container.decode(Int64.self, forKey: "s.cloud.fileId"))
|
||||
} catch {
|
||||
return .default
|
||||
default:
|
||||
assertionFailure()
|
||||
return .bundledModern(id: 0)
|
||||
}
|
||||
default:
|
||||
assertionFailure()
|
||||
return .bundledModern(id: 0)
|
||||
}
|
||||
}
|
||||
|
||||
static func decodeInline(_ container: PostboxDecoder) -> PeerMessageSound {
|
||||
switch container.decodeInt32ForKey("s.v", orElse: 0) {
|
||||
case PeerMessageSoundValue.none.rawValue:
|
||||
return .none
|
||||
case PeerMessageSoundValue.bundledModern.rawValue:
|
||||
return .bundledModern(id: container.decodeInt32ForKey("s.i", orElse: 0))
|
||||
case PeerMessageSoundValue.bundledClassic.rawValue:
|
||||
return .bundledClassic(id: container.decodeInt32ForKey("s.i", orElse: 0))
|
||||
case PeerMessageSoundValue.default.rawValue:
|
||||
return .default
|
||||
default:
|
||||
assertionFailure()
|
||||
return .bundledModern(id: 0)
|
||||
case PeerMessageSoundValue.none.rawValue:
|
||||
return .none
|
||||
case PeerMessageSoundValue.bundledModern.rawValue:
|
||||
return .bundledModern(id: container.decodeInt32ForKey("s.i", orElse: 0))
|
||||
case PeerMessageSoundValue.bundledClassic.rawValue:
|
||||
return .bundledClassic(id: container.decodeInt32ForKey("s.i", orElse: 0))
|
||||
case PeerMessageSoundValue.default.rawValue:
|
||||
return .default
|
||||
case PeerMessageSoundValue.cloud.rawValue:
|
||||
return .cloud(fileId: container.decodeInt64ForKey("s.cloud.fileId", orElse: 0))
|
||||
default:
|
||||
assertionFailure()
|
||||
return .bundledModern(id: 0)
|
||||
}
|
||||
}
|
||||
|
||||
func encodeInline(_ container: inout KeyedEncodingContainer<StringCodingKey>) throws {
|
||||
switch self {
|
||||
case .none:
|
||||
try container.encode(PeerMessageSoundValue.none.rawValue, forKey: "s.v")
|
||||
case let .bundledModern(id):
|
||||
try container.encode(PeerMessageSoundValue.bundledModern.rawValue, forKey: "s.v")
|
||||
try container.encode(id, forKey: "s.i")
|
||||
case let .bundledClassic(id):
|
||||
try container.encode(PeerMessageSoundValue.bundledClassic.rawValue, forKey: "s.v")
|
||||
try container.encode(id, forKey: "s.i")
|
||||
case .default:
|
||||
try container.encode(PeerMessageSoundValue.default.rawValue, forKey: "s.v")
|
||||
case .none:
|
||||
try container.encode(PeerMessageSoundValue.none.rawValue, forKey: "s.v")
|
||||
case let .bundledModern(id):
|
||||
try container.encode(PeerMessageSoundValue.bundledModern.rawValue, forKey: "s.v")
|
||||
try container.encode(id, forKey: "s.i")
|
||||
case let .bundledClassic(id):
|
||||
try container.encode(PeerMessageSoundValue.bundledClassic.rawValue, forKey: "s.v")
|
||||
try container.encode(id, forKey: "s.i")
|
||||
case let .cloud(fileId):
|
||||
try container.encode(PeerMessageSoundValue.cloud.rawValue, forKey: "s.v")
|
||||
try container.encode(fileId, forKey: "s.cloud.fileId")
|
||||
case .default:
|
||||
try container.encode(PeerMessageSoundValue.default.rawValue, forKey: "s.v")
|
||||
}
|
||||
}
|
||||
|
||||
func encodeInline(_ encoder: PostboxEncoder) {
|
||||
switch self {
|
||||
case .none:
|
||||
encoder.encodeInt32(PeerMessageSoundValue.none.rawValue, forKey: "s.v")
|
||||
case let .bundledModern(id):
|
||||
encoder.encodeInt32(PeerMessageSoundValue.bundledModern.rawValue, forKey: "s.v")
|
||||
encoder.encodeInt32(id, forKey: "s.i")
|
||||
case let .bundledClassic(id):
|
||||
encoder.encodeInt32(PeerMessageSoundValue.bundledClassic.rawValue, forKey: "s.v")
|
||||
encoder.encodeInt32(id, forKey: "s.i")
|
||||
case .default:
|
||||
encoder.encodeInt32(PeerMessageSoundValue.default.rawValue, forKey: "s.v")
|
||||
case .none:
|
||||
encoder.encodeInt32(PeerMessageSoundValue.none.rawValue, forKey: "s.v")
|
||||
case let .bundledModern(id):
|
||||
encoder.encodeInt32(PeerMessageSoundValue.bundledModern.rawValue, forKey: "s.v")
|
||||
encoder.encodeInt32(id, forKey: "s.i")
|
||||
case let .bundledClassic(id):
|
||||
encoder.encodeInt32(PeerMessageSoundValue.bundledClassic.rawValue, forKey: "s.v")
|
||||
encoder.encodeInt32(id, forKey: "s.i")
|
||||
case let .cloud(fileId):
|
||||
encoder.encodeInt32(PeerMessageSoundValue.cloud.rawValue, forKey: "s.v")
|
||||
encoder.encodeInt64(fileId, forKey: "s.cloud.fileId")
|
||||
case .default:
|
||||
encoder.encodeInt32(PeerMessageSoundValue.default.rawValue, forKey: "s.v")
|
||||
}
|
||||
}
|
||||
|
||||
public static func ==(lhs: PeerMessageSound, rhs: PeerMessageSound) -> Bool {
|
||||
switch lhs {
|
||||
case .none:
|
||||
if case .none = rhs {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
case let .bundledModern(id):
|
||||
if case .bundledModern(id) = rhs {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
case let .bundledClassic(id):
|
||||
if case .bundledClassic(id) = rhs {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
case .default:
|
||||
if case .default = rhs {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
case .none:
|
||||
if case .none = rhs {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
case let .bundledModern(id):
|
||||
if case .bundledModern(id) = rhs {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
case let .bundledClassic(id):
|
||||
if case .bundledClassic(id) = rhs {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
case .default:
|
||||
if case .default = rhs {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
case let .cloud(fileId):
|
||||
if case .cloud(fileId) = rhs {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,241 @@
|
|||
import Foundation
|
||||
import SwiftSignalKit
|
||||
import Postbox
|
||||
import TelegramApi
|
||||
|
||||
public final class NotificationSoundList: Equatable, Codable {
|
||||
public final class NotificationSound: Equatable, Codable {
|
||||
private enum CodingKeys: String, CodingKey {
|
||||
case file
|
||||
}
|
||||
|
||||
public let file: TelegramMediaFile
|
||||
|
||||
public init(
|
||||
file: TelegramMediaFile
|
||||
) {
|
||||
self.file = file
|
||||
}
|
||||
|
||||
public static func ==(lhs: NotificationSound, rhs: NotificationSound) -> Bool {
|
||||
if lhs.file != rhs.file {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
public init(from decoder: Decoder) throws {
|
||||
let container = try decoder.container(keyedBy: CodingKeys.self)
|
||||
|
||||
let fileData = try container.decode(AdaptedPostboxDecoder.RawObjectData.self, forKey: .file)
|
||||
self.file = TelegramMediaFile(decoder: PostboxDecoder(buffer: MemoryBuffer(data: fileData.data)))
|
||||
}
|
||||
|
||||
public func encode(to encoder: Encoder) throws {
|
||||
var container = encoder.container(keyedBy: CodingKeys.self)
|
||||
|
||||
try container.encode(PostboxEncoder().encodeObjectToRawData(self.file), forKey: .file)
|
||||
}
|
||||
}
|
||||
|
||||
private enum CodingKeys: String, CodingKey {
|
||||
case hash
|
||||
case sounds
|
||||
}
|
||||
|
||||
public let hash: Int64
|
||||
public let sounds: [NotificationSound]
|
||||
|
||||
public init(
|
||||
hash: Int64,
|
||||
sounds: [NotificationSound]
|
||||
) {
|
||||
self.hash = hash
|
||||
self.sounds = sounds
|
||||
}
|
||||
|
||||
public static func ==(lhs: NotificationSoundList, rhs: NotificationSoundList) -> Bool {
|
||||
if lhs.hash != rhs.hash {
|
||||
return false
|
||||
}
|
||||
if lhs.sounds != rhs.sounds {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
public init(from decoder: Decoder) throws {
|
||||
let container = try decoder.container(keyedBy: CodingKeys.self)
|
||||
|
||||
self.hash = try container.decode(Int64.self, forKey: .hash)
|
||||
self.sounds = try container.decode([NotificationSound].self, forKey: .sounds)
|
||||
}
|
||||
|
||||
public func encode(to encoder: Encoder) throws {
|
||||
var container = encoder.container(keyedBy: CodingKeys.self)
|
||||
|
||||
try container.encode(self.hash, forKey: .hash)
|
||||
try container.encode(self.sounds, forKey: .sounds)
|
||||
}
|
||||
}
|
||||
|
||||
private extension NotificationSoundList.NotificationSound {
|
||||
convenience init?(apiDocument: Api.Document) {
|
||||
guard let file = telegramMediaFileFromApiDocument(apiDocument) else {
|
||||
return nil
|
||||
}
|
||||
self.init(file: file)
|
||||
}
|
||||
}
|
||||
|
||||
func _internal_cachedNotificationSoundList(postbox: Postbox) -> Signal<NotificationSoundList?, NoError> {
|
||||
return postbox.transaction { transaction -> NotificationSoundList? in
|
||||
return _internal_cachedNotificationSoundList(transaction: transaction)
|
||||
}
|
||||
}
|
||||
|
||||
func _internal_cachedNotificationSoundListCacheKey() -> ItemCacheEntryId {
|
||||
let key = ValueBoxKey(length: 8)
|
||||
key.setInt64(0, value: 0)
|
||||
|
||||
return ItemCacheEntryId(collectionId: Namespaces.CachedItemCollection.notificationSoundList, key: key)
|
||||
}
|
||||
|
||||
func _internal_cachedNotificationSoundList(transaction: Transaction) -> NotificationSoundList? {
|
||||
let cached = transaction.retrieveItemCacheEntry(id: _internal_cachedNotificationSoundListCacheKey())?.get(NotificationSoundList.self)
|
||||
if let cached = cached {
|
||||
return cached
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func _internal_setCachedNotificationSoundList(transaction: Transaction, notificationSoundList: NotificationSoundList) {
|
||||
if let entry = CodableEntry(notificationSoundList) {
|
||||
transaction.putItemCacheEntry(id: _internal_cachedNotificationSoundListCacheKey(), entry: entry, collectionSpec: ItemCacheCollectionSpec(lowWaterItemCount: 10, highWaterItemCount: 10))
|
||||
}
|
||||
}
|
||||
|
||||
private func pollNotificationSoundList(postbox: Postbox, network: Network) -> Signal<Never, NoError> {
|
||||
return Signal<Never, NoError> { subscriber in
|
||||
let signal: Signal<Never, NoError> = _internal_cachedNotificationSoundList(postbox: postbox)
|
||||
|> mapToSignal { current in
|
||||
return (network.request(Api.functions.account.getSavedRingtones(hash: current?.hash ?? 0))
|
||||
|> map(Optional.init)
|
||||
|> `catch` { _ -> Signal<Api.account.SavedRingtones?, NoError> in
|
||||
return .single(nil)
|
||||
}
|
||||
|> mapToSignal { result -> Signal<Never, NoError> in
|
||||
return postbox.transaction { transaction -> Signal<Never, NoError> in
|
||||
guard let result = result else {
|
||||
return .complete()
|
||||
}
|
||||
switch result {
|
||||
case let .savedRingtones(hash, ringtones):
|
||||
let notificationSoundList = NotificationSoundList(
|
||||
hash: hash,
|
||||
sounds: ringtones.compactMap(NotificationSoundList.NotificationSound.init(apiDocument:))
|
||||
)
|
||||
_internal_setCachedNotificationSoundList(transaction: transaction, notificationSoundList: notificationSoundList)
|
||||
case .savedRingtonesNotModified:
|
||||
break
|
||||
}
|
||||
|
||||
var signals: [Signal<Never, NoError>] = []
|
||||
|
||||
if let notificationSoundList = _internal_cachedNotificationSoundList(transaction: transaction) {
|
||||
var resources: [MediaResource] = []
|
||||
|
||||
for sound in notificationSoundList.sounds {
|
||||
resources.append(sound.file.resource)
|
||||
}
|
||||
|
||||
for resource in resources {
|
||||
signals.append(
|
||||
fetchedMediaResource(mediaBox: postbox.mediaBox, reference: .standalone(resource: resource))
|
||||
|> ignoreValues
|
||||
|> `catch` { _ -> Signal<Never, NoError> in
|
||||
return .complete()
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
return combineLatest(signals)
|
||||
|> ignoreValues
|
||||
}
|
||||
|> switchToLatest
|
||||
})
|
||||
}
|
||||
|
||||
return signal.start(completed: {
|
||||
subscriber.putCompletion()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func managedSynchronizeNotificationSoundList(postbox: Postbox, network: Network) -> Signal<Never, NoError> {
|
||||
let poll = pollNotificationSoundList(postbox: postbox, network: network)
|
||||
|
||||
return (
|
||||
poll
|
||||
|> then(
|
||||
.complete()
|
||||
|> suspendAwareDelay(1.0 * 60.0 * 60.0, queue: Queue.concurrentDefaultQueue())
|
||||
)
|
||||
)
|
||||
|> restart
|
||||
}
|
||||
|
||||
func _internal_saveNotificationSound(account: Account, file: TelegramMediaFile) -> Signal<Never, UploadNotificationSoundError> {
|
||||
guard let resource = file.resource as? CloudDocumentMediaResource else {
|
||||
return .fail(.generic)
|
||||
}
|
||||
return account.network.request(Api.functions.account.saveRingtone(id: .inputDocument(id: resource.fileId, accessHash: resource.accessHash, fileReference: Buffer(data: resource.fileReference)), unsave: .boolFalse))
|
||||
|> mapError { _ -> UploadNotificationSoundError in
|
||||
return .generic
|
||||
}
|
||||
|> mapToSignal { _ -> Signal<Never, UploadNotificationSoundError> in
|
||||
return pollNotificationSoundList(postbox: account.postbox, network: account.network)
|
||||
|> castError(UploadNotificationSoundError.self)
|
||||
}
|
||||
}
|
||||
|
||||
public enum UploadNotificationSoundError {
|
||||
case generic
|
||||
}
|
||||
|
||||
func _internal_uploadNotificationSound(account: Account, title: String, data: Data) -> Signal<NotificationSoundList.NotificationSound, UploadNotificationSoundError> {
|
||||
return multipartUpload(network: account.network, postbox: account.postbox, source: .data(data), encrypt: false, tag: nil, hintFileSize: data.count, hintFileIsLarge: false, forceNoBigParts: true, useLargerParts: false, increaseParallelParts: false, useMultiplexedRequests: false, useCompression: false)
|
||||
|> mapError { _ -> UploadNotificationSoundError in
|
||||
return .generic
|
||||
}
|
||||
|> mapToSignal { value -> Signal<NotificationSoundList.NotificationSound, UploadNotificationSoundError> in
|
||||
switch value {
|
||||
case let .inputFile(file):
|
||||
return account.network.request(Api.functions.account.uploadRingtone(file: file, fileName: title, mimeType: "audio/mpeg"))
|
||||
|> mapError { _ -> UploadNotificationSoundError in
|
||||
return .generic
|
||||
}
|
||||
|> mapToSignal { result -> Signal<NotificationSoundList.NotificationSound, UploadNotificationSoundError> in
|
||||
guard let file = telegramMediaFileFromApiDocument(result) else {
|
||||
return .fail(.generic)
|
||||
}
|
||||
return account.postbox.transaction { transaction -> NotificationSoundList.NotificationSound in
|
||||
let item = NotificationSoundList.NotificationSound(file: file)
|
||||
|
||||
account.postbox.mediaBox.storeResourceData(file.resource.id, data: data, synchronous: true)
|
||||
|
||||
let notificationSoundList = _internal_cachedNotificationSoundList(transaction: transaction) ?? NotificationSoundList(hash: 0, sounds: [])
|
||||
let updatedNotificationSoundList = NotificationSoundList(hash: notificationSoundList.hash, sounds: [item] + notificationSoundList.sounds)
|
||||
_internal_setCachedNotificationSoundList(transaction: transaction, notificationSoundList: updatedNotificationSoundList)
|
||||
|
||||
return item
|
||||
}
|
||||
|> castError(UploadNotificationSoundError.self)
|
||||
}
|
||||
default:
|
||||
return .never()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,3 +1,4 @@
|
|||
import Foundation
|
||||
import Postbox
|
||||
|
||||
public enum EnginePeer: Equatable {
|
||||
|
|
@ -75,6 +76,7 @@ public enum EnginePeer: Equatable {
|
|||
case `default`
|
||||
case bundledModern(id: Int32)
|
||||
case bundledClassic(id: Int32)
|
||||
case cloud(fileId: Int64)
|
||||
}
|
||||
|
||||
public enum DisplayPreviews {
|
||||
|
|
@ -200,6 +202,8 @@ public extension EnginePeer.NotificationSettings.MessageSound {
|
|||
self = .bundledClassic(id: id)
|
||||
case let .bundledModern(id):
|
||||
self = .bundledModern(id: id)
|
||||
case let .cloud(fileId):
|
||||
self = .cloud(fileId: fileId)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -213,6 +217,8 @@ public extension EnginePeer.NotificationSettings.MessageSound {
|
|||
return .bundledClassic(id: id)
|
||||
case let .bundledModern(id):
|
||||
return .bundledModern(id: id)
|
||||
case let .cloud(fileId):
|
||||
return .cloud(fileId: fileId)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -684,6 +684,25 @@ public extension TelegramEngine {
|
|||
public func updatePeerAllowedReactions(peerId: PeerId, allowedReactions: [String]) -> Signal<Never, UpdatePeerAllowedReactionsError> {
|
||||
return _internal_updatePeerAllowedReactions(account: account, peerId: peerId, allowedReactions: allowedReactions)
|
||||
}
|
||||
|
||||
public func notificationSoundList() -> Signal<NotificationSoundList?, NoError> {
|
||||
let key = PostboxViewKey.cachedItem(_internal_cachedNotificationSoundListCacheKey())
|
||||
return self.account.postbox.combinedView(keys: [key])
|
||||
|> map { views -> NotificationSoundList? in
|
||||
guard let view = views.views[key] as? CachedItemView else {
|
||||
return nil
|
||||
}
|
||||
return view.value?.get(NotificationSoundList.self)
|
||||
}
|
||||
}
|
||||
|
||||
public func saveNotificationSound(file: TelegramMediaFile) -> Signal<Never, UploadNotificationSoundError> {
|
||||
return _internal_saveNotificationSound(account: self.account, file: file)
|
||||
}
|
||||
|
||||
public func uploadNotificationSound(title: String, data: Data) -> Signal<NotificationSoundList.NotificationSound, UploadNotificationSoundError> {
|
||||
return _internal_uploadNotificationSound(account: self.account, title: title, data: data)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -38,6 +38,18 @@ public func presentationStringsFormattedNumber(_ count: Int32, _ groupingSeparat
|
|||
}
|
||||
}
|
||||
|
||||
public func dayIntervalString(strings: PresentationStrings, days: Int32) -> String {
|
||||
return strings.MessageTimer_Days(max(0, days))
|
||||
}
|
||||
|
||||
public func hoursIntervalString(strings: PresentationStrings, hours: Int32) -> String {
|
||||
return strings.MessageTimer_Hours(max(0, hours))
|
||||
}
|
||||
|
||||
public func minutesIntervalString(strings: PresentationStrings, minutes: Int32) -> String {
|
||||
return strings.MessageTimer_Minutes(max(0, minutes))
|
||||
}
|
||||
|
||||
public func timeIntervalString(strings: PresentationStrings, value: Int32, preferLowerValue: Bool = false) -> String {
|
||||
if preferLowerValue {
|
||||
if value <= 60 {
|
||||
|
|
|
|||
|
|
@ -273,6 +273,8 @@ public enum PresentationResourceKey: Int32 {
|
|||
case chatKeyboardActionButtonProfileIcon
|
||||
case chatKeyboardActionButtonAddToChatIcon
|
||||
case chatKeyboardActionButtonWebAppIcon
|
||||
|
||||
case uploadToneIcon
|
||||
}
|
||||
|
||||
public enum PresentationResourceParameterKey: Hashable {
|
||||
|
|
|
|||
|
|
@ -269,4 +269,10 @@ public struct PresentationResourcesItemList {
|
|||
})?.stretchableImage(withLeftCapWidth: 25, topCapHeight: 25)
|
||||
})
|
||||
}
|
||||
|
||||
public static func uploadToneIcon(_ theme: PresentationTheme) -> UIImage? {
|
||||
return theme.image(PresentationResourceKey.uploadToneIcon.rawValue, { theme in
|
||||
return generateTintedImage(image: UIImage(bundleImageName: "Settings/UploadTone"), color: theme.list.itemAccentColor)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,41 +28,52 @@ private let classicSoundNamePaths: [KeyPath<PresentationStrings, String>] = [
|
|||
\.NotificationsSound_Telegraph
|
||||
]
|
||||
|
||||
private func soundName(strings: PresentationStrings, sound: PeerMessageSound) -> String {
|
||||
private func soundName(strings: PresentationStrings, sound: PeerMessageSound, notificationSoundList: NotificationSoundList?) -> String {
|
||||
switch sound {
|
||||
case .none:
|
||||
return strings.NotificationsSound_None
|
||||
case .default:
|
||||
return ""
|
||||
case let .bundledModern(id):
|
||||
if id >= 0 && Int(id) < modernSoundsNamePaths.count {
|
||||
return strings[keyPath: modernSoundsNamePaths[Int(id)]]
|
||||
case .none:
|
||||
return strings.NotificationsSound_None
|
||||
case .default:
|
||||
return ""
|
||||
case let .bundledModern(id):
|
||||
if id >= 0 && Int(id) < modernSoundsNamePaths.count {
|
||||
return strings[keyPath: modernSoundsNamePaths[Int(id)]]
|
||||
}
|
||||
return "Sound \(id)"
|
||||
case let .bundledClassic(id):
|
||||
if id >= 0 && Int(id) < classicSoundNamePaths.count {
|
||||
return strings[keyPath: classicSoundNamePaths[Int(id)]]
|
||||
}
|
||||
return "Sound \(id)"
|
||||
case let .cloud(fileId):
|
||||
guard let notificationSoundList = notificationSoundList else {
|
||||
//TODO:localize
|
||||
return "Loading..."
|
||||
}
|
||||
for sound in notificationSoundList.sounds {
|
||||
if sound.file.fileId.id == fileId {
|
||||
return sound.file.fileName ?? "Cloud Tone"
|
||||
}
|
||||
return "Sound \(id)"
|
||||
case let .bundledClassic(id):
|
||||
if id >= 0 && Int(id) < classicSoundNamePaths.count {
|
||||
return strings[keyPath: classicSoundNamePaths[Int(id)]]
|
||||
}
|
||||
return "Sound \(id)"
|
||||
}
|
||||
return ""
|
||||
}
|
||||
}
|
||||
|
||||
public func localizedPeerNotificationSoundString(strings: PresentationStrings, sound: PeerMessageSound, default: PeerMessageSound? = nil) -> String {
|
||||
public func localizedPeerNotificationSoundString(strings: PresentationStrings, notificationSoundList: NotificationSoundList?, sound: PeerMessageSound, default: PeerMessageSound? = nil) -> String {
|
||||
switch sound {
|
||||
case .default:
|
||||
if let defaultSound = `default` {
|
||||
let name = soundName(strings: strings, sound: defaultSound)
|
||||
let actualName: String
|
||||
if name.isEmpty {
|
||||
actualName = soundName(strings: strings, sound: .bundledModern(id: 0))
|
||||
} else {
|
||||
actualName = name
|
||||
}
|
||||
return strings.UserInfo_NotificationsDefaultSound(actualName).string
|
||||
case .default:
|
||||
if let defaultSound = `default` {
|
||||
let name = soundName(strings: strings, sound: defaultSound, notificationSoundList: notificationSoundList)
|
||||
let actualName: String
|
||||
if name.isEmpty {
|
||||
actualName = soundName(strings: strings, sound: .bundledModern(id: 0), notificationSoundList: notificationSoundList)
|
||||
} else {
|
||||
return strings.UserInfo_NotificationsDefault
|
||||
actualName = name
|
||||
}
|
||||
default:
|
||||
return soundName(strings: strings, sound: sound)
|
||||
return strings.UserInfo_NotificationsDefaultSound(actualName).string
|
||||
} else {
|
||||
return strings.UserInfo_NotificationsDefault
|
||||
}
|
||||
default:
|
||||
return soundName(strings: strings, sound: sound, notificationSoundList: notificationSoundList)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
12
submodules/TelegramUI/Images.xcassets/Chat/Context Menu/ClearMessages.imageset/Contents.json
vendored
Normal file
12
submodules/TelegramUI/Images.xcassets/Chat/Context Menu/ClearMessages.imageset/Contents.json
vendored
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "clearmessages_24.pdf",
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
285
submodules/TelegramUI/Images.xcassets/Chat/Context Menu/ClearMessages.imageset/clearmessages_24.pdf
vendored
Normal file
285
submodules/TelegramUI/Images.xcassets/Chat/Context Menu/ClearMessages.imageset/clearmessages_24.pdf
vendored
Normal file
|
|
@ -0,0 +1,285 @@
|
|||
%PDF-1.7
|
||||
|
||||
1 0 obj
|
||||
<< >>
|
||||
endobj
|
||||
|
||||
2 0 obj
|
||||
<< /Length 3 0 R >>
|
||||
stream
|
||||
/DeviceRGB CS
|
||||
/DeviceRGB cs
|
||||
q
|
||||
1.000000 0.000000 -0.000000 1.000000 3.000000 3.630371 cm
|
||||
0.000000 0.000000 0.000000 scn
|
||||
6.036711 3.044792 m
|
||||
5.888044 2.396624 l
|
||||
6.036711 3.044792 l
|
||||
h
|
||||
4.213051 1.739638 m
|
||||
3.887771 2.319654 l
|
||||
3.887771 2.319654 l
|
||||
4.213051 1.739638 l
|
||||
h
|
||||
1.977577 1.386564 m
|
||||
1.720352 0.773327 l
|
||||
1.977577 1.386564 l
|
||||
h
|
||||
2.890895 4.595274 m
|
||||
2.498061 4.058705 l
|
||||
2.890895 4.595274 l
|
||||
h
|
||||
8.000000 16.704628 m
|
||||
12.112072 16.704628 15.335000 13.688025 15.335000 10.096902 c
|
||||
16.665001 10.096902 l
|
||||
16.665001 14.539012 12.724484 18.034630 8.000000 18.034630 c
|
||||
8.000000 16.704628 l
|
||||
h
|
||||
15.335000 10.096902 m
|
||||
15.335000 6.505779 12.112072 3.489175 8.000000 3.489175 c
|
||||
8.000000 2.159175 l
|
||||
12.724484 2.159175 16.665001 5.654792 16.665001 10.096902 c
|
||||
15.335000 10.096902 l
|
||||
h
|
||||
8.000000 3.489175 m
|
||||
7.372782 3.489175 6.764923 3.560034 6.185379 3.692961 c
|
||||
5.888044 2.396624 l
|
||||
6.564841 2.241389 7.272436 2.159175 8.000000 2.159175 c
|
||||
8.000000 3.489175 l
|
||||
h
|
||||
6.185379 3.692961 m
|
||||
5.804111 3.780411 5.513260 3.569372 5.413143 3.494156 c
|
||||
5.290826 3.402263 5.147437 3.265127 5.034352 3.161364 c
|
||||
4.781663 2.929504 4.434368 2.626192 3.887771 2.319654 c
|
||||
4.538331 1.159622 l
|
||||
5.211778 1.537300 5.645048 1.916672 5.933547 2.181390 c
|
||||
6.091055 2.325915 6.158414 2.390541 6.212014 2.430810 c
|
||||
6.287813 2.487756 6.138047 2.339281 5.888044 2.396624 c
|
||||
6.185379 3.692961 l
|
||||
h
|
||||
3.887771 2.319654 m
|
||||
3.572365 2.142771 3.165311 2.048659 2.790003 2.014445 c
|
||||
2.607043 1.997766 2.446026 1.996657 2.327112 2.003073 c
|
||||
2.267397 2.006294 2.224190 2.011101 2.197881 2.015177 c
|
||||
2.158949 2.021208 2.183327 2.021393 2.234801 1.999803 c
|
||||
1.720352 0.773327 l
|
||||
1.821844 0.730755 1.926930 0.711287 1.994275 0.700853 c
|
||||
2.074244 0.688465 2.162884 0.679998 2.255463 0.675005 c
|
||||
2.441139 0.664988 2.666504 0.667671 2.910749 0.689938 c
|
||||
3.389851 0.733614 4.000499 0.858000 4.538331 1.159622 c
|
||||
3.887771 2.319654 l
|
||||
h
|
||||
2.234801 1.999803 m
|
||||
2.265677 1.986851 2.404851 1.923249 2.493219 1.747771 c
|
||||
2.589725 1.556132 2.551083 1.383581 2.526376 1.313473 c
|
||||
2.504906 1.252550 2.480861 1.226551 2.497980 1.249567 c
|
||||
2.510608 1.266544 2.534224 1.295128 2.576988 1.342783 c
|
||||
2.735965 1.519941 3.080277 1.865030 3.376156 2.318596 c
|
||||
2.262219 3.045261 l
|
||||
2.039068 2.703184 1.800315 2.468651 1.587115 2.231068 c
|
||||
1.536834 2.175037 1.480586 2.110241 1.430826 2.043344 c
|
||||
1.385558 1.982486 1.316601 1.882117 1.271991 1.755535 c
|
||||
1.224144 1.619764 1.184133 1.390259 1.305339 1.149572 c
|
||||
1.418406 0.925049 1.608346 0.820307 1.720352 0.773327 c
|
||||
2.234801 1.999803 l
|
||||
h
|
||||
3.376156 2.318596 m
|
||||
3.725287 2.853793 3.824730 3.434122 3.801171 3.906185 c
|
||||
3.789388 4.142282 3.746260 4.366606 3.677134 4.560054 c
|
||||
3.618218 4.724927 3.504569 4.970161 3.283730 5.131843 c
|
||||
2.498061 4.058705 l
|
||||
2.393648 4.135148 2.394127 4.198050 2.424695 4.112509 c
|
||||
2.445051 4.055541 2.466761 3.961368 2.472824 3.839892 c
|
||||
2.484955 3.596812 2.432118 3.305708 2.262219 3.045261 c
|
||||
3.376156 2.318596 l
|
||||
h
|
||||
3.283730 5.131843 m
|
||||
1.614924 6.353613 0.665000 8.040656 0.665000 10.096902 c
|
||||
-0.665000 10.096902 l
|
||||
-0.665000 7.571545 0.525193 5.503087 2.498061 4.058705 c
|
||||
3.283730 5.131843 l
|
||||
h
|
||||
0.665000 10.096902 m
|
||||
0.665000 13.688025 3.887928 16.704628 8.000000 16.704628 c
|
||||
8.000000 18.034630 l
|
||||
3.275515 18.034630 -0.665000 14.539012 -0.665000 10.096902 c
|
||||
0.665000 10.096902 l
|
||||
h
|
||||
f
|
||||
n
|
||||
Q
|
||||
q
|
||||
-1.000000 -0.000000 -0.000000 1.000000 21.700012 1.535767 cm
|
||||
0.000000 0.000000 0.000000 scn
|
||||
6.036711 3.139397 m
|
||||
5.888044 2.491228 l
|
||||
6.036711 3.139397 l
|
||||
h
|
||||
4.213051 1.834243 m
|
||||
3.887771 2.414258 l
|
||||
3.887771 2.414258 l
|
||||
4.213051 1.834243 l
|
||||
h
|
||||
1.977577 1.481169 m
|
||||
1.720352 0.867930 l
|
||||
1.977577 1.481169 l
|
||||
h
|
||||
2.890895 4.689878 m
|
||||
2.498061 4.153310 l
|
||||
2.890895 4.689878 l
|
||||
h
|
||||
1.435227 13.141423 m
|
||||
1.613510 13.462519 1.497738 13.867344 1.176643 14.045628 c
|
||||
0.855548 14.223910 0.450722 14.108138 0.272439 13.787044 c
|
||||
1.435227 13.141423 l
|
||||
h
|
||||
9.828376 2.430831 m
|
||||
10.188738 2.501724 10.423399 2.851326 10.352506 3.211688 c
|
||||
10.281612 3.572050 9.932011 3.806711 9.571649 3.735818 c
|
||||
9.828376 2.430831 l
|
||||
h
|
||||
8.000000 3.583779 m
|
||||
7.372782 3.583779 6.764923 3.654638 6.185379 3.787565 c
|
||||
5.888044 2.491228 l
|
||||
6.564841 2.335994 7.272436 2.253779 8.000000 2.253779 c
|
||||
8.000000 3.583779 l
|
||||
h
|
||||
6.185379 3.787565 m
|
||||
5.804111 3.875015 5.513260 3.663977 5.413143 3.588760 c
|
||||
5.290826 3.496867 5.147437 3.359732 5.034352 3.255968 c
|
||||
4.781663 3.024109 4.434368 2.720797 3.887771 2.414258 c
|
||||
4.538331 1.254228 l
|
||||
5.211778 1.631905 5.645048 2.011276 5.933547 2.275994 c
|
||||
6.091055 2.420520 6.158414 2.485146 6.212014 2.525414 c
|
||||
6.287813 2.582360 6.138047 2.433886 5.888044 2.491228 c
|
||||
6.185379 3.787565 l
|
||||
h
|
||||
3.887771 2.414258 m
|
||||
3.572365 2.237375 3.165311 2.143264 2.790003 2.109050 c
|
||||
2.607043 2.092371 2.446026 2.091262 2.327112 2.097677 c
|
||||
2.267397 2.100899 2.224190 2.105705 2.197881 2.109781 c
|
||||
2.158949 2.115812 2.183327 2.115997 2.234801 2.094407 c
|
||||
1.720352 0.867930 l
|
||||
1.821844 0.825360 1.926930 0.805891 1.994275 0.795458 c
|
||||
2.074244 0.783070 2.162884 0.774603 2.255463 0.769608 c
|
||||
2.441139 0.759591 2.666504 0.762276 2.910749 0.784542 c
|
||||
3.389851 0.828218 4.000499 0.952604 4.538331 1.254228 c
|
||||
3.887771 2.414258 l
|
||||
h
|
||||
2.234801 2.094407 m
|
||||
2.265677 2.081455 2.404851 2.017854 2.493219 1.842376 c
|
||||
2.589725 1.650737 2.551083 1.478186 2.526376 1.408076 c
|
||||
2.504906 1.347156 2.480861 1.321156 2.497980 1.344172 c
|
||||
2.510608 1.361148 2.534224 1.389732 2.576988 1.437387 c
|
||||
2.735965 1.614546 3.080277 1.959635 3.376156 2.413200 c
|
||||
2.262219 3.139866 l
|
||||
2.039068 2.797789 1.800315 2.563255 1.587115 2.325672 c
|
||||
1.536834 2.269642 1.480586 2.204845 1.430826 2.137948 c
|
||||
1.385558 2.077090 1.316601 1.976722 1.271991 1.850140 c
|
||||
1.224144 1.714369 1.184133 1.484863 1.305339 1.244177 c
|
||||
1.418406 1.019652 1.608346 0.914912 1.720352 0.867930 c
|
||||
2.234801 2.094407 l
|
||||
h
|
||||
3.376156 2.413200 m
|
||||
3.725287 2.948398 3.824730 3.528727 3.801171 4.000790 c
|
||||
3.789388 4.236886 3.746260 4.461210 3.677134 4.654658 c
|
||||
3.618218 4.819531 3.504569 5.064766 3.283730 5.226447 c
|
||||
2.498061 4.153310 l
|
||||
2.393648 4.229753 2.394127 4.292655 2.424695 4.207113 c
|
||||
2.445051 4.150146 2.466761 4.055972 2.472824 3.934497 c
|
||||
2.484955 3.691417 2.432118 3.400312 2.262219 3.139866 c
|
||||
3.376156 2.413200 l
|
||||
h
|
||||
3.283730 5.226447 m
|
||||
1.614924 6.448217 0.665000 8.135260 0.665000 10.191506 c
|
||||
-0.665000 10.191506 l
|
||||
-0.665000 7.666149 0.525193 5.597691 2.498061 4.153310 c
|
||||
3.283730 5.226447 l
|
||||
h
|
||||
0.665000 10.191506 m
|
||||
0.665000 11.250713 0.941389 12.252002 1.435227 13.141423 c
|
||||
0.272439 13.787044 l
|
||||
-0.326097 12.709055 -0.665000 11.486644 -0.665000 10.191506 c
|
||||
0.665000 10.191506 l
|
||||
h
|
||||
9.571649 3.735818 m
|
||||
9.065956 3.636334 8.540168 3.583779 8.000000 3.583779 c
|
||||
8.000000 2.253779 l
|
||||
8.626554 2.253779 9.238318 2.314750 9.828376 2.430831 c
|
||||
9.571649 3.735818 l
|
||||
h
|
||||
f
|
||||
n
|
||||
Q
|
||||
q
|
||||
1.000000 0.000000 -0.000000 1.000000 7.335022 9.700195 cm
|
||||
0.000000 0.000000 0.000000 scn
|
||||
1.135226 7.265065 m
|
||||
0.875527 7.524764 0.454473 7.524764 0.194774 7.265065 c
|
||||
-0.064925 7.005366 -0.064925 6.584311 0.194774 6.324613 c
|
||||
2.724548 3.794839 l
|
||||
0.194774 1.265065 l
|
||||
-0.064925 1.005366 -0.064925 0.584311 0.194774 0.324613 c
|
||||
0.454473 0.064914 0.875527 0.064914 1.135226 0.324613 c
|
||||
3.665000 2.854387 l
|
||||
6.194774 0.324613 l
|
||||
6.454473 0.064914 6.875527 0.064914 7.135226 0.324613 c
|
||||
7.394925 0.584311 7.394925 1.005366 7.135226 1.265065 c
|
||||
4.605452 3.794839 l
|
||||
7.135226 6.324613 l
|
||||
7.394925 6.584311 7.394925 7.005366 7.135226 7.265065 c
|
||||
6.875527 7.524764 6.454473 7.524764 6.194774 7.265065 c
|
||||
3.665000 4.735291 l
|
||||
1.135226 7.265065 l
|
||||
h
|
||||
f*
|
||||
n
|
||||
Q
|
||||
|
||||
endstream
|
||||
endobj
|
||||
|
||||
3 0 obj
|
||||
7291
|
||||
endobj
|
||||
|
||||
4 0 obj
|
||||
<< /Annots []
|
||||
/Type /Page
|
||||
/MediaBox [ 0.000000 0.000000 24.000000 24.000000 ]
|
||||
/Resources 1 0 R
|
||||
/Contents 2 0 R
|
||||
/Parent 5 0 R
|
||||
>>
|
||||
endobj
|
||||
|
||||
5 0 obj
|
||||
<< /Kids [ 4 0 R ]
|
||||
/Count 1
|
||||
/Type /Pages
|
||||
>>
|
||||
endobj
|
||||
|
||||
6 0 obj
|
||||
<< /Pages 5 0 R
|
||||
/Type /Catalog
|
||||
>>
|
||||
endobj
|
||||
|
||||
xref
|
||||
0 7
|
||||
0000000000 65535 f
|
||||
0000000010 00000 n
|
||||
0000000034 00000 n
|
||||
0000007381 00000 n
|
||||
0000007404 00000 n
|
||||
0000007577 00000 n
|
||||
0000007651 00000 n
|
||||
trailer
|
||||
<< /ID [ (some) (id) ]
|
||||
/Root 6 0 R
|
||||
/Size 7
|
||||
>>
|
||||
startxref
|
||||
7710
|
||||
%%EOF
|
||||
12
submodules/TelegramUI/Images.xcassets/Chat/Context Menu/Customize.imageset/Contents.json
vendored
Normal file
12
submodules/TelegramUI/Images.xcassets/Chat/Context Menu/Customize.imageset/Contents.json
vendored
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "custom_24.pdf",
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
163
submodules/TelegramUI/Images.xcassets/Chat/Context Menu/Customize.imageset/custom_24.pdf
vendored
Normal file
163
submodules/TelegramUI/Images.xcassets/Chat/Context Menu/Customize.imageset/custom_24.pdf
vendored
Normal file
|
|
@ -0,0 +1,163 @@
|
|||
%PDF-1.7
|
||||
|
||||
1 0 obj
|
||||
<< >>
|
||||
endobj
|
||||
|
||||
2 0 obj
|
||||
<< /Length 3 0 R >>
|
||||
stream
|
||||
/DeviceRGB CS
|
||||
/DeviceRGB cs
|
||||
q
|
||||
1.000000 0.000000 -0.000000 1.000000 10.500000 15.669922 cm
|
||||
0.000000 0.000000 0.000000 scn
|
||||
0.000000 1.995078 m
|
||||
-0.367269 1.995078 -0.665000 1.697348 -0.665000 1.330078 c
|
||||
-0.665000 0.962809 -0.367269 0.665078 0.000000 0.665078 c
|
||||
0.000000 1.995078 l
|
||||
h
|
||||
9.000000 0.665078 m
|
||||
9.367270 0.665078 9.665000 0.962809 9.665000 1.330078 c
|
||||
9.665000 1.697348 9.367270 1.995078 9.000000 1.995078 c
|
||||
9.000000 0.665078 l
|
||||
h
|
||||
0.000000 0.665078 m
|
||||
9.000000 0.665078 l
|
||||
9.000000 1.995078 l
|
||||
0.000000 1.995078 l
|
||||
0.000000 0.665078 l
|
||||
h
|
||||
f
|
||||
n
|
||||
Q
|
||||
q
|
||||
1.000000 0.000000 -0.000000 1.000000 4.500000 5.669922 cm
|
||||
0.000000 0.000000 0.000000 scn
|
||||
0.000000 1.995078 m
|
||||
-0.367269 1.995078 -0.665000 1.697348 -0.665000 1.330078 c
|
||||
-0.665000 0.962809 -0.367269 0.665078 0.000000 0.665078 c
|
||||
0.000000 1.995078 l
|
||||
h
|
||||
9.000000 0.665078 m
|
||||
9.367270 0.665078 9.665000 0.962809 9.665000 1.330078 c
|
||||
9.665000 1.697348 9.367270 1.995078 9.000000 1.995078 c
|
||||
9.000000 0.665078 l
|
||||
h
|
||||
0.000000 0.665078 m
|
||||
9.000000 0.665078 l
|
||||
9.000000 1.995078 l
|
||||
0.000000 1.995078 l
|
||||
0.000000 0.665078 l
|
||||
h
|
||||
f
|
||||
n
|
||||
Q
|
||||
q
|
||||
1.000000 0.000000 -0.000000 1.000000 4.000000 12.669922 cm
|
||||
0.000000 0.000000 0.000000 scn
|
||||
5.335000 4.330078 m
|
||||
5.335000 3.040493 4.289585 1.995078 3.000000 1.995078 c
|
||||
3.000000 0.665078 l
|
||||
5.024124 0.665078 6.665000 2.305954 6.665000 4.330078 c
|
||||
5.335000 4.330078 l
|
||||
h
|
||||
3.000000 1.995078 m
|
||||
1.710415 1.995078 0.665000 3.040493 0.665000 4.330078 c
|
||||
-0.665000 4.330078 l
|
||||
-0.665000 2.305954 0.975876 0.665078 3.000000 0.665078 c
|
||||
3.000000 1.995078 l
|
||||
h
|
||||
0.665000 4.330078 m
|
||||
0.665000 5.619663 1.710415 6.665078 3.000000 6.665078 c
|
||||
3.000000 7.995078 l
|
||||
0.975876 7.995078 -0.665000 6.354202 -0.665000 4.330078 c
|
||||
0.665000 4.330078 l
|
||||
h
|
||||
3.000000 6.665078 m
|
||||
4.289585 6.665078 5.335000 5.619663 5.335000 4.330078 c
|
||||
6.665000 4.330078 l
|
||||
6.665000 6.354202 5.024124 7.995078 3.000000 7.995078 c
|
||||
3.000000 6.665078 l
|
||||
h
|
||||
f
|
||||
n
|
||||
Q
|
||||
q
|
||||
1.000000 0.000000 -0.000000 1.000000 14.000000 2.669922 cm
|
||||
0.000000 0.000000 0.000000 scn
|
||||
5.335000 4.330078 m
|
||||
5.335000 3.040493 4.289585 1.995078 3.000000 1.995078 c
|
||||
3.000000 0.665078 l
|
||||
5.024124 0.665078 6.665000 2.305954 6.665000 4.330078 c
|
||||
5.335000 4.330078 l
|
||||
h
|
||||
3.000000 1.995078 m
|
||||
1.710415 1.995078 0.665000 3.040493 0.665000 4.330078 c
|
||||
-0.665000 4.330078 l
|
||||
-0.665000 2.305954 0.975876 0.665078 3.000000 0.665078 c
|
||||
3.000000 1.995078 l
|
||||
h
|
||||
0.665000 4.330078 m
|
||||
0.665000 5.619663 1.710415 6.665078 3.000000 6.665078 c
|
||||
3.000000 7.995078 l
|
||||
0.975876 7.995078 -0.665000 6.354202 -0.665000 4.330078 c
|
||||
0.665000 4.330078 l
|
||||
h
|
||||
3.000000 6.665078 m
|
||||
4.289585 6.665078 5.335000 5.619663 5.335000 4.330078 c
|
||||
6.665000 4.330078 l
|
||||
6.665000 6.354202 5.024124 7.995078 3.000000 7.995078 c
|
||||
3.000000 6.665078 l
|
||||
h
|
||||
f
|
||||
n
|
||||
Q
|
||||
|
||||
endstream
|
||||
endobj
|
||||
|
||||
3 0 obj
|
||||
2650
|
||||
endobj
|
||||
|
||||
4 0 obj
|
||||
<< /Annots []
|
||||
/Type /Page
|
||||
/MediaBox [ 0.000000 0.000000 24.000000 24.000000 ]
|
||||
/Resources 1 0 R
|
||||
/Contents 2 0 R
|
||||
/Parent 5 0 R
|
||||
>>
|
||||
endobj
|
||||
|
||||
5 0 obj
|
||||
<< /Kids [ 4 0 R ]
|
||||
/Count 1
|
||||
/Type /Pages
|
||||
>>
|
||||
endobj
|
||||
|
||||
6 0 obj
|
||||
<< /Pages 5 0 R
|
||||
/Type /Catalog
|
||||
>>
|
||||
endobj
|
||||
|
||||
xref
|
||||
0 7
|
||||
0000000000 65535 f
|
||||
0000000010 00000 n
|
||||
0000000034 00000 n
|
||||
0000002740 00000 n
|
||||
0000002763 00000 n
|
||||
0000002936 00000 n
|
||||
0000003010 00000 n
|
||||
trailer
|
||||
<< /ID [ (some) (id) ]
|
||||
/Root 6 0 R
|
||||
/Size 7
|
||||
>>
|
||||
startxref
|
||||
3069
|
||||
%%EOF
|
||||
12
submodules/TelegramUI/Images.xcassets/Chat/Context Menu/DownloadTone.imageset/Contents.json
vendored
Normal file
12
submodules/TelegramUI/Images.xcassets/Chat/Context Menu/DownloadTone.imageset/Contents.json
vendored
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "downloadtone_24.pdf",
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
116
submodules/TelegramUI/Images.xcassets/Chat/Context Menu/DownloadTone.imageset/downloadtone_24.pdf
vendored
Normal file
116
submodules/TelegramUI/Images.xcassets/Chat/Context Menu/DownloadTone.imageset/downloadtone_24.pdf
vendored
Normal file
|
|
@ -0,0 +1,116 @@
|
|||
%PDF-1.7
|
||||
|
||||
1 0 obj
|
||||
<< >>
|
||||
endobj
|
||||
|
||||
2 0 obj
|
||||
<< /Length 3 0 R >>
|
||||
stream
|
||||
/DeviceRGB CS
|
||||
/DeviceRGB cs
|
||||
q
|
||||
1.000000 0.000000 -0.000000 1.000000 2.334961 1.926270 cm
|
||||
0.000000 0.000000 0.000000 scn
|
||||
18.499836 17.264488 m
|
||||
18.499828 17.485374 18.289789 17.645796 18.076683 17.587671 c
|
||||
14.576791 16.633081 l
|
||||
14.431045 16.593330 14.329936 16.460947 14.329941 16.309877 c
|
||||
14.330013 13.944344 l
|
||||
18.253044 15.014344 l
|
||||
18.398790 15.054096 18.499899 15.186479 18.499895 15.337549 c
|
||||
18.499836 17.264488 l
|
||||
h
|
||||
13.000040 13.073683 m
|
||||
12.999941 16.309837 l
|
||||
12.999918 17.060677 13.502439 17.718637 14.226819 17.916210 c
|
||||
17.726713 18.870800 l
|
||||
18.785870 19.159685 19.829802 18.362379 19.829836 17.264528 c
|
||||
19.829895 15.337589 l
|
||||
19.829918 14.586750 19.327396 13.928788 18.603016 13.731215 c
|
||||
14.330040 12.565768 l
|
||||
14.330040 5.073744 l
|
||||
14.330001 5.073744 l
|
||||
14.330006 4.174320 l
|
||||
14.330013 2.634279 13.299263 1.284771 11.813485 0.879566 c
|
||||
11.386369 0.763084 l
|
||||
9.429031 0.229277 7.499888 1.702747 7.499878 3.731570 c
|
||||
7.499871 5.119122 8.428559 6.335007 9.767220 6.700088 c
|
||||
13.000040 7.581746 l
|
||||
13.000040 13.073662 l
|
||||
13.000040 13.073683 l
|
||||
h
|
||||
12.999995 6.203160 m
|
||||
10.117160 5.416950 l
|
||||
9.357137 5.209676 8.829874 4.519358 8.829878 3.731577 c
|
||||
8.829884 2.579716 9.925153 1.743153 11.036430 2.046223 c
|
||||
11.463547 2.162704 l
|
||||
12.370687 2.410101 13.000010 3.234043 13.000006 4.174314 c
|
||||
12.999995 6.203160 l
|
||||
h
|
||||
3.665000 17.738770 m
|
||||
4.032269 17.738770 4.330000 17.441038 4.330000 17.073769 c
|
||||
4.330000 10.679222 l
|
||||
6.194774 12.543995 l
|
||||
6.454473 12.803694 6.875527 12.803694 7.135226 12.543995 c
|
||||
7.394925 12.284297 7.394925 11.863242 7.135226 11.603544 c
|
||||
4.135226 8.603543 l
|
||||
3.875527 8.343845 3.454473 8.343845 3.194774 8.603543 c
|
||||
0.194774 11.603544 l
|
||||
-0.064925 11.863242 -0.064925 12.284297 0.194774 12.543995 c
|
||||
0.454473 12.803694 0.875527 12.803694 1.135226 12.543995 c
|
||||
3.000000 10.679222 l
|
||||
3.000000 17.073769 l
|
||||
3.000000 17.441038 3.297731 17.738770 3.665000 17.738770 c
|
||||
h
|
||||
f*
|
||||
n
|
||||
Q
|
||||
|
||||
endstream
|
||||
endobj
|
||||
|
||||
3 0 obj
|
||||
1860
|
||||
endobj
|
||||
|
||||
4 0 obj
|
||||
<< /Annots []
|
||||
/Type /Page
|
||||
/MediaBox [ 0.000000 0.000000 24.000000 24.000000 ]
|
||||
/Resources 1 0 R
|
||||
/Contents 2 0 R
|
||||
/Parent 5 0 R
|
||||
>>
|
||||
endobj
|
||||
|
||||
5 0 obj
|
||||
<< /Kids [ 4 0 R ]
|
||||
/Count 1
|
||||
/Type /Pages
|
||||
>>
|
||||
endobj
|
||||
|
||||
6 0 obj
|
||||
<< /Pages 5 0 R
|
||||
/Type /Catalog
|
||||
>>
|
||||
endobj
|
||||
|
||||
xref
|
||||
0 7
|
||||
0000000000 65535 f
|
||||
0000000010 00000 n
|
||||
0000000034 00000 n
|
||||
0000001950 00000 n
|
||||
0000001973 00000 n
|
||||
0000002146 00000 n
|
||||
0000002220 00000 n
|
||||
trailer
|
||||
<< /ID [ (some) (id) ]
|
||||
/Root 6 0 R
|
||||
/Size 7
|
||||
>>
|
||||
startxref
|
||||
2279
|
||||
%%EOF
|
||||
12
submodules/TelegramUI/Images.xcassets/Settings/UploadTone.imageset/Contents.json
vendored
Normal file
12
submodules/TelegramUI/Images.xcassets/Settings/UploadTone.imageset/Contents.json
vendored
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "addtone_30.pdf",
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
118
submodules/TelegramUI/Images.xcassets/Settings/UploadTone.imageset/addtone_30.pdf
vendored
Normal file
118
submodules/TelegramUI/Images.xcassets/Settings/UploadTone.imageset/addtone_30.pdf
vendored
Normal file
|
|
@ -0,0 +1,118 @@
|
|||
%PDF-1.7
|
||||
|
||||
1 0 obj
|
||||
<< >>
|
||||
endobj
|
||||
|
||||
2 0 obj
|
||||
<< /Length 3 0 R >>
|
||||
stream
|
||||
/DeviceRGB CS
|
||||
/DeviceRGB cs
|
||||
q
|
||||
1.000000 0.000000 -0.000000 1.000000 2.335022 2.524536 cm
|
||||
0.000000 0.000000 0.000000 scn
|
||||
24.000023 22.149782 m
|
||||
24.000023 22.372349 23.786995 22.533037 23.572990 22.471893 c
|
||||
18.572990 21.043322 l
|
||||
18.429174 21.002232 18.330023 20.870783 18.330023 20.721212 c
|
||||
18.330023 17.357124 l
|
||||
23.757053 18.907703 l
|
||||
23.900869 18.948795 24.000023 19.080244 24.000023 19.229815 c
|
||||
24.000023 22.149782 l
|
||||
h
|
||||
18.330023 15.973903 m
|
||||
24.122433 17.628878 l
|
||||
24.837221 17.833101 25.330023 18.486425 25.330023 19.229815 c
|
||||
25.330023 22.149782 l
|
||||
25.330023 23.255974 24.271240 24.054613 23.207611 23.750721 c
|
||||
18.207611 22.322149 l
|
||||
17.492825 22.117924 17.000023 21.464602 17.000023 20.721212 c
|
||||
17.000023 16.475513 l
|
||||
17.000023 8.977081 l
|
||||
12.574430 7.712626 l
|
||||
11.050592 7.277245 10.000000 5.884441 10.000000 4.299627 c
|
||||
10.000000 1.941366 12.257193 0.238766 14.524715 0.886629 c
|
||||
15.671853 1.214382 l
|
||||
17.245243 1.663923 18.330000 3.102016 18.330000 4.738369 c
|
||||
18.330000 5.475513 l
|
||||
18.330023 5.475513 l
|
||||
18.330023 15.973903 l
|
||||
h
|
||||
17.000000 7.593853 m
|
||||
12.939809 6.433800 l
|
||||
11.986943 6.161552 11.330000 5.290623 11.330000 4.299627 c
|
||||
11.330000 2.824991 12.741438 1.760342 14.159337 2.165457 c
|
||||
15.306474 2.493210 l
|
||||
16.308893 2.779615 17.000000 3.695837 17.000000 4.738369 c
|
||||
17.000000 7.593853 l
|
||||
h
|
||||
5.665000 21.140503 m
|
||||
6.032269 21.140503 6.330000 20.842772 6.330000 20.475502 c
|
||||
6.330000 16.140503 l
|
||||
10.665000 16.140503 l
|
||||
11.032269 16.140503 11.330000 15.842772 11.330000 15.475503 c
|
||||
11.330000 15.108233 11.032269 14.810503 10.665000 14.810503 c
|
||||
6.330000 14.810503 l
|
||||
6.330000 10.475503 l
|
||||
6.330000 10.108233 6.032269 9.810503 5.665000 9.810503 c
|
||||
5.297730 9.810503 5.000000 10.108233 5.000000 10.475503 c
|
||||
5.000000 14.810503 l
|
||||
0.665000 14.810503 l
|
||||
0.297731 14.810503 0.000000 15.108233 0.000000 15.475503 c
|
||||
0.000000 15.842772 0.297731 16.140503 0.665000 16.140503 c
|
||||
5.000000 16.140503 l
|
||||
5.000000 20.475502 l
|
||||
5.000000 20.842772 5.297730 21.140503 5.665000 21.140503 c
|
||||
h
|
||||
f*
|
||||
n
|
||||
Q
|
||||
|
||||
endstream
|
||||
endobj
|
||||
|
||||
3 0 obj
|
||||
1956
|
||||
endobj
|
||||
|
||||
4 0 obj
|
||||
<< /Annots []
|
||||
/Type /Page
|
||||
/MediaBox [ 0.000000 0.000000 30.000000 30.000000 ]
|
||||
/Resources 1 0 R
|
||||
/Contents 2 0 R
|
||||
/Parent 5 0 R
|
||||
>>
|
||||
endobj
|
||||
|
||||
5 0 obj
|
||||
<< /Kids [ 4 0 R ]
|
||||
/Count 1
|
||||
/Type /Pages
|
||||
>>
|
||||
endobj
|
||||
|
||||
6 0 obj
|
||||
<< /Pages 5 0 R
|
||||
/Type /Catalog
|
||||
>>
|
||||
endobj
|
||||
|
||||
xref
|
||||
0 7
|
||||
0000000000 65535 f
|
||||
0000000010 00000 n
|
||||
0000000034 00000 n
|
||||
0000002046 00000 n
|
||||
0000002069 00000 n
|
||||
0000002242 00000 n
|
||||
0000002316 00000 n
|
||||
trailer
|
||||
<< /ID [ (some) (id) ]
|
||||
/Root 6 0 R
|
||||
/Size 7
|
||||
>>
|
||||
startxref
|
||||
2375
|
||||
%%EOF
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -260,7 +260,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
|||
private let temporaryHiddenGalleryMediaDisposable = MetaDisposable()
|
||||
|
||||
private let chatBackgroundNode: WallpaperBackgroundNode
|
||||
private var controllerInteraction: ChatControllerInteraction?
|
||||
private(set) var controllerInteraction: ChatControllerInteraction?
|
||||
private var interfaceInteraction: ChatPanelInterfaceInteraction?
|
||||
|
||||
private let messageContextDisposable = MetaDisposable()
|
||||
|
|
@ -5679,7 +5679,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
|||
if let strongSelf = self, case let .message(index) = toIndex {
|
||||
if case let .message(messageSubject, _, _) = strongSelf.subject, initial, case let .id(messageId) = messageSubject, messageId != index.id {
|
||||
if messageId.peerId == index.id.peerId {
|
||||
strongSelf.present(UndoOverlayController(presentationData: strongSelf.presentationData, content: .info(text: strongSelf.presentationData.strings.Conversation_MessageDoesntExist), elevatedLayout: false, action: { _ in return true }), in: .current)
|
||||
strongSelf.present(UndoOverlayController(presentationData: strongSelf.presentationData, content: .info(title: nil, text: strongSelf.presentationData.strings.Conversation_MessageDoesntExist), elevatedLayout: false, action: { _ in return true }), in: .current)
|
||||
}
|
||||
} else if let controllerInteraction = strongSelf.controllerInteraction {
|
||||
if let message = strongSelf.chatDisplayNode.historyNode.messageInCurrentHistoryView(index.id) {
|
||||
|
|
@ -8168,7 +8168,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
|||
presentAddMembers(context: strongSelf.context, updatedPresentationData: strongSelf.updatedPresentationData, parentController: strongSelf, groupPeer: peer, selectAddMemberDisposable: strongSelf.selectAddMemberDisposable, addMemberDisposable: strongSelf.addMemberDisposable)
|
||||
}, presentGigagroupHelp: { [weak self] in
|
||||
if let strongSelf = self {
|
||||
strongSelf.present(UndoOverlayController(presentationData: strongSelf.presentationData, content: .info(text: strongSelf.presentationData.strings.Conversation_GigagroupDescription), elevatedLayout: false, action: { _ in return true }), in: .current)
|
||||
strongSelf.present(UndoOverlayController(presentationData: strongSelf.presentationData, content: .info(title: nil, text: strongSelf.presentationData.strings.Conversation_GigagroupDescription), elevatedLayout: false, action: { _ in return true }), in: .current)
|
||||
}
|
||||
}, editMessageMedia: { [weak self] messageId, draw in
|
||||
if let strongSelf = self {
|
||||
|
|
@ -8295,6 +8295,8 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
|||
}))
|
||||
})
|
||||
}
|
||||
}, chatController: { [weak self] in
|
||||
return self
|
||||
}, statuses: ChatPanelInterfaceInteractionStatuses(editingMessage: self.editingMessage.get(), startingBot: self.startingBot.get(), unblockingPeer: self.unblockingPeer.get(), searching: self.searching.get(), loadingMessage: self.loadingMessage.get(), inlineSearch: self.performingInlineSearch.get()))
|
||||
|
||||
do {
|
||||
|
|
@ -9074,7 +9076,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
|||
let attributedText = parseMarkdownIntoAttributedString(text, attributes: MarkdownAttributes(body: body, bold: bold, link: body, linkAttribute: { _ in return nil }), textAlignment: .center)
|
||||
|
||||
let controller = richTextAlertController(context: strongSelf.context, title: attributedTitle, text: attributedText, actions: [TextAlertAction(type: .genericAction, title: strongSelf.presentationData.strings.Common_Cancel, action: {
|
||||
strongSelf.present(UndoOverlayController(presentationData: strongSelf.presentationData, content: .info(text: strongSelf.presentationData.strings.BroadcastGroups_LimitAlert_SettingsTip), elevatedLayout: false, action: { _ in return false }), in: .current)
|
||||
strongSelf.present(UndoOverlayController(presentationData: strongSelf.presentationData, content: .info(title: nil, text: strongSelf.presentationData.strings.BroadcastGroups_LimitAlert_SettingsTip), elevatedLayout: false, action: { _ in return false }), in: .current)
|
||||
}), TextAlertAction(type: .defaultAction, title: strongSelf.presentationData.strings.BroadcastGroups_LimitAlert_LearnMore, action: {
|
||||
|
||||
let context = strongSelf.context
|
||||
|
|
@ -15387,18 +15389,21 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
|||
return
|
||||
}
|
||||
|
||||
let controller = peerAutoremoveSetupScreen(context: self.context, updatedPresentationData: self.updatedPresentationData, peerId: peer.id, completion: { [weak self] updatedValue in
|
||||
if case let .updated(value) = updatedValue {
|
||||
let controller = ChatTimerScreen(context: self.context, updatedPresentationData: self.updatedPresentationData, peerId: peer.id, style: .default, mode: .autoremove, currentTime: self.presentationInterfaceState.autoremoveTimeout, dismissByTapOutside: true, completion: { [weak self] value in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
|
||||
let _ = (strongSelf.context.engine.peers.setChatMessageAutoremoveTimeoutInteractively(peerId: peer.id, timeout: value == 0 ? nil : value)
|
||||
|> deliverOnMainQueue).start(completed: {
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
|
||||
strongSelf.updateChatPresentationInterfaceState(animated: false, interactive: false, { $0.updatedInterfaceState({ $0.withoutSelectionState() }) })
|
||||
|
||||
var isOn: Bool = true
|
||||
var text: String?
|
||||
if let myValue = value.value {
|
||||
text = strongSelf.presentationData.strings.Conversation_AutoremoveChanged("\(timeIntervalString(strings: strongSelf.presentationData.strings, value: myValue))").string
|
||||
if value != 0 {
|
||||
text = strongSelf.presentationData.strings.Conversation_AutoremoveChanged("\(timeIntervalString(strings: strongSelf.presentationData.strings, value: value))").string
|
||||
} else {
|
||||
isOn = false
|
||||
text = strongSelf.presentationData.strings.Conversation_AutoremoveOff
|
||||
|
|
@ -15406,10 +15411,10 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
|||
if let text = text {
|
||||
strongSelf.present(UndoOverlayController(presentationData: strongSelf.presentationData, content: .autoDelete(isOn: isOn, title: nil, text: text), elevatedLayout: false, action: { _ in return false }), in: .current)
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
self.chatDisplayNode.dismissInput()
|
||||
self.push(controller)
|
||||
self.present(controller, in: .window(.root))
|
||||
}
|
||||
|
||||
private func presentChatRequestAdminInfo() {
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ import TranslateUI
|
|||
import DebugSettingsUI
|
||||
import ChatPresentationInterfaceState
|
||||
import Pasteboard
|
||||
import SettingsUI
|
||||
|
||||
private struct MessageContextMenuData {
|
||||
let starStatus: Bool?
|
||||
|
|
@ -819,51 +820,6 @@ func contextMenuForChatPresentationInterfaceState(chatPresentationInterfaceState
|
|||
}
|
||||
f(.default)
|
||||
})))
|
||||
|
||||
if resourceAvailable {
|
||||
for media in message.media {
|
||||
if let file = media as? TelegramMediaFile, (["audio/mp3", "audio/mpeg3"] as [String]).contains(file.mimeType.lowercased()) {
|
||||
actions.append(.action(ContextMenuActionItem(text: "Set as Message Tone", icon: { _ in
|
||||
return nil
|
||||
}, action: { _, f in
|
||||
for media in message.media {
|
||||
if let file = media as? TelegramMediaFile {
|
||||
let _ = (context.account.postbox.mediaBox.resourceData(file.resource, option: .incremental(waitUntilFetchStatus: false))
|
||||
|> take(1)
|
||||
|> deliverOnMainQueue).start(next: { data in
|
||||
if data.complete {
|
||||
let documentsDirectoryPath = NSSearchPathForDirectoriesInDomains(.libraryDirectory, .userDomainMask, true)[0]
|
||||
let soundsDirectoryPath = documentsDirectoryPath + "/Sounds"
|
||||
|
||||
let _ = try? FileManager.default.createDirectory(atPath: soundsDirectoryPath, withIntermediateDirectories: true, attributes: nil)
|
||||
|
||||
let containerSoundsPath = context.sharedContext.applicationBindings.containerPath + "/Library/Sounds"
|
||||
|
||||
let _ = try? FileManager.default.createDirectory(atPath: containerSoundsPath, withIntermediateDirectories: true, attributes: nil)
|
||||
|
||||
let soundFileName = "\(UInt32.random(in: 0 ..< UInt32.max)).mp3"
|
||||
let soundPath = soundsDirectoryPath + "/\(soundFileName)"
|
||||
|
||||
let _ = try? FileManager.default.copyItem(atPath: data.path, toPath: soundPath)
|
||||
let _ = try? FileManager.default.copyItem(atPath: data.path, toPath: "\(containerSoundsPath)/\(soundFileName)")
|
||||
|
||||
let _ = updateInAppNotificationSettingsInteractively(accountManager: context.sharedContext.accountManager, { settings in
|
||||
var settings = settings
|
||||
|
||||
settings.customSound = soundFileName
|
||||
|
||||
return settings
|
||||
}).start()
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
f(.default)
|
||||
})))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let (canTranslate, _) = canTranslateText(context: context, text: messageText, showTranslate: translationSettings.showTranslate, ignoredLanguages: translationSettings.ignoredLanguages)
|
||||
|
|
@ -914,6 +870,54 @@ func contextMenuForChatPresentationInterfaceState(chatPresentationInterfaceState
|
|||
}
|
||||
}
|
||||
|
||||
for media in message.media {
|
||||
if let file = media as? TelegramMediaFile, let size = file.size, size < 200 * 1024, (["audio/mpeg", "audio/mp3", "audio/mpeg3"] as [String]).contains(file.mimeType.lowercased()) {
|
||||
actions.append(.action(ContextMenuActionItem(text: "Save for Notifications", icon: { theme in
|
||||
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/DownloadTone"), color: theme.actionSheet.primaryTextColor)
|
||||
}, action: { _, f in
|
||||
let _ = context.engine.peers.saveNotificationSound(file: file).start(completed: {
|
||||
//TODO:localize
|
||||
controllerInteraction.displayUndo(.notificationSoundAdded(title: "Sound added", text: "You can now use this sound as a notification tone in your [custom notification settings]().", action: {
|
||||
controllerInteraction.navigationController()?.pushViewController(notificationsAndSoundsController(context: context, exceptionsList: nil))
|
||||
}))
|
||||
})
|
||||
|
||||
f(.default)
|
||||
})))
|
||||
|
||||
/*
|
||||
|
||||
let _ = (context.account.postbox.mediaBox.resourceData(file.resource, option: .incremental(waitUntilFetchStatus: false))
|
||||
|> take(1)
|
||||
|> deliverOnMainQueue).start(next: { data in
|
||||
if data.complete {
|
||||
let documentsDirectoryPath = NSSearchPathForDirectoriesInDomains(.libraryDirectory, .userDomainMask, true)[0]
|
||||
let soundsDirectoryPath = documentsDirectoryPath + "/Sounds"
|
||||
|
||||
let _ = try? FileManager.default.createDirectory(atPath: soundsDirectoryPath, withIntermediateDirectories: true, attributes: nil)
|
||||
|
||||
let containerSoundsPath = context.sharedContext.applicationBindings.containerPath + "/Library/Sounds"
|
||||
|
||||
let _ = try? FileManager.default.createDirectory(atPath: containerSoundsPath, withIntermediateDirectories: true, attributes: nil)
|
||||
|
||||
let soundFileName = "\(UInt32.random(in: 0 ..< UInt32.max)).mp3"
|
||||
let soundPath = soundsDirectoryPath + "/\(soundFileName)"
|
||||
|
||||
let _ = try? FileManager.default.copyItem(atPath: data.path, toPath: soundPath)
|
||||
let _ = try? FileManager.default.copyItem(atPath: data.path, toPath: "\(containerSoundsPath)/\(soundFileName)")
|
||||
|
||||
let _ = updateInAppNotificationSettingsInteractively(accountManager: context.sharedContext.accountManager, { settings in
|
||||
var settings = settings
|
||||
|
||||
settings.customSound = soundFileName
|
||||
|
||||
return settings
|
||||
}).start()
|
||||
}
|
||||
})*/
|
||||
}
|
||||
}
|
||||
|
||||
var downloadableMediaResourceInfos: [String] = []
|
||||
for media in message.media {
|
||||
if let file = media as? TelegramMediaFile {
|
||||
|
|
|
|||
|
|
@ -55,6 +55,9 @@ final class ChatPinnedMessageTitlePanelNode: ChatTitleAccessoryPanelNode {
|
|||
private let textNode: TextNode
|
||||
private var spoilerTextNode: TextNode?
|
||||
private var dustNode: InvisibleInkDustNode?
|
||||
private let actionButton: HighlightableButtonNode
|
||||
private let actionButtonTitleNode: ImmediateTextNode
|
||||
private let actionButtonBackgroundNode: ASImageNode
|
||||
|
||||
private let imageNode: TransformImageNode
|
||||
private let imageNodeContainer: ASDisplayNode
|
||||
|
|
@ -93,6 +96,14 @@ final class ChatPinnedMessageTitlePanelNode: ChatTitleAccessoryPanelNode {
|
|||
self.closeButton.hitTestSlop = UIEdgeInsets(top: -8.0, left: -8.0, bottom: -8.0, right: -8.0)
|
||||
self.closeButton.displaysAsynchronously = false
|
||||
|
||||
self.actionButton = HighlightableButtonNode()
|
||||
self.actionButton.isHidden = true
|
||||
self.actionButtonTitleNode = ImmediateTextNode()
|
||||
self.actionButtonTitleNode.isHidden = true
|
||||
self.actionButtonBackgroundNode = ASImageNode()
|
||||
self.actionButtonBackgroundNode.isHidden = true
|
||||
self.actionButtonBackgroundNode.displaysAsynchronously = false
|
||||
|
||||
self.listButton = HighlightableButtonNode()
|
||||
self.listButton.hitTestSlop = UIEdgeInsets(top: -8.0, left: -8.0, bottom: -8.0, right: -8.0)
|
||||
self.listButton.displaysAsynchronously = false
|
||||
|
|
@ -153,8 +164,21 @@ final class ChatPinnedMessageTitlePanelNode: ChatTitleAccessoryPanelNode {
|
|||
}
|
||||
}
|
||||
|
||||
self.actionButton.highligthedChanged = { [weak self] highlighted in
|
||||
if let strongSelf = self {
|
||||
if highlighted {
|
||||
strongSelf.actionButton.layer.removeAnimation(forKey: "opacity")
|
||||
strongSelf.actionButton.alpha = 0.4
|
||||
} else {
|
||||
strongSelf.actionButton.alpha = 1.0
|
||||
strongSelf.actionButton.layer.animateAlpha(from: 0.4, to: 1.0, duration: 0.2)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
self.closeButton.addTarget(self, action: #selector(self.closePressed), forControlEvents: [.touchUpInside])
|
||||
self.listButton.addTarget(self, action: #selector(self.listPressed), forControlEvents: [.touchUpInside])
|
||||
self.actionButton.addTarget(self, action: #selector(self.actionButtonPressed), forControlEvents: [.touchUpInside])
|
||||
|
||||
self.addSubnode(self.contextContainer)
|
||||
|
||||
|
|
@ -168,6 +192,9 @@ final class ChatPinnedMessageTitlePanelNode: ChatTitleAccessoryPanelNode {
|
|||
self.imageNodeContainer.addSubnode(self.imageNode)
|
||||
self.contentContainer.addSubnode(self.imageNodeContainer)
|
||||
|
||||
self.actionButton.addSubnode(self.actionButtonBackgroundNode)
|
||||
self.actionButton.addSubnode(self.actionButtonTitleNode)
|
||||
self.buttonsContainer.addSubnode(self.actionButton)
|
||||
self.buttonsContainer.addSubnode(self.closeButton)
|
||||
self.buttonsContainer.addSubnode(self.listButton)
|
||||
self.contextContainer.addSubnode(self.buttonsContainer)
|
||||
|
|
@ -207,6 +234,8 @@ final class ChatPinnedMessageTitlePanelNode: ChatTitleAccessoryPanelNode {
|
|||
self.closeButton.setImage(PresentationResourcesChat.chatInputPanelCloseIconImage(interfaceState.theme), for: [])
|
||||
self.listButton.setImage(PresentationResourcesChat.chatInputPanelPinnedListIconImage(interfaceState.theme), for: [])
|
||||
self.separatorNode.backgroundColor = interfaceState.theme.rootController.navigationBar.separatorColor
|
||||
|
||||
self.actionButtonBackgroundNode.image = generateStretchableFilledCircleImage(diameter: 14.0 * 2.0, color: interfaceState.theme.list.itemCheckColors.fillColor, strokeColor: nil, strokeWidth: nil, backgroundColor: nil)
|
||||
}
|
||||
|
||||
if self.statusDisposable == nil, let interfaceInteraction = self.interfaceInteraction, let statuses = interfaceInteraction.statuses {
|
||||
|
|
@ -259,6 +288,7 @@ final class ChatPinnedMessageTitlePanelNode: ChatTitleAccessoryPanelNode {
|
|||
|
||||
self.contextContainer.isGestureEnabled = !isReplyThread
|
||||
|
||||
var actionTitle: String?
|
||||
var messageUpdated = false
|
||||
var messageUpdatedAnimation: PinnedMessageAnimation?
|
||||
if let currentMessage = self.currentMessage, let pinnedMessage = interfaceState.pinnedMessage {
|
||||
|
|
@ -286,6 +316,16 @@ final class ChatPinnedMessageTitlePanelNode: ChatTitleAccessoryPanelNode {
|
|||
}
|
||||
}
|
||||
|
||||
if let currentMessage = self.currentMessage {
|
||||
for attribute in currentMessage.message.attributes {
|
||||
if let attribute = attribute as? ReplyMarkupMessageAttribute, attribute.flags.contains(.inline), attribute.rows.count == 1, attribute.rows[0].buttons.count == 1 {
|
||||
actionTitle = attribute.rows[0].buttons[0].title
|
||||
}
|
||||
}
|
||||
} else {
|
||||
actionTitle = nil
|
||||
}
|
||||
|
||||
if isReplyThread {
|
||||
self.closeButton.isHidden = true
|
||||
self.listButton.isHidden = true
|
||||
|
|
@ -302,12 +342,34 @@ final class ChatPinnedMessageTitlePanelNode: ChatTitleAccessoryPanelNode {
|
|||
self.closeButton.isHidden = true
|
||||
}
|
||||
|
||||
let rightInset: CGFloat = 18.0 + rightInset
|
||||
var rightInset: CGFloat = 18.0 + rightInset
|
||||
|
||||
let buttonsContainerSize = CGSize(width: 16.0, height: panelHeight)
|
||||
self.buttonsContainer.frame = CGRect(origin: CGPoint(x: width - buttonsContainerSize.width - rightInset, y: 0.0), size: buttonsContainerSize)
|
||||
|
||||
let closeButtonSize = self.closeButton.measure(CGSize(width: 100.0, height: 100.0))
|
||||
|
||||
if let actionTitle = actionTitle {
|
||||
self.actionButton.isHidden = false
|
||||
self.actionButtonBackgroundNode.isHidden = false
|
||||
self.actionButtonTitleNode.isHidden = false
|
||||
|
||||
self.actionButtonTitleNode.attributedText = NSAttributedString(string: actionTitle, font: Font.with(size: 15.0, design: .round, weight: .semibold, traits: [.monospacedNumbers]), textColor: interfaceState.theme.list.itemCheckColors.foregroundColor)
|
||||
|
||||
let actionButtonTitleSize = self.actionButtonTitleNode.updateLayout(CGSize(width: 150.0, height: .greatestFiniteMagnitude))
|
||||
let actionButtonSize = CGSize(width: actionButtonTitleSize.width + 20.0, height: 28.0)
|
||||
let actionButtonFrame = CGRect(origin: CGPoint(x: (buttonsContainerSize.width - closeButtonSize.width + 1.0) - 8.0 - actionButtonSize.width, y: floor((panelHeight - actionButtonSize.height) / 2.0)), size: actionButtonSize)
|
||||
transition.updateFrame(node: self.actionButton, frame: actionButtonFrame)
|
||||
transition.updateFrame(node: self.actionButtonBackgroundNode, frame: CGRect(origin: CGPoint(), size: actionButtonFrame.size))
|
||||
transition.updateFrame(node: self.actionButtonTitleNode, frame: CGRect(origin: CGPoint(x: floorToScreenPixels((actionButtonFrame.width - actionButtonTitleSize.width) / 2.0), y: floorToScreenPixels((actionButtonFrame.height - actionButtonTitleSize.height) / 2.0)), size: actionButtonTitleSize))
|
||||
|
||||
rightInset += actionButtonSize.width + 8.0
|
||||
} else {
|
||||
self.actionButton.isHidden = true
|
||||
self.actionButtonBackgroundNode.isHidden = true
|
||||
self.actionButtonTitleNode.isHidden = true
|
||||
}
|
||||
|
||||
transition.updateFrame(node: self.closeButton, frame: CGRect(origin: CGPoint(x: buttonsContainerSize.width - closeButtonSize.width + 1.0, y: 19.0), size: closeButtonSize))
|
||||
|
||||
let listButtonSize = self.listButton.measure(CGSize(width: 100.0, height: 100.0))
|
||||
|
|
@ -323,7 +385,7 @@ final class ChatPinnedMessageTitlePanelNode: ChatTitleAccessoryPanelNode {
|
|||
self.clippingContainer.frame = CGRect(origin: CGPoint(), size: CGSize(width: width, height: panelHeight))
|
||||
self.contentContainer.frame = CGRect(origin: CGPoint(), size: CGSize(width: width, height: panelHeight))
|
||||
|
||||
if self.currentLayout?.0 != width || self.currentLayout?.1 != leftInset || self.currentLayout?.2 != rightInset {
|
||||
if self.currentLayout?.0 != width || self.currentLayout?.1 != leftInset || self.currentLayout?.2 != rightInset || messageUpdated {
|
||||
self.currentLayout = (width, leftInset, rightInset)
|
||||
|
||||
if let currentMessage = self.currentMessage {
|
||||
|
|
@ -377,12 +439,17 @@ final class ChatPinnedMessageTitlePanelNode: ChatTitleAccessoryPanelNode {
|
|||
targetQueue = self.queue
|
||||
}
|
||||
|
||||
let contentLeftInset: CGFloat = leftInset + 10.0
|
||||
var textLineInset: CGFloat = 10.0
|
||||
var rightInset: CGFloat = 18.0 + rightInset
|
||||
|
||||
let textRightInset: CGFloat = 0.0
|
||||
|
||||
if !self.actionButton.isHidden {
|
||||
rightInset += self.actionButton.bounds.width + 8.0
|
||||
}
|
||||
|
||||
targetQueue.async { [weak self] in
|
||||
let contentLeftInset: CGFloat = leftInset + 10.0
|
||||
var textLineInset: CGFloat = 10.0
|
||||
let rightInset: CGFloat = 18.0 + rightInset
|
||||
let textRightInset: CGFloat = 0.0
|
||||
|
||||
var updatedMediaReference: AnyMediaReference?
|
||||
var imageDimensions: CGSize?
|
||||
|
||||
|
|
@ -610,4 +677,63 @@ final class ChatPinnedMessageTitlePanelNode: ChatTitleAccessoryPanelNode {
|
|||
interfaceInteraction.openPinnedList(message.message.id)
|
||||
}
|
||||
}
|
||||
|
||||
@objc private func actionButtonPressed() {
|
||||
if let interfaceInteraction = self.interfaceInteraction, let controller = interfaceInteraction.chatController() as? ChatControllerImpl, let controllerInteraction = controller.controllerInteraction, let message = self.currentMessage?.message {
|
||||
for attribute in message.attributes {
|
||||
if let attribute = attribute as? ReplyMarkupMessageAttribute, attribute.flags.contains(.inline), attribute.rows.count == 1, attribute.rows[0].buttons.count == 1 {
|
||||
let button = attribute.rows[0].buttons[0]
|
||||
switch button.action {
|
||||
case .text:
|
||||
controllerInteraction.sendMessage(button.title)
|
||||
case let .url(url):
|
||||
controllerInteraction.openUrl(url, true, nil, nil)
|
||||
case .requestMap:
|
||||
controllerInteraction.shareCurrentLocation()
|
||||
case .requestPhone:
|
||||
controllerInteraction.shareAccountContact()
|
||||
case .openWebApp:
|
||||
controllerInteraction.requestMessageActionCallback(message.id, nil, true, false)
|
||||
case let .callback(requiresPassword, data):
|
||||
controllerInteraction.requestMessageActionCallback(message.id, data, false, requiresPassword)
|
||||
case let .switchInline(samePeer, query):
|
||||
var botPeer: Peer?
|
||||
|
||||
var found = false
|
||||
for attribute in message.attributes {
|
||||
if let attribute = attribute as? InlineBotMessageAttribute {
|
||||
if let peerId = attribute.peerId {
|
||||
botPeer = message.peers[peerId]
|
||||
found = true
|
||||
}
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
botPeer = message.author
|
||||
}
|
||||
|
||||
var peerId: PeerId?
|
||||
if samePeer {
|
||||
peerId = message.id.peerId
|
||||
}
|
||||
if let botPeer = botPeer, let addressName = botPeer.addressName {
|
||||
controllerInteraction.activateSwitchInline(peerId, "@\(addressName) \(query)")
|
||||
}
|
||||
case .payment:
|
||||
controllerInteraction.openCheckoutOrReceipt(message.id)
|
||||
case let .urlAuth(url, buttonId):
|
||||
controllerInteraction.requestMessageActionUrlAuth(url, .message(id: message.id, buttonId: buttonId))
|
||||
case .setupPoll:
|
||||
break
|
||||
case let .openUserProfile(peerId):
|
||||
controllerInteraction.openPeer(peerId, .info, nil, nil)
|
||||
case let .openWebView(url, simple):
|
||||
controllerInteraction.openWebView(button.title, url, simple)
|
||||
}
|
||||
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -151,6 +151,8 @@ final class ChatRecentActionsController: TelegramBaseController {
|
|||
}, openSendAsPeer: { _, _ in
|
||||
}, presentChatRequestAdminInfo: {
|
||||
}, displayCopyProtectionTip: { _, _ in
|
||||
}, chatController: {
|
||||
return nil
|
||||
}, statuses: nil)
|
||||
|
||||
self.navigationItem.titleView = self.titleView
|
||||
|
|
|
|||
|
|
@ -946,27 +946,31 @@ final class ChatRecentActionsControllerNode: ViewControllerTracingNode {
|
|||
}
|
||||
|
||||
private func presentAutoremoveSetup() {
|
||||
let peer = self.peer
|
||||
|
||||
let controller = peerAutoremoveSetupScreen(context: self.context, updatedPresentationData: self.controller?.updatedPresentationData, peerId: peer.id, completion: { [weak self] updatedValue in
|
||||
if case let .updated(value) = updatedValue {
|
||||
/*let controller = ChatTimerScreen(context: self.context, updatedPresentationData: self.controller?.updatedPresentationData, peerId: self.peer.id, style: .default, mode: .autoremove, currentTime: currentValue, dismissByTapOutside: true, completion: { [weak self] value in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
|
||||
let _ = (strongSelf.context.engine.peers.setChatMessageAutoremoveTimeoutInteractively(peerId: strongSelf.peer.id, timeout: value == 0 ? nil : value)
|
||||
|> deliverOnMainQueue).start(completed: {
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
|
||||
var isOn: Bool = true
|
||||
var text: String?
|
||||
if let myValue = value.value {
|
||||
text = strongSelf.presentationData.strings.Conversation_AutoremoveChanged("\(timeIntervalString(strings: strongSelf.presentationData.strings, value: myValue))").string
|
||||
if value != 0 {
|
||||
text = strongSelf.presentationData.strings.Conversation_AutoremoveChanged("\(timeIntervalString(strings: strongSelf.presentationData.strings, value: value))").string
|
||||
} else {
|
||||
isOn = false
|
||||
text = strongSelf.presentationData.strings.Conversation_AutoremoveOff
|
||||
}
|
||||
if let text = text {
|
||||
strongSelf.presentController(UndoOverlayController(presentationData: strongSelf.presentationData, content: .autoDelete(isOn: isOn, title: nil, text: text), elevatedLayout: false, action: { _ in return false }), .current, nil)
|
||||
strongSelf.present(UndoOverlayController(presentationData: strongSelf.presentationData, content: .autoDelete(isOn: isOn, title: nil, text: text), elevatedLayout: false, action: { _ in return false }), in: .current)
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
self.pushController(controller)
|
||||
self.view.endEditing(true)
|
||||
self.present(controller, in: .window(.root))*/
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -273,6 +273,10 @@ class ChatTimerScreenNode: ViewControllerTracingNode, UIScrollViewDelegate, UIPi
|
|||
private let cancelButton: HighlightableButtonNode
|
||||
private let doneButton: SolidRoundedButtonNode
|
||||
|
||||
private let disableButton: HighlightableButtonNode
|
||||
private let disableButtonTitle: ImmediateTextNode
|
||||
|
||||
private var initialTime: Int32?
|
||||
private var pickerView: TimerPickerView?
|
||||
|
||||
private var containerLayout: (ContainerViewLayout, CGFloat)?
|
||||
|
|
@ -287,6 +291,7 @@ class ChatTimerScreenNode: ViewControllerTracingNode, UIScrollViewDelegate, UIPi
|
|||
self.presentationData = presentationData
|
||||
self.dismissByTapOutside = dismissByTapOutside
|
||||
self.mode = mode
|
||||
self.initialTime = currentTime
|
||||
|
||||
self.wrappingScrollNode = ASScrollNode()
|
||||
self.wrappingScrollNode.view.alwaysBounceVertical = true
|
||||
|
|
@ -349,6 +354,22 @@ class ChatTimerScreenNode: ViewControllerTracingNode, UIScrollViewDelegate, UIPi
|
|||
self.doneButton = SolidRoundedButtonNode(theme: SolidRoundedButtonTheme(theme: self.presentationData.theme), height: 52.0, cornerRadius: 11.0, gloss: false)
|
||||
self.doneButton.title = self.presentationData.strings.Conversation_Timer_Send
|
||||
|
||||
self.disableButton = HighlightableButtonNode()
|
||||
self.disableButtonTitle = ImmediateTextNode()
|
||||
self.disableButton.addSubnode(self.disableButtonTitle)
|
||||
//TODO:localize
|
||||
self.disableButtonTitle.attributedText = NSAttributedString(string: "Disable Auto-Delete", font: Font.regular(17.0), textColor: self.presentationData.theme.list.itemAccentColor)
|
||||
self.disableButton.isHidden = true
|
||||
|
||||
switch self.mode {
|
||||
case .autoremove:
|
||||
if self.initialTime != nil {
|
||||
self.disableButton.isHidden = false
|
||||
}
|
||||
default:
|
||||
break
|
||||
}
|
||||
|
||||
super.init()
|
||||
|
||||
self.backgroundColor = nil
|
||||
|
|
@ -369,17 +390,24 @@ class ChatTimerScreenNode: ViewControllerTracingNode, UIScrollViewDelegate, UIPi
|
|||
self.contentContainerNode.addSubnode(self.textNode)
|
||||
self.contentContainerNode.addSubnode(self.cancelButton)
|
||||
self.contentContainerNode.addSubnode(self.doneButton)
|
||||
self.contentContainerNode.addSubnode(self.disableButton)
|
||||
|
||||
self.cancelButton.addTarget(self, action: #selector(self.cancelButtonPressed), forControlEvents: .touchUpInside)
|
||||
self.doneButton.pressed = { [weak self] in
|
||||
if let strongSelf = self, let pickerView = strongSelf.pickerView {
|
||||
strongSelf.doneButton.isUserInteractionEnabled = false
|
||||
if let pickerView = pickerView as? TimerCustomPickerView {
|
||||
strongSelf.completion?(timerValues[pickerView.selectedRow(inComponent: 0)])
|
||||
switch strongSelf.mode {
|
||||
case .sendTimer:
|
||||
strongSelf.completion?(timerValues[pickerView.selectedRow(inComponent: 0)])
|
||||
case .autoremove:
|
||||
let timeInterval = pickerView.selectedRow(inComponent: 0) * 24 * 60 * 60 + pickerView.selectedRow(inComponent: 1) * 60 * 60 + pickerView.selectedRow(inComponent: 2) * 60
|
||||
strongSelf.completion?(Int32(timeInterval))
|
||||
case .mute:
|
||||
break
|
||||
}
|
||||
} else if let pickerView = pickerView as? TimerDatePickerView {
|
||||
switch strongSelf.mode {
|
||||
case .autoremove:
|
||||
strongSelf.completion?(Int32(pickerView.countDownDuration))
|
||||
case .mute:
|
||||
let timeInterval = max(0, Int32(pickerView.date.timeIntervalSince1970) - Int32(Date().timeIntervalSince1970))
|
||||
strongSelf.completion?(timeInterval)
|
||||
|
|
@ -390,9 +418,15 @@ class ChatTimerScreenNode: ViewControllerTracingNode, UIScrollViewDelegate, UIPi
|
|||
}
|
||||
}
|
||||
|
||||
self.disableButton.addTarget(self, action: #selector(self.disableButtonPressed), forControlEvents: .touchUpInside)
|
||||
|
||||
self.setupPickerView(currentTime: currentTime)
|
||||
}
|
||||
|
||||
@objc private func disableButtonPressed() {
|
||||
self.completion?(0)
|
||||
}
|
||||
|
||||
func setupPickerView(currentTime: Int32? = nil) {
|
||||
if let pickerView = self.pickerView {
|
||||
pickerView.removeFromSuperview()
|
||||
|
|
@ -408,17 +442,24 @@ class ChatTimerScreenNode: ViewControllerTracingNode, UIScrollViewDelegate, UIPi
|
|||
self.contentContainerNode.view.addSubview(pickerView)
|
||||
self.pickerView = pickerView
|
||||
case .autoremove:
|
||||
let pickerView = TimerDatePickerView()
|
||||
pickerView.locale = localeWithStrings(self.presentationData.strings)
|
||||
pickerView.datePickerMode = .countDownTimer
|
||||
if #available(iOS 13.4, *) {
|
||||
pickerView.preferredDatePickerStyle = .wheels
|
||||
}
|
||||
pickerView.selectorColor = UIColor(rgb: 0xffffff, alpha: 0.18)
|
||||
pickerView.addTarget(self, action: #selector(self.dataPickerChanged), for: .valueChanged)
|
||||
let pickerView = TimerCustomPickerView()
|
||||
pickerView.dataSource = self
|
||||
pickerView.delegate = self
|
||||
|
||||
pickerView.selectorColor = self.presentationData.theme.list.itemPrimaryTextColor.withMultipliedAlpha(0.18)
|
||||
|
||||
self.contentContainerNode.view.addSubview(pickerView)
|
||||
self.pickerView = pickerView
|
||||
|
||||
if let value = self.initialTime {
|
||||
let days = value / (24 * 60 * 60)
|
||||
let hours = (value % (24 * 60 * 60)) / (60 * 60)
|
||||
let minutes = (value % (60 * 60)) / 60
|
||||
|
||||
pickerView.selectRow(Int(days), inComponent: 0, animated: false)
|
||||
pickerView.selectRow(Int(hours), inComponent: 1, animated: false)
|
||||
pickerView.selectRow(Int(minutes), inComponent: 2, animated: false)
|
||||
}
|
||||
case .mute:
|
||||
let pickerView = TimerDatePickerView()
|
||||
pickerView.locale = localeWithStrings(self.presentationData.strings)
|
||||
|
|
@ -436,35 +477,87 @@ class ChatTimerScreenNode: ViewControllerTracingNode, UIScrollViewDelegate, UIPi
|
|||
}
|
||||
|
||||
@objc private func dataPickerChanged() {
|
||||
guard let _ = self.pickerView as? TimerDatePickerView else {
|
||||
return
|
||||
}
|
||||
|
||||
if let (layout, navigationBarHeight) = self.containerLayout {
|
||||
self.containerLayoutUpdated(layout, navigationBarHeight: navigationBarHeight, transition: .immediate)
|
||||
}
|
||||
}
|
||||
|
||||
func numberOfComponents(in pickerView: UIPickerView) -> Int {
|
||||
return 1
|
||||
switch self.mode {
|
||||
case .sendTimer:
|
||||
return 1
|
||||
case .autoremove:
|
||||
return 3
|
||||
case .mute:
|
||||
return 0
|
||||
}
|
||||
}
|
||||
|
||||
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
|
||||
return timerValues.count
|
||||
switch self.mode {
|
||||
case .sendTimer:
|
||||
return timerValues.count
|
||||
case .autoremove:
|
||||
switch component {
|
||||
case 0:
|
||||
return 365
|
||||
case 1:
|
||||
return 24
|
||||
case 2:
|
||||
return 60
|
||||
default:
|
||||
return 0
|
||||
}
|
||||
case .mute:
|
||||
return 0
|
||||
}
|
||||
}
|
||||
|
||||
func pickerView(_ pickerView: UIPickerView, viewForRow row: Int, forComponent component: Int, reusing view: UIView?) -> UIView {
|
||||
let value = timerValues[row]
|
||||
let string = timeIntervalString(strings: self.presentationData.strings, value: value)
|
||||
if let view = view as? TimerPickerItemView {
|
||||
switch self.mode {
|
||||
case .sendTimer:
|
||||
let value = timerValues[row]
|
||||
let string = timeIntervalString(strings: self.presentationData.strings, value: value)
|
||||
if let view = view as? TimerPickerItemView {
|
||||
view.value = (value, string)
|
||||
return view
|
||||
}
|
||||
|
||||
let view = TimerPickerItemView()
|
||||
view.value = (value, string)
|
||||
view.textColor = .white
|
||||
return view
|
||||
case .autoremove:
|
||||
let itemView: TimerPickerItemView
|
||||
if let current = view as? TimerPickerItemView {
|
||||
itemView = current
|
||||
} else {
|
||||
itemView = TimerPickerItemView()
|
||||
itemView.textColor = self.presentationData.theme.list.itemPrimaryTextColor
|
||||
}
|
||||
|
||||
let string: String
|
||||
switch component {
|
||||
case 0:
|
||||
string = dayIntervalString(strings: self.presentationData.strings, days: Int32(row))
|
||||
case 1:
|
||||
string = hoursIntervalString(strings: self.presentationData.strings, hours: Int32(row))
|
||||
case 2:
|
||||
string = minutesIntervalString(strings: self.presentationData.strings, minutes: Int32(row))
|
||||
default:
|
||||
preconditionFailure()
|
||||
}
|
||||
|
||||
itemView.value = (Int32(row), string)
|
||||
|
||||
return itemView
|
||||
case .mute:
|
||||
preconditionFailure()
|
||||
}
|
||||
|
||||
let view = TimerPickerItemView()
|
||||
view.value = (value, string)
|
||||
view.textColor = .white
|
||||
return view
|
||||
}
|
||||
|
||||
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
|
||||
self.dataPickerChanged()
|
||||
}
|
||||
|
||||
func updatePresentationData(_ presentationData: PresentationData) {
|
||||
|
|
@ -575,11 +668,16 @@ class ChatTimerScreenNode: ViewControllerTracingNode, UIScrollViewDelegate, UIPi
|
|||
let cleanInsets = layout.insets(options: [.statusBar])
|
||||
insets.top = max(10.0, insets.top)
|
||||
|
||||
let buttonOffset: CGFloat = 0.0
|
||||
var buttonOffset: CGFloat = 0.0
|
||||
let bottomInset: CGFloat = 10.0 + cleanInsets.bottom
|
||||
let titleHeight: CGFloat = 54.0
|
||||
var contentHeight = titleHeight + bottomInset + 52.0 + 17.0
|
||||
let pickerHeight: CGFloat = min(216.0, layout.size.height - contentHeight)
|
||||
|
||||
if !self.disableButton.isHidden {
|
||||
buttonOffset += 52.0
|
||||
}
|
||||
|
||||
contentHeight = titleHeight + bottomInset + 52.0 + 17.0 + pickerHeight + buttonOffset
|
||||
|
||||
let width = horizontalContainerFillingSizeForLayout(layout: layout, sideInset: 0.0)
|
||||
|
|
@ -612,11 +710,8 @@ class ChatTimerScreenNode: ViewControllerTracingNode, UIScrollViewDelegate, UIPi
|
|||
case .sendTimer:
|
||||
break
|
||||
case .autoremove:
|
||||
if let pickerView = self.pickerView as? TimerDatePickerView, pickerView.countDownDuration > 0.0 {
|
||||
self.doneButton.title = "Auto-Delete after \(timeIntervalString(strings: self.presentationData.strings, value: Int32(pickerView.countDownDuration)))"
|
||||
} else {
|
||||
self.doneButton.title = self.presentationData.strings.Common_Close
|
||||
}
|
||||
//TODO:localize
|
||||
self.doneButton.title = "Set Auto-Delete"
|
||||
case .mute:
|
||||
if let pickerView = self.pickerView as? TimerDatePickerView {
|
||||
let timeInterval = max(0, Int32(pickerView.date.timeIntervalSince1970) - Int32(Date().timeIntervalSince1970))
|
||||
|
|
@ -635,7 +730,13 @@ class ChatTimerScreenNode: ViewControllerTracingNode, UIScrollViewDelegate, UIPi
|
|||
}
|
||||
|
||||
let doneButtonHeight = self.doneButton.updateLayout(width: contentFrame.width - buttonInset * 2.0, transition: transition)
|
||||
transition.updateFrame(node: self.doneButton, frame: CGRect(x: buttonInset, y: contentHeight - doneButtonHeight - insets.bottom - 16.0 - buttonOffset, width: contentFrame.width, height: doneButtonHeight))
|
||||
let doneButtonFrame = CGRect(x: buttonInset, y: contentHeight - doneButtonHeight - insets.bottom - 16.0 - buttonOffset, width: contentFrame.width, height: doneButtonHeight)
|
||||
transition.updateFrame(node: self.doneButton, frame: doneButtonFrame)
|
||||
|
||||
let disableButtonTitleSize = self.disableButtonTitle.updateLayout(CGSize(width: contentFrame.width, height: doneButtonHeight))
|
||||
let disableButtonFrame = CGRect(origin: CGPoint(x: doneButtonFrame.minX, y: doneButtonFrame.maxY), size: CGSize(width: contentFrame.width - buttonInset * 2.0, height: doneButtonHeight))
|
||||
transition.updateFrame(node: self.disableButton, frame: disableButtonFrame)
|
||||
transition.updateFrame(node: self.disableButtonTitle, frame: CGRect(origin: CGPoint(x: floor((disableButtonFrame.width - disableButtonTitleSize.width) / 2.0), y: floor((disableButtonFrame.height - disableButtonTitleSize.height) / 2.0)), size: disableButtonTitleSize))
|
||||
|
||||
self.pickerView?.frame = CGRect(origin: CGPoint(x: 0.0, y: 54.0), size: CGSize(width: contentFrame.width, height: pickerHeight))
|
||||
|
||||
|
|
|
|||
|
|
@ -346,6 +346,8 @@ final class PeerInfoSelectionPanelNode: ASDisplayNode {
|
|||
}, presentChatRequestAdminInfo: {
|
||||
}, displayCopyProtectionTip: { node, save in
|
||||
displayCopyProtectionTip(node, save)
|
||||
}, chatController: {
|
||||
return nil
|
||||
}, statuses: nil)
|
||||
|
||||
self.selectionPanel.interfaceInteraction = interfaceInteraction
|
||||
|
|
@ -3540,6 +3542,42 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate
|
|||
|
||||
var items: [ContextMenuItem] = []
|
||||
|
||||
var isSoundEnabled = true
|
||||
if let notificationSettings = self.data?.notificationSettings {
|
||||
switch notificationSettings.messageSound {
|
||||
case .none:
|
||||
isSoundEnabled = false
|
||||
default:
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if !isSoundEnabled {
|
||||
//TODO:localize
|
||||
items.append(.action(ContextMenuActionItem(text: "Enable Sound", icon: { theme in
|
||||
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Unmute"), color: theme.contextMenu.primaryColor)
|
||||
}, action: { [weak self] _, f in
|
||||
f(.default)
|
||||
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
let _ = strongSelf.context.engine.peers.updatePeerNotificationSoundInteractive(peerId: strongSelf.peerId, sound: .default).start()
|
||||
})))
|
||||
} else {
|
||||
//TODO:localize
|
||||
items.append(.action(ContextMenuActionItem(text: "Disable Sound", icon: { theme in
|
||||
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Muted"), color: theme.contextMenu.primaryColor)
|
||||
}, action: { [weak self] _, f in
|
||||
f(.default)
|
||||
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
let _ = strongSelf.context.engine.peers.updatePeerNotificationSoundInteractive(peerId: strongSelf.peerId, sound: .none).start()
|
||||
})))
|
||||
}
|
||||
|
||||
items.append(.action(ContextMenuActionItem(text: "Mute for...", icon: { theme in
|
||||
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Mute2d"), color: theme.contextMenu.primaryColor)
|
||||
}, action: { [weak self] c, _ in
|
||||
|
|
@ -3586,59 +3624,10 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate
|
|||
|
||||
c.pushItems(items: .single(ContextController.Items(content: .list(subItems))))
|
||||
})))
|
||||
|
||||
items.append(.separator)
|
||||
|
||||
var isSoundEnabled = true
|
||||
if let notificationSettings = self.data?.notificationSettings {
|
||||
switch notificationSettings.messageSound {
|
||||
case .none:
|
||||
isSoundEnabled = false
|
||||
default:
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
//TODO:localize
|
||||
items.append(.action(ContextMenuActionItem(text: "Sound On", icon: { theme in
|
||||
if !isSoundEnabled {
|
||||
return nil
|
||||
}
|
||||
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Check"), color: theme.contextMenu.primaryColor)
|
||||
}, action: { [weak self] _, f in
|
||||
f(.default)
|
||||
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
if isSoundEnabled {
|
||||
return
|
||||
}
|
||||
let _ = strongSelf.context.engine.peers.updatePeerNotificationSoundInteractive(peerId: strongSelf.peerId, sound: .default).start()
|
||||
})))
|
||||
|
||||
//TODO:localize
|
||||
items.append(.action(ContextMenuActionItem(text: "Sound Off", icon: { theme in
|
||||
if isSoundEnabled {
|
||||
return nil
|
||||
}
|
||||
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Check"), color: theme.contextMenu.primaryColor)
|
||||
}, action: { [weak self] _, f in
|
||||
f(.default)
|
||||
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
if !isSoundEnabled {
|
||||
return
|
||||
}
|
||||
let _ = strongSelf.context.engine.peers.updatePeerNotificationSoundInteractive(peerId: strongSelf.peerId, sound: .none).start()
|
||||
})))
|
||||
|
||||
items.append(.separator)
|
||||
|
||||
items.append(.action(ContextMenuActionItem(text: "Customize", icon: { theme in
|
||||
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Settings"), color: theme.contextMenu.primaryColor)
|
||||
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Customize"), color: theme.contextMenu.primaryColor)
|
||||
}, action: { [weak self] _, f in
|
||||
f(.dismissWithoutContent)
|
||||
|
||||
|
|
@ -3738,16 +3727,6 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate
|
|||
canChangeColors = true
|
||||
}
|
||||
|
||||
if canChangeColors {
|
||||
items.append(.action(ContextMenuActionItem(text: presentationData.strings.UserInfo_ChangeColors, icon: { theme in
|
||||
generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/ApplyTheme"), color: theme.contextMenu.primaryColor)
|
||||
}, action: { _, f in
|
||||
f(.dismissWithoutContent)
|
||||
|
||||
self?.openChatForThemeChange()
|
||||
})))
|
||||
}
|
||||
|
||||
var currentAutoremoveTimeout: Int32?
|
||||
if let cachedData = data.cachedData as? CachedUserData {
|
||||
switch cachedData.autoremoveTimeout {
|
||||
|
|
@ -3979,26 +3958,38 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate
|
|||
}
|
||||
})))
|
||||
}
|
||||
|
||||
if canChangeColors {
|
||||
items.append(.action(ContextMenuActionItem(text: presentationData.strings.UserInfo_ChangeColors, icon: { theme in
|
||||
generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/ApplyTheme"), color: theme.contextMenu.primaryColor)
|
||||
}, action: { _, f in
|
||||
f(.dismissWithoutContent)
|
||||
|
||||
self?.openChatForThemeChange()
|
||||
})))
|
||||
}
|
||||
|
||||
if strongSelf.peerId.namespace == Namespaces.Peer.CloudUser && user.botInfo == nil && !user.flags.contains(.isSupport) {
|
||||
items.append(.action(ContextMenuActionItem(text: presentationData.strings.UserInfo_StartSecretChat, icon: { theme in
|
||||
generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Timer"), color: theme.contextMenu.primaryColor)
|
||||
}, action: { [weak self] _, f in
|
||||
}, action: { _, f in
|
||||
f(.dismissWithoutContent)
|
||||
|
||||
self?.openStartSecretChat()
|
||||
})))
|
||||
}
|
||||
|
||||
/*if strongSelf.peerId.namespace == Namespaces.Peer.CloudUser {
|
||||
items.append(.action(ContextMenuActionItem(text: "", icon: { theme in
|
||||
generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Clear"), color: theme.contextMenu.primaryColor)
|
||||
}, action: { [weak self] _, f in
|
||||
f(.dismissWithoutContent)
|
||||
|
||||
self?.openStartSecretChat()
|
||||
})))
|
||||
}*/
|
||||
let clearPeerHistory = ClearPeerHistory(context: strongSelf.context, peer: user, chatPeer: user, cachedData: strongSelf.data?.cachedData)
|
||||
if clearPeerHistory.canClearForMyself != nil || clearPeerHistory.canClearForEveryone != nil {
|
||||
if strongSelf.peerId.namespace == Namespaces.Peer.CloudUser {
|
||||
//TODO:localize
|
||||
items.append(.action(ContextMenuActionItem(text: "Clear Messages", icon: { theme in
|
||||
generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/ClearMessages"), color: theme.contextMenu.primaryColor)
|
||||
}, action: { c, _ in
|
||||
self?.openClearHistory(contextController: c, clearPeerHistory: clearPeerHistory, peer: user, chatPeer: user)
|
||||
})))
|
||||
}
|
||||
}
|
||||
|
||||
if strongSelf.peerId.namespace == Namespaces.Peer.CloudUser && user.botInfo == nil && !user.flags.contains(.isSupport) {
|
||||
if data.isContact {
|
||||
|
|
@ -4006,7 +3997,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate
|
|||
} else {
|
||||
items.append(.action(ContextMenuActionItem(text: presentationData.strings.Conversation_BlockUser, textColor: .destructive, icon: { theme in
|
||||
generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Restrict"), color: theme.contextMenu.destructiveColor)
|
||||
}, action: { [weak self] _, f in
|
||||
}, action: { _, f in
|
||||
f(.dismissWithoutContent)
|
||||
|
||||
self?.updateBlocked(block: true)
|
||||
|
|
@ -4058,6 +4049,16 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate
|
|||
})))
|
||||
}
|
||||
|
||||
let clearPeerHistory = ClearPeerHistory(context: strongSelf.context, peer: channel, chatPeer: channel, cachedData: strongSelf.data?.cachedData)
|
||||
if clearPeerHistory.canClearForMyself != nil || clearPeerHistory.canClearForEveryone != nil {
|
||||
//TODO:localize
|
||||
items.append(.action(ContextMenuActionItem(text: "Clear Messages", icon: { theme in
|
||||
generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/ClearMessages"), color: theme.contextMenu.primaryColor)
|
||||
}, action: { c, _ in
|
||||
self?.openClearHistory(contextController: c, clearPeerHistory: clearPeerHistory, peer: channel, chatPeer: channel)
|
||||
})))
|
||||
}
|
||||
|
||||
switch channel.info {
|
||||
case .broadcast:
|
||||
if case .member = channel.participationStatus, !headerButtons.contains(.leave) {
|
||||
|
|
@ -4087,6 +4088,16 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate
|
|||
}
|
||||
}
|
||||
} else if let group = peer as? TelegramGroup {
|
||||
let clearPeerHistory = ClearPeerHistory(context: strongSelf.context, peer: group, chatPeer: group, cachedData: strongSelf.data?.cachedData)
|
||||
if clearPeerHistory.canClearForMyself != nil || clearPeerHistory.canClearForEveryone != nil {
|
||||
//TODO:localize
|
||||
items.append(.action(ContextMenuActionItem(text: "Clear Messages", icon: { theme in
|
||||
generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/ClearMessages"), color: theme.contextMenu.primaryColor)
|
||||
}, action: { c, _ in
|
||||
self?.openClearHistory(contextController: c, clearPeerHistory: clearPeerHistory, peer: group, chatPeer: group)
|
||||
})))
|
||||
}
|
||||
|
||||
if case .Member = group.membership, !headerButtons.contains(.leave) {
|
||||
if !items.isEmpty {
|
||||
items.append(.separator)
|
||||
|
|
@ -4162,28 +4173,6 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate
|
|||
}
|
||||
|
||||
private func openAutoremove(currentValue: Int32?) {
|
||||
/*let controller = peerAutoremoveSetupScreen(context: self.context, updatedPresentationData: self.controller?.updatedPresentationData, peerId: self.peerId, completion: { [weak self] updatedValue in
|
||||
if case let .updated(value) = updatedValue {
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
|
||||
var isOn: Bool = true
|
||||
var text: String?
|
||||
if let myValue = value.value {
|
||||
text = strongSelf.presentationData.strings.Conversation_AutoremoveChanged("\(timeIntervalString(strings: strongSelf.presentationData.strings, value: myValue))").string
|
||||
} else {
|
||||
isOn = false
|
||||
text = strongSelf.presentationData.strings.Conversation_AutoremoveOff
|
||||
}
|
||||
if let text = text {
|
||||
strongSelf.controller?.present(UndoOverlayController(presentationData: strongSelf.presentationData, content: .autoDelete(isOn: isOn, title: nil, text: text), elevatedLayout: false, action: { _ in return false }), in: .current)
|
||||
}
|
||||
}
|
||||
})
|
||||
self.controller?.view.endEditing(true)
|
||||
self.controller?.push(controller)*/
|
||||
|
||||
let controller = ChatTimerScreen(context: self.context, updatedPresentationData: self.controller?.updatedPresentationData, peerId: self.peerId, style: .default, mode: .autoremove, currentTime: currentValue, dismissByTapOutside: true, completion: { [weak self] value in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
|
|
@ -4340,6 +4329,94 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate
|
|||
})
|
||||
}
|
||||
|
||||
private func openClearHistory(contextController: ContextControllerProtocol, clearPeerHistory: ClearPeerHistory, peer: Peer, chatPeer: Peer) {
|
||||
var subItems: [ContextMenuItem] = []
|
||||
|
||||
subItems.append(.action(ContextMenuActionItem(text: self.presentationData.strings.Common_Back, icon: { theme in
|
||||
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Back"), color: theme.contextMenu.primaryColor)
|
||||
}, action: { c, _ in
|
||||
c.popItems()
|
||||
})))
|
||||
subItems.append(.separator)
|
||||
|
||||
//TODO:localize
|
||||
|
||||
guard let anyType = clearPeerHistory.canClearForEveryone ?? clearPeerHistory.canClearForMyself else {
|
||||
return
|
||||
}
|
||||
|
||||
let title: String
|
||||
switch anyType {
|
||||
case .user, .secretChat, .savedMessages:
|
||||
title = "Are you sure you want to delete all messages with \(EnginePeer(chatPeer).compactDisplayTitle)?"
|
||||
case .group, .channel:
|
||||
title = "Are you sure you want to delete all messages in \(EnginePeer(chatPeer).compactDisplayTitle)?"
|
||||
}
|
||||
|
||||
subItems.append(.action(ContextMenuActionItem(text: title, textLayout: .multiline, textFont: .small, icon: { _ in
|
||||
return nil
|
||||
}, action: nil as ((ContextControllerProtocol, @escaping (ContextMenuActionResult) -> Void) -> Void)?)))
|
||||
|
||||
let beginClear: (InteractiveHistoryClearingType) -> Void = { [weak self] type in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
let statusText: String
|
||||
if case .forEveryone = type {
|
||||
statusText = strongSelf.presentationData.strings.Undo_ChatClearedForBothSides
|
||||
} else {
|
||||
statusText = strongSelf.presentationData.strings.Undo_ChatCleared
|
||||
}
|
||||
|
||||
strongSelf.controller?.present(UndoOverlayController(presentationData: strongSelf.context.sharedContext.currentPresentationData.with { $0 }, content: .removedChat(text: statusText), elevatedLayout: false, action: { value in
|
||||
if value == .commit {
|
||||
guard let strongSelf = self else {
|
||||
return false
|
||||
}
|
||||
|
||||
let _ = strongSelf.context.engine.messages.clearHistoryInteractively(peerId: peer.id, type: type).start(completed: {
|
||||
})
|
||||
return true
|
||||
} else if value == .undo {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}), in: .current)
|
||||
}
|
||||
|
||||
if let canClearForEveryone = clearPeerHistory.canClearForEveryone {
|
||||
let text: String
|
||||
switch canClearForEveryone {
|
||||
case .user, .secretChat, .savedMessages:
|
||||
text = self.presentationData.strings.Conversation_DeleteMessagesFor(EnginePeer(chatPeer).compactDisplayTitle).string
|
||||
case .channel, .group:
|
||||
text = self.presentationData.strings.Conversation_DeleteMessagesForEveryone
|
||||
}
|
||||
|
||||
subItems.append(.action(ContextMenuActionItem(text: text, textColor: .destructive, icon: { _ in
|
||||
return nil
|
||||
}, action: { _, f in
|
||||
f(.default)
|
||||
|
||||
beginClear(.forEveryone)
|
||||
})))
|
||||
}
|
||||
|
||||
if let _ = clearPeerHistory.canClearForMyself {
|
||||
let text: String = self.presentationData.strings.Conversation_DeleteMessagesForMe
|
||||
|
||||
subItems.append(.action(ContextMenuActionItem(text: text, textColor: .destructive, icon: { _ in
|
||||
return nil
|
||||
}, action: { _, f in
|
||||
f(.default)
|
||||
|
||||
beginClear(.forLocalPeer)
|
||||
})))
|
||||
}
|
||||
|
||||
contextController.pushItems(items: .single(ContextController.Items(content: .list(subItems))))
|
||||
}
|
||||
|
||||
private func openUsername(value: String) {
|
||||
let shareController = ShareController(context: self.context, subject: .url("https://t.me/\(value)"), updatedPresentationData: self.controller?.updatedPresentationData)
|
||||
shareController.completed = { [weak self] peerIds in
|
||||
|
|
@ -4541,16 +4618,19 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate
|
|||
|
||||
private func editingOpenNotificationSettings() {
|
||||
let peerId = self.peerId
|
||||
let _ = (self.context.account.postbox.transaction { transaction -> (TelegramPeerNotificationSettings, GlobalNotificationSettings) in
|
||||
let _ = (combineLatest(self.context.account.postbox.transaction { transaction -> (TelegramPeerNotificationSettings, GlobalNotificationSettings) in
|
||||
let peerSettings: TelegramPeerNotificationSettings = (transaction.getPeerNotificationSettings(peerId) as? TelegramPeerNotificationSettings) ?? TelegramPeerNotificationSettings.defaultSettings
|
||||
let globalSettings: GlobalNotificationSettings = transaction.getPreferencesEntry(key: PreferencesKeys.globalNotifications)?.get(GlobalNotificationSettings.self) ?? GlobalNotificationSettings.defaultSettings
|
||||
return (peerSettings, globalSettings)
|
||||
}
|
||||
|> deliverOnMainQueue).start(next: { [weak self] peerSettings, globalSettings in
|
||||
}, self.context.engine.peers.notificationSoundList())
|
||||
|> deliverOnMainQueue).start(next: { [weak self] settings, notificationSoundList in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
let muteSettingsController = notificationMuteSettingsController(presentationData: strongSelf.presentationData, notificationSettings: globalSettings.effective.groupChats, soundSettings: nil, openSoundSettings: {
|
||||
|
||||
let (peerSettings, globalSettings) = settings
|
||||
|
||||
let muteSettingsController = notificationMuteSettingsController(presentationData: strongSelf.presentationData, notificationSoundList: notificationSoundList, notificationSettings: globalSettings.effective.groupChats, soundSettings: nil, openSoundSettings: {
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
|
|
@ -4660,7 +4740,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate
|
|||
|> deliverOnMainQueue).start(completed: { [weak self] in
|
||||
if let strongSelf = self, let peer = strongSelf.data?.peer {
|
||||
let presentationData = strongSelf.context.sharedContext.currentPresentationData.with { $0 }
|
||||
let controller = UndoOverlayController(presentationData: presentationData, content: .info(text: presentationData.strings.Conversation_DeletedFromContacts(EnginePeer(peer).displayTitle(strings: strongSelf.presentationData.strings, displayOrder: strongSelf.presentationData.nameDisplayOrder)).string), elevatedLayout: false, animateInAsReplacement: false, action: { _ in return false })
|
||||
let controller = UndoOverlayController(presentationData: presentationData, content: .info(title: nil, text: presentationData.strings.Conversation_DeletedFromContacts(EnginePeer(peer).displayTitle(strings: strongSelf.presentationData.strings, displayOrder: strongSelf.presentationData.nameDisplayOrder)).string), elevatedLayout: false, animateInAsReplacement: false, action: { _ in return false })
|
||||
controller.keepOnParentDismissal = true
|
||||
strongSelf.controller?.present(controller, in: .window(.root))
|
||||
|
||||
|
|
@ -8480,3 +8560,73 @@ func presentAddMembers(context: AccountContext, updatedPresentationData: (initia
|
|||
}
|
||||
})
|
||||
}
|
||||
|
||||
struct ClearPeerHistory {
|
||||
enum ClearType {
|
||||
case savedMessages
|
||||
case secretChat
|
||||
case group
|
||||
case channel
|
||||
case user
|
||||
}
|
||||
|
||||
var canClearCache: Bool = false
|
||||
var canClearForMyself: ClearType? = nil
|
||||
var canClearForEveryone: ClearType? = nil
|
||||
|
||||
init(context: AccountContext, peer: Peer, chatPeer: Peer, cachedData: CachedPeerData?) {
|
||||
if peer.id == context.account.peerId {
|
||||
canClearCache = false
|
||||
canClearForMyself = .savedMessages
|
||||
canClearForEveryone = nil
|
||||
} else if chatPeer is TelegramSecretChat {
|
||||
canClearCache = false
|
||||
canClearForMyself = .secretChat
|
||||
canClearForEveryone = nil
|
||||
} else if let group = chatPeer as? TelegramGroup {
|
||||
canClearCache = false
|
||||
|
||||
switch group.role {
|
||||
case .creator:
|
||||
canClearForMyself = .group
|
||||
canClearForEveryone = .group
|
||||
case .admin, .member:
|
||||
canClearForMyself = .group
|
||||
canClearForEveryone = nil
|
||||
}
|
||||
} else if let channel = chatPeer as? TelegramChannel {
|
||||
var canDeleteHistory = false
|
||||
if let cachedData = cachedData as? CachedChannelData {
|
||||
canDeleteHistory = cachedData.flags.contains(.canDeleteHistory)
|
||||
}
|
||||
|
||||
var canDeleteLocally = true
|
||||
if case .broadcast = channel.info {
|
||||
canDeleteLocally = false
|
||||
} else if channel.username != nil {
|
||||
canDeleteLocally = false
|
||||
}
|
||||
|
||||
if !canDeleteHistory {
|
||||
canClearCache = true
|
||||
|
||||
canClearForMyself = canDeleteLocally ? .channel : nil
|
||||
canClearForEveryone = nil
|
||||
} else {
|
||||
canClearCache = true
|
||||
canClearForMyself = canDeleteLocally ? .channel : nil
|
||||
|
||||
canClearForEveryone = .channel
|
||||
}
|
||||
} else {
|
||||
canClearCache = false
|
||||
canClearForMyself = .user
|
||||
|
||||
if let user = chatPeer as? TelegramUser, user.botInfo != nil {
|
||||
canClearForEveryone = nil
|
||||
} else {
|
||||
canClearForEveryone = .user
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -347,6 +347,8 @@ final class PeerSelectionControllerNode: ASDisplayNode {
|
|||
}, openSendAsPeer: { _, _ in
|
||||
}, presentChatRequestAdminInfo: {
|
||||
}, displayCopyProtectionTip: { _, _ in
|
||||
}, chatController: {
|
||||
return nil
|
||||
}, statuses: nil)
|
||||
|
||||
self.readyValue.set(self.chatListNode.ready)
|
||||
|
|
|
|||
|
|
@ -23,6 +23,9 @@
|
|||
#import "platform/darwin/VideoSampleBufferView.h"
|
||||
#import "platform/darwin/VideoCaptureView.h"
|
||||
#import "platform/darwin/CustomExternalCapturer.h"
|
||||
|
||||
#include "platform/darwin/iOS/tgcalls_audio_device_module_ios.h"
|
||||
|
||||
#endif
|
||||
|
||||
#import "group/GroupInstanceImpl.h"
|
||||
|
|
@ -1039,9 +1042,11 @@ static void (*InternalVoipLoggingFunction)(NSString *) = NULL;
|
|||
[strongSelf signalingDataEmitted:mappedData];
|
||||
}
|
||||
}];
|
||||
},
|
||||
.createAudioDeviceModule = [](webrtc::TaskQueueFactory *taskQueueFactory) -> rtc::scoped_refptr<webrtc::AudioDeviceModule> {
|
||||
return rtc::make_ref_counted<webrtc::tgcalls_ios_adm::AudioDeviceModuleIOS>(false, false, 1);
|
||||
}
|
||||
});
|
||||
|
||||
_state = OngoingCallStateInitializing;
|
||||
_signalBars = 4;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ public enum UndoOverlayContent {
|
|||
case hidArchive(title: String, text: String, undo: Bool)
|
||||
case revealedArchive(title: String, text: String, undo: Bool)
|
||||
case succeed(text: String)
|
||||
case info(text: String)
|
||||
case info(title: String?, text: String)
|
||||
case emoji(name: String, text: String)
|
||||
case swipeToReply(title: String, text: String)
|
||||
case actionSucceeded(title: String, text: String, cancel: String)
|
||||
|
|
@ -40,6 +40,7 @@ public enum UndoOverlayContent {
|
|||
case paymentSent(currencyValue: String, itemTitle: String)
|
||||
case inviteRequestSent(title: String, text: String)
|
||||
case image(image: UIImage, text: String)
|
||||
case notificationSoundAdded(title: String, text: String, action: (() -> Void)?)
|
||||
}
|
||||
|
||||
public enum UndoOverlayAction {
|
||||
|
|
|
|||
|
|
@ -167,13 +167,17 @@ final class UndoOverlayControllerNode: ViewControllerTracingNode {
|
|||
self.textNode.maximumNumberOfLines = 5
|
||||
displayUndo = false
|
||||
self.originalRemainingSeconds = 3
|
||||
case let .info(text):
|
||||
case let .info(title, text):
|
||||
self.avatarNode = nil
|
||||
self.iconNode = nil
|
||||
self.iconCheckNode = nil
|
||||
self.animationNode = AnimationNode(animation: "anim_infotip", colors: ["info1.info1.stroke": self.animationBackgroundColor, "info2.info2.Fill": self.animationBackgroundColor], scale: 1.0)
|
||||
self.animatedStickerNode = nil
|
||||
|
||||
if let title = title {
|
||||
self.titleNode.attributedText = NSAttributedString(string: title, font: Font.semibold(14.0), textColor: .white)
|
||||
}
|
||||
|
||||
let body = MarkdownAttributeSet(font: Font.regular(14.0), textColor: .white)
|
||||
let bold = MarkdownAttributeSet(font: Font.semibold(14.0), textColor: .white)
|
||||
let attributedText = parseMarkdownIntoAttributedString(text, attributes: MarkdownAttributes(body: body, bold: bold, link: body, linkAttribute: { _ in return nil }), textAlignment: .natural)
|
||||
|
|
@ -750,6 +754,32 @@ final class UndoOverlayControllerNode: ViewControllerTracingNode {
|
|||
self.textNode.maximumNumberOfLines = 2
|
||||
displayUndo = false
|
||||
self.originalRemainingSeconds = 5
|
||||
case let .notificationSoundAdded(title, text, action):
|
||||
self.avatarNode = nil
|
||||
self.iconNode = nil
|
||||
self.iconCheckNode = nil
|
||||
self.animationNode = AnimationNode(animation: "anim_notificationsound", colors: [:], scale: 0.066)
|
||||
self.animatedStickerNode = nil
|
||||
self.titleNode.attributedText = NSAttributedString(string: title, font: Font.semibold(14.0), textColor: .white)
|
||||
|
||||
|
||||
let body = MarkdownAttributeSet(font: Font.regular(14.0), textColor: .white)
|
||||
let bold = MarkdownAttributeSet(font: Font.semibold(14.0), textColor: .white)
|
||||
let link = MarkdownAttributeSet(font: Font.regular(14.0), textColor: undoTextColor)
|
||||
let attributedText = parseMarkdownIntoAttributedString(text, attributes: MarkdownAttributes(body: body, bold: bold, link: link, linkAttribute: { _ in return nil }), textAlignment: .natural)
|
||||
self.textNode.attributedText = attributedText
|
||||
|
||||
self.textNode.maximumNumberOfLines = 5
|
||||
displayUndo = false
|
||||
self.originalRemainingSeconds = 5
|
||||
|
||||
if let action = action {
|
||||
self.textNode.tapAttributeAction = { attributes, _ in
|
||||
if let _ = attributes[NSAttributedString.Key(rawValue: "URL")] {
|
||||
action()
|
||||
}
|
||||
}
|
||||
}
|
||||
case let .image(image, text):
|
||||
self.avatarNode = nil
|
||||
self.iconNode = ASImageNode()
|
||||
|
|
@ -792,7 +822,7 @@ final class UndoOverlayControllerNode: ViewControllerTracingNode {
|
|||
switch content {
|
||||
case .removedChat:
|
||||
self.panelWrapperNode.addSubnode(self.timerTextNode)
|
||||
case .archivedChat, .hidArchive, .revealedArchive, .autoDelete, .succeed, .emoji, .swipeToReply, .actionSucceeded, .stickersModified, .chatAddedToFolder, .chatRemovedFromFolder, .messagesUnpinned, .setProximityAlert, .invitedToVoiceChat, .linkCopied, .banned, .importedMessage, .audioRate, .forward, .gigagroupConversion, .linkRevoked, .voiceChatRecording, .voiceChatFlag, .voiceChatCanSpeak, .sticker, .copy, .mediaSaved, .paymentSent, .image, .inviteRequestSent:
|
||||
case .archivedChat, .hidArchive, .revealedArchive, .autoDelete, .succeed, .emoji, .swipeToReply, .actionSucceeded, .stickersModified, .chatAddedToFolder, .chatRemovedFromFolder, .messagesUnpinned, .setProximityAlert, .invitedToVoiceChat, .linkCopied, .banned, .importedMessage, .audioRate, .forward, .gigagroupConversion, .linkRevoked, .voiceChatRecording, .voiceChatFlag, .voiceChatCanSpeak, .sticker, .copy, .mediaSaved, .paymentSent, .image, .inviteRequestSent, .notificationSoundAdded:
|
||||
break
|
||||
case .dice:
|
||||
self.panelWrapperNode.clipsToBounds = true
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue