diff --git a/.gitmodules b/.gitmodules index 9c7dc87aa6..c44a0bbf39 100644 --- a/.gitmodules +++ b/.gitmodules @@ -29,3 +29,6 @@ url=../tgcalls.git [submodule "third-party/dav1d/dav1d"] path = third-party/dav1d/dav1d url = https://github.com/ali-fareed/dav1d.git +[submodule "third-party/td/td"] + path = third-party/td/td + url = https://github.com/tdlib/td diff --git a/Telegram/Telegram-iOS/en.lproj/Localizable.strings b/Telegram/Telegram-iOS/en.lproj/Localizable.strings index 2857455b4d..3c508b2d67 100644 --- a/Telegram/Telegram-iOS/en.lproj/Localizable.strings +++ b/Telegram/Telegram-iOS/en.lproj/Localizable.strings @@ -14115,3 +14115,70 @@ Sorry for the inconvenience."; "WebApp.ImportData.AccountHeader" = "ACCOUNT TO IMPORT DATA FROM"; "WebApp.ImportData.CreatedOn" = "created on %@"; "WebApp.ImportData.Import" = "Import"; + +"CallList.ToastCallLinkCopied.Text" = "Call link copied"; +"CallList.ToastCallLinkCopied.Action" = "View Call"; +"CallList.NewCall" = "Start New Call"; +"CallList.NewCallLink" = "Create Call Link"; + +"Chat.SendStarsToBecomeTopInfo" = "Send %@ or more to highlight your profile"; + +"VideoChat.RevokeLink" = "Revoke Link"; + +"InviteLink.GroupCallLinkHelp" = "Anyone on Telegram can join your call by following the link below."; +"InviteLink.CallLinkTitle" = "Call Link"; +"InviteLink.CreatedGroupCallFooter" = "Be the first to join the call and add people from there. [Open Call >](open_call)"; +"InviteLink.QRCode.InfoGroupCall" = "Everyone on Telegram can scan this code to join your group call."; + +"Call.GenericGroupCallTitle" = "Group Call"; + +"VideoChat.EncryptionKeyLabel" = "End-to-end encrypted"; +"VideoChat.EncryptionKeyText" = "These four emojis represent the call's encryption key. They must match for all participants and change when someone joins or leaves."; +"VideoChat.EncryptionKeyDone" = "Close"; +"VideoChat.InviteMember" = "Add Member"; + +"VideoChat.GroupCallTitle" = "Group Call"; + +"Chat.ViewGroupCall" = "JOIN GROUP CALL"; + +"NewCall.SearchPlaceholder" = "Search for contacts or usernames"; +"NewCall.VideoOption" = "Call with video enabled"; +"NewCall.ActionCallSingle" = "Call %@"; +"NewCall.ActionCallMultiple" = "Call"; + +"Chat.ToastCallLinkExpired.Text" = "This link is no longer active"; + +"Chat.CallMessage.GroupCallParticipantCount_1" = "1 person"; +"Chat.CallMessage.GroupCallParticipantCount_any" = "%d people"; + +"Chat.CallMessage.DeclinedGroupCall" = "Declined Group Call"; +"Chat.CallMessage.MissedGroupCall" = "Missed Group Call"; +"Chat.CallMessage.CancelledGroupCall" = "Cancelled Group Call"; +"Chat.CallMessage.IncomingGroupCall" = "Incoming Group Call"; +"Chat.CallMessage.OutgoingGroupCall" = "Outgoing Group Call"; + +"Invitation.GroupCall" = "Group Call"; +"Invitation.JoinGroupCall" = "Join Group Call"; +"Invitation.PublicGroup" = "public group"; +"Invitation.PrivateGroup" = "private group"; + +"Invitation.GroupCall.Text" = "You are invited to join a group call."; + +"Invitation.Group.AlreadyJoinedSingle" = "**%@** already joined this group."; +"Invitation.Group.AlreadyJoinedMultiple" = "%@ already joined this group."; +"Invitation.Group.AlreadyJoinedMultipleWithCount_1" = "{} and **%d** other person already joined this group."; +"Invitation.Group.AlreadyJoinedMultipleWithCount_any" = "{} and **%d** other people already joined this group."; + +"Invitation.GroupCall.AlreadyJoinedSingle" = "**%@** already joined this call."; +"Invitation.GroupCall.AlreadyJoinedMultiple" = "%@ already joined this call."; +"Invitation.GroupCall.AlreadyJoinedMultipleWithCount_1" = "{} and **%d** other person already joined this call."; +"Invitation.GroupCall.AlreadyJoinedMultipleWithCount_any" = "{} and **%d** other people already joined this call."; + +"Call.ShareLink" = "Share Call Link"; +"Call.AddMemberTitle" = "Add Member"; + +"Call.IncomingGroupCallTitle.Single" = "%@"; +"Call.IncomingGroupCallTitle.Multiple_1" = "{} and 1 other"; +"Call.IncomingGroupCallTitle.Multiple_any" = "{} and %d others"; + +"GroupCall.RevokeLinkText" = "Are you sure you want to revoke this link? Once you do, no one will be able to join the call using it."; diff --git a/submodules/AccountContext/Sources/ContactSelectionController.swift b/submodules/AccountContext/Sources/ContactSelectionController.swift index 191e464c78..4b1ae89cca 100644 --- a/submodules/AccountContext/Sources/ContactSelectionController.swift +++ b/submodules/AccountContext/Sources/ContactSelectionController.swift @@ -99,6 +99,12 @@ public enum ContactListPeer: Equatable { } public final class ContactSelectionControllerParams { + public enum MultipleSelectionMode { + case disabled + case possible + case always + } + public let context: AccountContext public let updatedPresentationData: (initial: PresentationData, signal: Signal)? public let mode: ContactSelectionControllerMode @@ -107,7 +113,7 @@ public final class ContactSelectionControllerParams { public let options: Signal<[ContactListAdditionalOption], NoError> public let displayDeviceContacts: Bool public let displayCallIcons: Bool - public let multipleSelection: Bool + public let multipleSelection: MultipleSelectionMode public let requirePhoneNumbers: Bool public let allowChannelsInSearch: Bool public let confirmation: (ContactListPeer) -> Signal @@ -124,7 +130,7 @@ public final class ContactSelectionControllerParams { options: Signal<[ContactListAdditionalOption], NoError> = .single([]), displayDeviceContacts: Bool = false, displayCallIcons: Bool = false, - multipleSelection: Bool = false, + multipleSelection: MultipleSelectionMode = .disabled, requirePhoneNumbers: Bool = false, allowChannelsInSearch: Bool = false, confirmation: @escaping (ContactListPeer) -> Signal = { _ in .single(true) }, diff --git a/submodules/CallListUI/Sources/CallListCallItem.swift b/submodules/CallListUI/Sources/CallListCallItem.swift index a408a63cbc..17ae28f7d7 100644 --- a/submodules/CallListUI/Sources/CallListCallItem.swift +++ b/submodules/CallListUI/Sources/CallListCallItem.swift @@ -425,9 +425,8 @@ class CallListCallItemNode: ItemListRevealOptionsItemNode { isVideo = conferenceCall.flags.contains(.isVideo) if message.flags.contains(.Incoming) { hasIncoming = true - //TODO:localize let missedTimeout: Int32 - #if DEBUG + #if DEBUG && false missedTimeout = 5 #else missedTimeout = 30 @@ -463,8 +462,7 @@ class CallListCallItemNode: ItemListRevealOptionsItemNode { peersString.append(", ") } if peer.id == item.context.account.peerId { - //TODO:localize - peersString += "You" + peersString += item.presentationData.strings.DialogList_You } else { peersString += peer.compactDisplayTitle } diff --git a/submodules/CallListUI/Sources/CallListController.swift b/submodules/CallListUI/Sources/CallListController.swift index 1acf78752c..246fe5d891 100644 --- a/submodules/CallListUI/Sources/CallListController.swift +++ b/submodules/CallListUI/Sources/CallListController.swift @@ -108,7 +108,8 @@ public final class CallListController: TelegramBaseController { self.statusBar.statusBarStyle = self.presentationData.theme.rootController.statusBarStyle.style if case .tab = self.mode { - self.navigationItem.rightBarButtonItem = UIBarButtonItem(image: PresentationResourcesRootController.navigationCallIcon(self.presentationData.theme), style: .plain, target: self, action: #selector(self.callPressed)) + //self.navigationItem.rightBarButtonItem = UIBarButtonItem(image: PresentationResourcesRootController.navigationCallIcon(self.presentationData.theme), style: .plain, target: self, action: #selector(self.callPressed)) + self.navigationItem.rightBarButtonItem = nil let icon: UIImage? if useSpecialTabBarIcons() { @@ -191,7 +192,7 @@ public final class CallListController: TelegramBaseController { } } - self.navigationItem.rightBarButtonItem = UIBarButtonItem(image: PresentationResourcesRootController.navigationCallIcon(self.presentationData.theme), style: .plain, target: self, action: #selector(self.callPressed)) + //self.navigationItem.rightBarButtonItem = UIBarButtonItem(image: PresentationResourcesRootController.navigationCallIcon(self.presentationData.theme), style: .plain, target: self, action: #selector(self.callPressed)) case .navigation: if self.editingMode { self.navigationItem.rightBarButtonItem = UIBarButtonItem(title: self.presentationData.strings.Common_Done, style: .done, target: self, action: #selector(self.donePressed)) @@ -296,9 +297,8 @@ public final class CallListController: TelegramBaseController { if let result { switch result { case .linkCopied: - //TODO:localize let presentationData = self.context.sharedContext.currentPresentationData.with { $0 } - self.present(UndoOverlayController(presentationData: presentationData, content: .universal(animation: "anim_linkcopied", scale: 0.08, colors: ["info1.info1.stroke": UIColor.clear, "info2.info2.Fill": UIColor.clear], title: nil, text: "Call link copied.", customUndoText: "View Call", timeout: nil), elevatedLayout: false, animateInAsReplacement: false, action: { action in + self.present(UndoOverlayController(presentationData: presentationData, content: .universal(animation: "anim_linkcopied", scale: 0.08, colors: ["info1.info1.stroke": UIColor.clear, "info2.info2.Fill": UIColor.clear], title: nil, text: presentationData.strings.CallList_ToastCallLinkCopied_Text, customUndoText: presentationData.strings.CallList_ToastCallLinkCopied_Action, timeout: nil), elevatedLayout: false, animateInAsReplacement: false, action: { action in if case .undo = action { openCall() } @@ -383,7 +383,8 @@ public final class CallListController: TelegramBaseController { }) } else { strongSelf.navigationItem.setLeftBarButton(UIBarButtonItem(title: strongSelf.presentationData.strings.Common_Edit, style: .plain, target: strongSelf, action: #selector(strongSelf.editPressed)), animated: true) - strongSelf.navigationItem.setRightBarButton(UIBarButtonItem(image: PresentationResourcesRootController.navigationCallIcon(strongSelf.presentationData.theme), style: .plain, target: self, action: #selector(strongSelf.callPressed)), animated: true) + //strongSelf.navigationItem.setRightBarButton(UIBarButtonItem(image: PresentationResourcesRootController.navigationCallIcon(strongSelf.presentationData.theme), style: .plain, target: self, action: #selector(strongSelf.callPressed)), animated: true) + strongSelf.navigationItem.setRightBarButton(nil, animated: true) } case .navigation: if strongSelf.editingMode { @@ -399,9 +400,9 @@ public final class CallListController: TelegramBaseController { } } } - }, createGroupCall: { [weak self] in + }, openNewCall: { [weak self] in if let strongSelf = self { - strongSelf.createGroupCall(peerIds: [], isVideo: false) + strongSelf.callPressed() } }) @@ -515,8 +516,7 @@ public final class CallListController: TelegramBaseController { return } - //TODO:localize - let options = [ContactListAdditionalOption(title: "New Call Link", icon: .generic(PresentationResourcesItemList.linkIcon(presentationData.theme)!), action: { [weak self] in + let options = [ContactListAdditionalOption(title: self.presentationData.strings.CallList_NewCallLink, icon: .generic(PresentationResourcesItemList.linkIcon(presentationData.theme)!), action: { [weak self] in guard let self else { return } @@ -652,7 +652,8 @@ public final class CallListController: TelegramBaseController { switch self.mode { case .tab: self.navigationItem.setLeftBarButton(UIBarButtonItem(title: self.presentationData.strings.Common_Edit, style: .plain, target: self, action: #selector(self.editPressed)), animated: true) - self.navigationItem.setRightBarButton(UIBarButtonItem(image: PresentationResourcesRootController.navigationCallIcon(self.presentationData.theme), style: .plain, target: self, action: #selector(self.callPressed)), animated: true) + self.navigationItem.setRightBarButton(nil, animated: true) + //self.navigationItem.setRightBarButton(UIBarButtonItem(image: PresentationResourcesRootController.navigationCallIcon(self.presentationData.theme), style: .plain, target: self, action: #selector(self.callPressed)), animated: true) case .navigation: self.navigationItem.setLeftBarButton(nil, animated: true) self.navigationItem.setRightBarButton(UIBarButtonItem(title: self.presentationData.strings.Common_Edit, style: .plain, target: self, action: #selector(self.editPressed)), animated: true) @@ -738,8 +739,7 @@ public final class CallListController: TelegramBaseController { self.context.sharedContext.openCreateGroupCallUI(context: self.context, peerIds: conferenceCall.otherParticipants, parentController: self) default: let presentationData = self.context.sharedContext.currentPresentationData.with { $0 } - //TODO:localize - self.present(textAlertController(context: self.context, title: nil, text: "An error occurred", actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {})]), in: .window(.root)) + self.present(textAlertController(context: self.context, title: nil, text: presentationData.strings.Login_UnknownError, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {})]), in: .window(.root)) } }) } diff --git a/submodules/CallListUI/Sources/CallListControllerNode.swift b/submodules/CallListUI/Sources/CallListControllerNode.swift index 60be775f9b..cd9c6c87be 100644 --- a/submodules/CallListUI/Sources/CallListControllerNode.swift +++ b/submodules/CallListUI/Sources/CallListControllerNode.swift @@ -67,16 +67,16 @@ final class CallListNodeInteraction { let delete: ([EngineMessage.Id]) -> Void let updateShowCallsTab: (Bool) -> Void let openGroupCall: (EnginePeer.Id) -> Void - let createGroupCall: () -> Void + let openNewCall: () -> Void - init(setMessageIdWithRevealedOptions: @escaping (EngineMessage.Id?, EngineMessage.Id?) -> Void, call: @escaping (EngineMessage) -> Void, openInfo: @escaping (EnginePeer.Id, [EngineMessage]) -> Void, delete: @escaping ([EngineMessage.Id]) -> Void, updateShowCallsTab: @escaping (Bool) -> Void, openGroupCall: @escaping (EnginePeer.Id) -> Void, createGroupCall: @escaping () -> Void) { + init(setMessageIdWithRevealedOptions: @escaping (EngineMessage.Id?, EngineMessage.Id?) -> Void, call: @escaping (EngineMessage) -> Void, openInfo: @escaping (EnginePeer.Id, [EngineMessage]) -> Void, delete: @escaping ([EngineMessage.Id]) -> Void, updateShowCallsTab: @escaping (Bool) -> Void, openGroupCall: @escaping (EnginePeer.Id) -> Void, openNewCall: @escaping () -> Void) { self.setMessageIdWithRevealedOptions = setMessageIdWithRevealedOptions self.call = call self.openInfo = openInfo self.delete = delete self.updateShowCallsTab = updateShowCallsTab self.openGroupCall = openGroupCall - self.createGroupCall = createGroupCall + self.openNewCall = openNewCall } } @@ -125,10 +125,9 @@ private func mappedInsertEntries(context: AccountContext, presentationData: Item }), directionHint: entry.directionHint) case let .displayTabInfo(_, text): return ListViewInsertItem(index: entry.index, previousIndex: entry.previousIndex, item: ItemListTextItem(presentationData: presentationData, text: .plain(text), sectionId: 0), directionHint: entry.directionHint) - case .createGroupCall: - //TODO:localize - let item = ItemListPeerActionItem(presentationData: presentationData, style: showSettings ? .blocks : .plain, icon: PresentationResourcesItemList.linkIcon(presentationData.theme), title: "New Call Link", hasSeparator: false, sectionId: 1, noInsets: true, editing: false, action: { - nodeInteraction.createGroupCall() + case .openNewCall: + let item = ItemListPeerActionItem(presentationData: presentationData, style: showSettings ? .blocks : .plain, icon: PresentationResourcesRootController.callListCallIcon(presentationData.theme), title: presentationData.strings.CallList_NewCall, hasSeparator: false, sectionId: 1, height: .generic, noInsets: true, editing: false, action: { + nodeInteraction.openNewCall() }) return ListViewInsertItem(index: entry.index, previousIndex: entry.previousIndex, item: item, directionHint: entry.directionHint) case let .groupCall(peer, _, isActive): @@ -150,10 +149,9 @@ private func mappedUpdateEntries(context: AccountContext, presentationData: Item }), directionHint: entry.directionHint) case let .displayTabInfo(_, text): return ListViewUpdateItem(index: entry.index, previousIndex: entry.previousIndex, item: ItemListTextItem(presentationData: presentationData, text: .plain(text), sectionId: 0), directionHint: entry.directionHint) - case .createGroupCall: - //TODO:localize - let item = ItemListPeerActionItem(presentationData: presentationData, icon: PresentationResourcesItemList.linkIcon(presentationData.theme), title: "New Call Link", sectionId: 1, noInsets: true, editing: false, action: { - nodeInteraction.createGroupCall() + case .openNewCall: + let item = ItemListPeerActionItem(presentationData: presentationData, style: showSettings ? .blocks : .plain, icon: PresentationResourcesRootController.callListCallIcon(presentationData.theme), title: presentationData.strings.CallList_NewCall, hasSeparator: false, sectionId: 1, height: .generic, noInsets: true, editing: false, action: { + nodeInteraction.openNewCall() }) return ListViewUpdateItem(index: entry.index, previousIndex: entry.previousIndex, item: item, directionHint: entry.directionHint) case let .groupCall(peer, _, isActive): @@ -224,7 +222,7 @@ final class CallListControllerNode: ASDisplayNode { private let call: (EngineMessage) -> Void private let joinGroupCall: (EnginePeer.Id, EngineGroupCallDescription) -> Void - private let createGroupCall: () -> Void + private let openNewCall: () -> Void private let openInfo: (EnginePeer.Id, [EngineMessage]) -> Void private let emptyStateUpdated: (Bool) -> Void private let emptyStatePromise = Promise() @@ -234,7 +232,7 @@ final class CallListControllerNode: ASDisplayNode { private var previousContentOffset: ListViewVisibleContentOffset? - init(controller: CallListController, context: AccountContext, mode: CallListControllerMode, presentationData: PresentationData, call: @escaping (EngineMessage) -> Void, joinGroupCall: @escaping (EnginePeer.Id, EngineGroupCallDescription) -> Void, openInfo: @escaping (EnginePeer.Id, [EngineMessage]) -> Void, emptyStateUpdated: @escaping (Bool) -> Void, createGroupCall: @escaping () -> Void) { + init(controller: CallListController, context: AccountContext, mode: CallListControllerMode, presentationData: PresentationData, call: @escaping (EngineMessage) -> Void, joinGroupCall: @escaping (EnginePeer.Id, EngineGroupCallDescription) -> Void, openInfo: @escaping (EnginePeer.Id, [EngineMessage]) -> Void, emptyStateUpdated: @escaping (Bool) -> Void, openNewCall: @escaping () -> Void) { self.controller = controller self.context = context self.mode = mode @@ -243,7 +241,7 @@ final class CallListControllerNode: ASDisplayNode { self.joinGroupCall = joinGroupCall self.openInfo = openInfo self.emptyStateUpdated = emptyStateUpdated - self.createGroupCall = createGroupCall + self.openNewCall = openNewCall self.currentState = CallListNodeState(presentationData: ItemListPresentationData(presentationData), dateTimeFormat: presentationData.dateTimeFormat, disableAnimations: true, editing: false, messageIdWithRevealedOptions: nil) self.statePromise = ValuePromise(self.currentState, ignoreRepeated: true) @@ -447,11 +445,11 @@ final class CallListControllerNode: ASDisplayNode { strongSelf.joinGroupCall(peerId, activeCall) } })) - }, createGroupCall: { [weak self] in + }, openNewCall: { [weak self] in guard let strongSelf = self else { return } - strongSelf.createGroupCall() + strongSelf.openNewCall() }) let viewProcessingQueue = self.viewProcessingQueue @@ -516,28 +514,18 @@ final class CallListControllerNode: ASDisplayNode { }) } |> distinctUntilChanged - - let canCreateGroupCall = context.engine.data.subscribe(TelegramEngine.EngineData.Item.Configuration.App()) - |> map { configuration -> Bool in - var isConferencePossible = true - if let data = configuration.data, let value = data["ios_enable_conference"] as? Double { - isConferencePossible = value != 0.0 - } - return isConferencePossible - } let callListNodeViewTransition = combineLatest( callListViewUpdate, self.statePromise.get(), groupCalls, showCallsTab, - currentGroupCallPeerId, - canCreateGroupCall + currentGroupCallPeerId ) - |> mapToQueue { (updateAndType, state, groupCalls, showCallsTab, currentGroupCallPeerId, canCreateGroupCall) -> Signal in + |> mapToQueue { (updateAndType, state, groupCalls, showCallsTab, currentGroupCallPeerId) -> Signal in let (update, type) = updateAndType - let processedView = CallListNodeView(originalView: update.view, filteredEntries: callListNodeEntriesForView(view: update.view, canCreateGroupCall: canCreateGroupCall && mode == .tab, groupCalls: groupCalls, state: state, showSettings: showSettings, showCallsTab: showCallsTab, isRecentCalls: type == .all, currentGroupCallPeerId: currentGroupCallPeerId), presentationData: state.presentationData) + let processedView = CallListNodeView(originalView: update.view, filteredEntries: callListNodeEntriesForView(view: update.view, displayOpenNewCall: mode == .tab && type == .all, groupCalls: groupCalls, state: state, showSettings: showSettings, showCallsTab: showCallsTab, isRecentCalls: type == .all, currentGroupCallPeerId: currentGroupCallPeerId), presentationData: state.presentationData) let previous = previousView.swap(processedView) let previousType = previousType.swap(type) diff --git a/submodules/CallListUI/Sources/CallListNodeEntries.swift b/submodules/CallListUI/Sources/CallListNodeEntries.swift index 22356ea608..37d7733834 100644 --- a/submodules/CallListUI/Sources/CallListNodeEntries.swift +++ b/submodules/CallListUI/Sources/CallListNodeEntries.swift @@ -25,7 +25,7 @@ enum CallListNodeEntry: Comparable, Identifiable { enum SortIndex: Comparable { case displayTab case displayTabInfo - case createGroupCall + case openNewCall case groupCall(EnginePeer.Id, String) case message(EngineMessage.Index) case hole(EngineMessage.Index) @@ -41,7 +41,7 @@ enum CallListNodeEntry: Comparable, Identifiable { default: return false } - case .createGroupCall: + case .openNewCall: switch rhs { case .displayTab, .displayTabInfo: return false @@ -50,7 +50,7 @@ enum CallListNodeEntry: Comparable, Identifiable { } case let .groupCall(lhsPeerId, lhsTitle): switch rhs { - case .displayTab, .displayTabInfo, .createGroupCall: + case .displayTab, .displayTabInfo, .openNewCall: return false case let .groupCall(rhsPeerId, rhsTitle): if lhsTitle == rhsTitle { @@ -63,7 +63,7 @@ enum CallListNodeEntry: Comparable, Identifiable { } case let .hole(lhsIndex): switch rhs { - case .displayTab, .displayTabInfo, .groupCall, .createGroupCall: + case .displayTab, .displayTabInfo, .groupCall, .openNewCall: return false case let .hole(rhsIndex): return lhsIndex < rhsIndex @@ -72,7 +72,7 @@ enum CallListNodeEntry: Comparable, Identifiable { } case let .message(lhsIndex): switch rhs { - case .displayTab, .displayTabInfo, .groupCall, .createGroupCall: + case .displayTab, .displayTabInfo, .groupCall, .openNewCall: return false case let .hole(rhsIndex): return lhsIndex < rhsIndex @@ -86,7 +86,7 @@ enum CallListNodeEntry: Comparable, Identifiable { case displayTab(PresentationTheme, String, Bool) case displayTabInfo(PresentationTheme, String) - case createGroupCall + case openNewCall case groupCall(peer: EnginePeer, editing: Bool, isActive: Bool) case messageEntry(topMessage: EngineMessage, messages: [EngineMessage], theme: PresentationTheme, strings: PresentationStrings, dateTimeFormat: PresentationDateTimeFormat, editing: Bool, hasActiveRevealControls: Bool, displayHeader: Bool, missed: Bool) case holeEntry(index: EngineMessage.Index, theme: PresentationTheme) @@ -97,8 +97,8 @@ enum CallListNodeEntry: Comparable, Identifiable { return .displayTab case .displayTabInfo: return .displayTabInfo - case .createGroupCall: - return .createGroupCall + case .openNewCall: + return .openNewCall case let .groupCall(peer, _, _): return .groupCall(peer.id, peer.compactDisplayTitle) case let .messageEntry(message, _, _, _, _, _, _, _, _): @@ -114,7 +114,7 @@ enum CallListNodeEntry: Comparable, Identifiable { return .setting(0) case .displayTabInfo: return .setting(1) - case .createGroupCall: + case .openNewCall: return .setting(2) case let .groupCall(peer, _, _): return .groupCall(peer.id) @@ -143,8 +143,8 @@ enum CallListNodeEntry: Comparable, Identifiable { } else { return false } - case .createGroupCall: - if case .createGroupCall = rhs { + case .openNewCall: + if case .openNewCall = rhs { return true } else { return false @@ -212,7 +212,7 @@ enum CallListNodeEntry: Comparable, Identifiable { } } -func callListNodeEntriesForView(view: EngineCallList, canCreateGroupCall: Bool, groupCalls: [EnginePeer], state: CallListNodeState, showSettings: Bool, showCallsTab: Bool, isRecentCalls: Bool, currentGroupCallPeerId: EnginePeer.Id?) -> [CallListNodeEntry] { +func callListNodeEntriesForView(view: EngineCallList, displayOpenNewCall: Bool, groupCalls: [EnginePeer], state: CallListNodeState, showSettings: Bool, showCallsTab: Bool, isRecentCalls: Bool, currentGroupCallPeerId: EnginePeer.Id?) -> [CallListNodeEntry] { var result: [CallListNodeEntry] = [] for entry in view.items { switch entry { @@ -237,8 +237,8 @@ func callListNodeEntriesForView(view: EngineCallList, canCreateGroupCall: Bool, } } - if canCreateGroupCall { - result.append(.createGroupCall) + if displayOpenNewCall { + result.append(.openNewCall) } if showSettings { diff --git a/submodules/ChatListUI/Sources/Node/ChatListItemStrings.swift b/submodules/ChatListUI/Sources/Node/ChatListItemStrings.swift index d989d3e693..1e7012154e 100644 --- a/submodules/ChatListUI/Sources/Node/ChatListItemStrings.swift +++ b/submodules/ChatListUI/Sources/Node/ChatListItemStrings.swift @@ -298,9 +298,25 @@ public func chatListItemStrings(strings: PresentationStrings, nameDisplayOrder: messageText = invoice.title case let action as TelegramMediaAction: switch action.action { - case .conferenceCall: - //TODO:localize - messageText = "Group call" + case let .conferenceCall(conferenceCall): + let incoming = message.flags.contains(.Incoming) + + let missedTimeout: Int32 = 30 + let currentTime = Int32(Date().timeIntervalSince1970) + + if conferenceCall.flags.contains(.isMissed) { + messageText = strings.Chat_CallMessage_DeclinedGroupCall + } else if message.timestamp < currentTime - missedTimeout { + messageText = strings.Chat_CallMessage_MissedGroupCall + } else if conferenceCall.duration != nil { + messageText = strings.Chat_CallMessage_CancelledGroupCall + } else { + if incoming { + messageText = strings.Chat_CallMessage_IncomingGroupCall + } else { + messageText = strings.Chat_CallMessage_OutgoingGroupCall + } + } case let .phoneCall(_, discardReason, _, isVideo): hideAuthor = !isPeerGroup let incoming = message.flags.contains(.Incoming) diff --git a/submodules/ContactListUI/Sources/ContactsControllerNode.swift b/submodules/ContactListUI/Sources/ContactsControllerNode.swift index 36d11ff2a3..cccd381c9b 100644 --- a/submodules/ContactListUI/Sources/ContactsControllerNode.swift +++ b/submodules/ContactListUI/Sources/ContactsControllerNode.swift @@ -474,7 +474,7 @@ final class ContactsControllerNode: ASDisplayNode, ASGestureRecognizerDelegate { if let requestAddContact = self?.requestAddContact { requestAddContact(phoneNumber) } - }, openPeer: { [weak self] peer in + }, openPeer: { [weak self] peer, _ in if let requestOpenPeerFromSearch = self?.requestOpenPeerFromSearch { requestOpenPeerFromSearch(peer) } diff --git a/submodules/ContactListUI/Sources/ContactsSearchContainerNode.swift b/submodules/ContactListUI/Sources/ContactsSearchContainerNode.swift index 7a9a595cd6..442df4f39d 100644 --- a/submodules/ContactListUI/Sources/ContactsSearchContainerNode.swift +++ b/submodules/ContactListUI/Sources/ContactsSearchContainerNode.swift @@ -52,14 +52,14 @@ private enum ContactListSearchEntryId: Hashable { } private enum ContactListSearchEntry: Comparable, Identifiable { - case addContact(PresentationTheme, PresentationStrings, String) - case peer(Int, PresentationTheme, PresentationStrings, ContactListPeer, EnginePeer.Presence?, ContactListSearchGroup, Bool, Bool) + case addContact(theme: PresentationTheme, strings: PresentationStrings, phoneNumber: String) + case peer(index: Int, theme: PresentationTheme, strings: PresentationStrings, peer: ContactListPeer, presence: EnginePeer.Presence?, group: ContactListSearchGroup, enabled: Bool, requiresPremiumForMessaging: Bool, displayCallIcons: Bool) var stableId: ContactListSearchEntryId { switch self { case .addContact: return .addContact - case let .peer(_, _, _, peer, _, _, _, _): + case let .peer(_, _, _, peer, _, _, _, _, _): return .peerId(peer.id) } } @@ -72,9 +72,9 @@ private enum ContactListSearchEntry: Comparable, Identifiable { } else { return false } - case let .peer(lhsIndex, lhsTheme, lhsStrings, lhsPeer, lhsPresence, lhsGroup, lhsEnabled, lhsRequiresPremiumForMessaging): + case let .peer(lhsIndex, lhsTheme, lhsStrings, lhsPeer, lhsPresence, lhsGroup, lhsEnabled, lhsRequiresPremiumForMessaging, lhsDisplayCallIcons): switch rhs { - case let .peer(rhsIndex, rhsTheme, rhsStrings, rhsPeer, rhsPresence, rhsGroup, rhsEnabled, rhsRequiresPremiumForMessaging): + case let .peer(rhsIndex, rhsTheme, rhsStrings, rhsPeer, rhsPresence, rhsGroup, rhsEnabled, rhsRequiresPremiumForMessaging, rhsDisplayCallIcons): if lhsIndex != rhsIndex { return false } @@ -103,6 +103,9 @@ private enum ContactListSearchEntry: Comparable, Identifiable { if lhsRequiresPremiumForMessaging != rhsRequiresPremiumForMessaging { return false } + if lhsDisplayCallIcons != rhsDisplayCallIcons { + return false + } return true default: return false @@ -114,23 +117,23 @@ private enum ContactListSearchEntry: Comparable, Identifiable { switch lhs { case .addContact: return true - case let .peer(lhsIndex, _, _, _, _, _, _, _): + case let .peer(lhsIndex, _, _, _, _, _, _, _, _): switch rhs { case .addContact: return false - case let .peer(rhsIndex, _, _, _, _, _, _, _): + case let .peer(rhsIndex, _, _, _, _, _, _, _, _): return lhsIndex < rhsIndex } } } - func item(context: AccountContext, presentationData: PresentationData, nameSortOrder: PresentationPersonNameOrder, nameDisplayOrder: PresentationPersonNameOrder, timeFormat: PresentationDateTimeFormat, addContact: ((String) -> Void)?, openPeer: @escaping (ContactListPeer) -> Void, openDisabledPeer: @escaping (EnginePeer, ChatListDisabledPeerReason) -> Void, contextAction: ((EnginePeer, ASDisplayNode, ContextGesture?, CGPoint?) -> Void)?) -> ListViewItem { + func item(context: AccountContext, presentationData: PresentationData, nameSortOrder: PresentationPersonNameOrder, nameDisplayOrder: PresentationPersonNameOrder, timeFormat: PresentationDateTimeFormat, isPeerEnabled: @escaping (ContactListPeer) -> Bool, addContact: ((String) -> Void)?, openPeer: @escaping (ContactListPeer, ContactsSearchContainerNode.OpenPeerAction) -> Void, openDisabledPeer: @escaping (EnginePeer, ChatListDisabledPeerReason) -> Void, contextAction: ((EnginePeer, ASDisplayNode, ContextGesture?, CGPoint?) -> Void)?) -> ListViewItem { switch self { case let .addContact(theme, strings, phoneNumber): return ContactsAddItem(context: context, theme: theme, strings: strings, phoneNumber: phoneNumber, header: ChatListSearchItemHeader(type: .phoneNumber, theme: theme, strings: strings, actionTitle: nil, action: nil), action: { addContact?(phoneNumber) }) - case let .peer(_, theme, strings, peer, presence, group, enabled, requiresPremiumForMessaging): + case let .peer(_, theme, strings, peer, presence, group, enabled, requiresPremiumForMessaging, displayCallIcons): let header: ListViewItemHeader let status: ContactsPeerItemStatus switch group { @@ -161,8 +164,16 @@ private enum ContactListSearchEntry: Comparable, Identifiable { case let .deviceContact(stableId, contact): peerItem = .deviceContact(stableId: stableId, contact: contact) } - return ContactsPeerItem(presentationData: ItemListPresentationData(presentationData), sortOrder: nameSortOrder, displayOrder: nameDisplayOrder, context: context, peerMode: .peer, peer: peerItem, status: status, requiresPremiumForMessaging: requiresPremiumForMessaging, enabled: enabled, selection: .none, editing: ContactsPeerItemEditing(editable: false, editing: false, revealed: false), index: nil, header: header, action: { _ in - openPeer(peer) + var additionalActions: [ContactsPeerItemAction] = [] + if displayCallIcons { + additionalActions = [ContactsPeerItemAction(icon: .voiceCall, action: { _, sourceNode, gesture in + openPeer(peer, .voiceCall) + }), ContactsPeerItemAction(icon: .videoCall, action: { _, sourceNode, gesture in + openPeer(peer, .videoCall) + })] + } + return ContactsPeerItem(presentationData: ItemListPresentationData(presentationData), sortOrder: nameSortOrder, displayOrder: nameDisplayOrder, context: context, peerMode: .peer, peer: peerItem, status: status, requiresPremiumForMessaging: requiresPremiumForMessaging, enabled: enabled && isPeerEnabled(peer), selection: .none, editing: ContactsPeerItemEditing(editable: false, editing: false, revealed: false), additionalActions: additionalActions, index: nil, header: header, action: { _ in + openPeer(peer, .generic) }, disabledAction: { _ in if case let .peer(peer, _, _) = peer { openDisabledPeer(EnginePeer(peer), requiresPremiumForMessaging ? .premiumRequired : .generic) @@ -187,12 +198,12 @@ struct ContactListSearchContainerTransition { let query: String } -private func contactListSearchContainerPreparedRecentTransition(from fromEntries: [ContactListSearchEntry], to toEntries: [ContactListSearchEntry], isSearching: Bool, emptyResults: Bool, query: String, context: AccountContext, presentationData: PresentationData, nameSortOrder: PresentationPersonNameOrder, nameDisplayOrder: PresentationPersonNameOrder, timeFormat: PresentationDateTimeFormat, addContact: ((String) -> Void)?, openPeer: @escaping (ContactListPeer) -> Void, openDisabledPeer: @escaping (EnginePeer, ChatListDisabledPeerReason) -> Void, contextAction: ((EnginePeer, ASDisplayNode, ContextGesture?, CGPoint?) -> Void)?) -> ContactListSearchContainerTransition { +private func contactListSearchContainerPreparedRecentTransition(from fromEntries: [ContactListSearchEntry], to toEntries: [ContactListSearchEntry], isSearching: Bool, emptyResults: Bool, query: String, context: AccountContext, presentationData: PresentationData, nameSortOrder: PresentationPersonNameOrder, nameDisplayOrder: PresentationPersonNameOrder, timeFormat: PresentationDateTimeFormat, isPeerEnabled: @escaping (ContactListPeer) -> Bool, addContact: ((String) -> Void)?, openPeer: @escaping (ContactListPeer, ContactsSearchContainerNode.OpenPeerAction) -> Void, openDisabledPeer: @escaping (EnginePeer, ChatListDisabledPeerReason) -> Void, contextAction: ((EnginePeer, ASDisplayNode, ContextGesture?, CGPoint?) -> Void)?) -> ContactListSearchContainerTransition { let (deleteIndices, indicesAndItems, updateIndices) = mergeListsStableWithUpdates(leftList: fromEntries, rightList: toEntries) let deletions = deleteIndices.map { ListViewDeleteItem(index: $0, directionHint: nil) } - let insertions = indicesAndItems.map { ListViewInsertItem(index: $0.0, previousIndex: $0.2, item: $0.1.item(context: context, presentationData: presentationData, nameSortOrder: nameSortOrder, nameDisplayOrder: nameDisplayOrder, timeFormat: timeFormat, addContact: addContact, openPeer: openPeer, openDisabledPeer: openDisabledPeer, contextAction: contextAction), directionHint: nil) } - let updates = updateIndices.map { ListViewUpdateItem(index: $0.0, previousIndex: $0.2, item: $0.1.item(context: context, presentationData: presentationData, nameSortOrder: nameSortOrder, nameDisplayOrder: nameDisplayOrder, timeFormat: timeFormat, addContact: addContact, openPeer: openPeer, openDisabledPeer: openDisabledPeer, contextAction: contextAction), directionHint: nil) } + let insertions = indicesAndItems.map { ListViewInsertItem(index: $0.0, previousIndex: $0.2, item: $0.1.item(context: context, presentationData: presentationData, nameSortOrder: nameSortOrder, nameDisplayOrder: nameDisplayOrder, timeFormat: timeFormat, isPeerEnabled: isPeerEnabled, addContact: addContact, openPeer: openPeer, openDisabledPeer: openDisabledPeer, contextAction: contextAction), directionHint: nil) } + let updates = updateIndices.map { ListViewUpdateItem(index: $0.0, previousIndex: $0.2, item: $0.1.item(context: context, presentationData: presentationData, nameSortOrder: nameSortOrder, nameDisplayOrder: nameDisplayOrder, timeFormat: timeFormat, isPeerEnabled: isPeerEnabled, addContact: addContact, openPeer: openPeer, openDisabledPeer: openDisabledPeer, contextAction: contextAction), directionHint: nil) } return ContactListSearchContainerTransition(deletions: deletions, insertions: insertions, updates: updates, isSearching: isSearching, emptyResults: emptyResults, query: query) } @@ -211,9 +222,16 @@ public struct ContactsSearchCategories: OptionSet { } public final class ContactsSearchContainerNode: SearchDisplayControllerContentNode { + public enum OpenPeerAction { + case generic + case voiceCall + case videoCall + } + private let context: AccountContext + private let isPeerEnabled: (ContactListPeer) -> Bool private let addContact: ((String) -> Void)? - private let openPeer: (ContactListPeer) -> Void + private let openPeer: (ContactListPeer, ContactsSearchContainerNode.OpenPeerAction) -> Void private let openDisabledPeer: (EnginePeer, ChatListDisabledPeerReason) -> Void private let contextAction: ((EnginePeer, ASDisplayNode, ContextGesture?, CGPoint?) -> Void)? @@ -238,8 +256,9 @@ public final class ContactsSearchContainerNode: SearchDisplayControllerContentNo return true } - public init(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal)? = nil, onlyWriteable: Bool, categories: ContactsSearchCategories, filters: [ContactListFilter] = [.excludeSelf], addContact: ((String) -> Void)?, openPeer: @escaping (ContactListPeer) -> Void, openDisabledPeer: @escaping (EnginePeer, ChatListDisabledPeerReason) -> Void, contextAction: ((EnginePeer, ASDisplayNode, ContextGesture?, CGPoint?) -> Void)?) { + public init(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal)? = nil, onlyWriteable: Bool, categories: ContactsSearchCategories, filters: [ContactListFilter] = [.excludeSelf], displayCallIcons: Bool = false, isPeerEnabled: @escaping (ContactListPeer) -> Bool = { _ in true }, addContact: ((String) -> Void)?, openPeer: @escaping (ContactListPeer, ContactsSearchContainerNode.OpenPeerAction) -> Void, openDisabledPeer: @escaping (EnginePeer, ChatListDisabledPeerReason) -> Void, contextAction: ((EnginePeer, ASDisplayNode, ContextGesture?, CGPoint?) -> Void)?) { self.context = context + self.isPeerEnabled = isPeerEnabled self.addContact = addContact self.openPeer = openPeer self.openDisabledPeer = openDisabledPeer @@ -441,7 +460,7 @@ public final class ContactsSearchContainerNode: SearchDisplayControllerContentNo enabled = false } } - entries.append(.peer(index, themeAndStrings.0, themeAndStrings.1, .peer(peer: peer._asPeer(), isGlobal: false, participantCount: nil), localPeersAndPresences.1[peer.id], .contacts, enabled, requiresPremiumForMessaging)) + entries.append(.peer(index: index, theme: themeAndStrings.0, strings: themeAndStrings.1, peer: .peer(peer: peer._asPeer(), isGlobal: false, participantCount: nil), presence: localPeersAndPresences.1[peer.id], group: .contacts, enabled: enabled, requiresPremiumForMessaging: requiresPremiumForMessaging, displayCallIcons: displayCallIcons)) if searchDeviceContacts, case let .user(user) = peer, let phone = user.phone { existingNormalizedPhoneNumbers.insert(DeviceContactNormalizedPhoneNumber(rawValue: formatPhoneNumber(phone))) } @@ -483,7 +502,7 @@ public final class ContactsSearchContainerNode: SearchDisplayControllerContentNo } } - entries.append(.peer(index, themeAndStrings.0, themeAndStrings.1, .peer(peer: peer.peer, isGlobal: true, participantCount: peer.subscribers), nil, .global, enabled, requiresPremiumForMessaging)) + entries.append(.peer(index: index, theme: themeAndStrings.0, strings: themeAndStrings.1, peer: .peer(peer: peer.peer, isGlobal: true, participantCount: peer.subscribers), presence: nil, group: .global, enabled: enabled, requiresPremiumForMessaging: requiresPremiumForMessaging, displayCallIcons: displayCallIcons)) if searchDeviceContacts, let user = peer.peer as? TelegramUser, let phone = user.phone { existingNormalizedPhoneNumbers.insert(DeviceContactNormalizedPhoneNumber(rawValue: formatPhoneNumber(phone))) } @@ -518,7 +537,7 @@ public final class ContactsSearchContainerNode: SearchDisplayControllerContentNo } } - entries.append(.peer(index, themeAndStrings.0, themeAndStrings.1, .peer(peer: peer.peer, isGlobal: true, participantCount: peer.subscribers), nil, .global, enabled, requiresPremiumForMessaging)) + entries.append(.peer(index: index, theme: themeAndStrings.0, strings: themeAndStrings.1, peer: .peer(peer: peer.peer, isGlobal: true, participantCount: peer.subscribers), presence: nil, group: .global, enabled: enabled, requiresPremiumForMessaging: requiresPremiumForMessaging, displayCallIcons: displayCallIcons)) if searchDeviceContacts, let user = peer.peer as? TelegramUser, let phone = user.phone { existingNormalizedPhoneNumbers.insert(DeviceContactNormalizedPhoneNumber(rawValue: formatPhoneNumber(phone))) } @@ -539,13 +558,13 @@ public final class ContactsSearchContainerNode: SearchDisplayControllerContentNo continue outer } } - entries.append(.peer(index, themeAndStrings.0, themeAndStrings.1, .deviceContact(stableId, contact.0), nil, .deviceContacts, true, false)) + entries.append(.peer(index: index, theme: themeAndStrings.0, strings: themeAndStrings.1, peer: .deviceContact(stableId, contact.0), presence: nil, group: .deviceContacts, enabled: true, requiresPremiumForMessaging: false, displayCallIcons: displayCallIcons)) index += 1 } } if let _ = addContact, isViablePhoneNumber(query) { - entries.append(.addContact(themeAndStrings.0, themeAndStrings.1, query)) + entries.append(.addContact(theme: themeAndStrings.0, strings: themeAndStrings.1, phoneNumber: query)) } return (entries, query) @@ -571,9 +590,9 @@ public final class ContactsSearchContainerNode: SearchDisplayControllerContentNo } } - let transition = contactListSearchContainerPreparedRecentTransition(from: previousItems, to: items ?? [], isSearching: items != nil, emptyResults: items?.isEmpty ?? false, query: query, context: context, presentationData: strongSelf.presentationData, nameSortOrder: strongSelf.presentationData.nameSortOrder, nameDisplayOrder: strongSelf.presentationData.nameDisplayOrder, timeFormat: strongSelf.presentationData.dateTimeFormat, addContact: addContact, openPeer: { peer in + let transition = contactListSearchContainerPreparedRecentTransition(from: previousItems, to: items ?? [], isSearching: items != nil, emptyResults: items?.isEmpty ?? false, query: query, context: context, presentationData: strongSelf.presentationData, nameSortOrder: strongSelf.presentationData.nameSortOrder, nameDisplayOrder: strongSelf.presentationData.nameDisplayOrder, timeFormat: strongSelf.presentationData.dateTimeFormat, isPeerEnabled: strongSelf.isPeerEnabled, addContact: addContact, openPeer: { peer, action in self?.listNode.clearHighlightAnimated(true) - self?.openPeer(peer) + self?.openPeer(peer, action) }, openDisabledPeer: { peer, reason in guard let self else { return diff --git a/submodules/ContactListUI/Sources/InviteContactsControllerNode.swift b/submodules/ContactListUI/Sources/InviteContactsControllerNode.swift index 504582fbac..57124b8f37 100644 --- a/submodules/ContactListUI/Sources/InviteContactsControllerNode.swift +++ b/submodules/ContactListUI/Sources/InviteContactsControllerNode.swift @@ -508,7 +508,7 @@ final class InviteContactsControllerNode: ASDisplayNode { return } - self.searchDisplayController = SearchDisplayController(presentationData: self.presentationData, contentNode: ContactsSearchContainerNode(context: self.context, onlyWriteable: false, categories: [.deviceContacts], addContact: nil, openPeer: { [weak self] peer in + self.searchDisplayController = SearchDisplayController(presentationData: self.presentationData, contentNode: ContactsSearchContainerNode(context: self.context, onlyWriteable: false, categories: [.deviceContacts], addContact: nil, openPeer: { [weak self] peer, _ in if let strongSelf = self, case let .deviceContact(id, _) = peer { strongSelf.selectionState = strongSelf.selectionState.withSelectedContactId(id) strongSelf.requestDeactivateSearch?() diff --git a/submodules/ContextUI/Sources/ContextActionsContainerNode.swift b/submodules/ContextUI/Sources/ContextActionsContainerNode.swift index 8641e4d77c..e4f72eda92 100644 --- a/submodules/ContextUI/Sources/ContextActionsContainerNode.swift +++ b/submodules/ContextUI/Sources/ContextActionsContainerNode.swift @@ -438,9 +438,8 @@ final class InnerTextSelectionTipContainerNode: ASDisplayNode { icon = nil isUserInteractionEnabled = action != nil case let .starsReactions(topCount): - //TODO:localize self.action = nil - self.text = "Send \(topCount) or more to highlight your profile" + self.text = self.presentationData.strings.Chat_SendStarsToBecomeTopInfo("\(topCount)").string self.targetSelectionIndex = nil icon = nil isUserInteractionEnabled = action != nil diff --git a/submodules/InviteLinksUI/Sources/InviteLinkInviteController.swift b/submodules/InviteLinksUI/Sources/InviteLinkInviteController.swift index cf901db89a..34a52902e2 100644 --- a/submodules/InviteLinksUI/Sources/InviteLinkInviteController.swift +++ b/submodules/InviteLinksUI/Sources/InviteLinkInviteController.swift @@ -492,10 +492,9 @@ public final class InviteLinkInviteController: ViewController { let dismissAction: () -> Void = { [weak controller] in controller?.dismissAnimated() } - //TODO:localize controller.setItemGroups([ ActionSheetItemGroup(items: [ - ActionSheetTextItem(title: "Revoke Link"), + ActionSheetTextItem(title: presentationData.strings.GroupCall_RevokeLinkText), ActionSheetButtonItem(title: presentationData.strings.GroupInfo_InviteLink_RevokeLink, color: .destructive, action: { [weak self] in dismissAction() @@ -674,9 +673,8 @@ public final class InviteLinkInviteController: ViewController { } var entries: [InviteLinkInviteEntry] = [] - //TODO:localize - let helpText: String = "Anyone on Telegram can join your call by following the link below." - entries.append(.header(title: "Call Link", text: helpText)) + let helpText: String = presentationData.strings.InviteLink_GroupCallLinkHelp + entries.append(.header(title: presentationData.strings.InviteLink_CallLinkTitle, text: helpText)) let mainInvite: ExportedInvitation = .link(link: mainInvite?.link ?? "", title: nil, isPermanent: true, requestApproval: false, isRevoked: false, adminId: self.context.account.peerId, date: 0, startDate: nil, expireDate: nil, usageLimit: nil, count: nil, requestedCount: nil, pricing: nil) diff --git a/submodules/InviteLinksUI/Sources/ItemListPermanentInviteLinkItem.swift b/submodules/InviteLinksUI/Sources/ItemListPermanentInviteLinkItem.swift index e64aa14847..de6d03c3a7 100644 --- a/submodules/InviteLinksUI/Sources/ItemListPermanentInviteLinkItem.swift +++ b/submodules/InviteLinksUI/Sources/ItemListPermanentInviteLinkItem.swift @@ -369,8 +369,7 @@ public class ItemListPermanentInviteLinkItemNode: ListViewItemNode, ItemListItem return (TelegramTextAttributes.URL, contents) } ) - //TODO:localize - let justCreatedCallTextAttributedString = parseMarkdownIntoAttributedString("Be the first to join the call and add people from there. [Open Call >](open_call)", attributes: markdownAttributes).mutableCopy() as! NSMutableAttributedString + let justCreatedCallTextAttributedString = parseMarkdownIntoAttributedString(item.presentationData.strings.InviteLink_CreatedGroupCallFooter, attributes: markdownAttributes).mutableCopy() as! NSMutableAttributedString if let range = justCreatedCallTextAttributedString.string.range(of: ">"), let chevronImage { justCreatedCallTextAttributedString.addAttribute(.attachment, value: chevronImage, range: NSRange(range, in: justCreatedCallTextAttributedString.string)) } diff --git a/submodules/JoinLinkPreviewUI/Sources/JoinLinkPreviewController.swift b/submodules/JoinLinkPreviewUI/Sources/JoinLinkPreviewController.swift index 91c373bc47..5b23c18ed4 100644 --- a/submodules/JoinLinkPreviewUI/Sources/JoinLinkPreviewController.swift +++ b/submodules/JoinLinkPreviewUI/Sources/JoinLinkPreviewController.swift @@ -193,9 +193,7 @@ public func JoinLinkPreviewController( ) -> ViewController { if let data = context.currentAppConfiguration.with({ $0 }).data, data["ios_killswitch_legacy_join_link"] != nil { return LegacyJoinLinkPreviewController(context: context, link: link, navigateToPeer: navigateToPeer, parentNavigationController: parentNavigationController, resolvedState: resolvedState) - } else if case let .invite(invite) = resolvedState, !invite.flags.requestNeeded, !invite.flags.isBroadcast, !invite.flags.canRefulfillSubscription { - //TODO:release - + } else if case let .invite(invite) = resolvedState, !invite.flags.requestNeeded, !invite.flags.isBroadcast, !invite.flags.canRefulfillSubscription { var verificationStatus: JoinSubjectScreenMode.Group.VerificationStatus? if invite.flags.isFake { verificationStatus = .fake diff --git a/submodules/QrCodeUI/Sources/QrCodeScreen.swift b/submodules/QrCodeUI/Sources/QrCodeScreen.swift index 69e11b3c2e..c5630feda9 100644 --- a/submodules/QrCodeUI/Sources/QrCodeScreen.swift +++ b/submodules/QrCodeUI/Sources/QrCodeScreen.swift @@ -253,8 +253,7 @@ public final class QrCodeScreen: ViewController { case .channel: text = self.presentationData.strings.InviteLink_QRCode_InfoChannel case .groupCall: - //TODO:localize - text = "Everyone on Telegram can scan this code to join your group call." + text = self.presentationData.strings.InviteLink_QRCode_InfoGroupCall } case .chatFolder: title = self.presentationData.strings.InviteLink_QRCodeFolder_Title diff --git a/submodules/SettingsUI/Sources/Privacy and Security/SelectivePrivacySettingsController.swift b/submodules/SettingsUI/Sources/Privacy and Security/SelectivePrivacySettingsController.swift index bd4a4d56b3..a79f736255 100644 --- a/submodules/SettingsUI/Sources/Privacy and Security/SelectivePrivacySettingsController.swift +++ b/submodules/SettingsUI/Sources/Privacy and Security/SelectivePrivacySettingsController.swift @@ -1047,11 +1047,12 @@ private func selectivePrivacySettingsControllerEntries(presentationData: Present if let settingInfoText = settingInfoText { entries.append(.settingInfo(presentationData.theme, settingInfoText, settingInfoLink)) } - - entries.append(.phoneDiscoveryHeader(presentationData.theme, presentationData.strings.PrivacyPhoneNumberSettings_DiscoveryHeader)) - entries.append(.phoneDiscoveryEverybody(presentationData.theme, presentationData.strings.PrivacySettings_LastSeenEverybody, state.phoneDiscoveryEnabled != false)) - entries.append(.phoneDiscoveryMyContacts(presentationData.theme, presentationData.strings.PrivacySettings_LastSeenContacts, state.phoneDiscoveryEnabled == false)) - entries.append(.phoneDiscoveryInfo(presentationData.theme, state.phoneDiscoveryEnabled != false ? presentationData.strings.PrivacyPhoneNumberSettings_CustomPublicLink("+\(phoneNumber)").string : presentationData.strings.PrivacyPhoneNumberSettings_CustomDisabledHelp, phoneLink)) + if case .phoneNumber = kind { + entries.append(.phoneDiscoveryHeader(presentationData.theme, presentationData.strings.PrivacyPhoneNumberSettings_DiscoveryHeader)) + entries.append(.phoneDiscoveryEverybody(presentationData.theme, presentationData.strings.PrivacySettings_LastSeenEverybody, state.phoneDiscoveryEnabled != false)) + entries.append(.phoneDiscoveryMyContacts(presentationData.theme, presentationData.strings.PrivacySettings_LastSeenContacts, state.phoneDiscoveryEnabled == false)) + entries.append(.phoneDiscoveryInfo(presentationData.theme, state.phoneDiscoveryEnabled != false ? presentationData.strings.PrivacyPhoneNumberSettings_CustomPublicLink("+\(phoneNumber)").string : presentationData.strings.PrivacyPhoneNumberSettings_CustomDisabledHelp, phoneLink)) + } if case .voiceMessages = kind, !isPremium { diff --git a/submodules/TelegramCallsUI/Sources/CallController.swift b/submodules/TelegramCallsUI/Sources/CallController.swift index c667d45901..c7dd71d3fc 100644 --- a/submodules/TelegramCallsUI/Sources/CallController.swift +++ b/submodules/TelegramCallsUI/Sources/CallController.swift @@ -498,14 +498,12 @@ public final class CallController: ViewController { } static func openConferenceAddParticipant(context: AccountContext, disablePeerIds: [EnginePeer.Id], shareLink: (() -> Void)?, completion: @escaping ([(id: EnginePeer.Id, isVideo: Bool)]) -> Void) -> ViewController { - //TODO:localize let presentationData = context.sharedContext.currentPresentationData.with({ $0 }).withUpdated(theme: defaultDarkColorPresentationTheme) var options: [ContactListAdditionalOption] = [] var openShareLinkImpl: (() -> Void)? if shareLink != nil { - //TODO:localize - options.append(ContactListAdditionalOption(title: "Share Call Link", icon: .generic(UIImage(bundleImageName: "Contact List/LinkActionIcon")!), action: { + options.append(ContactListAdditionalOption(title: presentationData.strings.Call_ShareLink, icon: .generic(UIImage(bundleImageName: "Contact List/LinkActionIcon")!), action: { openShareLinkImpl?() }, clearHighlightAutomatically: false)) } @@ -515,11 +513,11 @@ public final class CallController: ViewController { updatedPresentationData: (initial: presentationData, signal: .single(presentationData)), mode: .generic, title: { strings in - //TODO:localize - return "Add Member" + return strings.Call_AddMemberTitle }, options: .single(options), displayCallIcons: true, + multipleSelection: .disabled, confirmation: { peer in switch peer { case let .peer(peer, _, _): diff --git a/submodules/TelegramCallsUI/Sources/PresentationCall.swift b/submodules/TelegramCallsUI/Sources/PresentationCall.swift index 41555bd8e4..c6b182ac82 100644 --- a/submodules/TelegramCallsUI/Sources/PresentationCall.swift +++ b/submodules/TelegramCallsUI/Sources/PresentationCall.swift @@ -765,8 +765,8 @@ public final class PresentationCallImpl: PresentationCall { self.localVideoEndpointId = nil self.remoteVideoEndpointId = nil - //TODO:localize - self.callKitIntegration?.updateCallIsConference(uuid: self.internalId, title: self.conferenceTitle ?? "Group Call") + let presentationData = self.context.sharedContext.currentPresentationData.with { $0 } + self.callKitIntegration?.updateCallIsConference(uuid: self.internalId, title: self.conferenceTitle ?? presentationData.strings.Call_GenericGroupCallTitle) } func internal_markAsCanBeRemoved() { diff --git a/submodules/TelegramCallsUI/Sources/PresentationGroupCall.swift b/submodules/TelegramCallsUI/Sources/PresentationGroupCall.swift index 4caf389cbc..3b8178798e 100644 --- a/submodules/TelegramCallsUI/Sources/PresentationGroupCall.swift +++ b/submodules/TelegramCallsUI/Sources/PresentationGroupCall.swift @@ -210,6 +210,11 @@ private final class PendingConferenceInvitationContext { case ringing } + enum InvitationError { + case generic + case privacy(peer: EnginePeer?) + } + private let engine: TelegramEngine private var requestDisposable: Disposable? private var stateDisposable: Disposable? @@ -218,19 +223,12 @@ private final class PendingConferenceInvitationContext { private var hadMessage: Bool = false private var didNotifyEnded: Bool = false - init(engine: TelegramEngine, reference: InternalGroupCallReference, peerId: PeerId, isVideo: Bool, onStateUpdated: @escaping (State) -> Void, onEnded: @escaping (Bool) -> Void) { + init(engine: TelegramEngine, reference: InternalGroupCallReference, peerId: PeerId, isVideo: Bool, onStateUpdated: @escaping (State) -> Void, onEnded: @escaping (Bool) -> Void, onError: @escaping (InvitationError) -> Void) { self.engine = engine - self.requestDisposable = (engine.calls.inviteConferenceCallParticipant(reference: reference, peerId: peerId, isVideo: isVideo).startStrict(next: { [weak self] messageId in + self.requestDisposable = ((engine.calls.inviteConferenceCallParticipant(reference: reference, peerId: peerId, isVideo: isVideo) |> deliverOnMainQueue).startStrict(next: { [weak self] messageId in guard let self else { return } - guard let messageId else { - if !self.didNotifyEnded { - self.didNotifyEnded = true - onEnded(false) - } - return - } self.messageId = messageId onStateUpdated(.ringing) @@ -296,6 +294,24 @@ private final class PendingConferenceInvitationContext { } } }) + }, error: { [weak self] error in + guard let self else { + return + } + + if !self.didNotifyEnded { + self.didNotifyEnded = true + onEnded(false) + } + + let mappedError: InvitationError + switch error { + case .privacy(let peer): + mappedError = .privacy(peer: peer) + default: + mappedError = .generic + } + onError(mappedError) })) } @@ -792,6 +808,8 @@ public final class PresentationGroupCallImpl: PresentationGroupCall { private let e2eContext: ConferenceCallE2EContext? + private var lastErrorAlertTimestamp: Double = 0.0 + init( accountContext: AccountContext, audioSession: ManagedAudioSession, @@ -841,6 +859,12 @@ public final class PresentationGroupCallImpl: PresentationGroupCall { self.isConference = isConference self.beginWithVideo = beginWithVideo self.keyPair = keyPair + + if self.isConference && conferenceSourceId == nil { + self.isMutedValue = .unmuted + self.isMutedPromise.set(self.isMutedValue) + self.stateValue.muteState = nil + } if let keyPair, let initialCall { self.e2eContext = ConferenceCallE2EContext( @@ -1742,6 +1766,15 @@ public final class PresentationGroupCallImpl: PresentationGroupCall { self.onMutedSpeechActivityDetected?(value) } }, isConference: self.isConference, audioIsActiveByDefault: audioIsActiveByDefault, isStream: self.isStream, sharedAudioDevice: self.sharedAudioContext?.audioDevice, encryptionContext: encryptionContext)) + + let isEffectivelyMuted: Bool + switch self.isMutedValue { + case let .muted(isPushToTalkActive): + isEffectivelyMuted = !isPushToTalkActive + case .unmuted: + isEffectivelyMuted = false + } + genericCallContext.setIsMuted(isEffectivelyMuted) } self.genericCallContext = genericCallContext @@ -1889,6 +1922,14 @@ public final class PresentationGroupCallImpl: PresentationGroupCall { } else { reference = .id(id: callInfo.id, accessHash: callInfo.accessHash) } + + let isEffectivelyMuted: Bool + switch self.isMutedValue { + case let .muted(isPushToTalkActive): + isEffectivelyMuted = !isPushToTalkActive + case .unmuted: + isEffectivelyMuted = false + } self.currentLocalSsrc = ssrc self.requestDisposable.set((self.accountContext.engine.calls.joinGroupCall( @@ -1896,7 +1937,7 @@ public final class PresentationGroupCallImpl: PresentationGroupCall { joinAs: self.joinAsPeerId, callId: callInfo.id, reference: reference, - preferMuted: true, + preferMuted: isEffectivelyMuted, joinPayload: joinPayload, peerAdminIds: peerAdminIds, inviteHash: self.invite, @@ -1962,7 +2003,11 @@ public final class PresentationGroupCallImpl: PresentationGroupCall { self.updateSessionState(internalState: .established(info: joinCallResult.callInfo, connectionMode: joinCallResult.connectionMode, clientParams: clientParams, localSsrc: ssrc, initialState: joinCallResult.state), audioSessionControl: self.audioSessionControl) - self.e2eContext?.begin() + if let e2eState = joinCallResult.e2eState { + self.e2eContext?.begin(initialState: e2eState) + } else { + self.e2eContext?.begin(initialState: nil) + } }, error: { [weak self] error in guard let self else { return @@ -3536,6 +3581,32 @@ public final class PresentationGroupCallImpl: PresentationGroupCall { onEnded: { success in didEndAlready = true onEnded?(success) + }, + onError: { [weak self] error in + guard let self else { + return + } + + let timestamp = CACurrentMediaTime() + if self.lastErrorAlertTimestamp > timestamp - 1.0 { + return + } + self.lastErrorAlertTimestamp = timestamp + + let presentationData = self.accountContext.sharedContext.currentPresentationData.with({ $0 }).withUpdated(theme: defaultDarkColorPresentationTheme) + + var errorText = presentationData.strings.Login_UnknownError + switch error { + case let .privacy(peer): + if let peer { + errorText = presentationData.strings.Call_PrivacyErrorMessage(peer.compactDisplayTitle).string + } + default: + break + } + self.accountContext.sharedContext.mainWindow?.present(standardTextAlertController(theme: AlertControllerTheme(presentationData: presentationData), title: nil, text: errorText, actions: [ + TextAlertAction(type: .genericAction, title: presentationData.strings.Common_OK, action: {}) + ]), on: .root, blockInteraction: false, completion: {}) } ) if !didEndAlready { diff --git a/submodules/TelegramCallsUI/Sources/VideoChatActionButtonComponent.swift b/submodules/TelegramCallsUI/Sources/VideoChatActionButtonComponent.swift index 5a68054ee1..5879d044a0 100644 --- a/submodules/TelegramCallsUI/Sources/VideoChatActionButtonComponent.swift +++ b/submodules/TelegramCallsUI/Sources/VideoChatActionButtonComponent.swift @@ -65,9 +65,9 @@ final class VideoChatActionButtonComponent: Component { } } - enum MicrophoneState { + enum MicrophoneState: Equatable { case connecting - case muted + case muted(forced: Bool) case unmuted case raiseHand case scheduled diff --git a/submodules/TelegramCallsUI/Sources/VideoChatEncryptionKeyComponent.swift b/submodules/TelegramCallsUI/Sources/VideoChatEncryptionKeyComponent.swift index 58d84e2d1b..83abd095f9 100644 --- a/submodules/TelegramCallsUI/Sources/VideoChatEncryptionKeyComponent.swift +++ b/submodules/TelegramCallsUI/Sources/VideoChatEncryptionKeyComponent.swift @@ -550,7 +550,7 @@ final class VideoChatEncryptionKeyComponent: Component { self.isUpdating = false } - #if DEBUG && true +#if DEBUG && false if self.component == nil { self.mockStateTimer = Foundation.Timer.scheduledTimer(withTimeInterval: 4.0, repeats: true, block: { [weak self] _ in guard let self else { @@ -614,11 +614,10 @@ final class VideoChatEncryptionKeyComponent: Component { ) } - //TODO:localize let collapsedTextSize = self.collapsedText.update( transition: .immediate, component: AnyComponent(MultilineTextComponent( - text: .plain(NSAttributedString(string: "End-to-end encrypted", font: Font.semibold(12.0), textColor: component.theme.list.itemPrimaryTextColor)) + text: .plain(NSAttributedString(string: component.strings.VideoChat_EncryptionKeyLabel, font: Font.semibold(12.0), textColor: component.theme.list.itemPrimaryTextColor)) )), environment: {}, containerSize: CGSize(width: 1000.0, height: 1000.0) @@ -627,7 +626,7 @@ final class VideoChatEncryptionKeyComponent: Component { let expandedTextSize = self.expandedText.update( transition: .immediate, component: AnyComponent(BalancedTextComponent( - text: .plain(NSAttributedString(string: "These four emojis represent the call's encryption key. They must match for all participants and change when someone joins or leaves.", font: Font.regular(12.0), textColor: component.theme.list.itemPrimaryTextColor)), + text: .plain(NSAttributedString(string: component.strings.VideoChat_EncryptionKeyText, font: Font.regular(12.0), textColor: component.theme.list.itemPrimaryTextColor)), maximumNumberOfLines: 0, lineSpacing: 0.3 )), @@ -638,7 +637,7 @@ final class VideoChatEncryptionKeyComponent: Component { let expandedButtonTextSize = self.expandedButtonText.update( transition: .immediate, component: AnyComponent(MultilineTextComponent( - text: .plain(NSAttributedString(string: "Close", font: Font.regular(17.0), textColor: component.theme.list.itemPrimaryTextColor)) + text: .plain(NSAttributedString(string: component.strings.VideoChat_EncryptionKeyDone, font: Font.regular(17.0), textColor: component.theme.list.itemPrimaryTextColor)) )), environment: {}, containerSize: CGSize(width: availableSize.width - expandedSideInset * 2.0, height: 1000.0) diff --git a/submodules/TelegramCallsUI/Sources/VideoChatMicButtonComponent.swift b/submodules/TelegramCallsUI/Sources/VideoChatMicButtonComponent.swift index 80c340ef08..6156b426d7 100644 --- a/submodules/TelegramCallsUI/Sources/VideoChatMicButtonComponent.swift +++ b/submodules/TelegramCallsUI/Sources/VideoChatMicButtonComponent.swift @@ -182,7 +182,7 @@ final class VideoChatMicButtonComponent: Component { enum Content: Equatable { case connecting - case muted + case muted(forced: Bool) case unmuted(pushToTalk: Bool) case raiseHand(isRaised: Bool) case scheduled(state: ScheduledState) @@ -263,9 +263,13 @@ final class VideoChatMicButtonComponent: Component { switch component.content { case .connecting, .unmuted, .raiseHand, .scheduled: self.beginTrackingWasPushToTalk = false - case .muted: - self.beginTrackingWasPushToTalk = true - component.updateUnmutedStateIsPushToTalk(true) + case let .muted(forced): + if forced { + self.beginTrackingWasPushToTalk = false + } else { + self.beginTrackingWasPushToTalk = true + component.updateUnmutedStateIsPushToTalk(true) + } } } @@ -291,8 +295,11 @@ final class VideoChatMicButtonComponent: Component { switch component.content { case .connecting: break - case .muted: - component.updateUnmutedStateIsPushToTalk(false) + case let .muted(forced): + if forced { + } else { + component.updateUnmutedStateIsPushToTalk(false) + } case .unmuted: if self.beginTrackingWasPushToTalk { if timestamp < self.beginTrackingTimestamp + 0.15 { @@ -340,8 +347,12 @@ final class VideoChatMicButtonComponent: Component { case .connecting: titleText = component.strings.VoiceChat_Connecting isEnabled = false - case .muted: - titleText = component.strings.VoiceChat_Unmute + case let .muted(forced): + if forced { + titleText = component.strings.VoiceChat_MutedByAdmin + } else { + titleText = component.strings.VoiceChat_Unmute + } case let .unmuted(isPushToTalk): titleText = isPushToTalk ? component.strings.VoiceChat_Live : component.strings.VoiceChat_Mute case let .raiseHand(isRaised): @@ -433,7 +444,9 @@ final class VideoChatMicButtonComponent: Component { context.fill(CGRect(origin: CGPoint(), size: size)) case .muted, .unmuted, .raiseHand, .scheduled: let colors: [UIColor] - if case .muted = component.content { + if case .muted(forced: true) = component.content { + colors = [UIColor(rgb: 0x3252EF), UIColor(rgb: 0xC64688)] + } else if case .muted(forced: false) = component.content { colors = [UIColor(rgb: 0x0080FF), UIColor(rgb: 0x00A1FE)] } else if case .raiseHand = component.content { colors = [UIColor(rgb: 0x3252EF), UIColor(rgb: 0xC64688)] @@ -606,7 +619,9 @@ final class VideoChatMicButtonComponent: Component { transition.setScale(view: blobView, scale: availableSize.width / 116.0) let blobsColor: UIColor - if case .muted = component.content { + if case .muted(forced: true) = component.content { + blobsColor = UIColor(rgb: 0x914BAD) + } else if case .muted(forced: false) = component.content { blobsColor = UIColor(rgb: 0x0086FF) } else if case .raiseHand = component.content { blobsColor = UIColor(rgb: 0x914BAD) @@ -657,7 +672,9 @@ final class VideoChatMicButtonComponent: Component { } let glowColor: UIColor - if case .muted = component.content { + if case .muted(forced: true) = component.content { + glowColor = UIColor(rgb: 0x3252EF) + } else if case .muted(forced: false) = component.content { glowColor = UIColor(rgb: 0x0086FF) } else if case .raiseHand = component.content { glowColor = UIColor(rgb: 0x3252EF) diff --git a/submodules/TelegramCallsUI/Sources/VideoChatParticipantsComponent.swift b/submodules/TelegramCallsUI/Sources/VideoChatParticipantsComponent.swift index de122e01a9..a354a1c543 100644 --- a/submodules/TelegramCallsUI/Sources/VideoChatParticipantsComponent.swift +++ b/submodules/TelegramCallsUI/Sources/VideoChatParticipantsComponent.swift @@ -1282,18 +1282,7 @@ final class VideoChatParticipantsComponent: Component { let invitedPeer = component.invitedPeers[i - self.listParticipants.count] participantPeerId = invitedPeer.peer.id - let subtitle: PeerListItemComponent.Subtitle - //TODO:localize - switch invitedPeer.state { - case .none: - subtitle = PeerListItemComponent.Subtitle(text: component.strings.VoiceChat_StatusInvited, color: .neutral) - case .connecting: - subtitle = PeerListItemComponent.Subtitle(text: "connecting...", color: .neutral) - case .requesting: - subtitle = PeerListItemComponent.Subtitle(text: "requesting...", color: .neutral) - case .ringing: - subtitle = PeerListItemComponent.Subtitle(text: "invited", color: .neutral) - } + let subtitle: PeerListItemComponent.Subtitle = PeerListItemComponent.Subtitle(text: component.strings.VoiceChat_StatusInvited, color: .neutral) let rightAccessoryComponent: AnyComponent = AnyComponent(VideoChatParticipantInvitedStatusComponent( theme: component.theme @@ -1861,11 +1850,10 @@ final class VideoChatParticipantsComponent: Component { let iconType: VideoChatListInviteComponent.Icon switch inviteOption.type { case let .invite(isMultiple): - //TODO:localize if isMultiple { inviteText = component.strings.VoiceChat_InviteMember } else { - inviteText = "Add Member" + inviteText = component.strings.VideoChat_InviteMember } iconType = .addUser case .shareLink: diff --git a/submodules/TelegramCallsUI/Sources/VideoChatScreen.swift b/submodules/TelegramCallsUI/Sources/VideoChatScreen.swift index 787ec7d39c..249521f415 100644 --- a/submodules/TelegramCallsUI/Sources/VideoChatScreen.swift +++ b/submodules/TelegramCallsUI/Sources/VideoChatScreen.swift @@ -685,9 +685,8 @@ final class VideoChatScreenComponent: Component { if let result { switch result { case .linkCopied: - //TODO:localize let presentationData = groupCall.accountContext.sharedContext.currentPresentationData.with { $0 } - self.environment?.controller()?.present(UndoOverlayController(presentationData: presentationData, content: .universal(animation: "anim_linkcopied", scale: 0.08, colors: ["info1.info1.stroke": UIColor.clear, "info2.info2.Fill": UIColor.clear], title: nil, text: "Call link copied.", customUndoText: nil, timeout: nil), elevatedLayout: false, animateInAsReplacement: false, action: { action in + self.environment?.controller()?.present(UndoOverlayController(presentationData: presentationData, content: .universal(animation: "anim_linkcopied", scale: 0.08, colors: ["info1.info1.stroke": UIColor.clear, "info2.info2.Fill": UIColor.clear], title: nil, text: presentationData.strings.CallList_ToastCallLinkCopied_Text, customUndoText: presentationData.strings.CallList_ToastCallLinkCopied_Action, timeout: nil), elevatedLayout: false, animateInAsReplacement: false, action: { action in return false }), in: .current) case .openCall: @@ -2038,11 +2037,10 @@ final class VideoChatScreenComponent: Component { maxTitleWidth -= 110.0 } - //TODO:localize let titleSize = self.title.update( transition: transition, component: AnyComponent(VideoChatTitleComponent( - title: self.callState?.title ?? self.peer?.debugDisplayTitle ?? "Group Call", + title: self.callState?.title ?? self.peer?.debugDisplayTitle ?? environment.strings.VideoChat_GroupCallTitle, status: idleTitleStatusText, isRecording: self.callState?.recordingStartTimestamp != nil, strings: environment.strings, @@ -2555,9 +2553,12 @@ final class VideoChatScreenComponent: Component { micButtonContent = .unmuted(pushToTalk: self.isPushToTalkActive) actionButtonMicrophoneState = .unmuted } else { - micButtonContent = .muted - actionButtonMicrophoneState = .muted + micButtonContent = .muted(forced: false) + actionButtonMicrophoneState = .muted(forced: false) } + } else if isConference { + micButtonContent = .muted(forced: true) + actionButtonMicrophoneState = .muted(forced: true) } else { micButtonContent = .raiseHand(isRaised: callState.raisedHand) actionButtonMicrophoneState = .raiseHand @@ -2708,6 +2709,18 @@ final class VideoChatScreenComponent: Component { } else if let expandedParticipantsVideoState = self.expandedParticipantsVideoState, !expandedParticipantsVideoState.isUIHidden { displayVideoControlButton = false } + if case .audio = videoControlButtonContent { + if let (availableOutputs, _) = self.audioOutputState { + if availableOutputs.count <= 0 { + displayVideoControlButton = false + } + } else { + displayVideoControlButton = false + } + } + if videoControlButtonContent == videoButtonContent { + displayVideoControlButton = false + } let videoControlButtonSize = self.videoControlButton.update( transition: transition, diff --git a/submodules/TelegramCallsUI/Sources/VideoChatScreenInviteMembers.swift b/submodules/TelegramCallsUI/Sources/VideoChatScreenInviteMembers.swift index 1fd32412b3..4d97fef81e 100644 --- a/submodules/TelegramCallsUI/Sources/VideoChatScreenInviteMembers.swift +++ b/submodules/TelegramCallsUI/Sources/VideoChatScreenInviteMembers.swift @@ -129,7 +129,6 @@ extension VideoChatScreenComponent.View { if let participant { dismissController?() - //TODO:release if groupCall.invitePeer(participant.peer.id, isVideo: false) { let text: String if case let .channel(channel) = self.peer, case .broadcast = channel.info { @@ -242,7 +241,6 @@ extension VideoChatScreenComponent.View { } dismissController?() - //TODO:release if groupCall.invitePeer(peer.id, isVideo: false) { let text: String if case let .channel(channel) = self.peer, case .broadcast = channel.info { @@ -315,7 +313,6 @@ extension VideoChatScreenComponent.View { } dismissController?() - //TODO:release if groupCall.invitePeer(peer.id, isVideo: false) { let text: String if case let .channel(channel) = self.peer, case .broadcast = channel.info { diff --git a/submodules/TelegramCallsUI/Sources/VoiceChatController.swift b/submodules/TelegramCallsUI/Sources/VoiceChatController.swift index 60cefcd87c..d3c7626b85 100644 --- a/submodules/TelegramCallsUI/Sources/VoiceChatController.swift +++ b/submodules/TelegramCallsUI/Sources/VoiceChatController.swift @@ -1256,7 +1256,6 @@ final class VoiceChatControllerImpl: ViewController, VoiceChatController { if let participant = participant { dismissController?() - //TODO:release if strongSelf.call.invitePeer(participant.peer.id, isVideo: false) { let text: String if let channel = strongSelf.peer as? TelegramChannel, case .broadcast = channel.info { @@ -1365,7 +1364,6 @@ final class VoiceChatControllerImpl: ViewController, VoiceChatController { } dismissController?() - //TODO:release if strongSelf.call.invitePeer(peer.id, isVideo: false) { let text: String if let channel = strongSelf.peer as? TelegramChannel, case .broadcast = channel.info { @@ -1434,7 +1432,6 @@ final class VoiceChatControllerImpl: ViewController, VoiceChatController { } dismissController?() - //TODO:release if strongSelf.call.invitePeer(peer.id, isVideo: false) { let text: String if let channel = strongSelf.peer as? TelegramChannel, case .broadcast = channel.info { diff --git a/submodules/TelegramCore/Sources/State/ConferenceCallE2EContext.swift b/submodules/TelegramCore/Sources/State/ConferenceCallE2EContext.swift index 31d81d6c05..5914833d9b 100644 --- a/submodules/TelegramCore/Sources/State/ConferenceCallE2EContext.swift +++ b/submodules/TelegramCore/Sources/State/ConferenceCallE2EContext.swift @@ -79,7 +79,7 @@ public final class ConferenceCallE2EContext { self.synchronizeRemovedParticipantsTimer?.invalidate() } - func begin() { + func begin(initialState: JoinGroupCallResult.E2EState?) { self.scheduledSynchronizeRemovedParticipantsAfterPoll = true self.synchronizeRemovedParticipantsTimer = Foundation.Timer.scheduledTimer(withTimeInterval: 10.0, repeats: true, block: { [weak self] _ in guard let self else { @@ -88,6 +88,13 @@ public final class ConferenceCallE2EContext { self.synchronizeRemovedParticipants() }) + if let initialState { + self.e2ePoll0Offset = initialState.subChain0.offset + self.e2ePoll1Offset = initialState.subChain1.offset + self.addE2EBlocks(blocks: initialState.subChain0.blocks, subChainId: 0) + self.addE2EBlocks(blocks: initialState.subChain1.blocks, subChainId: 1) + } + self.e2ePoll(subChainId: 0) self.e2ePoll(subChainId: 1) } @@ -182,7 +189,6 @@ public final class ConferenceCallE2EContext { self.e2eEncryptionKeyHashValue.set(outEmoji.isEmpty ? nil : outEmoji) for outBlock in outBlocks { - //TODO:release queue let _ = self.engine.calls.sendConferenceCallBroadcast(callId: self.callId, accessHash: self.accessHash, block: outBlock).startStandalone() } } @@ -400,7 +406,6 @@ public final class ConferenceCallE2EContext { } func kickPeer(id: EnginePeer.Id) { - //TODO:release if !self.pendingKickPeers.contains(id) { self.pendingKickPeers.append(id) @@ -426,9 +431,9 @@ public final class ConferenceCallE2EContext { }) } - public func begin() { + public func begin(initialState: JoinGroupCallResult.E2EState?) { self.impl.with { impl in - impl.begin() + impl.begin(initialState: initialState) } } diff --git a/submodules/TelegramCore/Sources/TelegramEngine/Calls/GroupCalls.swift b/submodules/TelegramCore/Sources/TelegramEngine/Calls/GroupCalls.swift index 3310d935b2..755d84711b 100644 --- a/submodules/TelegramCore/Sources/TelegramEngine/Calls/GroupCalls.swift +++ b/submodules/TelegramCore/Sources/TelegramEngine/Calls/GroupCalls.swift @@ -587,11 +587,22 @@ public struct JoinGroupCallResult { case rtc case broadcast(isExternalStream: Bool) } + + public struct E2EState { + public let subChain0: (offset: Int, blocks: [Data]) + public let subChain1: (offset: Int, blocks: [Data]) + + public init(subChain0: (offset: Int, blocks: [Data]), subChain1: (offset: Int, blocks: [Data])) { + self.subChain0 = subChain0 + self.subChain1 = subChain1 + } + } public var callInfo: GroupCallInfo public var state: GroupCallParticipantsContext.State public var connectionMode: ConnectionMode public var jsonParams: String + public var e2eState: E2EState? } public class JoinGroupCallE2E { @@ -791,7 +802,7 @@ func _internal_joinGroupCall(account: Account, peerId: PeerId?, joinAs: PeerId?, connectionMode = .broadcast(isExternalStream: false) } - return account.postbox.transaction { transaction -> JoinGroupCallResult in + return account.postbox.transaction { transaction -> Signal in if let peerId { transaction.updatePeerCachedData(peerIds: Set([peerId]), update: { _, cachedData -> CachedPeerData? in if let cachedData = cachedData as? CachedChannelData { @@ -806,6 +817,9 @@ func _internal_joinGroupCall(account: Account, peerId: PeerId?, joinAs: PeerId?, var state = state + var e2eSubChain1State: (offset: Int, blocks: [Data])? + var e2eSubChain0State: (offset: Int, blocks: [Data])? + for update in updates.allUpdates { switch update { case let .updateGroupCallParticipants(_, participants, _): @@ -852,21 +866,41 @@ func _internal_joinGroupCall(account: Account, peerId: PeerId?, joinAs: PeerId?, } } } + case let .updateGroupCallChainBlocks(_, subChainId, blocks, nextOffset): + if subChainId == 0 { + e2eSubChain0State = (offset: Int(nextOffset), blocks: blocks.map { $0.makeData() }) + } else { + e2eSubChain1State = (offset: Int(nextOffset), blocks: blocks.map { $0.makeData() }) + } default: break } } + + var e2eState: JoinGroupCallResult.E2EState? + if let e2eSubChain0State, let e2eSubChain1State { + e2eState = JoinGroupCallResult.E2EState( + subChain0: e2eSubChain0State, + subChain1: e2eSubChain1State + ) + } + + if generateE2E != nil && e2eState == nil { + return .fail(.error(.generic)) + } state.participants.sort(by: { GroupCallParticipantsContext.Participant.compare(lhs: $0, rhs: $1, sortAscending: state.sortAscending) }) - return JoinGroupCallResult( + return .single(JoinGroupCallResult( callInfo: parsedCall, state: state, connectionMode: connectionMode, - jsonParams: parsedClientParams - ) + jsonParams: parsedClientParams, + e2eState: e2eState + )) } |> castError(InternalJoinError.self) + |> switchToLatest } } } @@ -882,13 +916,19 @@ func _internal_joinGroupCall(account: Account, peerId: PeerId?, joinAs: PeerId?, } } -func _internal_inviteConferenceCallParticipant(account: Account, reference: InternalGroupCallReference, peerId: EnginePeer.Id, isVideo: Bool) -> Signal { +public enum InviteConferenceCallParticipantError { + case generic + case privacy(peer: EnginePeer?) +} + +func _internal_inviteConferenceCallParticipant(account: Account, reference: InternalGroupCallReference, peerId: EnginePeer.Id, isVideo: Bool) -> Signal { return account.postbox.transaction { transaction -> Api.InputUser? in return transaction.getPeer(peerId).flatMap(apiInputUser) } - |> mapToSignal { inputPeer -> Signal in + |> castError(InviteConferenceCallParticipantError.self) + |> mapToSignal { inputPeer -> Signal in guard let inputPeer else { - return .complete() + return .fail(.generic) } var flags: Int32 = 0 @@ -897,17 +937,26 @@ func _internal_inviteConferenceCallParticipant(account: Account, reference: Inte } return account.network.request(Api.functions.phone.inviteConferenceCallParticipant(flags: flags, call: reference.apiInputGroupCall, userId: inputPeer)) |> map(Optional.init) - |> `catch` { _ -> Signal in - return .single(nil) + |> `catch` { error -> Signal in + if error.errorDescription == "USER_PRIVACY_RESTRICTED" { + return account.postbox.transaction { transaction -> InviteConferenceCallParticipantError in + return .privacy(peer: transaction.getPeer(peerId).flatMap(EnginePeer.init)) + } + |> castError(InviteConferenceCallParticipantError.self) + |> mapToSignal { error -> Signal in + return .fail(error) + } + } + return .fail(.generic) } - |> mapToSignal { result -> Signal in + |> mapToSignal { result -> Signal in if let result { account.stateManager.addUpdates(result) if let message = result.messageIds.first { return .single(message) } } - return .single(nil) + return .fail(.generic) } } } diff --git a/submodules/TelegramCore/Sources/TelegramEngine/Calls/TelegramEngineCalls.swift b/submodules/TelegramCore/Sources/TelegramEngine/Calls/TelegramEngineCalls.swift index bc107740dd..77fc5f7ffc 100644 --- a/submodules/TelegramCore/Sources/TelegramEngine/Calls/TelegramEngineCalls.swift +++ b/submodules/TelegramCore/Sources/TelegramEngine/Calls/TelegramEngineCalls.swift @@ -109,7 +109,7 @@ public extension TelegramEngine { return _internal_sendConferenceCallBroadcast(account: self.account, callId: callId, accessHash: accessHash, block: block) } - public func inviteConferenceCallParticipant(reference: InternalGroupCallReference, peerId: EnginePeer.Id, isVideo: Bool) -> Signal { + public func inviteConferenceCallParticipant(reference: InternalGroupCallReference, peerId: EnginePeer.Id, isVideo: Bool) -> Signal { return _internal_inviteConferenceCallParticipant(account: self.account, reference: reference, peerId: peerId, isVideo: isVideo) } diff --git a/submodules/TelegramPresentationData/Sources/Resources/PresentationResourceKey.swift b/submodules/TelegramPresentationData/Sources/Resources/PresentationResourceKey.swift index 6afe54e1d7..2dea72f9a3 100644 --- a/submodules/TelegramPresentationData/Sources/Resources/PresentationResourceKey.swift +++ b/submodules/TelegramPresentationData/Sources/Resources/PresentationResourceKey.swift @@ -336,6 +336,8 @@ public enum PresentationResourceKey: Int32 { case peerStatusLockedImage case expandDownArrowImage case expandSmallDownArrowImage + + case callListCallIcon } public enum ChatExpiredStoryIndicatorType: Hashable { diff --git a/submodules/TelegramPresentationData/Sources/Resources/PresentationResourcesRootController.swift b/submodules/TelegramPresentationData/Sources/Resources/PresentationResourcesRootController.swift index 0e4915686b..d486af773d 100644 --- a/submodules/TelegramPresentationData/Sources/Resources/PresentationResourcesRootController.swift +++ b/submodules/TelegramPresentationData/Sources/Resources/PresentationResourcesRootController.swift @@ -199,4 +199,10 @@ public struct PresentationResourcesRootController { return generateTintedImage(image: UIImage(bundleImageName: "Peer Info/SortIcon"), color: .white) }) } + + public static func callListCallIcon(_ theme: PresentationTheme) -> UIImage? { + return theme.image(PresentationResourceKey.callListCallIcon.rawValue, { theme in + return generateTintedImage(image: UIImage(bundleImageName: "Call List/NewCallListIcon"), color: theme.rootController.navigationBar.accentTextColor) + }) + } } diff --git a/submodules/TelegramStringFormatting/Sources/ServiceMessageStrings.swift b/submodules/TelegramStringFormatting/Sources/ServiceMessageStrings.swift index f48614ca94..f2c557eb9a 100644 --- a/submodules/TelegramStringFormatting/Sources/ServiceMessageStrings.swift +++ b/submodules/TelegramStringFormatting/Sources/ServiceMessageStrings.swift @@ -616,9 +616,27 @@ public func universalServiceMessageString(presentationData: (PresentationTheme, } } attributedString = NSAttributedString(string: titleString, font: titleFont, textColor: primaryTextColor) - case .conferenceCall: - //TODO:localize - let titleString = "Group call" + case let .conferenceCall(conferenceCall): + var titleString: String + let incoming = message.flags.contains(.Incoming) + + let missedTimeout: Int32 = 30 + let currentTime = Int32(Date().timeIntervalSince1970) + + if conferenceCall.flags.contains(.isMissed) { + titleString = strings.Chat_CallMessage_DeclinedGroupCall + } else if message.timestamp < currentTime - missedTimeout { + titleString = strings.Chat_CallMessage_MissedGroupCall + } else if conferenceCall.duration != nil { + titleString = strings.Chat_CallMessage_CancelledGroupCall + } else { + if incoming { + titleString = strings.Chat_CallMessage_IncomingGroupCall + } else { + titleString = strings.Chat_CallMessage_OutgoingGroupCall + } + } + attributedString = NSAttributedString(string: titleString, font: titleFont, textColor: primaryTextColor) case let .groupPhoneCall(_, _, scheduleDate, duration): if let scheduleDate = scheduleDate { diff --git a/submodules/TelegramUI/Components/Chat/ChatMessageCallBubbleContentNode/Sources/ChatMessageCallBubbleContentNode.swift b/submodules/TelegramUI/Components/Chat/ChatMessageCallBubbleContentNode/Sources/ChatMessageCallBubbleContentNode.swift index 03136f8bde..29f242f634 100644 --- a/submodules/TelegramUI/Components/Chat/ChatMessageCallBubbleContentNode/Sources/ChatMessageCallBubbleContentNode.swift +++ b/submodules/TelegramUI/Components/Chat/ChatMessageCallBubbleContentNode/Sources/ChatMessageCallBubbleContentNode.swift @@ -153,8 +153,7 @@ public class ChatMessageCallBubbleContentNode: ChatMessageBubbleContentNode { callDuration = conferenceCall.duration if conferenceCall.otherParticipants.count > 0 { - //TODO:localize - peopleTextString = "\(conferenceCall.otherParticipants.count + 1) people" + peopleTextString = item.presentationData.strings.Chat_CallMessage_GroupCallParticipantCount(Int32(conferenceCall.otherParticipants.count + 1)) if let peer = item.message.author { peopleAvatars.append(peer) } @@ -165,9 +164,8 @@ public class ChatMessageCallBubbleContentNode: ChatMessageBubbleContentNode { } } - //TODO:localize let missedTimeout: Int32 - #if DEBUG + #if DEBUG && false missedTimeout = 5 #else missedTimeout = 30 @@ -175,16 +173,16 @@ public class ChatMessageCallBubbleContentNode: ChatMessageBubbleContentNode { let currentTime = Int32(Date().timeIntervalSince1970) if conferenceCall.flags.contains(.isMissed) { - titleString = "Declined Group Call" + titleString = item.presentationData.strings.Chat_CallMessage_DeclinedGroupCall } else if item.message.timestamp < currentTime - missedTimeout { - titleString = "Missed Group Call" + titleString = item.presentationData.strings.Chat_CallMessage_MissedGroupCall } else if conferenceCall.duration != nil { - titleString = "Cancelled Group Call" + titleString = item.presentationData.strings.Chat_CallMessage_CancelledGroupCall } else { if incoming { - titleString = "Incoming Group Call" + titleString = item.presentationData.strings.Chat_CallMessage_IncomingGroupCall } else { - titleString = "Outgoing Group Call" + titleString = item.presentationData.strings.Chat_CallMessage_OutgoingGroupCall } updateConferenceTimerEndTimeout = (item.message.timestamp + missedTimeout) - currentTime } @@ -280,7 +278,7 @@ public class ChatMessageCallBubbleContentNode: ChatMessageBubbleContentNode { var avatarsWidth: CGFloat = 0.0 if !peopleAvatars.isEmpty { avatarsWidth += avatarsLeftInset - avatarsWidth += 1.0 * peopleAvatarSize + CGFloat(peopleAvatars.count - 1) * peopleAvatarSpacing + avatarsWidth += 1.0 * peopleAvatarSize + CGFloat(min(3, peopleAvatars.count) - 1) * peopleAvatarSpacing avatarsWidth += avatarsRightInset labelsWidth += avatarsWidth } diff --git a/submodules/TelegramUI/Components/Chat/ChatMessageWebpageBubbleContentNode/Sources/ChatMessageWebpageBubbleContentNode.swift b/submodules/TelegramUI/Components/Chat/ChatMessageWebpageBubbleContentNode/Sources/ChatMessageWebpageBubbleContentNode.swift index bc905b9149..70025dff94 100644 --- a/submodules/TelegramUI/Components/Chat/ChatMessageWebpageBubbleContentNode/Sources/ChatMessageWebpageBubbleContentNode.swift +++ b/submodules/TelegramUI/Components/Chat/ChatMessageWebpageBubbleContentNode/Sources/ChatMessageWebpageBubbleContentNode.swift @@ -475,8 +475,7 @@ public final class ChatMessageWebpageBubbleContentNode: ChatMessageBubbleContent text = nil entities = nil case "telegram_call": - //TODO:localize - actionTitle = "JOIN GROUP CALL" + actionTitle = item.presentationData.strings.Chat_ViewGroupCall default: break } diff --git a/submodules/TelegramUI/Components/JoinSubjectScreen/Sources/JoinSubjectScreen.swift b/submodules/TelegramUI/Components/JoinSubjectScreen/Sources/JoinSubjectScreen.swift index 5f03c035fe..042be113c0 100644 --- a/submodules/TelegramUI/Components/JoinSubjectScreen/Sources/JoinSubjectScreen.swift +++ b/submodules/TelegramUI/Components/JoinSubjectScreen/Sources/JoinSubjectScreen.swift @@ -490,7 +490,7 @@ private final class JoinSubjectScreenComponent: Component { contentHeight += 31.0 titleString = group.title - subtitleString = group.isPublic ? "public group" : "private group" + subtitleString = group.isPublic ? environment.strings.Invitation_PublicGroup : environment.strings.Invitation_PrivateGroup descriptionTextString = group.about previewPeers = group.members @@ -528,10 +528,9 @@ private final class JoinSubjectScreenComponent: Component { } contentHeight += peerAvatarSize.height + 21.0 case let .groupCall(groupCall): - //TODO:localize - titleString = "Group Call" + titleString = environment.strings.Invitation_GroupCall subtitleString = nil - descriptionTextString = "You are invited to join a group call." + descriptionTextString = environment.strings.Invitation_GroupCall_Text previewPeers = groupCall.members totalMemberCount = groupCall.totalMemberCount @@ -691,12 +690,11 @@ private final class JoinSubjectScreenComponent: Component { if !previewPeers.isEmpty { contentHeight += 11.0 - //TODO:localize let previewPeersString: String switch component.mode { case .group: if previewPeers.count == 1 { - previewPeersString = "**\(previewPeers[0].compactDisplayTitle)** already joined this group." + previewPeersString = environment.strings.Invitation_Group_AlreadyJoinedSingle(previewPeers[0].compactDisplayTitle).string } else { let firstPeers = previewPeers.prefix(upTo: 2) let peersTextArray = firstPeers.map { "**\($0.compactDisplayTitle)**" } @@ -717,14 +715,14 @@ private final class JoinSubjectScreenComponent: Component { } } if totalMemberCount > firstPeers.count { - previewPeersString = "\(peersText) and **\(totalMemberCount - firstPeers.count)** other people already joined this group." + previewPeersString = environment.strings.Invitation_Group_AlreadyJoinedMultipleWithCount(Int32(totalMemberCount - firstPeers.count)).replacingOccurrences(of: "{}", with: peersText) } else { - previewPeersString = "\(peersText) already joined this group." + previewPeersString = environment.strings.Invitation_Group_AlreadyJoinedMultiple(peersText).string } } case .groupCall: if previewPeers.count == 1 { - previewPeersString = "**\(previewPeers[0].compactDisplayTitle)** already joined this call." + previewPeersString = environment.strings.Invitation_GroupCall_AlreadyJoinedSingle(previewPeers[0].compactDisplayTitle).string } else { let firstPeers = previewPeers.prefix(upTo: 2) let peersTextArray = firstPeers.map { "**\($0.compactDisplayTitle)**" } @@ -745,9 +743,9 @@ private final class JoinSubjectScreenComponent: Component { } } if totalMemberCount > firstPeers.count { - previewPeersString = "\(peersText) and **\(totalMemberCount - firstPeers.count)** other people already joined this call." + previewPeersString = environment.strings.Invitation_GroupCall_AlreadyJoinedMultipleWithCount(Int32(totalMemberCount - firstPeers.count)).replacingOccurrences(of: "{}", with: peersText) } else { - previewPeersString = "\(peersText) already joined this call." + previewPeersString = environment.strings.Invitation_GroupCall_AlreadyJoinedMultiple(peersText).string } } } @@ -854,8 +852,7 @@ private final class JoinSubjectScreenComponent: Component { case .group: actionButtonTitle = environment.strings.Invitation_JoinGroup case .groupCall: - //TODO:localize - actionButtonTitle = "Join Group Call" + actionButtonTitle = environment.strings.Invitation_JoinGroupCall } let actionButtonSize = self.actionButton.update( transition: transition, diff --git a/submodules/TelegramUI/Components/PeerInfo/PeerInfoScreen/Sources/PeerInfoScreen.swift b/submodules/TelegramUI/Components/PeerInfo/PeerInfoScreen/Sources/PeerInfoScreen.swift index fabc13e616..ebd3998789 100644 --- a/submodules/TelegramUI/Components/PeerInfo/PeerInfoScreen/Sources/PeerInfoScreen.swift +++ b/submodules/TelegramUI/Components/PeerInfo/PeerInfoScreen/Sources/PeerInfoScreen.swift @@ -11118,7 +11118,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro giftsContext?.updateSorting(sorting == .date ? .value : .date) }))) - if hasPinnedGifts && hasVisibility { + if hasPinnedGifts { items.append(.action(ContextMenuActionItem(text: strings.PeerInfo_Gifts_Reorder, icon: { theme in return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/ReorderItems"), color: theme.contextMenu.primaryColor) }, action: { _, f in diff --git a/submodules/TelegramUI/Components/PeerSelectionController/Sources/PeerSelectionControllerNode.swift b/submodules/TelegramUI/Components/PeerSelectionController/Sources/PeerSelectionControllerNode.swift index 1f027a0b52..bf71406a8c 100644 --- a/submodules/TelegramUI/Components/PeerSelectionController/Sources/PeerSelectionControllerNode.swift +++ b/submodules/TelegramUI/Components/PeerSelectionController/Sources/PeerSelectionControllerNode.swift @@ -1330,7 +1330,7 @@ final class PeerSelectionControllerNode: ASDisplayNode { if self.hasGlobalSearch { categories.insert(.global) } - self.searchDisplayController = SearchDisplayController(presentationData: self.presentationData, contentNode: ContactsSearchContainerNode(context: self.context, updatedPresentationData: self.updatedPresentationData, onlyWriteable: true, categories: categories, addContact: nil, openPeer: { [weak self] peer in + self.searchDisplayController = SearchDisplayController(presentationData: self.presentationData, contentNode: ContactsSearchContainerNode(context: self.context, updatedPresentationData: self.updatedPresentationData, onlyWriteable: true, categories: categories, addContact: nil, openPeer: { [weak self] peer, _ in if let strongSelf = self { var updated = false var count = 0 diff --git a/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryItemSetContainerViewSendMessage.swift b/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryItemSetContainerViewSendMessage.swift index 3f256ea534..2979941dea 100644 --- a/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryItemSetContainerViewSendMessage.swift +++ b/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryItemSetContainerViewSendMessage.swift @@ -1722,7 +1722,7 @@ final class StoryItemSetContainerSendMessage { case .contact: let theme = component.theme let updatedPresentationData: (initial: PresentationData, signal: Signal) = (component.context.sharedContext.currentPresentationData.with({ $0 }).withUpdated(theme: theme), component.context.sharedContext.presentationData |> map { $0.withUpdated(theme: theme) }) - let contactsController = component.context.sharedContext.makeContactSelectionController(ContactSelectionControllerParams(context: component.context, updatedPresentationData: updatedPresentationData, title: { $0.Contacts_Title }, displayDeviceContacts: true, multipleSelection: true)) + let contactsController = component.context.sharedContext.makeContactSelectionController(ContactSelectionControllerParams(context: component.context, updatedPresentationData: updatedPresentationData, title: { $0.Contacts_Title }, displayDeviceContacts: true, multipleSelection: .always)) contactsController.presentScheduleTimePicker = { [weak self, weak view] completion in guard let self, let view else { return diff --git a/submodules/TelegramUI/Images.xcassets/Call List/NewCallListIcon.imageset/Contents.json b/submodules/TelegramUI/Images.xcassets/Call List/NewCallListIcon.imageset/Contents.json new file mode 100644 index 0000000000..91489efbe6 --- /dev/null +++ b/submodules/TelegramUI/Images.xcassets/Call List/NewCallListIcon.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "newcall_30.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/submodules/TelegramUI/Images.xcassets/Call List/NewCallListIcon.imageset/newcall_30.pdf b/submodules/TelegramUI/Images.xcassets/Call List/NewCallListIcon.imageset/newcall_30.pdf new file mode 100644 index 0000000000..4a915649db Binary files /dev/null and b/submodules/TelegramUI/Images.xcassets/Call List/NewCallListIcon.imageset/newcall_30.pdf differ diff --git a/submodules/TelegramUI/Sources/AppDelegate.swift b/submodules/TelegramUI/Sources/AppDelegate.swift index 5184a47089..299138d62f 100644 --- a/submodules/TelegramUI/Sources/AppDelegate.swift +++ b/submodules/TelegramUI/Sources/AppDelegate.swift @@ -1977,6 +1977,22 @@ private func extractAccountManagerState(records: AccountRecordsView take(1) + |> deliverOnMainQueue).start(next: { sharedApplicationContext in + strings = sharedApplicationContext.sharedContext.currentPresentationData.with { $0.strings } + }) + + let displayTitle: String if let memberCountString = payloadJson["member_count"] as? String, let memberCount = Int(memberCountString) { - if memberCount == 1 { - displayTitle.append(" and 1 other") - } else { - displayTitle.append(" and \(memberCount) others") - } + displayTitle = strings.Call_IncomingGroupCallTitle_Multiple(Int32(memberCount)).replacingOccurrences(of: "{}", with: fromTitle) + } else { + displayTitle = strings.Call_IncomingGroupCallTitle_Single(fromTitle).string } callKitIntegration.reportIncomingCall( diff --git a/submodules/TelegramUI/Sources/ChatController.swift b/submodules/TelegramUI/Sources/ChatController.swift index f09798f46f..7bf2eaaf26 100644 --- a/submodules/TelegramUI/Sources/ChatController.swift +++ b/submodules/TelegramUI/Sources/ChatController.swift @@ -2898,7 +2898,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G return } - if let currentGroupCallController = self.context.sharedContext as? VoiceChatController, case let .group(groupCall) = currentGroupCallController.call, let currentCallId = groupCall.callId, currentCallId == conferenceCall.callId { + if let currentGroupCallController = self.context.sharedContext.currentGroupCallController as? VoiceChatController, case let .group(groupCall) = currentGroupCallController.call, let currentCallId = groupCall.callId, currentCallId == conferenceCall.callId { self.context.sharedContext.navigateToCurrentCall() return } @@ -2932,8 +2932,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G self.context.sharedContext.openCreateGroupCallUI(context: self.context, peerIds: conferenceCall.otherParticipants, parentController: self) default: let presentationData = self.context.sharedContext.currentPresentationData.with { $0 } - //TODO:localize - self.present(textAlertController(context: self.context, title: nil, text: "An error occurred", actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {})]), in: .window(.root)) + self.present(textAlertController(context: self.context, title: nil, text: presentationData.strings.Login_UnknownError, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {})]), in: .window(.root)) } }) }, longTap: { [weak self] action, params in @@ -7513,17 +7512,20 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G navigationController.pushViewController(self, animated: false) let updatedLayout = self.validLayout - let updatedFrame = self.view.frame if let initialLayout, let updatedLayout, transition.isAnimated { let initialView = self.view.superview + let updatedFrame = self.view.convert(self.view.bounds, to: navigationController.view) navigationController.view.addSubview(self.view) self.view.clipsToBounds = true self.view.frame = initialFrame self.containerLayoutUpdated(initialLayout, transition: .immediate) self.containerLayoutUpdated(updatedLayout, transition: transition) - + self.chatDisplayNode.historyNode.layer.animateScaleX(from: initialLayout.size.width / updatedLayout.size.width, to: 1.0, duration: 0.4, timingFunction: kCAMediaTimingFunctionSpring) + self.chatDisplayNode.historyNode.layer.animatePosition(from: CGPoint(x: (updatedLayout.size.width - initialLayout.size.width) / 2.0, y: 0.0), to: .zero, duration: 0.4, timingFunction: kCAMediaTimingFunctionSpring, additive: true) + self.chatDisplayNode.inputPanelBackgroundNode.layer.removeAllAnimations() + self.chatDisplayNode.inputPanelBackgroundNode.layer.animatePosition(from: CGPoint(x: 0.0, y: self.chatDisplayNode.inputPanelNode?.frame.height ?? 45.0), to: .zero, duration: 0.4, timingFunction: kCAMediaTimingFunctionSpring, additive: true) self.view.layer.animate(from: 14.0, to: updatedLayout.deviceMetrics.screenCornerRadius, keyPath: "cornerRadius", timingFunction: kCAMediaTimingFunctionSpring, duration: 0.4) transition.updateFrame(view: self.view, frame: updatedFrame, completion: { _ in diff --git a/submodules/TelegramUI/Sources/ChatControllerNode.swift b/submodules/TelegramUI/Sources/ChatControllerNode.swift index d9f6f31874..169a288c11 100644 --- a/submodules/TelegramUI/Sources/ChatControllerNode.swift +++ b/submodules/TelegramUI/Sources/ChatControllerNode.swift @@ -190,7 +190,7 @@ class ChatControllerNode: ASDisplayNode, ASScrollViewDelegate { let inputPanelContainerNode: ChatInputPanelContainer private let inputPanelOverlayNode: SparseNode private let inputPanelClippingNode: SparseNode - private let inputPanelBackgroundNode: NavigationBackgroundNode + let inputPanelBackgroundNode: NavigationBackgroundNode private var navigationBarBackgroundContent: WallpaperBubbleBackgroundNode? private var inputPanelBackgroundContent: WallpaperBubbleBackgroundNode? @@ -1880,9 +1880,9 @@ class ChatControllerNode: ASDisplayNode, ASScrollViewDelegate { displayMode = .aspectFit } else if case .compact = layout.metrics.widthClass { if layout.size.width < layout.size.height && layout.size.height < layout.deviceMetrics.screenSize.height { - wallpaperBounds.size.height = layout.deviceMetrics.screenSize.height + wallpaperBounds.size = layout.deviceMetrics.screenSize } else if layout.size.width > layout.size.height && layout.size.height < layout.deviceMetrics.screenSize.width { - wallpaperBounds.size.height = layout.deviceMetrics.screenSize.width + wallpaperBounds.size = layout.deviceMetrics.screenSize } } self.backgroundNode.updateLayout(size: wallpaperBounds.size, displayMode: displayMode, transition: transition) @@ -2296,13 +2296,21 @@ class ChatControllerNode: ASDisplayNode, ASScrollViewDelegate { self.navigateButtons.update(rect: apparentNavigateButtonsFrame, within: layout.size, transition: transition) if let titleAccessoryPanelNode = self.titleAccessoryPanelNode, let titleAccessoryPanelFrame, !titleAccessoryPanelNode.frame.equalTo(titleAccessoryPanelFrame) { + let previousFrame = titleAccessoryPanelNode.frame titleAccessoryPanelNode.frame = titleAccessoryPanelFrame - transition.animatePositionAdditive(node: titleAccessoryPanelNode, offset: CGPoint(x: 0.0, y: -titleAccessoryPanelFrame.height)) + if transition.isAnimated && previousFrame.width != titleAccessoryPanelFrame.width { + } else { + transition.animatePositionAdditive(node: titleAccessoryPanelNode, offset: CGPoint(x: 0.0, y: -titleAccessoryPanelFrame.height)) + } } if let chatTranslationPanel = self.chatTranslationPanel, let translationPanelFrame, !chatTranslationPanel.frame.equalTo(translationPanelFrame) { + let previousFrame = chatTranslationPanel.frame chatTranslationPanel.frame = translationPanelFrame - transition.animatePositionAdditive(node: chatTranslationPanel, offset: CGPoint(x: 0.0, y: -translationPanelFrame.height)) + if transition.isAnimated && previousFrame.width != translationPanelFrame.width { + } else { + transition.animatePositionAdditive(node: chatTranslationPanel, offset: CGPoint(x: 0.0, y: -translationPanelFrame.height)) + } } if let chatImportStatusPanel = self.chatImportStatusPanel, let importStatusPanelFrame, !chatImportStatusPanel.frame.equalTo(importStatusPanelFrame) { diff --git a/submodules/TelegramUI/Sources/ChatControllerOpenAttachmentMenu.swift b/submodules/TelegramUI/Sources/ChatControllerOpenAttachmentMenu.swift index 7f6a694b9b..94670977dc 100644 --- a/submodules/TelegramUI/Sources/ChatControllerOpenAttachmentMenu.swift +++ b/submodules/TelegramUI/Sources/ChatControllerOpenAttachmentMenu.swift @@ -424,7 +424,7 @@ extension ChatControllerImpl { let _ = currentLocationController.swap(controller) }) case .contact: - let contactsController = ContactSelectionControllerImpl(ContactSelectionControllerParams(context: strongSelf.context, updatedPresentationData: strongSelf.updatedPresentationData, title: { $0.Contacts_Title }, displayDeviceContacts: true, multipleSelection: true, requirePhoneNumbers: true)) + let contactsController = ContactSelectionControllerImpl(ContactSelectionControllerParams(context: strongSelf.context, updatedPresentationData: strongSelf.updatedPresentationData, title: { $0.Contacts_Title }, displayDeviceContacts: true, multipleSelection: .always, requirePhoneNumbers: true)) contactsController.presentScheduleTimePicker = { [weak self] completion in if let strongSelf = self { strongSelf.presentScheduleTimePicker(completion: completion) @@ -1620,7 +1620,7 @@ extension ChatControllerImpl { } func presentContactPicker() { - let contactsController = ContactSelectionControllerImpl(ContactSelectionControllerParams(context: self.context, updatedPresentationData: self.updatedPresentationData, title: { $0.Contacts_Title }, displayDeviceContacts: true, multipleSelection: true)) + let contactsController = ContactSelectionControllerImpl(ContactSelectionControllerParams(context: self.context, updatedPresentationData: self.updatedPresentationData, title: { $0.Contacts_Title }, displayDeviceContacts: true, multipleSelection: .always)) contactsController.navigationPresentation = .modal self.chatDisplayNode.dismissInput() self.effectiveNavigationController?.pushViewController(contactsController) diff --git a/submodules/TelegramUI/Sources/ComposeControllerNode.swift b/submodules/TelegramUI/Sources/ComposeControllerNode.swift index 6bb6a6b24b..20ec24de5b 100644 --- a/submodules/TelegramUI/Sources/ComposeControllerNode.swift +++ b/submodules/TelegramUI/Sources/ComposeControllerNode.swift @@ -120,7 +120,7 @@ final class ComposeControllerNode: ASDisplayNode { return } - self.searchDisplayController = SearchDisplayController(presentationData: self.presentationData, contentNode: ContactsSearchContainerNode(context: self.context, onlyWriteable: false, categories: [.cloudContacts, .global], addContact: nil, openPeer: { [weak self] peer in + self.searchDisplayController = SearchDisplayController(presentationData: self.presentationData, contentNode: ContactsSearchContainerNode(context: self.context, onlyWriteable: false, categories: [.cloudContacts, .global], addContact: nil, openPeer: { [weak self] peer, _ in if let requestOpenPeerFromSearch = self?.requestOpenPeerFromSearch, case let .peer(peer, _, _) = peer { requestOpenPeerFromSearch(peer.id) } diff --git a/submodules/TelegramUI/Sources/ContactMultiselectionController.swift b/submodules/TelegramUI/Sources/ContactMultiselectionController.swift index 31ffa8fc5f..82301ad2df 100644 --- a/submodules/TelegramUI/Sources/ContactMultiselectionController.swift +++ b/submodules/TelegramUI/Sources/ContactMultiselectionController.swift @@ -265,6 +265,10 @@ class ContactMultiselectionControllerImpl: ViewController, ContactMultiselection if isCall && count == 0 { self.titleView.title = CounterControllerTitle(title: self.params.title ?? self.presentationData.strings.Compose_NewGroupTitle, counter: nil) } else { + var count = count + if isCall { + count += 1 + } self.titleView.title = CounterControllerTitle(title: self.params.title ?? self.presentationData.strings.Compose_NewGroupTitle, counter: "\(count)/\(maxCount)") } if self.rightNavigationButton == nil && !isCall { diff --git a/submodules/TelegramUI/Sources/ContactMultiselectionControllerNode.swift b/submodules/TelegramUI/Sources/ContactMultiselectionControllerNode.swift index 58fa17ca74..3a2d3bc9cd 100644 --- a/submodules/TelegramUI/Sources/ContactMultiselectionControllerNode.swift +++ b/submodules/TelegramUI/Sources/ContactMultiselectionControllerNode.swift @@ -131,11 +131,10 @@ final class ContactMultiselectionControllerNode: ASDisplayNode { }, checkOptionTitle: nil) case let .groupCreation(isCall): if isCall { - //TODO:localize - placeholder = "Search for contacts or usernames" + placeholder = self.presentationData.strings.NewCall_SearchPlaceholder self.footerPanelNode = FooterPanelNode(theme: self.presentationData.theme, strings: self.presentationData.strings, action: { proceedImpl?() - }, checkOptionTitle: isCall ? "Call with video enabled" : nil) + }, checkOptionTitle: self.presentationData.strings.NewCall_VideoOption) } else { placeholder = self.presentationData.strings.Compose_TokenListPlaceholder self.footerPanelNode = nil @@ -483,15 +482,14 @@ final class ContactMultiselectionControllerNode: ASDisplayNode { count = contactListNode.selectionState?.selectedPeerIndices.count ?? 0 } if case let .groupCreation(isCall) = self.mode, isCall { - //TODO:localize if count == 0 { // Don't set anything to prevent state update } else if count <= 1 { let callTitle: String if case let .contacts(contactListNode) = self.contentNode, let peer = contactListNode.selectedPeers.first, case let .peer(peer, _, _) = peer { - callTitle = "Call \(EnginePeer(peer).compactDisplayTitle)" + callTitle = self.presentationData.strings.NewCall_ActionCallSingle(EnginePeer(peer).compactDisplayTitle).string } else { - callTitle = "Call" + callTitle = self.presentationData.strings.NewCall_ActionCallMultiple } footerPanelNode.content = FooterPanelNode.Content(title: callTitle, badge: "") } else { diff --git a/submodules/TelegramUI/Sources/ContactSelectionController.swift b/submodules/TelegramUI/Sources/ContactSelectionController.swift index 0cb897a7d2..a0946cb004 100644 --- a/submodules/TelegramUI/Sources/ContactSelectionController.swift +++ b/submodules/TelegramUI/Sources/ContactSelectionController.swift @@ -40,7 +40,7 @@ class ContactSelectionControllerImpl: ViewController, ContactSelectionController private let options: Signal<[ContactListAdditionalOption], NoError> private let displayDeviceContacts: Bool private let displayCallIcons: Bool - private let multipleSelection: Bool + private let multipleSelection: ContactSelectionControllerParams.MultipleSelectionMode private let requirePhoneNumbers: Bool private let allowChannelsInSearch: Bool @@ -153,15 +153,17 @@ class ContactSelectionControllerImpl: ViewController, ContactSelectionController } }) - if !params.multipleSelection { + if self.multipleSelection != .always { self.searchContentNode = NavigationBarSearchContentNode(theme: self.presentationData.theme, placeholder: self.presentationData.strings.Common_Search, activate: { [weak self] in self?.activateSearch() }) self.navigationBar?.setContentNode(self.searchContentNode, animated: false) } - if params.multipleSelection { + if self.multipleSelection == .always { self.navigationItem.rightBarButtonItem = UIBarButtonItem(image: PresentationResourcesRootController.navigationCompactSearchIcon(self.presentationData.theme), style: .plain, target: self, action: #selector(self.beginSearch)) + } else if self.multipleSelection == .possible { + self.navigationItem.rightBarButtonItem = UIBarButtonItem(title: self.presentationData.strings.Common_Select, style: .plain, target: self, action: #selector(self.beginSelection)) } self.getCurrentSendMessageContextMediaPreview = { [weak self] in @@ -220,7 +222,7 @@ class ContactSelectionControllerImpl: ViewController, ContactSelectionController } override func loadDisplayNode() { - self.displayNode = ContactSelectionControllerNode(context: self.context, mode: self.mode, presentationData: self.presentationData, options: self.options, displayDeviceContacts: self.displayDeviceContacts, displayCallIcons: self.displayCallIcons, multipleSelection: self.multipleSelection, requirePhoneNumbers: self.requirePhoneNumbers, allowChannelsInSearch: self.allowChannelsInSearch, isPeerEnabled: self.isPeerEnabled) + self.displayNode = ContactSelectionControllerNode(context: self.context, mode: self.mode, presentationData: self.presentationData, options: self.options, displayDeviceContacts: self.displayDeviceContacts, displayCallIcons: self.displayCallIcons, multipleSelection: self.multipleSelection == .always, requirePhoneNumbers: self.requirePhoneNumbers, allowChannelsInSearch: self.allowChannelsInSearch, isPeerEnabled: self.isPeerEnabled) self._ready.set(self.contactsNode.contactListNode.ready) self.contactsNode.navigationBar = self.navigationBar @@ -229,8 +231,8 @@ class ContactSelectionControllerImpl: ViewController, ContactSelectionController self?.deactivateSearch() } - self.contactsNode.requestOpenPeerFromSearch = { [weak self] peer in - self?.openPeer(peer: peer, action: .generic, node: nil, gesture: nil) + self.contactsNode.requestOpenPeerFromSearch = { [weak self] peer, action in + self?.openPeer(peer: peer, action: action, node: nil, gesture: nil) } self.contactsNode.contactListNode.activateSearch = { [weak self] in @@ -335,7 +337,7 @@ class ContactSelectionControllerImpl: ViewController, ContactSelectionController if let searchContentNode = self.searchContentNode as? NavigationBarSearchContentNode { self.contactsNode.activateSearch(placeholderNode: searchContentNode.placeholderNode) self.setDisplayNavigationBar(false, transition: .animated(duration: 0.5, curve: .spring)) - } else if self.multipleSelection { + } else if self.multipleSelection == .always { let contentNode = ContactsSearchNavigationContentNode(presentationData: self.presentationData, dismissSearch: { [weak self] in if let strongSelf = self, let navigationBar = strongSelf.navigationBar, let searchContentNode = strongSelf.searchContentNode as? ContactsSearchNavigationContentNode { searchContentNode.deactivate() diff --git a/submodules/TelegramUI/Sources/ContactSelectionControllerNode.swift b/submodules/TelegramUI/Sources/ContactSelectionControllerNode.swift index 58abf88ff3..78d954af74 100644 --- a/submodules/TelegramUI/Sources/ContactSelectionControllerNode.swift +++ b/submodules/TelegramUI/Sources/ContactSelectionControllerNode.swift @@ -37,7 +37,7 @@ final class ContactSelectionControllerNode: ASDisplayNode { var navigationBar: NavigationBar? var requestDeactivateSearch: (() -> Void)? - var requestOpenPeerFromSearch: ((ContactListPeer) -> Void)? + var requestOpenPeerFromSearch: ((ContactListPeer, ContactListAction) -> Void)? var requestOpenDisabledPeerFromSearch: ((EnginePeer, ChatListDisabledPeerReason) -> Void)? var requestMultipleAction: ((_ silent: Bool, _ scheduleTime: Int32?, _ parameters: ChatSendMessageActionSheetController.SendParameters?) -> Void)? var dismiss: (() -> Void)? @@ -258,7 +258,7 @@ final class ContactSelectionControllerNode: ASDisplayNode { categories.insert(.channels) } - let searchContainerNode = ContactsSearchContainerNode(context: self.context, updatedPresentationData: (self.presentationData, self.presentationDataPromise.get()), onlyWriteable: false, categories: categories, filters: self.filters, addContact: nil, openPeer: { [weak self] peer in + let searchContainerNode = ContactsSearchContainerNode(context: self.context, updatedPresentationData: (self.presentationData, self.presentationDataPromise.get()), onlyWriteable: false, categories: categories, filters: self.filters, displayCallIcons: self.displayCallIcons, isPeerEnabled: self.isPeerEnabled, addContact: nil, openPeer: { [weak self] peer, action in if let strongSelf = self { var updated = false strongSelf.contactListNode.updateSelectionState { state -> ContactListNodeGroupSelectionState? in @@ -285,7 +285,16 @@ final class ContactSelectionControllerNode: ASDisplayNode { if updated { strongSelf.requestDeactivateSearch?() } else { - strongSelf.requestOpenPeerFromSearch?(peer) + let mappedAction: ContactListAction + switch action { + case .generic: + mappedAction = .generic + case .voiceCall: + mappedAction = .voiceCall + case .videoCall: + mappedAction = .videoCall + } + strongSelf.requestOpenPeerFromSearch?(peer, mappedAction) } } }, openDisabledPeer: { [weak self] peer, reason in @@ -330,7 +339,7 @@ final class ContactSelectionControllerNode: ASDisplayNode { categories.insert(.channels) } - self.searchDisplayController = SearchDisplayController(presentationData: self.presentationData, contentNode: ContactsSearchContainerNode(context: self.context, updatedPresentationData: (self.presentationData, self.presentationDataPromise.get()), onlyWriteable: false, categories: categories, filters: self.filters, addContact: nil, openPeer: { [weak self] peer in + self.searchDisplayController = SearchDisplayController(presentationData: self.presentationData, contentNode: ContactsSearchContainerNode(context: self.context, updatedPresentationData: (self.presentationData, self.presentationDataPromise.get()), onlyWriteable: false, categories: categories, filters: self.filters, displayCallIcons: self.displayCallIcons, isPeerEnabled: self.isPeerEnabled, addContact: nil, openPeer: { [weak self] peer, action in if let strongSelf = self { var updated = false strongSelf.contactListNode.updateSelectionState { state -> ContactListNodeGroupSelectionState? in @@ -357,7 +366,16 @@ final class ContactSelectionControllerNode: ASDisplayNode { if updated { strongSelf.requestDeactivateSearch?() } else { - strongSelf.requestOpenPeerFromSearch?(peer) + let mappedAction: ContactListAction + switch action { + case .generic: + mappedAction = .generic + case .voiceCall: + mappedAction = .voiceCall + case .videoCall: + mappedAction = .videoCall + } + strongSelf.requestOpenPeerFromSearch?(peer, mappedAction) } } }, openDisabledPeer: { [weak self] peer, reason in diff --git a/submodules/TelegramUI/Sources/OpenResolvedUrl.swift b/submodules/TelegramUI/Sources/OpenResolvedUrl.swift index bcb6f012d2..10a241d5ee 100644 --- a/submodules/TelegramUI/Sources/OpenResolvedUrl.swift +++ b/submodules/TelegramUI/Sources/OpenResolvedUrl.swift @@ -394,6 +394,11 @@ func openResolvedUrlImpl( let _ = (signal |> deliverOnMainQueue).startStandalone(next: { [weak navigationController] resolvedCallLink in + if let currentGroupCallController = context.sharedContext.currentGroupCallController as? VoiceChatController, case let .group(groupCall) = currentGroupCallController.call, let currentCallId = groupCall.callId, currentCallId == resolvedCallLink.id { + context.sharedContext.navigateToCurrentCall() + return + } + navigationController?.pushViewController(context.sharedContext.makeJoinSubjectScreen(context: context, mode: JoinSubjectScreenMode.groupCall(JoinSubjectScreenMode.GroupCall( id: resolvedCallLink.id, accessHash: resolvedCallLink.accessHash, @@ -407,8 +412,7 @@ func openResolvedUrlImpl( if case .chat = urlContext { elevatedLayout = false } - //TODO:localize - present(UndoOverlayController(presentationData: presentationData, content: .linkRevoked(text: "This link is no longer active"), elevatedLayout: elevatedLayout, animateInAsReplacement: false, action: { _ in + present(UndoOverlayController(presentationData: presentationData, content: .linkRevoked(text: presentationData.strings.Chat_ToastCallLinkExpired_Text), elevatedLayout: elevatedLayout, animateInAsReplacement: false, action: { _ in return true }), nil) }) diff --git a/submodules/TelegramUI/Sources/SharedAccountContext.swift b/submodules/TelegramUI/Sources/SharedAccountContext.swift index 75717b4f5a..9da36e5bcc 100644 --- a/submodules/TelegramUI/Sources/SharedAccountContext.swift +++ b/submodules/TelegramUI/Sources/SharedAccountContext.swift @@ -1963,10 +1963,11 @@ public final class SharedAccountContextImpl: SharedAccountContext { return } + let isVideo = controller?.isCallVideoOptionSelected ?? false + if peerIds.count == 1 { - //TODO:release isVideo controller?.dismiss() - self.performCall(context: context, parentController: parentController, peerId: peerIds[0], isVideo: false, began: { + self.performCall(context: context, parentController: parentController, peerId: peerIds[0], isVideo: isVideo, began: { let _ = (context.sharedContext.hasOngoingCall.get() |> filter { $0 } |> timeout(1.0, queue: Queue.mainQueue(), alternate: .single(true)) @@ -1981,7 +1982,7 @@ public final class SharedAccountContextImpl: SharedAccountContext { }) }) } else { - self.createGroupCall(context: context, parentController: parentController, peerIds: peerIds, completion: { + self.createGroupCall(context: context, parentController: parentController, peerIds: peerIds, isVideo: isVideo, completion: { controller?.dismiss() }) } @@ -2012,7 +2013,7 @@ public final class SharedAccountContextImpl: SharedAccountContext { }) } - private func createGroupCall(context: AccountContext, parentController: ViewController, peerIds: [EnginePeer.Id], completion: (() -> Void)? = nil) { + private func createGroupCall(context: AccountContext, parentController: ViewController, peerIds: [EnginePeer.Id], isVideo: Bool, completion: (() -> Void)? = nil) { parentController.view.endEditing(true) var cancelImpl: (() -> Void)? @@ -2058,7 +2059,7 @@ public final class SharedAccountContextImpl: SharedAccountContext { isStream: false ), reference: .id(id: call.callInfo.id, accessHash: call.callInfo.accessHash), - beginWithVideo: false, + beginWithVideo: isVideo, invitePeerIds: peerIds ) completion?() @@ -2080,9 +2081,8 @@ public final class SharedAccountContextImpl: SharedAccountContext { if let result { switch result { case .linkCopied: - //TODO:localize let presentationData = context.sharedContext.currentPresentationData.with { $0 } - parentController.present(UndoOverlayController(presentationData: presentationData, content: .universal(animation: "anim_linkcopied", scale: 0.08, colors: ["info1.info1.stroke": UIColor.clear, "info2.info2.Fill": UIColor.clear], title: nil, text: "Call link copied.", customUndoText: "View Call", timeout: nil), elevatedLayout: false, animateInAsReplacement: false, action: { action in + parentController.present(UndoOverlayController(presentationData: presentationData, content: .universal(animation: "anim_linkcopied", scale: 0.08, colors: ["info1.info1.stroke": UIColor.clear, "info2.info2.Fill": UIColor.clear], title: nil, text: presentationData.strings.CallList_ToastCallLinkCopied_Text, customUndoText: presentationData.strings.CallList_ToastCallLinkCopied_Action, timeout: nil), elevatedLayout: false, animateInAsReplacement: false, action: { action in if case .undo = action { openCall() } diff --git a/submodules/TelegramVoip/Sources/GroupCallContext.swift b/submodules/TelegramVoip/Sources/GroupCallContext.swift index dc3bc51f68..e631caf116 100644 --- a/submodules/TelegramVoip/Sources/GroupCallContext.swift +++ b/submodules/TelegramVoip/Sources/GroupCallContext.swift @@ -899,6 +899,7 @@ public final class OngoingGroupCallContext { } return OngoingGroupCallRequestedVideoChannel( audioSsrc: channel.audioSsrc, + userId: channel.peerId, endpointId: channel.endpointId, ssrcGroups: channel.ssrcGroups.map { group in return OngoingGroupCallSsrcGroup( diff --git a/third-party/td/td b/third-party/td/td new file mode 160000 index 0000000000..a03a90470d --- /dev/null +++ b/third-party/td/td @@ -0,0 +1 @@ +Subproject commit a03a90470d6fca9a5a3db747ba3f3e4a465b5fe7 diff --git a/third-party/td/td/.clang-format b/third-party/td/td/.clang-format deleted file mode 100644 index 8f0a588366..0000000000 --- a/third-party/td/td/.clang-format +++ /dev/null @@ -1,194 +0,0 @@ ---- -Language: Cpp -# BasedOnStyle: Google -AccessModifierOffset: -1 -AlignAfterOpenBracket: Align -AlignArrayOfStructures: None -AlignConsecutiveAssignments: - Enabled: false - AcrossEmptyLines: false - AcrossComments: false - AlignCompound: false - PadOperators: true -AlignConsecutiveBitFields: - Enabled: false - AcrossEmptyLines: false - AcrossComments: false - AlignCompound: false - PadOperators: false -AlignConsecutiveDeclarations: - Enabled: false - AcrossEmptyLines: false - AcrossComments: false - AlignCompound: false - PadOperators: false -AlignConsecutiveMacros: - Enabled: false - AcrossEmptyLines: false - AcrossComments: false - AlignCompound: false - PadOperators: false -AlignEscapedNewlines: Left -AlignOperands: Align -AlignTrailingComments: - Kind: Always - OverEmptyLines: 0 -AllowAllArgumentsOnNextLine: true -AllowAllParametersOfDeclarationOnNextLine: true -AllowShortBlocksOnASingleLine: Never -AllowShortCaseLabelsOnASingleLine: false -AllowShortEnumsOnASingleLine: true -AllowShortFunctionsOnASingleLine: None # All -AllowShortIfStatementsOnASingleLine: Never # WithoutElse -AllowShortLambdasOnASingleLine: Inline # All -AllowShortLoopsOnASingleLine: false # true -AlwaysBreakAfterDefinitionReturnType: None -AlwaysBreakAfterReturnType: None -AlwaysBreakBeforeMultilineStrings: true -AlwaysBreakTemplateDeclarations: Yes -# AttributeMacros: -# - __capability -BinPackArguments: true -BinPackParameters: true -BitFieldColonSpacing: Both -BraceWrapping: - AfterCaseLabel: false - AfterClass: false - AfterControlStatement: Never - AfterEnum: false - AfterExternBlock: false - AfterFunction: false - AfterNamespace: false - AfterObjCDeclaration: false - AfterStruct: false - AfterUnion: false - BeforeCatch: false - BeforeElse: false - BeforeLambdaBody: false - BeforeWhile: false - IndentBraces: false - SplitEmptyFunction: true - SplitEmptyRecord: true - SplitEmptyNamespace: true -BreakAfterAttributes: Never -# BreakAfterJavaFieldAnnotations: false -BreakArrays: true -BreakBeforeBinaryOperators: None -BreakBeforeBraces: Attach -BreakBeforeConceptDeclarations: Always -BreakBeforeInlineASMColon: OnlyMultiline -BreakBeforeTernaryOperators: true -BreakConstructorInitializers: BeforeComma # BeforeColon -BreakInheritanceList: BeforeComma # BeforeColon -BreakStringLiterals: true -ColumnLimit: 120 # 80 -CommentPragmas: '^ IWYU pragma:' -CompactNamespaces: false -ConstructorInitializerIndentWidth: 4 -ContinuationIndentWidth: 4 -Cpp11BracedListStyle: true -DerivePointerAlignment: true -DisableFormat: false -EmptyLineAfterAccessModifier: Never -EmptyLineBeforeAccessModifier: LogicalBlock -ExperimentalAutoDetectBinPacking: false -FixNamespaceComments: true -ForEachMacros: - - Q_FOREACH_THIS_LIST_MUST_BE_NON_EMPTY -IncludeBlocks: Preserve -IncludeCategories: - - Regex: '.*' - Priority: 0 -IndentAccessModifiers: false -IndentCaseBlocks: false -IndentCaseLabels: true -IndentExternBlock: AfterExternBlock -IndentGotoLabels: true -IndentPPDirectives: None -IndentRequiresClause: true -IndentWidth: 2 -IndentWrappedFunctionNames: false -InsertBraces: false -InsertNewlineAtEOF: false -# InsertTrailingCommas: None -IntegerLiteralSeparator: - Binary: 0 - Decimal: 0 - Hex: 0 -# JavaScriptQuotes: Leave -# JavaScriptWrapImports: true -KeepEmptyLinesAtTheStartOfBlocks: false -LambdaBodyIndentation: Signature -LineEnding: DeriveLF -MacroBlockBegin: '' -MacroBlockEnd: '' -MaxEmptyLinesToKeep: 1 -NamespaceIndentation: None -# ObjCBinPackProtocolList: Never -# ObjCBlockIndentWidth: 2 -# ObjCBreakBeforeNestedBlockParam: true -# ObjCSpaceAfterProperty: false -# ObjCSpaceBeforeProtocolList: true -PackConstructorInitializers: NextLine -PenaltyBreakAssignment: 2 -PenaltyBreakBeforeFirstCallParameter: 1 -PenaltyBreakComment: 300 -PenaltyBreakFirstLessLess: 120 -PenaltyBreakOpenParenthesis: 0 -PenaltyBreakString: 1000 -PenaltyBreakTemplateDeclaration: 10 -PenaltyExcessCharacter: 1000000 -PenaltyIndentedWhitespace: 0 -PenaltyReturnTypeOnItsOwnLine: 200 -PointerAlignment: Right # Left -PPIndentWidth: -1 -QualifierAlignment: Leave -ReferenceAlignment: Pointer -ReflowComments: false # true -RemoveBracesLLVM: false -RemoveSemicolon: false -RequiresClausePosition: OwnLine -RequiresExpressionIndentation: OuterScope -SeparateDefinitionBlocks: Leave -ShortNamespaceLines: 0 # 1 -SortIncludes: CaseInsensitive # CaseSensitive -# SortJavaStaticImport: Before -SortUsingDeclarations: Lexicographic # LexicographicNumeric -SpaceAfterCStyleCast: false -SpaceAfterLogicalNot: false -SpaceAfterTemplateKeyword: true -SpaceAroundPointerQualifiers: Default -SpaceBeforeAssignmentOperators: true -SpaceBeforeCaseColon: false -SpaceBeforeCpp11BracedList: false -SpaceBeforeCtorInitializerColon: true -SpaceBeforeInheritanceColon: true -SpaceBeforeParens: ControlStatements -SpaceBeforeParensOptions: - AfterControlStatements: true - AfterForeachMacros: true - AfterFunctionDefinitionName: false - AfterFunctionDeclarationName: false - AfterIfMacros: true - AfterOverloadedOperator: false - AfterRequiresInClause: false - AfterRequiresInExpression: false - BeforeNonEmptyParentheses: false -SpaceBeforeRangeBasedForLoopColon: true -SpaceBeforeSquareBrackets: false -SpaceInEmptyBlock: false -SpaceInEmptyParentheses: false -SpacesBeforeTrailingComments: 2 -SpacesInAngles: Never -SpacesInConditionalStatement: false -SpacesInContainerLiterals: true -SpacesInCStyleCastParentheses: false -SpacesInLineCommentPrefix: - Minimum: 1 - Maximum: 1 # -1 -SpacesInParentheses: false -SpacesInSquareBrackets: false -Standard: Auto -TabWidth: 100 # 8 -UseTab: Never -... diff --git a/third-party/td/td/.gitattributes b/third-party/td/td/.gitattributes deleted file mode 100644 index 8a58f71824..0000000000 --- a/third-party/td/td/.gitattributes +++ /dev/null @@ -1,39 +0,0 @@ -* text=auto - -*.cpp text whitespace=blank-at-eol,space-before-tab,blank-at-eof,tab-in-indent -*.hpp text whitespace=blank-at-eol,space-before-tab,blank-at-eof,tab-in-indent -*.h text whitespace=blank-at-eol,space-before-tab,blank-at-eof,tab-in-indent -*.c text whitespace=blank-at-eol,space-before-tab,blank-at-eof,tab-in-indent -*.tl text whitespace=blank-at-eol,space-before-tab,blank-at-eof,tab-in-indent -*.mm text whitespace=blank-at-eol,space-before-tab,blank-at-eof,tab-in-indent -*.txt text whitespace=blank-at-eol,space-before-tab,blank-at-eof,tab-in-indent -*.sh text whitespace=blank-at-eol,space-before-tab,blank-at-eof,tab-in-indent eol=lf -*.php text whitespace=blank-at-eol,space-before-tab,blank-at-eof,tab-in-indent -*.ps1 text whitespace=blank-at-eol,space-before-tab,blank-at-eof,tab-in-indent eol=crlf -*.cmake text whitespace=blank-at-eol,space-before-tab,blank-at-eof,tab-in-indent -*.md text whitespace=blank-at-eol,space-before-tab,blank-at-eof,tab-in-indent -*.in text whitespace=blank-at-eol,space-before-tab,blank-at-eof,tab-in-indent -*.html text whitespace=blank-at-eol,space-before-tab,blank-at-eof,tab-in-indent - -*.java text whitespace=blank-at-eol,space-before-tab,blank-at-eof,tab-in-indent -*.py text whitespace=blank-at-eol,space-before-tab,blank-at-eof,tab-in-indent -*.js text whitespace=blank-at-eol,space-before-tab,blank-at-eof,tab-in-indent -*.patch text whitespace=blank-at-eol,space-before-tab,blank-at-eof,tab-in-indent -*.swift text whitespace=blank-at-eol,space-before-tab,blank-at-eof,tab-in-indent -*.pbxproj text whitespace=blank-at-eol,space-before-tab,blank-at-eof,tab-in-indent -*.cs text whitespace=blank-at-eol,space-before-tab,blank-at-eof,tab-in-indent -*.xaml text whitespace=blank-at-eol,space-before-tab,blank-at-eof,tab-in-indent -*.appxmanifest text whitespace=blank-at-eol,space-before-tab,blank-at-eof,tab-in-indent -*.vsixmanifest text whitespace=blank-at-eol,space-before-tab,blank-at-eof,tab-in-indent -*.nuspec text whitespace=blank-at-eol,space-before-tab,blank-at-eof,tab-in-indent -*.targets text whitespace=blank-at-eol,space-before-tab,blank-at-eof,tab-in-indent -*.json text whitespace=blank-at-eol,space-before-tab,blank-at-eof,tab-in-indent -*.csproj text whitespace=blank-at-eol,space-before-tab,blank-at-eof,tab-in-indent -*.sln text whitespace=blank-at-eol,space-before-tab,blank-at-eof,tab-in-indent -*.xml text whitespace=blank-at-eol,space-before-tab,blank-at-eof,tab-in-indent -*.config text whitespace=blank-at-eol,space-before-tab,blank-at-eof,tab-in-indent - -sqlite/sqlite/* linguist-vendored - -*.pfx binary -*.png binary diff --git a/third-party/td/td/.gitignore b/third-party/td/td/.gitignore deleted file mode 100644 index 9ce887b5f1..0000000000 --- a/third-party/td/td/.gitignore +++ /dev/null @@ -1,8 +0,0 @@ -**/*build*/ -**/.*.swp -**/.DS_Store -**/auto/ -docs/ -/tdlib/ -vcpkg/ -.clang-tidy diff --git a/third-party/td/td/CHANGELOG.md b/third-party/td/td/CHANGELOG.md deleted file mode 100644 index f590b3ef62..0000000000 --- a/third-party/td/td/CHANGELOG.md +++ /dev/null @@ -1,1520 +0,0 @@ -Changes in 1.8.0 (29 Dec 2021): - -* Changed the type of user, basic group and supergroup identifiers from `int32` to `int53`. -* Simplified chat list loading and removed the ability to misuse the method `getChats`: - - Renamed the method `getChats` to `loadChats`. - - Removed the parameters `offset_order` and `offset_chat_id` from the method `loadChats`. Chats are now always loaded - from the last known chat in the list. - - Changed the type of the result in the method `loadChats` to `ok`. If no chats were loaded, a 404 error is returned. - The order of chats in the list must be maintained using the updates `updateChatPosition`, `updateChatLastMessage`, - and `updateChatDraftMessage`. - - Added the convenience method `getChats`, which returns the requested number of chats from the beginning of a chat - list and can be used if the list of chats doesn't need to be maintained in a consistent state. -* Added the ability to hook TDLib log messages: - - Added the function `td_set_log_message_callback` to JSON interface. - - Added the function `set_log_message_callback` to the class `ClientManager`. - - Added the function `SetLogMessageCallback` to the UWP native wrapper through C++/CX. - - Deprecated the function `td_set_log_fatal_error_callback` in JSON interface in favor of - the function `td_set_log_message_callback`. - - Deprecated the function `Log::set_fatal_error_callback` in favor of - the function `ClientManager::set_log_message_callback`. -* Added support for sending messages on behalf of public channels owned by the user: - - Added the field `message_sender_id` to the class `chat`, containing the identifier of the currently selected - message sender. - - Added the update `updateChatMessageSender`. - - Added the method `getChatAvailableMessageSenders`, returning the list of available message senders for the chat. - - Added the method `setChatMessageSender`, changing the currently selected message sender. - - Added the field `need_another_sender` to the class `messageSendingStateFailed`. If it is true, an alert needs - to be shown to the user that the message will be re-sent on behalf of another sender. - - Replaced the method `deleteChatMessagesFromUser` with the method `deleteChatMessagesBySender`, expecting - a `MessageSender` instead of a user identifier. - - Replaced the update `updateUserChatAction` with the update `updateChatAction`, containing a `MessageSender` - instead of a user identifier as a source of the chat action. -* Added the ability to ban supergroups and channels in other supergroups and channels: - - Replaced the fields `user_id` with the fields `member_id` in the classes `chatMember` and - `chatEventMemberRestricted`. - - Replaced the parameters `user_id` with the parameters `member_id` in the methods `setChatMemberStatus` and - `getChatMember`. -* Improved support for animated emoji: - - Added the class `animatedEmoji`, containing information about an animated emoji. - - Added the class `messageAnimatedEmoji` to the types of message content. - - Added the method `clickAnimatedEmojiMessage` to be called when an animated emoji is clicked. - - Added the update `updateAnimatedEmojiMessageClicked`, received when a big animated sticker must be played. - - Added the class `chatActionWatchingAnimations` to the types of chat action. - - Added the method `getAnimatedEmoji`, returning an animated emoji corresponding to a given emoji. - - Added the writable option "disable_animated_emoji". - - Removed the option "animated_emoji_sticker_set_name". -* Added support for automatic message deletion in all chat types: - - Added the field `message_ttl` to the class `chat`. - - Added the update `updateChatMessageTtl`. - - Added the method `setChatMessageTtl`. - - Added the class `chatEventMessageTtlChanged`, representing change of the field `message_ttl` in the chat event log. - - Removed the field `ttl` from the class `secretChat` in favor of the field `message_ttl` in the class `chat`. - - Removed the method `sendChatSetTtlMessage` in favor of the method `setChatMessageTtl`. -* Improved names of the fields of the type `MessageSender`: - - Renamed the fields `sender` to `sender_id` in the classes `message` and `notificationTypeNewPushMessage`. - - Renamed the parameter `sender` to `sender_id` in the methods `searchChatMessages`, `addLocalMessage`, and - `toggleMessageSenderIsBlocked`. - - Renamed the field `recent_repliers` to `recent_replier_ids` in the class `messageReplyInfo`. - - Renamed the field `traveler` to `traveler_id` in the class `messageProximityAlertTriggered`. - - Renamed the field `watcher` to `watcher_id` in the class `messageProximityAlertTriggered`. -* The field `formatted_phone_number` in the class `phoneNumberInfo` now contains the character '-' at the places of - expected digits. -* Added the synchronous method `getPhoneNumberInfoSync` that can be used instead of the method `getPhoneNumberInfo` - to synchronously receive information about a phone number by its prefix. -* Replaced the field `user_id` in the class `chatEvent` with the field `member_id` of the type `MessageSender`. -* Improved support for bot payments: - - Allowed sending invoices as results of inline queries by allowing bots to use the class `inputMessageInvoice` as - the value of the field `input_message_content` in the classes `inputInlineQueryResultAnimation`, - `inputInlineQueryResultArticle`, `inputInlineQueryResultAudio`, `inputInlineQueryResultContact`, - `inputInlineQueryResultDocument`, `inputInlineQueryResultLocation`, `inputInlineQueryResultPhoto`, - `inputInlineQueryResultSticker`, `inputInlineQueryResultVenue`, `inputInlineQueryResultVideo`, and - `inputInlineQueryResultVoiceNote`. - - Allowed sending invoice messages to basic group, supergroup and channel chats. - - Allowed bots to send forwardable invoices by specifying an empty field `start_parameter` in - the class `inputMessageInvoice`. - - Added the field `invoice_chat_id` to the class `messagePaymentSuccessful`. - - Added the field `id` to the class `paymentForm`, containing a unique payment form identifier. - - Added the parameter `payment_form_id` to the method `sendPaymentForm`. - - Added the field `seller_bot_user_id` to the class `paymentForm`, containing the user identifier of the seller bot. - - Added the field `payments_provider_user_id` to the class `paymentForm`, containing the user identifier of - the payment provider bot. - - Added the fields `title`, `description`, `photo`, and `seller_bot_user_id` to the class `paymentReceipt`. - - Added the fields `max_tip_amount` and `suggested_tip_amounts` to the class `invoice`. - - Added the parameter `tip_amount` to the method `sendPaymentForm`. - - Added the field `tip_amount` to the class `paymentReceipt`. - - Renamed the class `inputCredentialsAndroidPay` to `inputCredentialsGooglePay`. - - Added the class `paymentFormTheme`, containing the desired colors for a payment form. - - Added the parameter `theme` to the method `getPaymentForm`. - - Removed the field `invoice_message_id` from the class `messagePaymentSuccessfulBot`. -* Added the method `deleteChat`, which can be used to completely delete a chat along with all messages. -* Removed the method `deleteSupergroup` in favor of the method `deleteChat`. -* Changed the type of the result in the method `getProxyLink` to the class `httpUrl` instead of the class `text`. -* Removed support for secret chat layers before 73. -* Added support for sponsored messages: - - Added the class `sponsoredMessage`. - - Added the method `getChatSponsoredMessage`. - - Added the ability to pass identifiers of sponsored messages to `viewMessages`. The method must be called when - the entire text of the sponsored message is shown on the screen (excluding the button). -* Added support for video chats: - - Added the class `groupCall`, representing a group call. - - Added the method `getGroupCall` for fetching information about a group call. - - Added the update `updateGroupCall`. - - Added the class `videoChat`, representing a video chat, i.e. group call bound to a chat. - - Added the field `video_chat` to the class `chat`. - - Added the update `updateChatVideoChat`. - - Added the classes `messageVideoChatScheduled`, `messageVideoChatStarted`, and `messageVideoChatEnded` to - the types of message content. - - Added the class `messageInviteVideoChatParticipants` to the types of message content. - - Added the field `can_manage_video_chats` to the class `chatMemberStatusAdministrator`. - - Added the class `groupCallId`. - - Added the method `createVideoChat` for video chat creation. - - Added the method `startScheduledGroupCall`. - - Added the method `toggleGroupCallEnabledStartNotification`. - - Added the method `joinGroupCall`. - - Added the method `leaveGroupCall`. - - Added the method `endGroupCall`. - - Added the method `toggleGroupCallIsMyVideoEnabled`. - - Added the method `toggleGroupCallIsMyVideoPaused`. - - Added the methods `startGroupCallScreenSharing`, `toggleGroupCallScreenSharingIsPaused`, - `endGroupCallScreenSharing` for managing screen sharing during group calls. - - Added the method `setGroupCallTitle`. - - Added the method `toggleGroupCallMuteNewParticipants`. - - Added the classes `groupCallVideoSourceGroup` and `groupCallParticipantVideoInfo`, describing available - video streams. - - Added the class `groupCallParticipant`. - - Added the update `updateGroupCallParticipant`. - - Added the method `loadGroupCallParticipants`. - - Added the method `toggleGroupCallParticipantIsHandRaised`. - - Added the method `setGroupCallParticipantIsSpeaking`. - - Added the methods `toggleGroupCallParticipantIsMuted` and `setGroupCallParticipantVolumeLevel` for managing - the volume level of group call participants. - - Added the method `inviteGroupCallParticipants`. - - Added the method `getGroupCallInviteLink` and `revokeGroupCallInviteLink` for managing group call invite links. - - Added the methods `startGroupCallRecording` and `endGroupCallRecording` for managing group call recordings. - - Added the method `getVideoChatAvailableParticipants`, returning the list of participants, on whose behalf - a video chat in the chat can be joined. - - Added the method `setVideoChatDefaultParticipant` for changing the default participant on whose behalf a video chat - will be joined. - - Added the class `GroupCallVideoQuality` and the method `getGroupCallStreamSegment` for downloading segments of - live streams. - - Added the class `groupCallRecentSpeaker`, representing a group call participant that was recently speaking. - - Added the field `video_chat_changes` to the class `chatEventLogFilters`. - - Added the class `chatEventVideoChatCreated`, representing a video chat being created in the chat event log. - - Added the class `chatEventVideoChatEnded`, representing a video chat being ended in the chat event log. - - Added the class `chatEventVideoChatMuteNewParticipantsToggled`, representing changes of - the setting `mute_new_participants` of a video chat in the chat event log. - - Added the class `chatEventVideoChatParticipantIsMutedToggled`, representing a video chat participant being muted or - unmuted in the chat event log. - - Added the class `chatEventVideoChatParticipantVolumeLevelChanged`, representing a video chat participant's - volume level being changed in the chat event log. -* Added "; pass null" documentation for all TDLib method parameters, for which null is an expected value. -* Added support for link processing: - - Added the method `getInternalLinkType`, which can parse internal links and return the exact link type and actions - to be done when the link is clicked. - - Added the classes `internalLinkTypeActiveSessions`, `internalLinkTypeAuthenticationCode`, - `internalLinkTypeBackground`, `internalLinkTypeBotStart`, `internalLinkTypeBotStartInGroup`, - `internalLinkTypeChangePhoneNumber`, `internalLinkTypeChatInvite`, `internalLinkTypeFilterSettings`, - `internalLinkTypeGame`, `internalLinkTypeLanguagePack`, `internalLinkTypeMessage`, `internalLinkTypeMessageDraft`, - `internalLinkTypePassportDataRequest`, `internalLinkTypePhoneNumberConfirmation`, `internalLinkTypeProxy`, - `internalLinkTypePublicChat`, `internalLinkTypeQrCodeAuthentication`, `internalLinkTypeSettings`, - `internalLinkTypeStickerSet`, `internalLinkTypeTheme`, `internalLinkTypeThemeSettings`, - `internalLinkTypeUnknownDeepLink`, `internalLinkTypeUnsupportedProxy`, and `internalLinkTypeVideoChat` to represent - different types of internal links. - - Added the method `getExternalLinkInfo`, which needs to be called if the clicked link wasn't recognized as - an internal link. - - Added the method `getExternalLink`, which needs to be called after the method `getExternalLinkInfo` if the user - confirms automatic authorization on the website. -* Added support for expiring chat invite links: - - Added the field `is_primary` to the class `chatInviteLink`. The primary invite link can't have a name, - expiration date, or usage limit. There is exactly one primary invite link for each administrator with - the can_invite_users right at any given time. - - Added the field `name` to the class `chatInviteLink`. - - Added the field `creator_user_id` to the class `chatInviteLink`. - - Added the field `date` to the class `chatInviteLink`, containing the link creation date. - - Added the field `edit_date` to the class `chatInviteLink`, containing the date the link was last edited. - - Added the fields `expiration_date` and `member_limit` to the class `chatInviteLink`, limiting link usage. - - Added the field `member_count` to the class `chatInviteLink`. - - Added the field `is_revoked` to the class `chatInviteLink`. - - Changed the type of the fields `invite_link` in the classes `basicGroupFullInfo` and `supergroupFullInfo` to - `chatInviteLink`. - - Added the field `description` to the class `chatInviteLinkInfo`, containing the description of the chat. - - Replaced the method `generateChatInviteLink` with the method `replacePrimaryChatInviteLink`. - - Added the method `createChatInviteLink` for creating new invite links. - - Added the method `editChatInviteLink` for editing non-primary invite links. - - Added the method `revokeChatInviteLink`. - - Added the method `deleteRevokedChatInviteLink`. - - Added the method `deleteAllRevokedChatInviteLink`. - - Added the method `getChatInviteLink`. - - Added the class `chatInviteLinks`, containing a list of chat invite links. - - Added the method `getChatInviteLinks`. - - Added the classes `chatInviteLinkCount` and `chatInviteLinkCounts`. - - Added the method `getChatInviteLinkCounts`, returning the number of invite links created by chat administrators. - - Added the classes `chatInviteLinkMember` and `chatInviteLinkMembers`. - - Added the method `getChatInviteLinkMembers`. - - Added the field `invite_link_changes` to the class `chatEventLogFilters`. - - Added the class `chatEventMemberJoinedByInviteLink`, representing a user joining the chat via invite link in - the chat event log. - - Added the class `chatEventInviteLinkEdited` to the types of chat event. - - Added the class `chatEventInviteLinkRevoked` to the types of chat event. - - Added the class `chatEventInviteLinkDeleted` to the types of chat event. - - Added the class `chatActionBarInviteMembers` to the types of chat action bar. -* Added support for chat invite links that create join requests: - - Added the class `messageChatJoinByRequest` to the types of message content. - - Added the class `pushMessageContentChatJoinByRequest` to the types of push message content. - - Added the field `pending_join_requests` to the class `chat`. - - Added the class `chatJoinRequestsInfo`, containing basic information about pending join requests for the chat. - - Added the update `updateChatPendingJoinRequests`. - - Added the fields `creates_join_request` to the classes `chatInviteLink` and `chatInviteLinkInfo`. - - Added the field `pending_join_request_count` to the class `chatInviteLink`. - - Added the class `chatJoinRequest`, describing a user that sent a join request. - - Added the class `chatJoinRequests`, containing a list of requests to join the chat. - - Added the method `getChatJoinRequests`. - - Added the method `processChatJoinRequest` for processing a request to join the chat. - - Added the method `processChatJoinRequests` for processing all requests to join the chat. - - Added the class `chatActionBarJoinRequest` to the types of chat action bar. - - Added the class `chatEventMemberJoinedByRequest`, representing a user approved to join the chat after - a join request in the chat event log. - - Added the update `updateNewChatJoinRequest` for bots. -* Added the ability to see viewers of outgoing messages in small group chats: - - Added the method `getMessageViewers`. - - Added the field `can_get_viewers` to the class `message`. -* Added the parameter `only_preview` to the method `forwardMessages`, which can be used to receive a preview of - forwarded messages. -* Added the method `getRecentlyOpenedChats`, returning the list of recently opened chats. -* Increased number of recently found chats that are stored to 50. -* Added the ability to get information about chat messages, which are split by days: - - Added the class `messageCalendarDay`, representing found messages, sent on a specific day. - - Added the class `messageCalendar`, representing found messages, split by days. - - Added the writable option "utc_time_offset", which contains a UTC time offset used for splitting messages by days. - The option is reset automatically on each TDLib instance launch, so it needs to be set manually only if - the time offset is changed during execution. - - Added the method `getChatMessageCalendar`, returning information about chat messages, which are split by days. -* Added the ability to get messages of the specified type in sparse positions for hyper-speed scrolling implementation: - - Added the class `messagePosition`, containing an identifier and send date of a message in - a specific chat history position. - - Added the class `messagePositions`, containing a list of message positions. - - Added the method `getChatSparseMessagePositions`. -* Added the field `can_manage_chat` to the class `chatMemberStatusAdministrator` to allow promoting chat administrators - without additional rights. -* Improved support for bot commands: - - Bot command entities in chats without bots are now automatically hidden. - - Added the class `botCommands`, representing a list of bot commands. - - Added the field `commands` to the class `userFullInfo`, containing the list of commands to be used in - the private chat with the bot. - - Added the fields `bot_commands` to the classes `basicGroupFullInfo` and `supergroupFullInfo`. - - Removed the class `botInfo`. - - Removed the fields `bot_info` from the classes `userFullInfo` and `chatMember`. - - Added the class `BotCommandScope`. - - Added the methods `setCommands`, `deleteCommands`, `getCommands` for bots. -* Added the read-only options "suggested_video_note_length", "suggested_video_note_video_bitrate", and - "suggested_video_note_audio_bitrate", containing suggested video note encoding parameters. -* Added the read-only option "channel_bot_user_id", containing the identifier of the bot which is shown in - outdated clients as the sender of messages sent on behalf of channels. -* Added the ability to fetch the actual value of the option "is_location_visible" using the method `getOption` in case - the value of the option was changed from another device. -* Added the field `minithumbnail` to the class `profilePhoto`, representing a profile photo minithumbnail. -* Added the field `minithumbnail` to the class `chatPhotoInfo`, representing a chat photo minithumbnail. -* Added support for sticker outlines: - - Added the field `outline` to the class `sticker`. - - Added the fields `thumbnail_outline` to the classes `stickerSet` and `stickerSetInfo`. - - Added the class `closedVectorPath`, representing a closed vector path. - - Added the class `VectorPathCommand`, representing one edge of a closed vector path. - - Added the class `point`, representing a point on a Cartesian plane. -* Added support for chats and messages with protected content: - - Added the field `has_protected_content` to the class `chat`. - - Added the update `updateChatHasProtectedContent`. - - Added the method `toggleChatHasProtectedContent`. - - Added the class `chatEventHasProtectedContentToggled`, representing a change of the setting `has_protected_content` - in the chat event log. - - Added the field `can_be_saved` to the class `message`. -* Added support for broadcast groups, i.e. supergroups without a limit on the number of members in which - only administrators can send messages: - - Added the field `is_broadcast_group` to the class `supergroup`. - - Added the method `toggleSupergroupIsBroadcastGroup`. Conversion of a supergroup to a broadcast group - can't be undone. - - Added the class `suggestedActionConvertToBroadcastGroup`, representing a suggestion to convert a supergroup to - a broadcast group. -* Improved chat reports: - - Added the parameter `text` to the method `reportChat`, allowing to add additional details to all - chat reporting reasons. - - Removed the field `text` from the class `chatReportReasonCustom`. - - Added the method `reportChatPhoto` for reporting chat photos. -* Added support for users and chats reported as fake: - - Added the field `is_fake` to the class `user`. - - Added the field `is_fake` to the class `supergroup`. - - Added the class `chatReportReasonFake` to the types of chat reporting reasons. -* Added the class `inlineKeyboardButtonTypeUser` to the types of inline keyboard buttons. -* Added the field `input_field_placeholder` to the classes `replyMarkupForceReply` and `replyMarkupShowKeyboard`. -* Added support for media timestamp entities in messages: - - Added the class `textEntityTypeMediaTimestamp` to the types of text entities. - - Added the field `has_timestamped_media` to the class `message`, describing whether media timestamp entities refer - to the message itself or to the replied message. - - Added the parameter `media_timestamp` to the method `getMessageLink` to support creating message links with - a given media timestamp. - - Added the field `can_get_media_timestamp_links` to the class `message`. - - Added the field `media_timestamp` to the class `messageLinkInfo` for handling of message links with - a specified media timestamp. -* Added the ability to change properties of active sessions: - - Added the field `can_accept_secret_chats` to the class `session`. - - Added the method `toggleSessionCanAcceptSecretChats`. - - Added the field `can_accept_calls` to the class `session`. - - Added the method `toggleSessionCanAcceptCalls`. - - Added the field `inactive_session_ttl_days` to the class `sessions`. - - Added the method `setInactiveSessionTtl`. -* Added new ways for phone number verification: - - Added the class `authenticationCodeTypeMissedCall`, describing an authentication code delivered by - a canceled phone call to the given number. The last digits of the phone number that calls are the code that - must be entered manually by the user. - - Added the field `allow_missed_call` to the class `phoneNumberAuthenticationSettings`. - - Added the read-only option "authentication_token", which can be received when logging out and contains - an authentication token to be used on subsequent authorizations. - - Added the field `authentication_tokens` to the class `phoneNumberAuthenticationSettings`. -* Added support for resetting the password from an active session: - - Added the class `ResetPasswordResult` and the method `resetPassword`. - - Added the method `cancelPasswordReset`, which can be used to cancel a pending password reset. - - Added the field `pending_reset_date` to the class `passwordState`. -* Added the ability to set a new 2-step verification password after recovering a lost password using - a recovery email address: - - Added the parameters `new_password` and `new_hint` to the methods `recoverAuthenticationPassword` and - `recoverPassword`. - - Added the method `checkAuthenticationPasswordRecoveryCode`. - - Added the method `checkPasswordRecoveryCode`. -* Added the class `chatActionChoosingSticker` to the types of chat action. -* Added the class `backgroundFillFreeformGradient` to the types of background fill. -* Added the field `is_inverted` to the class `backgroundTypePattern` for inverted patterns for dark themes. -* Added support for chat themes: - - Added the field `theme_name` to the class `chat`. - - Added the method `setChatTheme`. - - Added the update `updateChatTheme`, received when a theme was changed in a chat. - - Added the class `messageChatSetTheme` to the types of message content. - - Added the class `pushMessageContentChatSetTheme` to the types of push message content. - - Added the class `themeSettings`, representing basic theme settings. - - Added the class `chatTheme`, representing a chat theme. - - Added the update `updateChatThemes`, received when the list of available chat themes changes. -* Added the ability for regular users to create sticker sets: - - Allowed to use the methods `uploadStickerFile` and `createNewStickerSet` as regular users. - - Replaced the parameter `png_sticker` in the method `uploadStickerFile` with the parameter `sticker` of - the type `InputSticker`. - - Added the parameter `source` to the method `createNewStickerSet`. - - Added the method `getSuggestedStickerSetName`. - - Added the class `CheckStickerSetNameResult` and the method `checkStickerSetName` for checking a sticker set name - before creating a sticker set. -* Added support for importing chat history from an external source: - - Added the method `importMessages`. - - Added the method `getMessageImportConfirmationText`. - - Added the class `MessageFileType` and the method `getMessageFileType`, which can be used to check whether - the format of a file with exported message history is supported. - - Added the class `messageForwardOriginMessageImport` to the types of forwarded message origins for - imported messages. - - Added the parameter `for_import` to the method `createNewSupergroupChat`, which needs to be set to true whenever - the chat is created for a subsequent message history import. -* Added new types of suggested actions: - - Added the class `suggestedActionSetPassword`, suggesting the user to set a 2-step verification password to be able - to log in again before the specified number of days pass. - - Added the class `suggestedActionCheckPassword`, suggesting the user to check whether they still remember - their 2-step verification password. - - Added the class `suggestedActionViewChecksHint`, suggesting the user to see a hint about the meaning of - one and two check marks on sent messages. -* Added the method `getSuggestedFileName`, which returns a suggested name for saving a file in a given directory. -* Added the method `deleteAllCallMessages`. -* Added the method `deleteChatMessagesByDate`, which can be used to delete all messages between the specified dates in - a chat. -* Added the field `unread_message_count` to the class `messageThreadInfo`. -* Added the field `has_private_forwards` to the class `userFullInfo`. -* Added the field `description` to the class `userFullInfo`, containing description of the bot. -* Added the field `emoji` to the class `inputMessageSticker`, allowing to specify the emoji that was used to choose - the sent sticker. -* Added the method `banChatMember` that can be used to ban chat members instead of the method `setChatMemberStatus` and - allows to revoke messages from the banned user in basic groups. -* Allowed to use the method `setChatMemberStatus` for adding chat members. -* Removed the parameter `user_id` from the method `reportSupergroupSpam`. Messages from different senders can now - be reported simultaneously. -* Added the field `feedback_link` to the class `webPageInstantView`. -* Added the method `getApplicationDownloadLink`, returning the link for downloading official Telegram applications. -* Removed unusable search message filters `searchMessagesFilterCall` and `searchMessagesFilterMissedCall`. -* Removed the method `getChatStatisticsUrl`. -* Removed the method `getInviteText` in favor of the method `getApplicationDownloadLink`. -* Added the field `chat_type` to the update `updateNewInlineQuery` for bots. -* Added the update `updateChatMember` for bots. -* Improved the appearance of the [TDLib build instructions generator](https://tdlib.github.io/td/build.html). -* Added support for the illumos operating system. -* Added support for network access on real watchOS devices. -* Added support for OpenSSL 3.0. -* Improved the iOS/watchOS/tvOS build example to generate a universal XCFramework. -* Added support for ARM64 simulators in the iOS/watchOS/tvOS build example. -* Added the option `-release_only` to the build script for Universal Windows Platform, allowing to build - TDLib SDK for Universal Windows Platform in release-only mode. -* Rewritten the native .NET binding using the new `ClientManager` interface: - - Replaced the method `Client.send` with a static method that must be called exactly once in a dedicated thread. - The callbacks `ClientResultHandler` will be called in this thread for all clients. - - Removed the function `Client.Dispose()` from the C++/CLI native binding. The objects of the type `Client` - don't need to be explicitly disposed anymore. -* Rewritten the C binding using the new `ClientManager` interface: - - Renamed the fields `id` in the structs `TdRequest` and `TdResponse` to `request_id`. - - Added the field `client_id` to the struct `TdResponse`. - - Replaced the method `TdCClientCreate` with the method `TdCClientCreateId`. - - Replaced the parameter `instance` with the parameter `client_id` in the function `TdCClientSend`. - - Added the methods `TdCClientReceive` and `TdCClientExecute`. - - Removed the methods `TdCClientSendCommandSync`, `TdCClientDestroy`, and `TdCClientSetVerbosity`. - ------------------------------------------------------------------------------------------------------------------------ - -Changes in 1.7.0 (28 Nov 2020): - -* Added a new simplified JSON interface in which updates and responses to requests from all TDLib instances - are received in the same thread: - - The TDLib instance is identified by the unique `client_id` identifier, which is returned by the method - `td_create_client_id`. - - Use the method `td_send` to send a request to a specified client. The TDLib instance is created on the first - request sent to it. - - Use the method `td_receive` to receive updates and request responses from TDLib. The response will contain - the identifier of the client from which the event was received in the field "@client_id". - - Use the method `td_execute` to synchronously execute suitable TDLib methods. -* Added support for adding chats to more than one chat list: - - Added the class `chatPosition`, describing the position of the chat within a chat list. - - Replaced the fields `chat_list`, `order`, `is_sponsored` and `is_pinned` in the class `chat` with - the field `positions`, containing a list of the chat positions in various chat list. - - Replaced the field `order` with the field `positions` in the updates `updateChatLastMessage` and - `updateChatDraftMessage`. - - Added the update `updateChatPosition`. - - Removed the superfluous updates `updateChatChatList`, `updateChatIsSponsored`, `updateChatOrder` and - `updateChatIsPinned`. - - Added the parameter `chat_list` to the method `toggleChatIsPinned`. - - Added the class `chatLists`, containing a list of chat lists. - - Added the method `getChatListsToAddChat`, returning all chat lists to which a chat can be added. - - Added the method `addChatToList`, which can be used to add a chat to a chat list. - - Remove the method `setChatChatList`. -* Added support for chat filters: - - Added the new chat list type `chatListFilter`. - - Added the classes `chatFilterInfo` and `chatFilter`, describing a filter of user chats. - - Added the update `updateChatFilters`, which is sent when the list of chat filters is changed. - - Added the methods `createChatFilter`, `editChatFilter` and `deleteChatFilter` for managing chat filters. - - Added the method `reorderChatFilters` for changing the order of chat filters. - - Added the method `getChatFilter`, returning full information about a chat filter. - - Added the synchronous method `getChatFilterDefaultIconName`. - - Added the classes `recommendedChatFilter` and `recommendedChatFilters`. - - Added the method `getRecommendedChatFilters`, returning a list of recommended chat filters. -* Added support for messages sent on behalf of chats instead of users: - - Added the class `MessageSender`, representing a user or a chat which sent a message. - - Added the class `MessageSenders`, representing a list of message senders. - - Replaced the field `sender_user_id` with the field `sender` of the type `MessageSender` in the classes `message` - and `notificationTypeNewPushMessage`. - - Added the class `messageForwardOriginChat`, which describe a chat as the original sender of a message. - - Added the ability to search messages sent by a chat by replacing the parameter `sender_user_id` with - the parameter `sender` of the type `MessageSender` in the method `searchChatMessages`. - - Added the ability to specify a chat as a local message sender by replacing the parameter `sender_user_id` with - the parameter `sender` of the type `MessageSender` in the method `addLocalMessage`. -* Added support for video calls: - - Added the class `callServer`, describing a server for relaying call data. - - Added the classes `callServerTypeTelegramReflector` and `callServerTypeWebrtc`, representing different types of - supported call servers. - - Replaced the field `connections` with the field `servers` in the class `callStateReady`. - - Removed the class `callConnection`. - - Added the update `updateNewCallSignalingData`. - - Added the method `sendCallSignalingData`. - - Added the field `supports_video_calls` to the class `userFullInfo`. - - Added the field `is_video` to the class `messageCall`. - - Added the field `is_video` to the class `call`. - - Added the parameter `is_video` to the method `createCall`. - - Added the parameter `is_video` to the method `discardCall`. - - Added two new types of call problems `callProblemDistortedVideo` and `callProblemPixelatedVideo`. - - Added the field `library_versions` to the class `callProtocol`, which must be used to specify all supported - call library versions. -* Added support for multiple pinned messages and the ability to pin messages in private chats: - - Added the ability to pin messages in all private chats. - - Added the ability to pin mutiple messages in all chats. - - Added the field `is_pinned` to the class `message`. - - Added the update `updateMessageIsPinned`. - - Added the parameter `only_for_self` to the method `pinChatMessage`, allowing to pin messages in private chats for - one side only. - - Added the ability to find pinned messages in a chat using the filter `searchMessagesFilterPinned`. - - Added the parameter `message_id` to the method `unpinChatMessage`. - - Added the field `message` to the class `chatEventMessageUnpinned`. - - Added the method `unpinAllChatMessages`, which can be used to simultaneously unpin all pinned messages in a chat. - - Documented that notifications about new pinned messages are always silent in channels and private chats. - - The method `getChatPinnedMessage` now returns the newest pinned message in the chat. - - Removed the field `pinned_message_id` from the class `chat`. - - Removed the update `updateChatPinnedMessage`. -* Improved thumbnail representation and added support for animated MPEG4 thumbnails: - - Added the class `ThumbnailFormat`, representing the various supported thumbnail formats. - - Added the class `thumbnail`, containing information about a thumbnail. - - Changed the type of all thumbnail fields from `photoSize` to `thumbnail`. - - Added support for thumbnails in the format `thumbnailFormatMpeg4` for some animations and videos. - - Replaced the classes `inputInlineQueryResultAnimatedGif` and `inputInlineQueryResultAnimatedMpeg4` with - the generic class `inputInlineQueryResultAnimation`. - - Added support for animated thumbnails in the class `inputInlineQueryResultAnimation`. - - The class `photoSize` is now only used for JPEG images. -* Improved support for user profile photos and chat photos: - - Added the field `photo` to the class `userFullInfo`, containing full information about the user photo. - - Added the field `photo` to the class `basicGroupFullInfo`, containing full information about the group photo. - - Added the field `photo` to the class `supergroupFullInfo`, containing full information about the group photo. - - Renamed the class `chatPhoto` to `chatPhotoInfo`. - - Added the field `has_animation` to the classes `profilePhoto` and `chatPhotoInfo`, which is set to true for - animated chat photos. - - Added the classes `chatPhoto` and `chatPhotos`. - - Added minithumbnail support via the field `minithumbnail` in the class `chatPhoto`. - - Added the class `animatedChatPhoto`. - - Added animated chat photo support via the field `animation` in the class `chatPhoto`. - - Removed the classes `userProfilePhoto` and `userProfilePhotos`. - - Changed the type of the field `photo` in the class `messageChatChangePhoto` to `chatPhoto`. - - Changed the type of the fields `old_photo` and `new_photo` in the class `chatEventPhotoChanged` to `chatPhoto`. - - Changed the return type of the method `getUserProfilePhotos` to `chatPhotos`. - - Added the class `InputChatPhoto`, representing a chat or a profile photo to set. - - Changed the type of the parameter `photo` in the methods `setProfilePhoto` and `setChatPhoto` to - the `InputChatPhoto`. - - Added the ability to explicitly re-use previously set profile photos using the class `inputChatPhotoPrevious`. - - Added the ability to set animated chat photos using the class `inputChatPhotoAnimated`. -* Added support for message threads in supergroups and channel comments: - - Added the field `message_thread_id` to the class `message`. - - Added the class `messageThreadInfo`, containing information about a message thread. - - Added the class `messageReplyInfo`, containing information about replies to a message. - - Added the field `reply_info` to the class `messageInteractionInfo`, containing information about message replies. - - Added the field `can_get_message_thread` to the class `message`. - - Added the method `getMessageThread`, returning information about the message thread to which a message belongs. - - Added the method `getMessageThreadHistory`, returning messages belonging to a message thread. - - Added the parameter `message_thread_id` to the methods `sendMessage`, `sendMessageAlbum` and - `sendInlineQueryResultMessage` for sending messages within a thread. - - Added the parameter `message_thread_id` to the method `searchChatMessages` to search messages within a thread. - - Added the parameter `message_thread_id` to the method `viewMessages`. - - Added the parameter `message_thread_id` to the method `setChatDraftMessage`. - - Added the parameter `message_thread_id` to the method `sendChatAction` to send chat actions to a thread. - - Added the field `message_thread_id` to the update `updateUserChatAction`. -* Improved support for message albums: - - Added support for sending and receiving messages of the types `messageAudio` and `messageDocument` as albums. - - Added automatic grouping into audio or document albums in the method `forwardMessages` if all forwarded or - copied messages are of the same type. - - Removed the parameter `as_album` from the method `forwardMessages`. Forwarded message albums are now determined - automatically. -* Simplified usage of methods generating an HTTP link to a message: - - Added the class `messageLink`, representing an HTTP link to a message. - - Combined the methods `getPublicMessageLink` and `getMessageLink` into the method `getMessageLink`, which - now returns a public link to the message if possible and a private link otherwise. The combined method is - an offline method now. - - Added the parameter `for_comment` to the method `getMessageLink`, which allows to get a message link to the message - that opens it in a thread. - - Removed the class `publicMessageLink`. - - Added the field `for_comment` to the class `messageLinkInfo`. - - Added the separate method `getMessageEmbeddingCode`, returning an HTML code for embedding a message. -* Added the ability to block private messages sent via the @replies bot from chats: - - Added the field `is_blocked` to the class `chat`. - - Added the update `updateChatIsBlocked`. - - Added the method `blockMessageSenderFromReplies`. - - Replaced the methods `blockUser` and `unblockUser` with the method `toggleMessageSenderIsBlocked`. - - Replaced the method `getBlockedUsers` with the method `getBlockedMessageSenders`. -* Added support for incoming messages which are replies to messages in different chats: - - Added the field `reply_in_chat_id` to the class `message`. - - The method `getRepliedMessage` can now return the replied message in a different chat. -* Renamed the class `sendMessageOptions` to `messageSendOptions`. -* Added the new `tdapi` static library, which needs to be additionally linked in when static linking is used. -* Changed the type of the field `value` in the class `optionValueInteger` from `int32` to `int64`. -* Changed the type of the field `description` in the class `webPage` from `string` to `formattedText`. -* Improved Instant View support: - - Added the field `view_count` to the class `webPageInstantView`. - - Added the class `richTextAnchorLink`, containing a link to an anchor on the same page. - - Added the class `richTextReference`, containing a reference to a text on the same page. - - Removed the field `text` from the class `richTextAnchor`. - - Removed the field `url` which is no longer needed from the class `webPageInstantView`. -* Allowed the update `updateServiceNotification` to be sent before authorization is completed. -* Disallowed to pass messages in non-strictly increasing order to the method `forwardMessages`. -* Improved sending copies of messages: - - Added the class `messageCopyOptions` and the field `copy_options` to the class `inputMessageForwarded`. - - Removed the fields `send_copy` and `remove_caption` from the class `inputMessageForwarded`. - - Allowed to replace captions in copied messages using the fields `replace_caption` and `new_caption` in - the class `messageCopyOptions`. - - Allowed to specify `reply_to_message_id` when sending a copy of a message. - - Allowed to specify `reply_markup` when sending a copy of a message. -* Allowed passing multiple input language codes to `searchEmojis` by replacing the parameter `input_language_code` with - the parameter `input_language_codes`. -* Added support for public service announcements: - - Added the class `ChatSource` and the field `source` to the class `chatPosition`. - - Added the new type of chat source `chatSourcePublicServiceAnnouncement`. - - Added the field `public_service_announcement_type` to the class `messageForwardInfo`. -* Added support for previewing of private supergroups and channels by their invite link. - - The field `chat_id` in the class `chatInviteLinkInfo` is now non-zero for private supergroups and channels to which - the temporary read access is granted. - - Added the field `accessible_for` to the class `chatInviteLinkInfo`, containing the amount of time for which - read access to the chat will remain available. -* Improved methods for message search: - - Replaced the field `next_from_search_id` with a string field `next_offset` in the class `foundMessages`. - - Added the field `total_count` to the class `foundMessages`; can be -1 if the total count of matching messages is - unknown. - - Replaced the parameter `from_search_id` with the parameter `offset` in the method `searchSecretMessages`. - - Added the parameter `filter` to the method `searchMessages`. - - Added the parameters `min_date` and `max_date` to the method `searchMessages` to search messages sent only within - a particular timeframe. -* Added pkg-config file generation for all installed libraries. -* Added automatic operating system version detection. Use an empty field `system_version` in - the class `tdlibParameters` for the automatic detection. -* Increased maximum file size from 1500 MB to 2000 MB. -* Added support for human-friendly Markdown formatting: - - Added the synchronous method `parseMarkdown` for human-friendly parsing of text entities. - - Added the synchronous method `getMarkdownText` for replacing text entities with a human-friendly - Markdown formatting. - - Added the writable option "always_parse_markdown" which enables automatic parsing of text entities in - all `inputMessageText` objects. -* Added support for dice with random values in messages: - - Added the class `messageDice` to the types of message content; contains a dice. - - Added the class `DiceStickers`, containing animated stickers needed to show the dice. - - Added the class `inputMessageDice` to the types of new input message content; can be used to send a dice. - - Added the update `updateDiceEmojis`, containing information about supported dice emojis. -* Added support for chat statistics in channels and supergroups: - - Added the field `can_get_statistics` to the class `supergroupFullInfo`. - - Added the class `ChatStatistics`, which represents a supergroup or a channel statistics. - - Added the method `getChatStatistics` returning detailed statistics about a chat. - - Added the classes `chatStatisticsMessageInteractionInfo`, `chatStatisticsAdministratorActionsInfo`, - `chatStatisticsMessageSenderInfo` and `chatStatisticsInviterInfo` representing various parts of chat statistics. - - Added the class `statisticalValue` describing recent changes of a statistical value. - - Added the class `StatisticalGraph` describing a statistical graph. - - Added the method `getStatisticalGraph`, which can be used for loading asynchronous or zoomed in statistical graphs. - - Added the class `dateRange` representing a date range for which statistics are available. - - Removed the field `can_view_statistics` from the class `supergroupFullInfo` and marked - the method `getChatStatisticsUrl` as disabled and not working. -* Added support for detailed statistics about interactions with messages: - - Added the class `messageInteractionInfo`, containing information about message views, forwards and replies. - - Added the field `interaction_info` to the class `message`. - - Added the update `updateMessageInteractionInfo`. - - Added the field `can_get_statistics` to the class `message`. - - Added the class `messageStatistics`. - - Added the method `getMessageStatistics`. - - Added the method `getMessagePublicForwards`, returning all forwards of a message to public channels. - - Removed the now superfluous field `views` from the class `message`. - - Removed the now superfluous update `updateMessageViews`. -* Improved support for native polls: - - Added the field `explanation` to the class `pollTypeQuiz`. - - Added the fields `close_date` and `open_period` to the class `poll`. - - Added the fields `close_date` and `open_period` to the class `inputMessagePoll`; for bots only. - - Increased maximum poll question length to 300 characters for bots. -* Added support for anonymous administrators in supergroups: - - Added the field `is_anonymous` to the classes `chatMemberStatusCreator` and `chatMemberStatusAdministrator`. - - The field `author_signature` in the class `message` can now contain a custom title of the anonymous administrator - that sent the message. -* Added support for a new type of inline keyboard buttons, requiring user password entry: - - Added the class `inlineKeyboardButtonTypeCallbackWithPassword`, representing a button requiring password entry from - a user. - - Added the class `callbackQueryPayloadDataWithPassword`, representing new type of callback button payload, - which must be used for the buttons of the type `inlineKeyboardButtonTypeCallbackWithPassword`. -* Added support for making the location of the user public: - - Added the writable option "is_location_visible" to allow other users see location of the current user. - - Added the method `setLocation`, which should be called if `getOption("is_location_visible")` is true and location - changes by more than 1 kilometer. -* Improved Notification API: - - Added the field `sender_name` to the class `notificationTypeNewPushMessage`. - - Added the writable option "disable_sent_scheduled_message_notifications" for disabling notifications about - outgoing scheduled messages that were sent. - - Added the field `is_outgoing` to the class `notificationTypeNewPushMessage` for recognizing - outgoing scheduled messages that were sent. - - Added the fields `has_audios` and `has_documents` to the class `pushMessageContentMediaAlbum`. -* Added the field `date` to the class `draftMessage`. -* Added the update `updateStickerSet`, which is sent after a sticker set is changed. -* Added support for pagination in trending sticker sets: - - Added the parameters `offset` and `limit` to the method `getTrendingStickerSets`. - - Changed the field `sticker_sets` in the update `updateTrendingStickerSets` to contain only the prefix of - trending sticker sets. -* Messages that failed to send can now be found using the filter `searchMessagesFilterFailedToSend`. -* Added the ability to disable automatic server-side file type detection using the new field - `disable_content_type_detection` of the class `inputMessageDocument`. -* Improved chat action bar: - - Added the field `can_unarchive` to the classes `chatActionBarReportSpam` and `chatActionBarReportAddBlock`, - which is true whenever the chat was automatically archived. - - Added the field `distance` to the class `chatActionBarReportAddBlock`, - which denotes the distance between the users. -* Added support for actions suggested to the user by the server: - - Added the class `SuggestedAction`, representing possible actions suggested by the server. - - Added the update `updateSuggestedActions`. - - Added the method `hideSuggestedAction`, which can be used to dismiss a suggested action. -* Supported attaching stickers to animations: - - Added the field `has_stickers` to the class `animation`. - - Added the field `added_sticker_file_ids` to the class `inputMessageAnimation`. -* Added methods for phone number formatting: - - Added the class `countryInfo`, describing a country. - - Added the class `countries`, containing a list of countries. - - Added the method `getCountries`, returning a list of all existing countries. - - Added the class `phonenumberinfo` and the method `getPhoneNumberInfo`, which can be used to format a phone number - according to local rules. -* Improved location support: - - Added the field `horizontal_accuracy` to the class `location`. - - Added the field `heading` to the classes `messageLocation` and `inputMessageLocation` for live locations. - - Added the parameter `heading` to the methods `editMessageLiveLocation` and `editInlineMessageLiveLocation`. -* Added support for proximity alerts in live locations: - - Added the field `proximity_alert_radius` to the classes `messageLocation` and `inputMessageLocation`. - - Added the parameter `proximity_alert_radius` to the methods `editMessageLiveLocation` and - `editInlineMessageLiveLocation`. - - Added the new message content `messageProximityAlertTriggered`, received whenever a proximity alert is triggered. -* Added `CentOS 7` and `CentOS 8` operating systems to the - [TDLib build instructions generator](https://tdlib.github.io/td/build.html). -* Added the CMake configuration option TD_ENABLE_MULTI_PROCESSOR_COMPILATION, which can be used to enable parallel - build with MSVC. -* Added support for sending and receiving messages in secret chats with silent notifications. -* Added the field `progressive_sizes` to the class `photo` to allow partial progressive JPEG photo download. -* Added the field `redirect_stderr` to the class `logStreamFile` to allow explicit control over stderr redirection to - the log file. -* Added the read-only option "can_archive_and_mute_new_chats_from_unknown_users", which can be used to check, whether - the option "archive_and_mute_new_chats_from_unknown_users" can be changed. -* Added the writable option "archive_and_mute_new_chats_from_unknown_users", which can be used to automatically archive - and mute new chats from non-contacts. The option can be set only if the option - "can_archive_and_mute_new_chats_from_unknown_users" is true. -* Added the writable option "message_unload_delay", which can be used to change the minimum delay before messages are - unloaded from the memory. -* Added the writable option "disable_persistent_network_statistics", which can be used to disable persistent - network usage statistics, significantly reducing disk usage. -* Added the writable option "disable_time_adjustment_protection", which can be used to disable protection from - external time adjustment, significantly reducing disk usage. -* Added the writable option "ignore_default_disable_notification" to allow the application to manually specify the - `disable_notification` option each time when sending messages instead of following the default per-chat settings. -* Added the read-only option "telegram_service_notifications_chat_id", containing the identifier of - the Telegram service notifications chat. -* Added the read-only option "replies_bot_chat_id", containing the identifier of the @replies bot. -* Added the read-only option "group_anonymous_bot_user_id", containing the identifier of the bot which is shown as - the sender of anonymous group messages when viewed from an outdated client. -* Added the new venue provider value "gplaces" for Google Places. -* Added the parameter `return_deleted_file_statistics` to the method `optimizeStorage` to return information about - the files that were deleted instead of the ones that were not. -* Added the ability to search for supergroup members to mention by their name and username: - - Added the new filter `supergroupMembersFilterMention` for the method `getSupergroupMembers`. - - Added the new filter `chatMembersFilterMention` for the method `searchChatMembers`. -* Added support for highlighting bank card numbers: - - Added the new text entity `textEntityTypeBankCardNumber`. - - Added the classes `bankCardInfo` and `bankCardActionOpenUrl`, containing information about a bank card. - - Added the method `getBankCardInfo`, returning information about a bank card. -* Improved methods for managing sticker sets by bots: - - Added the method `setStickerSetThumbnail`. - - Added the ability to create new animated sticker sets and add new stickers to them by adding - the class `inputStickerAnimated`. - - Renamed the class `inputSticker` to `inputStickerStatic`. - - Renamed the field `png_sticker` to `sticker` in the class `inputStickerStatic`. -* Added the method `setCommands` for bots. -* Added the method `getCallbackQueryMessage` for bots. -* Added support for starting bots in private chats through `sendBotStartMessage`. -* Added the field `total_count` to the class `chats`. The field should have a precise value for the responses of - the methods `getChats`, `searchChats` and `getGroupsInCommon`. -* Added the update `updateAnimationSearchParameters`, containing information about animation search parameters. -* Documented that `getRepliedMessage` can be used to get a pinned message, a game message, or an invoice message for - messages of the types `messagePinMessage`, `messageGameScore`, and `messagePaymentSuccessful` respectively. -* Added guarantees that the field `member_count` in the class `supergroup` is known if the supergroup was received from - the methods `searchChatsNearby`, `getInactiveSupergroupChats`, `getSuitableDiscussionChats`, `getGroupsInCommon`, or - `getUserPrivacySettingRules`. -* Updated SQLCipher to 4.4.0. -* Updated dependencies in the prebuilt TDLib for Android: - - Updated SDK to SDK 30. - - Updated NDK to r21d, which dropped support for 32-bit ARM devices without Neon support. -* Updated recommended `emsdk` version for `tdweb` building to the 2.0.6. -* Removed the ability to change the update handler after client creation in native .NET binding, Java example and - prebuilt library for Android. -* Removed the ability to change the default exception handler after client creation in Java example and - prebuilt library for Android. -* Removed the ability to close Client using close() method in Java example and prebuilt library for Android. - Use the method TdApi.close() instead. -* Changed license of source code in prebuilt library for Android to Boost Software License, Version 1.0. - ------------------------------------------------------------------------------------------------------------------------ - -Changes in 1.6.0 (31 Jan 2020): - -* Added support for multiple chat lists. Currently, only two chat lists Main and Archive are supported: - - Added the class `ChatList`, which represents a chat list and could be `chatListMain` or `chatListArchive`. - - Added the field `chat_list` to the class `chat`, denoting the chat list to which the chat belongs. - - Added the parameter `chat_list` to the methods `getChats`, `searchMessages` and `setPinnedChats`. - - Added the field `chat_list` to the updates `updateUnreadMessageCount` and `updateUnreadChatCount`. - - Added the field `total_count` to the update `updateUnreadChatCount`, containing the total number of chats in - the list. - - Added the update `updateChatChatList`, which is sent after a chat is moved to or from a chat list. - - Added the method `setChatChatList`, which can be used to move a chat between chat lists. - - Added the option `pinned_archived_chat_count_max` for the maximum number of pinned chats in the Archive chat list. -* Added support for scheduled messages: - - Added the classes `messageSchedulingStateSendAtDate` and `messageSchedulingStateSendWhenOnline`, - representing the scheduling state of a message. - - Added the field `scheduling_state` to the class `message`, which allows to distinguish between scheduled and - ordinary messages. - - The update `updateNewMessage` can now contain a scheduled message and must be handled appropriately. - - The updates `updateMessageContent`, `updateDeleteMessages`, `updateMessageViews`, `updateMessageSendSucceeded`, - `updateMessageSendFailed`, and `updateMessageSendAcknowledged` can now contain identifiers of scheduled messages. - - Added the class `sendMessageOptions`, which contains options for sending messages, - including the scheduling state of the messages. - - Replaced the parameters `disable_notification` and `from_background` in the methods `sendMessage`, - `sendMessageAlbum`, `sendInlineQueryResultMessage`, and `forwardMessages` with the new field `options` of - the type `sendMessageOptions`. - - Added the method `editMessageSchedulingState`, which can be used to reschedule a message or send it immediately. - - Added the method `getChatScheduledMessages`, which returns all scheduled messages in a chat. - - Added the field `has_scheduled_messages` to the class `chat`. - - Added the update `updateChatHasScheduledMessages`, which is sent whenever the field `has_scheduled_messages` - changes in a chat. - - Added support for reminders in Saved Messages and notifications about other sent scheduled messages in - the [Notification API](https://core.telegram.org/tdlib/notification-api/). -* Added support for adding users without a known phone number to the list of contacts: - - Added the method `addContact` for adding or renaming contacts without a known phone number. - - Added the field `need_phone_number_privacy_exception` to the class `userFullInfo`, containing the default value for - the second parameter of the method `addContact`. - - Added the fields `is_contact` and `is_mutual_contact` to the class `user`. - - Removed the class `LinkState` and the fields `outgoing_link` and `incoming_link` from the class `user`. -* Improved support for the top chat action bar: - - Added the class `ChatActionBar`, representing all possible types of the action bar. - - Added the field `action_bar` to the class `chat`. - - Removed the legacy class `chatReportSpamState`. - - Removed the legacy methods `getChatReportSpamState` and `changeChatReportSpamState`. - - Added the update `updateChatActionBar`. - - Added the method `removeChatActionBar`, which allows to dismiss the action bar. - - Added the method `sharePhoneNumber`, allowing to share the phone number of the current user with a mutual contact. - - Added the new reason `chatReportReasonUnrelatedLocation` for reporting location-based groups unrelated to - their stated location. -* Improved support for text entities: - - Added the new types of text entities `textEntityTypeUnderline` and `textEntityTypeStrikethrough`. - - Added support for nested entities. Entities can be nested, but must not mutually intersect with each other. - Pre, Code and PreCode entities can't contain other entities. Bold, Italic, Underline and Strikethrough entities can - contain and be contained in all other entities. All other entities can't contain each other. - - Added the field `version` to the method `textParseModeMarkdown`. Versions 0 and 1 correspond to Bot API Markdown - parse mode, version 2 to Bot API MarkdownV2 parse mode with underline, strikethrough and nested entities support. - - The new entity types and nested entities are supported in secret chats also if its layer is at least 101. -* Added support for native non-anonymous, multiple answer, and quiz-style polls: - - Added support for quiz-style polls, which has exactly one correct answer option and can be answered only once. - - Added support for regular polls, which allows multiple answers. - - Added the classes `pollTypeRegular` and `pollTypeQuiz`, representing the possible types of a poll. - - Added the field `type` to the classes `poll` and `inputMessagePoll`. - - Added support for non-anonymous polls with visible votes by adding the field `is_anonymous` to the classes `poll` - and `inputMessagePoll`. - - Added the method `getPollVoters` returning users that voted for the specified option in a non-anonymous poll. - - Added the new reply markup keyboard button `keyboardButtonTypeRequestPoll`. - - Added the field `is_regular` to the class `pushMessageContentPoll`. - - Added the update `updatePollAnswer` for bots only. - - Added the field `is_closed` to the class `inputMessagePoll`, which can be used by bots to send a closed poll. -* Clarified in the documentation that file remote ID is guaranteed to be usable only if the corresponding file is - still accessible to the user and is known to TDLib. For example, if the file is from a message, then the message - must be not deleted and accessible to the user. If the file database is disabled, then the corresponding object with - the file must be preloaded by the client. -* Added support for administrator custom titles: - - Added the field `custom_title` to `chatMemberStatusCreator` and `chatMemberStatusAdministrator` classes. - - Added the classes `chatAdministrator` and `chatAdministrators`, containing user identifiers along with - their custom administrator title and owner status. - - Replaced the result type of the method `getChatAdministrators` with `chatAdministrators`. -* Improved Instant View support: - - Added the new web page block `pageBlockVoiceNote`. - - Changed value of invisible cells in `pageBlockTableCell` to null. - - Added the field `is_cached` to the class `richTextUrl`. -* Improved support for chat backgrounds: - - Added the classes `backgroundFillSolid` for solid color backgrounds and `backgroundFillGradient` for - gradient backgrounds. - - Added support for TGV (gzipped subset of SVG with MIME type "application/x-tgwallpattern") background patterns - in addition to PNG patterns. Background pattern thumbnails are still always in PNG format. - - Replaced the field `color` in the class `backgroundTypePattern` with the field `fill` of type `BackgroundFill`. - - Replaced the class `backgroundTypeSolid` with the class `backgroundTypeFill`. -* Added support for discussion groups for channel chats: - - Added the field `linked_chat_id` to the class `supergroupFullInfo` containing the identifier of a discussion - supergroup for the channel, or a channel, for which the supergroup is the designated discussion supergroup. - - Added the field `has_linked_chat` to the class `supergroup`. - - Added the method `getSuitableDiscussionChats`, which returns a list of chats which can be assigned as - a discussion group for a channel by the current user. - - Added the method `setChatDiscussionGroup`, which can be used to add or remove a discussion group from a channel. - - Added the class `chatEventLinkedChatChanged` representing a change of the linked chat in the chat event log. -* Added support for slow mode in supergroups: - - Added the field `is_slow_mode_enabled` to the class `supergroup`. - - Added the field `slow_mode_delay` to the class `supergroupFullInfo`. - - Added the method `setChatSlowModeDelay`, which can be used to change the slow mode delay setting in a supergroup. - - Added the class `chatEventSlowModeDelayChanged` representing a change of the slow mode delay setting in - the chat event log. -* Improved privacy settings support: - - Added the classes `userPrivacySettingRuleAllowChatMembers` and `userPrivacySettingRuleRestrictChatMembers` - to include or exclude all group members in a privacy setting rule. - - Added the class `userPrivacySettingShowPhoneNumber` for managing the visibility of the user's phone number. - - Added the class `userPrivacySettingAllowFindingByPhoneNumber` for managing whether the user can be found by - their phone number. -* Added the method `checkCreatedPublicChatsLimit` for checking whether the maximum number of owned public chats - has been reached. -* Added support for transferring ownership of supergroup and channel chats: - - Added the method `transferChatOwnership`. - - Added the class `CanTransferOwnershipResult` and the method `canTransferOwnership` for checking - whether chat ownership can be transferred from the current session. -* Added support for location-based supergroups: - - Added the class `chatLocation`, which contains the location to which the supergroup is connected. - - Added the field `has_location` to the class `supergroup`. - - Added the field `location` to the class `supergroupFullInfo`. - - Added the ability to create location-based supergroups via the new field `location` in - the method `createNewSupergroupChat`. - - Added the method `setChatLocation`, which allows to change location of location-based supergroups. - - Added the field `can_set_location` to the class `supergroupFullInfo`. - - Added the class `PublicChatType`, which can be one of `publicChatTypeHasUsername` or - `publicChatTypeIsLocationBased`. - - Added the parameter `type` to the method `getCreatedPublicChats`, which allows to get location-based supergroups - owned by the user. - - Supported location-based supergroups as public chats where appropriate. - - Added the class `chatEventLocationChanged` representing a change of the location of a chat in the chat event log. -* Added support for searching chats and users nearby: - - Added the classes `chatNearby` and `chatsNearby`, containing information about chats along with - the distance to them. - - Added the method `searchChatsNearby`, which returns chats and users nearby. - - Added the update `updateUsersNearby`, which is sent 60 seconds after a successful `searchChatsNearby` request. -* Improved support for inline keyboard buttons of the type `inlineKeyboardButtonTypeLoginUrl`: - - Added the class `LoginUrlInfo` and the method `getLoginUrlInfo`, which allows to get information about - an inline button of the type `inlineKeyboardButtonTypeLoginUrl`. - - Added the method `getLoginUrl` for automatic authorization on the target website. -* Improved support for content restrictions: - - The field `restriction_reason` in the classes `user` and `channel` now contains only a human-readable description - why access must be restricted. It is non-empty if and only if access to the chat needs to be restricted. - - Added the field `restriction_reason` to the class `message`. It is non-empty if and only if access to the message - needs to be restricted. - - Added the writable option `ignore_platform_restrictions`, which can be set in non-store apps to ignore restrictions - specific to the currently used operating system. - - Added the writable option `ignore_sensitive_content_restrictions`, which can be set to show sensitive content on - all user devices. `getOption("ignore_sensitive_content_restrictions")` can be used to fetch the actual value of - the option, the option will not be immediately updated after a change from another device. - - Added the read-only option `can_ignore_sensitive_content_restrictions`, which can be used to check, whether - the option `ignore_sensitive_content_restrictions` can be changed. -* Added support for QR code authentication for already registered users: - - Added the authorization state `authorizationStateWaitOtherDeviceConfirmation`. - - Added the method `requestQrCodeAuthentication`, which can be used in the `authorizationStateWaitPhoneNumber` state - instead of the method `setAuthenticationPhoneNumber` to request QR code authentication. - - Added the method `confirmQrCodeAuthentication` for authentication confirmation from another device. -* Added the update `updateMessageLiveLocationViewed`, which is supposed to trigger an edit of the corresponding - live location. -* Added the parameter `input_language_code` to the method `searchEmojis`. -* Added the method `getInactiveSupergroupChats`, to be used when the user receives a CHANNELS_TOO_MUCH error after - reaching the limit on the number of joined supergroup and channel chats. -* Added the field `unique_id` to the class `remoteFile`, which can be used to identify the same file for - different users. -* Added the new category of top chat list `topChatCategoryForwardChats`. -* Added the read-only option `animated_emoji_sticker_set_name`, containing name of a sticker set with animated emojis. -* Added the read-only option `unix_time`, containing an estimation of the current Unix timestamp. - The option will not be updated automatically unless the difference between the previous estimation and - the locally available monotonic clocks changes significantly. -* Added the field `is_silent` to the class `notification`, so silent notifications can be shown with - the appropriate mark. -* Added the field `video_upload_bitrate` to the class `autoDownloadSettings`. -* Disallowed to call `setChatNotificationSettings` method on the chat with self, which never worked. -* Added support for `ton://` URLs in messages and inline keyboard buttons. - ------------------------------------------------------------------------------------------------------------------------ - -Changes in 1.5.0 (9 Sep 2019): - -* Changed authorization workflow: - - Added the state `authorizationStateWaitRegistration`, which will be received after `authorizationStateWaitCode` for - users who are not registered yet. - - Added the method `registerUser`, which must be used in the `authorizationStateWaitRegistration` state to finish - registration of the user. - - Removed the fields `is_registered` and `terms_of_service` from the class `authorizationStateWaitCode`. - - Removed the parameters `first_name` and `last_name` from the method `checkAuthenticationCode`. -* Added support for messages with an unknown sender (zero `sender_user_id`) in private chats, basic groups and - supergroups. Currently, the sender is unknown for posts in channels and for channel posts automatically forwarded to - the discussion group. -* Added support for the new permission system for non-administrator users in groups: - - Added the class `chatPermissions` containing all supported permissions, including new permissions `can_send_polls`, - `can_change_info`, `can_invite_users` and `can_pin_messages`. - - Added the field `permissions` to the class `chat`, describing actions that non-administrator chat members are - allowed to take in the chat. - - Added the update `updateChatPermissions`. - - Added the method `setChatPermissions` for changing chat permissions. - - Added the class `chatEventPermissionsChanged` representing a change of chat permissions in the chat event log. - - Replaced the fields `can_send_messages`, `can_send_media_messages`, `can_send_other_messages`, - `can_add_web_page_previews` in the class `chatMemberStatusRestricted` with the field `permissions` of - the type `chatPermissions`. - - Removed the field `everyone_is_administrator` from the `basicGroup` class in favor of the field `permissions` of - the class `chat`. - - Removed the field `anyone_can_invite` from the `supergroup` class in favor of the field `permissions` of - the class `chat`. - - Removed the method `toggleBasicGroupAdministrators` in favor of `setChatPermissions`. - - Removed the method `toggleSupergroupInvites` in favor of `setChatPermissions`. - - Renamed the field `anyone_can_invite` to `can_invite_users` in the class `chatEventInvitesToggled`. - - The permissions `can_send_other_messages` and `can_add_web_page_previews` now imply only `can_send_messages` - instead of `can_send_media_messages`. - - Allowed administrators in basic groups to use the method `generateChatInviteLink`. -* Added out of the box `OpenBSD` and `NetBSD` operating systems support. -* Added possibility to use `LibreSSL` >= 2.7.0 instead of `OpenSSL` to build TDLib. -* Added instructions for building TDLib on `Debian 10`, `OpenBSD` and `NetBSD` to - the [TDLib build instructions generator](https://tdlib.github.io/td/build.html). -* Added support for Backgrounds 2.0: - - Added the classes `BackgroundType`, `background`, `backgrounds` and `InputBackground`. - - Added the method `getBackground` returning the list of backgrounds installed by the user. - - Added the method `setBackground` for changing the background selected by the user. - - Added the update `updateSelectedBackground`, which is sent right after a successful initialization and whenever - the selected background changes. - - Added the method `removeBackground` for removing a background from the list of installed backgrounds. - - Added the method `resetBackgrounds` for restoring the default list of installed backgrounds. - - Added the method `searchBackground` returning a background by its name. - - Added the method `getBackgroundUrl` returning a persistent URL for a background. - - Removed the `getWallpapers` method. - - Removed the `wallpaper` and the `wallpapers` classes. - - The class `fileTypeWallpaper` can be used for remote file identifiers of both old wallpapers and new backgrounds. -* Added support for descriptions in basic groups: - - Added the field `description` to the class `basicGroupFullInfo`. - - Replaced the method `setSupergroupDescription` with `setChatDescription` which can be used for any chat type. -* Added support for emoji suggestions: - - Added the method `searchEmojis` for searching emojis by keywords. - - Added the method `getEmojiSuggestionsUrl`, which can be used to automatically log in to the translation platform - and suggest new emoji replacements. - - Renamed the class `stickerEmojis` to `emojis`. -* Changed type of the fields `old_photo` and `new_photo` in the class `chatEventPhotoChanged` from `chatPhoto` to - `photo`. -* Changed recommended size for `inputThumbnail` from 90x90 to 320x320. -* Combined all supported settings for phone number authentication: - - Added the class `phoneNumberAuthenticationSettings` which contains all the settings. - - Replaced the parameters `is_current_phone_number` and `allow_flash_call` in the methods - `setAuthenticationPhoneNumber`, `sendPhoneNumberConfirmationCode`, `sendPhoneNumberVerificationCode` and - `changePhoneNumber` with the parameter `settings` of the type `phoneNumberAuthenticationSettings`. - - Added support for automatic SMS code verification for official applications via the new field `allow_app_hash` in - the class `phoneNumberAuthenticationSettings`. -* Added support for auto-download settings presets. - - Added the classes `autoDownloadSettings` and `autoDownloadSettingsPresets`. - - Added the method `getAutoDownloadSettingsPresets` for getting the settings. - - Added the method `setAutoDownloadSettings`, which needs to be called whenever the user changes the settings. -* Added support for minithumbnails - thumbnail images of a very poor quality and low resolution: - - Added the class `minithumbnail`. - - Added the field `minithumbnail` to `animation`, `document`, `photo`, `video` and `videoNote` classes. - - Added the field `audio_cover_minithumbnail` to the class `audio`. -* Added support for resending messages which failed to send: - - Added the fields `error_code`, `error_message`, `can_retry` and `retry_after` to - the class `messageSendingStateFailed`. - - Added the method `resendMessages`. -* Added the field `is_animated` to the `sticker`, `stickerSet` and `stickerSetInfo` classes. - Animated stickers can be received anywhere where non-animated stickers can appear. -* Added the parameters `send_copy` and `remove_caption` to the `forwardMessages` method to allow forwarding of - messages without links to the originals. -* Added the fields `send_copy` and `remove_caption` to `inputMessageForwarded` method to allow forwarding of - a message without link to the original message. -* Added the method `getMessageLinkInfo` for getting information about a link to a message in a chat. -* Added the class `userPrivacySettingShowProfilePhoto` for managing visibility of the user's profile photo. -* Added the class `userPrivacySettingShowLinkInForwardedMessages` for managing whether a link to the user's account is - included with forwarded messages. -* Added the field `thumbnail` to the classes `stickerSet` and `stickerSetInfo`, containing a thumbnail for - the sticker set. -* Added the field `is_scam` to the classes `user` and `supergroup`. -* Added a new kind of inline keyboard button `inlineKeyboardButtonTypeLoginUrl`, which for the moment must be processed - in the same way as an `inlineKeyboardButtonTypeUrl`. -* Added the new class `supergroupMembersFilterContacts`, allowing to only search for contacts - in `getSupergroupMembers`. -* Added the new class `chatMembersFilterContacts`, allowing to only search for contacts in `searchChatMembers`. -* Added the class `chatEventPollStopped` representing the closing of a poll in a message in the chat event log. -* Added ability to specify the exact types of problems with a call in the method `sendCallRating` and - the new class `CallProblem`. -* Changes in [tdweb](https://github.com/tdlib/td/blob/master/example/web/): - - Supported non-zero `offset` and `limit` in `readFilePart`. - ------------------------------------------------------------------------------------------------------------------------ - -Changes in 1.4.0 (1 May 2019): - -* Added a [TDLib build instructions generator](https://tdlib.github.io/td/build.html), covering in details - TDLib building on the most popular operating systems. -* Added an example of TDLib building and usage from a browser. - See https://github.com/tdlib/td/blob/master/example/web/ for more details. -* Allowed to pass NULL pointer to `td_json_client_execute` instead of a previously created JSON client. - Now you can use synchronous TDLib methods through a JSON interface before creating a TDLib JSON client. -* Added support for media streaming by allowing to download any part of a file: - - Added the `offset` parameter to `downloadFile` which specifies the starting position - from which the file should be downloaded. - - Added the `limit` parameter to `downloadFile` which specifies how many bytes should be downloaded starting from - the `offset` position. - - Added the field `download_offset` to the class `localFile` which contains the current download offset. - - The field `downloaded_prefix_size` of the `localFile` class now contains the number of available bytes - from the position `download_offset` instead of from the beginning of the file. - - Added the method `getFileDownloadedPrefixSize` which can be used to get the number of locally available file bytes - from a given offset without actually changing the download offset. -* Added the parameter `synchronous` to `downloadFile` which causes the request to return the result only after - the download is completed. -* Added support for native polls in messages: - - Added `messagePoll` to the types of message content; contains a poll. - - Added the classes `poll` and `pollOption` describing a poll and a poll answer option respectively. - - Added `inputMessagePoll` to the types of new input message content; can be used to send a poll. - - Added the method `setPollAnswer` which can be used for voting in polls. - - Added the method `stopPoll` which can be used to stop polls. Use the `Message.can_be_edited` field to check whether - this method can be called on a message. - - Added the update `updatePoll` for bots only. Ordinary users receive poll updates through `updateMessageContent`. -* Added a Notification API. See article https://core.telegram.org/tdlib/notification-api for a detailed description. - - Added the class `pushReceiverId` which contains a globally unique identifier of the push notification subscription. - - Changed the return type of the method `registerDevice` to `pushReceiverId` to allow matching of push notifications - with TDLib instances. - - Removed the fields `disable_notification` and `contains_mention` from `updateNewMessage`. - - Renamed the class `deviceTokenGoogleCloudMessaging` to `deviceTokenFirebaseCloudMessaging`. - - Added the field `encrypt` to classes `deviceTokenApplePushVoIP` and `deviceTokenFirebaseCloudMessaging` - which allows to subscribe for end-to-end encrypted push notifications. - - Added the option `notification_group_count_max` which can be used to enable the Notification API and set - the maximum number of notification groups to be shown simultaneously. - - Added the option `notification_group_size_max` which can be used to set the maximum number of simultaneously shown - notifications in a group. - - Added the synchronous method `getPushReceiverId` for matching a push notification with a TDLib instance. - - Added the method `processPushNotification` for handling of push notifications. - - Removed the method `processDcUpdate` in favor of the general `processPushNotification` method. - - Added the update `updateNotificationGroup`, sent whenever a notification group changes. - - Added the update `updateNotification`, sent whenever a notification changes. - - Added the update `updateActiveNotifications` for syncing the list of active notifications on startup. - - Added the update `updateHavePendingNotifications` which can be used to improve lifetime handling of - the TDLib instance. - - Added the possibility to disable special handling of notifications about pinned messages via the new settings - `use_default_disable_pinned_message_notifications`, `disable_pinned_message_notifications` in - the class `chatNotificationSettings` and the new setting `disable_pinned_message_notifications` in - the class `scopeNotificationSettings`. - - Added the possibility to disable special handling of notifications about mentions and replies via the new settings - `use_default_disable_mention_notifications`, `disable_mention_notifications` in - the class `chatNotificationSettings` and the new setting `disable_mention_notifications` in - the class `scopeNotificationSettings`. - - Added the class `PushMessageContent` describing the content of a notification, received through - a push notification. - - Added the class `NotificationType` describing a type of notification. - - Added the class `notification` containing information about a notification. - - Added the class `NotificationGroupType` describing a type of notification group. - - Added the class `notificationGroup` describing a state of a notification group. - - Added the methods `removeNotification` and `removeNotificationGroup` for handling notifications removal - by the user. - - Added the separate notification scope `notificationSettingsScopeChannelChats` for channel chats. -* Added support for pinned notifications in basic groups and Saved Messages: - - Added the field `pinned_message_id` to the class `chat`. - - Removed the field `pinned_message_id` from the class `supergroupFullInfo` in favor of `chat.pinned_message_id`. - - Added the update `updateChatPinnedMessage`. - - The right `can_pin_messages` is now applicable to both basic groups and supergroups. - - Replaced the method `pinSupergroupMessage` with `pinChatMessage` which can be used for any chat type. - - Replaced the method `unpinSupergroupMessage` with `unpinChatMessage` which can be used for any chat type. -* Added new synchronous methods for managing TDLib internal logging. The old functions are deprecated and - will be removed in TDLib 2.0.0. - - Added the synchronous method `setLogStream` for changing the stream to which the TDLib internal log is written. - - Added the synchronous method `getLogStream` for getting information about the currently used log stream. - - Added the classes `logStreamDefault`, `logStreamFile` and `logStreamEmpty` describing different supported kinds of - log streams. - - Added the class `logVerbosityLevel` containing the verbosity level of the TDLib internal log. - - Added the class `logTags` containing a list of available TDLib internal log tags. - - Added the synchronous method `setLogVerbosityLevel` for changing verbosity level of logging. - - Added the synchronous method `getLogVerbosityLevel` for getting the current verbosity level of logging. - - Added the synchronous method `getLogTags` returning all currently supported log tags. - - Added the synchronous method `setLogTagVerbosityLevel` for changing the verbosity level of logging for - some specific part of the code. - - Added the synchronous method `getLogTagVerbosityLevel` for getting the current verbosity level for a specific part - of the code. - - Added the synchronous method `addLogMessage` for using the TDLib internal log by the application. -* Added support for Instant View 2.0: - - Replaced the field `has_instant_view` in class `webPage` with the `instant_view_version` field. - - Added the field `version` to the class `webPageInstantView`. - - Added the class `pageBlockCaption`. - - Changed the type of `caption` fields in `pageBlockAnimation`, `pageBlockAudio`, `pageBlockPhoto`, `pageBlockVideo`, - `pageBlockEmbedded`, `pageBlockEmbeddedPost`, `pageBlockCollage` and `pageBlockSlideshow` from - `RichText` to `pageBlockCaption`. - - Added the class `pageBlockListItem` and replaced the content of the `pageBlockList` class with a list of - `pageBlockListItem`. - - Added 6 new kinds of `RichText`: `richTextSubscript`, `richTextSuperscript`, `richTextMarked`, - `richTextPhoneNumber`, `richTextIcon` and `richTextAnchor`. - - Added new classes `pageBlockRelatedArticle`, `PageBlockHorizontalAlignment`, `PageBlockVerticalAlignment` and - `pageBlockTableCell`. - - Added new block types `pageBlockKicker`, `pageBlockRelatedArticles`, `pageBlockTable`, `pageBlockDetails` and - `pageBlockMap`. - - Added the flag `is_rtl` to the class `webPageInstantView`. - - Renamed the field `caption` in classes `pageBlockBlockQuote` and `pageBlockPullQuote` to `credit`. - - Dimensions in `pageBlockEmbedded` can now be unknown. - - Added the field `url` to `pageBlockPhoto` which contains a URL that needs to be opened when the photo is clicked. - - Added the field `url` to `webPageInstantView` which must be used for the correct handling of anchors. -* Added methods for confirmation of the 2-step verification recovery email address: - - Added the method `checkRecoveryEmailAddressCode` for checking the verification code. - - Added the method `resendRecoveryEmailAddressCode` for resending the verification code. - - Replaced the field `unconfirmed_recovery_email_address_pattern` in the class `passwordState` with - the `recovery_email_address_code_info` field containing full information about the code. - - The necessity of recovery email address confirmation in `setPassword` and `setRecoveryEmailAddress` methods - is now returned by the corresponding `passwordState` and not by the error `EMAIL_UNCONFIRMED`. -* Improved the `MessageForwardInfo` class and added support for hidden original senders: - - Removed the old `messageForwardedPost` and `messageForwardedFromUser` classes. - - Added the class `messageForwardInfo` which contains information about the origin of the message, original sending - date and identifies the place from which the message was forwarded the last time for messages forwarded to - Saved Messages. - - Added the classes `messageForwardOriginUser`, `messageForwardOriginHiddenUser` and `messageForwardOriginChannel` - which describe the exact origins of a message. -* Improved getting the list of user profile photos: - - Added the class `userProfilePhoto`, containing `id`, `added_date` and `sizes` of a profile photo. - - Changed the type of the field `photos` in `userProfilePhotos` to a list of `userProfilePhoto` instead of - a list of `photo`. `getUserProfilePhotos` now returns a date for each profile photo. - - Removed the field `id` from the class `photo` (this field was only needed in the result of `getUserProfilePhotos`). -* Added the possibility to get a Telegram Passport authorization form before asking the user for a password: - - Removed the parameter `password` from the method `getPassportAuthorizationForm`. - - Moved the fields `elements` and `errors` from the class `passportAuthorizationForm` to - the new class `passportElementsWithErrors`. - - Added the method `getPassportAuthorizationFormAvailableElements` that takes the user's password and - returns previously uploaded Telegram Passport elements and errors in them. -* Added the field `file_index` to the classes `passportElementErrorSourceFile` and - `passportElementErrorSourceTranslationFile`. -* Added the method `getCurrentState` returning all updates describing the current `TDLib` state. It can be used to - restore the correct state after connecting to a running TDLib instance. -* Added the class `updates` which contains a list of updates and is returned by the `getCurrentState` method. -* Added the update `updateChatOnlineMemberCount` which is automatically sent for open group chats if the number of - online members in a group changes. -* Added support for custom language packs downloaded from the server: - - Added the fields `base_language_pack_id`` to the class `languagePackInfo`. Strings from the base language pack - must be used for untranslated keys from the chosen language pack. - - Added the fields `plural_code`, `is_official`, `is_rtl`, `is_beta`, `is_installed`, `total_string_count`, - `translated_string_count`, `translation_url` to the class `languagePackInfo`. - - Added the method `addCustomServerLanguagePack` which adds a custom server language pack to the list of - installed language packs. - - Added the method `getLanguagePackInfo` which can be used for handling `https://t.me/setlanguage/...` links. - - Added the method `synchronizeLanguagePack` which can be used to fetch the latest versions of all strings from - a language pack. - The method doesn't need to be called explicitly for the current used/base language packs. - - The method `deleteLanguagePack` now also removes the language pack from the list of installed language packs. -* Added the method `getChatNotificationSettingsExceptions` which can be used to get chats with - non-default notification settings. -* Added the parameter `hide_via_bot` to `sendInlineQueryResultMessage` which can be used for - `getOption("animation_search_bot_username")`, `getOption("photo_search_bot_username")` and - `getOption("venue_search_bot_username")` bots to hide that the message was sent via the bot. -* Added the class `chatReportReasonChildAbuse` which can be used to report a chat for child abuse. -* Added the method `getMessageLocally` which returns a message only if it is available locally without - a network request. -* Added the method `writeGeneratedFilePart` which can be used to write a generated file if there is no direct access to - TDLib's file system. -* Added the method `readFilePart` which can be used to read a file from the TDLib file cache. -* Added the class `filePart` to represent the result of the new `readFilePart` method. -* Added the field `log_size` to the `storageStatisticsFast` class which contains the size of the TDLib internal log. - Previously the size was included into the value of the `database_size` field. -* Added the field `language_pack_database_size` to the `storageStatisticsFast` class which contains the size of the - language pack database. -* Added the field `is_support` to the class `user` which can be used to identify Telegram Support accounts. -* Added the class `HttpUrl` encapsulating an HTTP URL. -* Added the method `getMessageLink` which can be used to create a private link (which works only for members) to - a message in a supergroup or channel. -* Added support for channel statistics (coming soon): - - Added the field `can_view_statistics` to the `supergroupFullInfo` class. - - Added the method `getChatStatisticsUrl` which returns a URL with the chat statistics. -* Added support for server-side peer-to-peer calls privacy: - - Added the class `userPrivacySettingAllowPeerToPeerCalls` for managing privacy. - - Added the field `allow_p2p` to `callStateReady` class which must be used to determine whether - a peer-to-peer connection can be used. -* Added the option `ignore_background_updates` which allows to skip all updates received while the TDLib instance was - not running. The option does nothing if the database or secret chats are used. -* Added the read-only option `expect_blocking`, suggesting whether Telegram is blocked for the user. -* Added the read-only option `enabled_proxy_id`, containing the ID of the enabled proxy. -* Added the ability to identify password pending sessions (where the code was entered but not - the two-step verification password) via the flag `is_password_pending` in the `session` class. - TDLib guarantees that the sessions will be returned by the `getActiveSessions` method in the correct order. -* Added the classes `JsonValue` and `jsonObjectMember` which represent a JSON value and - a member of a JSON object respectively as TDLib API objects. -* Added the synchronous methods `getJsonValue` and `getJsonString` for simple conversion between - a JSON-encoded string and `JsonValue` TDLib API class. -* Added the methods `getApplicationConfig` and `saveApplicationLogEvent` to be used for testing purposes. -* Added the temporarily class `databaseStatistics` and the method `getDatabaseStatistics` for rough estimations of - database tables size in a human-readable format. -* Made the method `Client.Execute` static in .NET interface. -* Removed the `on_closed` callback virtual method from low-level C++ ClientActor interface. - Callback destructor can be used instead. -* Updated dependencies in the prebuilt TDLib for Android: - - Updated SDK to SDK 28 in which helper classes were moved from `android.support.` to `androidx.` package. - - Updated NDK to r19c, which dropped support for Android versions up to 4.0.4, so the minimum supported version is - Android 4.1. - - Updated OpenSSL to version 1.1.1. - - Added x86_64 libraries. -* Added out of the box `FreeBSD` support. -* Significantly improved TDLib compilation time and decreased compiler RAM usage: - - In native C++ interface `td_api::object_ptr` is now a simple homebrew const-propagating class instead of - `std::unique_ptr`. - - Added the script `SplitSource.php`, which can be used to split some source code files before building - the library to reduce maximum RAM usage per file at the expense of increased build time. -* The update `updateOption` with the `version` option is now guaranteed to come before all other updates. - It can now be used to dynamically discover available methods. -* Added the ability to delete incoming messages in private chats and revoke messages without a time limit: - - Added the parameter `revoke` to the method `deleteChatHistory`; use it to delete chat history for all chat members. - - Added the fields `can_be_deleted_only_for_self` and `can_be_deleted_for_all_users` to the class `chat` - which can be used to determine for whom the chat can be deleted through the `deleteChatHistory` method. - - The fields `Message.can_be_deleted_only_for_self` and `Message.can_be_deleted_for_all_users` can still be used - to determine for whom the message can be deleted through the `deleteMessages` method. -* Added support for server-generated notifications about newly registered contacts: - - Setting the option `disable_contact_registered_notifications` now affects all user sessions. - When the option is enabled, the client will still receive `messageContactRegistered` message in the private chat, - but there will be no notification about the message. - - `getOption("disable_contact_registered_notifications")` can be used to fetch the actual value of the option, - the option will not be updated automatically after a change from another device. -* Decreased the maximum allowed first name and last name length to 64, chat title length to 128, - matching the new server-side limits. -* Decreased the maximum allowed value of the `forward_limit` parameter of the `addChatMember` method from 300 to 100, - matching the new server-side limit. -* Added protection from opening two TDLib instances with the same database directory from one process. -* Added copying of notification settings of new secret chats from notification settings of - the corresponding private chat. -* Excluded the sponsored chat (when using sponsored proxies) from unread counters. -* Allowed to pass decreased local_size in `setFileGenerationProgress` to restart the generation from the beginning. -* Added a check for modification time of original file in `inputFileGenerated` whenever possible. - If the original file was changed, then TDLib will restart the generation. -* Added the destruction of MTProto keys on the server during log out. -* Added support for hexadecimal-encoded and decimal-encoded IPv4 proxy server addresses. -* Improved the behavior of `changeImportedContacts` which now also deletes contacts of users without Telegram accounts - from the server. -* Added the ability to call `getStorageStatistics` before authorization. -* Allowed to pass `limit` = -`offset` for negative offset in the `getChatHistory` method. -* Changed the recommended `inputThumbnail` size to be at most 320x320 instead of the previous 90x90. -* Disabled building by default of the native C interface. Use `cmake --build . --target tdc` to build it. -* Numerous optimizations and bug fixes: - - Network implementation for Windows was completely rewritten to allow a literally unlimited number of - simultaneously used TDLib instances. - - TDLib instances can now share working threads with each other. Only a limited number of threads will be created - even if there are thousands of TDLib instances in a single process. - - Removed the restriction on the size of update or response result in JSON interface. - - Fixed pinning of the 5th chat when there is a sponsored chat. - - Fixed IPv6 on Windows. - - Improved network connections balancing, aliveness checks and overall stability. - - Various autogenerated documentation fixes and improvements. - ------------------------------------------------------------------------------------------------------------------------ - -Changes in 1.3.0 (5 Sep 2018): - -* Added a review of existing TDLib based [frameworks](https://github.com/tdlib/td/blob/master/example/README.md) - in different programming languages. -* Added a [Getting started](https://core.telegram.org/tdlib/getting-started) guide describing the main TDLib concepts - and basic principles required for library usage. -* When a chat is opened, only those messages that have been viewed are marked as read. -* Improved the proxy settings API: - - A list of proxies is stored instead of just one proxy. - - New methods `addProxy`, `editProxy`, `enableProxy`, `disableProxy`, `removeProxy` and `getProxies` were added - instead of `setProxy` and `getProxy`. - - Added the method `pingProxy` which can be used to compute time needed to receive a response from a Telegram server - through a proxy or directly. - - Added support for MTProto proxy via class `proxyTypeMtproto`. - - Added support for HTTP proxy via class `proxyTypeHttp`. - - For each proxy last time it was used is remembered. - - Added the method `getProxyLink` which returns an HTTPS link that can be used to share a proxy with others. -* Improved the notification settings API. Scope notification settings are now properly synchronized between all devices - and chat notification settings can be reset to their default values: - - The `notificationSettings` class was split into `chatNotificationSettings` and `scopeNotificationSettings`. - - Only two notification settings scopes are left: `notificationSettingsScopePrivateChats` which is responsible for - default notification settings for private and secret chats and `notificationSettingsScopeGroupChats` for all other - chats. - - `updateNotificationSettings` was split into `updateChatNotificationSettings` and `updateScopeNotificationSettings`. - - `setNotificationSettings` was split into `setChatNotificationSettings` and `setScopeNotificationSettings`. - - `getNotificationSettings` was replaced with `getScopeNotificationSettings`. -* Added the field `filter` to the `searchChatMembers` method to support searching among administrators, bots, - restricted and banned members. -* Added the ability to use synchronous requests and `setAlarm` before the library is initialized. -* Added the ability to send requests that don't need authentication before the library is initialized. These requests - will be postponed and executed at the earliest opportunity. For example, `setNetworkType` can be used to disable the - network for TDLib before the library tries to use it; `addProxy` can be used to add a proxy before any network - activity; or `setOption("use_pfs")` can be used to guarantee that PFS is used for all requests. -* Added support for tg:// links in `inlineKeyboardButtonTypeUrl` and `textEntityTypeTextUrl`. -* Added the ability to call `deleteAccount` in the `authorizationStateWaitPassword` authorization state. -* Added the ability to call `checkAuthenticationCode` with an empty `first_name` for unregistered users to check the - code validity. -* Added the methods `editMessageMedia` and `editInlineMessageMedia` for editing media messages content. -* Renamed the class `shippingAddress` to `address`. -* Changed the return value of the `requestPasswordRecovery` method from `passwordRecoveryInfo` to - `emailAddressAuthenticationCodeInfo`. -* Added support for sponsored channels promoted by MTProto-proxies: - - Added the field `is_sponsored` to the `chat` class. - - Added `updateChatIsSponsored`, sent when this field changes. -* Added support for marking chats as unread: - - Added the field `is_marked_as_unread` to `chat`. - - Added the update `updateChatIsMarkedAsUnread`. - - Added the method `toggleChatIsMarkedAsUnread`. -* Added support for a default value of `disable_notification`, used when a message is sent to the chat: - - Added the field `default_disable_notification` to `chat` class. - - Added the update `updateChatDefaultDisableNotification`. - - Added the method `toggleChatDefaultDisableNotification`. -* Added the field `vcard` to the `contact` class. -* Added the field `type` to `venue`, which contains a provider-specific type of the venue, -* Added the update `updateUnreadChatCount`, enabled when the message database is used and sent when - the number of unread chats has changed. -* Added the method `addLocalMessage` for adding a local message to a chat. -* Added the method `getDeepLinkInfo`, which can return information about `tg://` links that are not supported by - the client. -* Added support for language packs: - - Added the writable option `language_pack_database_path` which can be used to specify a path to a database - for storing language pack strings, so that this database can be shared between different accounts. - If not specified, language pack strings will be stored only in memory. - Changes to the option are applied only on the next TDLib launch. - - Added the writable option `localization_target` for setting up a name for the current localization target - (currently supported: "android", "android_x", "ios", "macos" and "tdesktop"). - - Added the writable option `language_pack_id` for setting up an identifier of the currently used language pack from - the current localization target (a "language pack" represents the collection of strings that can be used to display - the interface of a particular application in a particular language). - - Added the class `LanguagePackStringValue` describing the possible values of a string from a language pack. - - Added the class `languagePackString` describing a string from a language pack. - - Added the class `languagePackStrings` containing a list of language pack strings. - - Added the class `languagePackInfo` containing information about a language pack from a localization target. - - Added the class `localizationTargetInfo` containing information about a localization target. - - Added the update `updateLanguagePackStrings` which is sent when some strings in a language pack have changed. - - Added the synchronous method `getLanguagePackString` which can be used to get a language pack string from - the local database. - - Added the method `getLocalizationTargetInfo` which returns information about the current localization target. - - Added the method `getLanguagePackStrings` which returns some or all strings from a language pack, possibly fetching - them from the server. - - Added the method `setCustomLanguagePack` for adding or editing a custom language pack. - - Added the method `editCustomLanguagePackInfo` for editing information about a custom language pack. - - Added the method `setCustomLanguagePackString` for adding, editing or deleting a string in a custom language pack. - - Added the method `deleteLanguagePack` for deleting a language pack from the database. - - Added the read-only option `suggested_language_pack_id` containing the identifier of the language pack, - suggested for the user by the server. -* Added support for Telegram Passport: - - Added two new message contents `messagePassportDataSent` for ordinary users and `messagePassportDataReceived` - for bots containing information about Telegram Passport data shared with a bot. - - Added the new file type `fileTypeSecure`. - - Added the class `datedFile` containing information about a file along with the date it was uploaded. - - Added the helper classes `date`, `personalDetails`, `identityDocument`, `inputIdentityDocument`, - `personalDocument`, `inputPersonalDocument`, `passportElements`. - - Added the class `PassportElementType` describing all supported types of Telegram Passport elements. - - Added the class `PassportElement` containing information about a Telegram Passport element. - - Added the class `InputPassportElement` containing information about a Telegram Passport element to save. - - Added the classes `passportElementError` and `PassportElementErrorSource` describing an error in - a Telegram Passport element. - - Added the field `has_passport_data` to the `passwordState` class. - - Added the methods `getPassportElement`, `getAllPassportElements`, `setPassportElement`, `deletePassportElement` - for managing Telegram Passport elements. - - Added the methods `getPassportAuthorizationForm` and `sendPassportAuthorizationForm` used for sharing - Telegram Passport data with a service via a bot. - - Added the methods `sendPhoneNumberVerificationCode`, `resendPhoneNumberVerificationCode` and - `checkPhoneNumberVerificationCode` for verification of a phone number used for Telegram Passport. - - Added the methods `sendEmailAddressVerificationCode`, `resendEmailAddressVerificationCode` and - `checkEmailAddressVerificationCode` for verification of an email address used for Telegram Passport. - - Added the method `getPreferredCountryLanguage` returning a most popular language in a country. - - Added the classes `inputPassportElementError` and `InputPassportElementErrorSource` for bots describing an error in - a Telegram Passport element. - - Added the method `setPassportElementErrors` for bots. - - Added the class `encryptedPassportElement` and `encryptedCredentials` for bots describing - an encrypted Telegram Passport element. -* Improved support for Telegram terms of service: - - Added the class `termsOfService`, containing information about the Telegram terms of service. - - Added the field `terms_of_service` to `authorizationStateWaitCode`. - - Added the update `updateTermsOfService` coming when new terms of service need to be accepted by the user. - - Added the method `acceptTermsOfService` for accepting terms of service. - - Removed the method `getTermsOfService`. -* Added the method `getMapThumbnailFile` which can be used to register and download a map thumbnail file. -* Added the methods `sendPhoneNumberConfirmationCode`, `resendPhoneNumberConfirmationCode` and - `checkPhoneNumberConfirmationCode` which can be used to prevent an account from being deleted. -* Added the convenience methods `joinChat` and `leaveChat` which can be used instead of `setChatMemberStatus` to manage - the current user's membership in a chat. -* Added the convenience method `getContacts` which can be used instead of `searchContacts` to get all contacts. -* Added the synchronous method `cleanFileName` which removes potentially dangerous characters from a file name. -* Added the method `getChatMessageCount` which can be used to get the number of shared media. -* Added the writable option `ignore_inline_thumbnails` which can be used to prevent file thumbnails sent - by the server along with messages from being saved on the disk. -* Added the writable option `prefer_ipv6` which can be used to prefer IPv6 connections over IPv4. -* Added the writable option `disable_top_chats` which can be used to disable support for top chats. -* Added the class `chatReportReasonCopyright` for reporting chats containing infringing content. -* Added the method `clearAllDraftMessages` which can be used to delete all cloud drafts. -* Added the read-only options `message_text_length_max` and `message_caption_length_max`. -* Added the read-only options `animation_search_bot_username`, `photo_search_bot_username` and - `venue_search_bot_username` containing usernames of bots which can be used in inline mode for animations, photos and - venues search respectively. -* Numerous optimizations and bug fixes: - - Fixed string encoding for .NET binding. - - Fixed building TDLib SDK for Universal Windows Platform for ARM with MSVC 2017. - - Fixed the Swift example project. - - Fixed the syntax error in the Python example. - - Sticker thumbnails can now have `webp` extensions if they are more likely to be in WEBP format. - ------------------------------------------------------------------------------------------------------------------------ - -Changes in 1.2.0 (20 Mar 2018): - -* Added support for native .NET bindings through `C++/CLI` and `C++/CX`. - See [using in .NET projects](README.md#using-dotnet) for more details. -* Added a C# example. See [README](example/csharp/README.md) for build and usage instructions. -* Added a build and usage example of TDLib SDK for Universal Windows Platform. See [README](example/uwp/README.md) - for detailed build and usage instructions. Also, see [Unigram](https://github.com/UnigramDev/Unigram), which is - a full-featured client rewritten from scratch using TDLib SDK for Universal Windows Platform in less than 2 months. -* Added a Swift example. See [README](example/swift/README.md) for build and usage instructions. -* Added an example of building TDLib for iOS, watchOS, tvOS, and also macOS. See [README](example/ios/README.md) for - detailed build instructions. -* Added README to [C++](example/cpp/README.md) and [python](example/python/README.md) examples. -* Link Time Optimization is disabled by default. Use `-DTD_ENABLE_LTO=ON` CMake option and CMake >= 3.9 to enable it. -* `updateNotificationSettings` is now automatically sent when the mute time expires for a chat. -* Added automatic sending of a corresponding `chatAction` when a file is being uploaded. -* `updateUserChatAction` with `chatActionCancel` is now automatically sent when the timeout expires for an action. -* Authorization states `authorizationStateWaitCode` and `authorizationStateWaitPassword` are now saved between - library restarts for 5 minutes. -* Added new message content type `messageWebsiteConnected`. -* Added new text entity types `textEntityTypeCashtag` and `textEntityTypePhoneNumber`. -* Added new update `updateUnreadMessageCount`, enabled when message database is used. -* Method `joinChatByInviteLink` now returns the joined `chat`. -* Method `getWebPagePreview` now accepts `formattedText` instead of plain `string`. -* Added field `phone_number` to `authenticationCodeInfo`, which contains a phone number that is being authenticated. -* Added field `is_secret` to `messageAnimation`, `messagePhoto`, `messageVideo` and `messageVideoNote` classes, - which denotes whether the thumbnail for the content must be blurred and the content must be shown only while tapped. -* Added field `expires_in` to `messageLocation` for live locations. -* Added flag `can_be_reported` to `chat` class. -* Added flag `supports_streaming` to classes `video` and `inputMessageVideo`. -* Added parameter `message_ids` to `reportChat`, which can be used to report specific messages. -* Added method `checkChatUsername` for checking whether a username can be set for a chat. -* Added method `getRepliedMessage`, which returns a message that is replied by a given message. -* Added method `getChatPinnedMessage`, which returns the pinned message from a chat. -* Added method `searchStickers` to search by emoji for popular stickers suggested by the server. -* Added method `searchStickerSets` to search by title and name for popular sticker sets suggested by the server. -* Added method `searchInstalledStickerSets` to search by title and name for installed sticker sets. -* Added methods for handling connected websites: `getConnectedWebsites`, `disconnectWebsite` and - `disconnectAllWebsites`. -* Added method `getCountryCode`, which uses current user IP address to identify their country. -* Added option `t_me_url`. -* Fixed `BlackBerry` spelling in `deviceTokenBlackBerryPush`. -* Fixed return type of `getChatMessageByDate` method, which is `Message` and not `Messages`. -* Ensured that updateOption("my_id") comes before `updateAuthorizationState` with `authorizationStateReady`. -* Numerous optimizations and bug fixes. - ------------------------------------------------------------------------------------------------------------------------ - -Changes in 1.1.1 (4 Feb 2018): -* Fixed C JSON bindings compilation error. -* Fixed locale-dependent JSON generation. - ------------------------------------------------------------------------------------------------------------------------ - -Changes in 1.1.0 (31 Jan 2018): - -* Methods `td::Log::set_file_path` and `td_set_log_file_path` now return whether they succeeded. -* Added methods `td::Log::set_max_file_size` and `td_set_log_max_file_size` for restricting maximum TDLib log size. -* Added methods `td::Log::set_fatal_error_callback` and `td_set_log_fatal_error_callback` for providing callbacks - on fatal errors. -* JNI-bindings are now package-agnostic. Use CMake option `TD_ENABLE_JNI` to enable JNI-bindings. -* Added a Java example. See [README](example/java/README.md) for build and usage instructions. -* Added support for text entities in media captions. - - Added new type `formattedText` containing a text with entities. - - Replaced all string fields `caption` with fields of type `formattedText`. - - Replaced fields `text` and `entities` with the field `text` of type `formattedText` in class `messageText`. - - Replaced fields `text` and `entities` with the field `text` of type `formattedText` in class `inputMessageText`. - - Replaced fields `text` and `text_entities` with the field `text` of type `formattedText` in class `game`. - - Removed field `parse_mode` from class `inputMessageText`. - - Added synchronous method `parseTextEntities`. -* updateNewMessage is now sent for all sent messages. -* updateChatLastMessage is now sent when any field of the last message in a chat changes. -* Reworked the `registerDevice` method: - - Added parameter `other_user_ids` to method `registerDevice` to support multiple accounts. - - It is now possible to specify tokens for VoIP pushes, WNS, web Push API, Tizen Push Service as `DeviceToken`. - - Added support for Apple Push Notification Service inside App Sandbox. -* Added method `searchChatsOnServer` analogous to `searchChats`, but using server search. -* Results from the `searchChatsOnServer` method are now excluded from `searchPublicChats` results, - so `searchChatsOnServer` (along with `searchContacts`) should be called whenever `searchPublicChats` is called - to ensure that no results were omitted. -* Added parameter `as_album` to method `getPublicMessageLink` to enable getting public links for media albums. -* Added field `html` to class `publicMessageLink`, containing HTML-code for message/message album embedding. -* Added parameter `only_if_pending` to method `cancelDownloadFile` to allow keeping already started downloads. -* Methods `createPrivateChat`, `createBasicGroupChat`, `createSupergroupChat` and `createSecretChat` - can now be called without a prior call to `getUser`/`getBasicGroup`/`getSupergroup`/`getSecretChat`. -* Added parameter `force` to methods `createPrivateChat`, `createBasicGroupChat` and `createSupergroupChat` to allow - creating a chat without network requests. -* Numerous optimizations and bug fixes. - ------------------------------------------------------------------------------------------------------------------------ diff --git a/third-party/td/td/CMake/AddCXXCompilerFlag.cmake b/third-party/td/td/CMake/AddCXXCompilerFlag.cmake deleted file mode 100644 index 6fb615a1f7..0000000000 --- a/third-party/td/td/CMake/AddCXXCompilerFlag.cmake +++ /dev/null @@ -1,74 +0,0 @@ -# - Adds a compiler flag if it is supported by the compiler -# -# This function checks that the supplied compiler flag is supported and then -# adds it to the corresponding compiler flags -# -# add_cxx_compiler_flag( []) -# -# - Example -# -# include(AddCXXCompilerFlag) -# add_cxx_compiler_flag(-Wall) -# add_cxx_compiler_flag(-no-strict-aliasing RELEASE) -# Requires CMake 2.6+ - -if (__add_cxx_compiler_flag) - return() -endif() -set(__add_cxx_compiler_flag INCLUDED) - -include(CheckCXXCompilerFlag) - -function(mangle_compiler_flag FLAG OUTPUT) - string(TOUPPER "HAVE_CXX_FLAG_${FLAG}" SANITIZED_FLAG) - string(REPLACE "+" "X" SANITIZED_FLAG ${SANITIZED_FLAG}) - string(REGEX REPLACE "[^A-Za-z_0-9]" "_" SANITIZED_FLAG ${SANITIZED_FLAG}) - string(REGEX REPLACE "_+" "_" SANITIZED_FLAG ${SANITIZED_FLAG}) - set(${OUTPUT} "${SANITIZED_FLAG}" PARENT_SCOPE) -endfunction(mangle_compiler_flag) - -function(add_cxx_compiler_flag FLAG) - string(REPLACE "-Wno-" "-W" MAIN_FLAG ${FLAG}) - mangle_compiler_flag("${MAIN_FLAG}" MANGLED_FLAG_NAME) - if (DEFINED CMAKE_REQUIRED_FLAGS) - set(OLD_CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS}") - set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} ${FLAG}") - else() - set(CMAKE_REQUIRED_FLAGS "${FLAG}") - endif() - check_cxx_compiler_flag("${MAIN_FLAG}" ${MANGLED_FLAG_NAME}) - if (DEFINED OLD_CMAKE_REQUIRED_FLAGS) - set(CMAKE_REQUIRED_FLAGS "${OLD_CMAKE_REQUIRED_FLAGS}") - else() - unset(CMAKE_REQUIRED_FLAGS) - endif() - if (${MANGLED_FLAG_NAME}) - set(VARIANT ${ARGV1}) - if (ARGV1) - string(TOUPPER "_${VARIANT}" VARIANT) - endif() - set(CMAKE_CXX_FLAGS${VARIANT} "${CMAKE_CXX_FLAGS${VARIANT}} ${FLAG}" PARENT_SCOPE) - endif() -endfunction() - -function(add_required_cxx_compiler_flag FLAG) - string(REPLACE "-Wno-" "-W" MAIN_FLAG ${FLAG}) - mangle_compiler_flag("${MAIN_FLAG}" MANGLED_FLAG_NAME) - set(OLD_CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS}") - set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} ${FLAG}") - check_cxx_compiler_flag("${MAIN_FLAG}" ${MANGLED_FLAG_NAME}) - set(CMAKE_REQUIRED_FLAGS "${OLD_CMAKE_REQUIRED_FLAGS}") - if (${MANGLED_FLAG_NAME}) - set(VARIANT ${ARGV1}) - if (ARGV1) - string(TOUPPER "_${VARIANT}" VARIANT) - endif() - set(CMAKE_CXX_FLAGS${VARIANT} "${CMAKE_CXX_FLAGS${VARIANT}} ${FLAG}" PARENT_SCOPE) - set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${FLAG}" PARENT_SCOPE) - set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${FLAG}" PARENT_SCOPE) - set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} ${FLAG}" PARENT_SCOPE) - set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} ${FLAG}" PARENT_SCOPE) - else() - message(FATAL_ERROR "Required flag '${FLAG}' is not supported by the compiler") - endif() -endfunction() diff --git a/third-party/td/td/CMake/FindAtomics.cmake b/third-party/td/td/CMake/FindAtomics.cmake deleted file mode 100644 index a855132581..0000000000 --- a/third-party/td/td/CMake/FindAtomics.cmake +++ /dev/null @@ -1,62 +0,0 @@ -# Original issue: -# * https://gitlab.kitware.com/cmake/cmake/-/issues/23021#note_1098733 -# -# For reference: -# * https://gcc.gnu.org/wiki/Atomic/GCCMM -# -# riscv64 specific: -# * https://lists.debian.org/debian-riscv/2022/01/msg00009.html -# -# ATOMICS_FOUND - system has C++ atomics -# ATOMICS_LIBRARIES - libraries needed to use C++ atomics - -if (ATOMICS_FOUND) - return() -endif() - -include(CheckCXXSourceCompiles) - -# RISC-V only has 32-bit and 64-bit atomic instructions. GCC is supposed -# to convert smaller atomics to those larger ones via masking and -# shifting like LLVM, but it's a known bug that it does not. This means -# anything that wants to use atomics on 1-byte or 2-byte types needs -# to link atomic library, but not 4-byte or 8-byte (though it does no harm). -set(ATOMIC_CODE - " - #include - #include - std::atomic n8{0}; // riscv64 - std::atomic n64{0}; // armel, mipsel, powerpc - int main() { - ++n8; - ++n64; - }") - -set(ATOMICS_LIBS " " "-latomic") -if (CMAKE_SYSTEM_NAME MATCHES "NetBSD") - set(ATOMICS_LIBS "${ATOMICS_LIBS}" /usr/pkg/gcc12/x86_64--netbsd/lib/libatomic.so /usr/pkg/gcc12/i486--netbsdelf/lib/libatomic.so) -endif() - -foreach (ATOMICS_LIBRARY ${ATOMICS_LIBS}) - unset(ATOMICS_FOUND CACHE) - set(CMAKE_REQUIRED_LIBRARIES "${ATOMICS_LIBRARY}") - check_cxx_source_compiles("${ATOMIC_CODE}" ATOMICS_FOUND) - unset(CMAKE_REQUIRED_LIBRARIES) - if (ATOMICS_FOUND) - if (NOT ATOMICS_LIBRARY STREQUAL " ") - include(FindPackageHandleStandardArgs) - find_package_handle_standard_args(Atomics DEFAULT_MSG ATOMICS_LIBRARY) - set(ATOMICS_LIBRARIES "${ATOMICS_LIBRARY}" CACHE STRING "Atomic library" FORCE) - else() - set(ATOMICS_LIBRARIES "" CACHE STRING "Atomic operations library" FORCE) - endif() - break() - endif() -endforeach() -if (Atomics_FIND_REQUIRED AND NOT ATOMICS_FOUND) - message(FATAL_ERROR "Atomic operations library isn't found.") -endif() - -unset(ATOMICS_LIBRARY) -unset(ATOMICS_LIBS) -unset(ATOMIC_CODE) diff --git a/third-party/td/td/CMake/FindReadline.cmake b/third-party/td/td/CMake/FindReadline.cmake deleted file mode 100644 index 94b92ef558..0000000000 --- a/third-party/td/td/CMake/FindReadline.cmake +++ /dev/null @@ -1,25 +0,0 @@ -if (APPLE) - find_path(READLINE_INCLUDE_DIR readline/readline.h /opt/homebrew/opt/readline/include /usr/local/opt/readline/include /opt/local/include /opt/include /usr/local/include /usr/include NO_DEFAULT_PATH) -endif() -find_path(READLINE_INCLUDE_DIR readline/readline.h) - -if (APPLE) - find_library(READLINE_LIBRARY readline /opt/homebrew/opt/readline/lib /usr/local/opt/readline/lib /opt/local/lib /opt/lib /usr/local/lib /usr/lib NO_DEFAULT_PATH) -endif() -find_library(READLINE_LIBRARY readline) - -if (READLINE_INCLUDE_DIR AND READLINE_LIBRARY AND NOT GNU_READLINE_FOUND) - set(CMAKE_REQUIRED_INCLUDES "${READLINE_INCLUDE_DIR}") - set(CMAKE_REQUIRED_LIBRARIES "${READLINE_LIBRARY}") - include(CheckCXXSourceCompiles) - unset(GNU_READLINE_FOUND CACHE) - check_cxx_source_compiles("#include \n#include \nint main() { rl_replace_line(\"\", 0); }" GNU_READLINE_FOUND) - if (NOT GNU_READLINE_FOUND) - unset(READLINE_INCLUDE_DIR CACHE) - unset(READLINE_LIBRARY CACHE) - endif() -endif() - -include(FindPackageHandleStandardArgs) -find_package_handle_standard_args(Readline DEFAULT_MSG READLINE_INCLUDE_DIR READLINE_LIBRARY) -mark_as_advanced(READLINE_INCLUDE_DIR READLINE_LIBRARY) diff --git a/third-party/td/td/CMake/GeneratePkgConfig.cmake b/third-party/td/td/CMake/GeneratePkgConfig.cmake deleted file mode 100644 index 3d3fa01d1f..0000000000 --- a/third-party/td/td/CMake/GeneratePkgConfig.cmake +++ /dev/null @@ -1,99 +0,0 @@ -function(get_relative_link OUTPUT PATH) - if (PATH MATCHES "^[$]<[$]:") - set(${OUTPUT} "" PARENT_SCOPE) - return() - endif() - string(REGEX REPLACE "^[$]<[$]>:(.*)>$" "\\1" PATH "${PATH}") - - get_filename_component(NAME "${PATH}" NAME_WE) - if (IS_ABSOLUTE ${PATH}) - get_filename_component(DIRECTORY_NAME "${PATH}" DIRECTORY) - if (WIN32) - set(${OUTPUT} "-l\"${DIRECTORY_NAME}/${NAME}\"" PARENT_SCOPE) - else() - get_filename_component(FULL_NAME "${PATH}" NAME) - set(${OUTPUT} "-L\"${DIRECTORY_NAME}\" -l:${FULL_NAME}" PARENT_SCOPE) - endif() - return() - endif() - - if (NOT WIN32 AND NAME MATCHES "^lib") - string(REGEX REPLACE "^lib" "-l" LINK "${NAME}") - elseif (NAME MATCHES "^-") - set(LINK "${NAME}") - else() - string(CONCAT LINK "-l" "${NAME}") - endif() - set(${OUTPUT} "${LINK}" PARENT_SCOPE) -endfunction() - -function(generate_pkgconfig TARGET DESCRIPTION) - # message("Generating pkg-config for ${TARGET}") - get_filename_component(PREFIX "${CMAKE_INSTALL_PREFIX}" REALPATH) - - get_target_property(LIST "${TARGET}" LINK_LIBRARIES) - set(REQS "") - set(LIBS "") - foreach (LIB ${LIST}) - if (TARGET "${LIB}") - set(HAS_REQS 1) - list(APPEND REQS "${LIB}") - else() - set(HAS_LIBS 1) - get_relative_link(LINK "${LIB}") - if (NOT LINK EQUAL "") - list(APPEND LIBS "${LINK}") - endif() - endif() - endforeach() - - if (HAS_REQS) - set(REQUIRES "") - foreach (REQ ${REQS}) - set(REQUIRES "${REQUIRES} ${REQ}") - endforeach() - set(REQUIRES "Requires.private:${REQUIRES}\n") - endif() - if (HAS_LIBS) - set(LIBRARIES "") - list(REVERSE LIBS) - list(REMOVE_DUPLICATES LIBS) - foreach (LIB ${LIBS}) - set(LIBRARIES " ${LIB}${LIBRARIES}") - endforeach() - set(LIBRARIES "Libs.private:${LIBRARIES}\n") - endif() - - if (IS_ABSOLUTE "${CMAKE_INSTALL_INCLUDEDIR}") - set(PKGCONFIG_INCLUDEDIR "${CMAKE_INSTALL_INCLUDEDIR}") - else() - set(PKGCONFIG_INCLUDEDIR "\${prefix}/${CMAKE_INSTALL_INCLUDEDIR}") - endif() - - if (IS_ABSOLUTE "${CMAKE_INSTALL_LIBDIR}") - set(PKGCONFIG_LIBDIR "${CMAKE_INSTALL_LIBDIR}") - else() - set(PKGCONFIG_LIBDIR "\${prefix}/${CMAKE_INSTALL_LIBDIR}") - endif() - - file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/pkgconfig") - file(GENERATE OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/pkgconfig/${TARGET}.pc" CONTENT -"prefix=${PREFIX} - -Name: ${TARGET} -Description: ${DESCRIPTION} -Version: ${PROJECT_VERSION} - -CFlags: -I\"${PKGCONFIG_INCLUDEDIR}\" -Libs: -L\"${PKGCONFIG_LIBDIR}\" -l${TARGET} -${REQUIRES}${LIBRARIES}") - - get_target_property(LIBRARY_TYPE "${TARGET}" TYPE) - if (LIBRARY_TYPE STREQUAL "STATIC_LIBRARY" OR LIBRARY_TYPE STREQUAL "SHARED_LIBRARY") - install(FILES "${CMAKE_CURRENT_BINARY_DIR}/pkgconfig/${TARGET}.pc" DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig") - elseif (LIBRARY_TYPE STREQUAL "INTERFACE_LIBRARY") - # TODO: support interface libraries - else() - message(FATAL_ERROR "Don't know how to handle ${TARGET} of type ${LIBRARY_TYPE}") - endif() -endfunction() diff --git a/third-party/td/td/CMake/GetGitRevisionDescription.cmake b/third-party/td/td/CMake/GetGitRevisionDescription.cmake deleted file mode 100644 index 746c29d583..0000000000 --- a/third-party/td/td/CMake/GetGitRevisionDescription.cmake +++ /dev/null @@ -1,127 +0,0 @@ -# - Returns a version string from Git -# -# These functions force a re-configure on each git commit so that you can -# trust the values of the variables in your build system. -# -# get_git_head_revision( ) -# -# Requires CMake 2.6 or newer (uses the 'function' command) -# -# Original Author: -# 2009-2020 Ryan Pavlik -# http://academic.cleardefinition.com -# -# Copyright 2009-2013, Iowa State University. -# Copyright 2013-2020, Ryan Pavlik -# Copyright 2013-2020, Contributors -# SPDX-License-Identifier: BSL-1.0 -# Distributed under the Boost Software License, Version 1.0. -# (See accompanying file LICENSE_1_0.txt or copy at -# http://www.boost.org/LICENSE_1_0.txt) - -if (__get_git_revision_description) - return() -endif() -set(__get_git_revision_description YES) - -# We must run the following at "include" time, not at function call time, -# to find the path to this module rather than the path to a calling list file -get_filename_component(_gitdescmoddir ${CMAKE_CURRENT_LIST_FILE} PATH) - -# Function _git_find_closest_git_dir finds the next closest .git directory -# that is part of any directory in the path defined by _start_dir. -# The result is returned in the parent scope variable whose name is passed -# as variable _git_dir_var. If no .git directory can be found, the -# function returns an empty string via _git_dir_var. -# -# Example: Given a path C:/bla/foo/bar and assuming C:/bla/.git exists and -# neither foo nor bar contain a file/directory .git. This will return -# C:/bla/.git -# -function(_git_find_closest_git_dir _start_dir _git_dir_var) - set(cur_dir "${_start_dir}") - set(git_dir "${_start_dir}/.git") - while (NOT EXISTS "${git_dir}") - # .git dir not found, search parent directories - set(git_previous_parent "${cur_dir}") - get_filename_component(cur_dir "${cur_dir}" DIRECTORY) - if (cur_dir STREQUAL git_previous_parent) - # We have reached the root directory, we are not in git - set(${_git_dir_var} "" PARENT_SCOPE) - return() - endif() - set(git_dir "${cur_dir}/.git") - endwhile() - set(${_git_dir_var} "${git_dir}" PARENT_SCOPE) -endfunction() - -function(get_git_head_revision _refspecvar _hashvar) - _git_find_closest_git_dir("${CMAKE_CURRENT_SOURCE_DIR}" GIT_DIR) - - if (NOT GIT_DIR STREQUAL "") - file(RELATIVE_PATH _relative_to_source_dir "${CMAKE_CURRENT_SOURCE_DIR}" "${GIT_DIR}") - if (_relative_to_source_dir MATCHES "^[.][.]") - # We've gone above the CMake root dir. - set(GIT_DIR "") - endif() - endif() - if (GIT_DIR STREQUAL "") - set(${_refspecvar} "GITDIR-NOTFOUND" PARENT_SCOPE) - set(${_hashvar} "GITDIR-NOTFOUND" PARENT_SCOPE) - return() - endif() - - find_package(Git QUIET) - - # Check if the current source dir is a git submodule or a worktree. - # In both cases .git is a file instead of a directory. - # - if ((NOT IS_DIRECTORY ${GIT_DIR}) AND Git_FOUND) - # The following git command will return a non empty string that - # points to the super project working tree if the current - # source dir is inside a git submodule. - # Otherwise, the command will return an empty string. - # - execute_process( - COMMAND "${GIT_EXECUTABLE}" rev-parse --show-superproject-working-tree - WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" - OUTPUT_VARIABLE out - ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE) - if (NOT out STREQUAL "") - # If out is non-empty, GIT_DIR/CMAKE_CURRENT_SOURCE_DIR is in a submodule - file(READ ${GIT_DIR} submodule) - string(REGEX REPLACE "gitdir: (.*)$" "\\1" GIT_DIR_RELATIVE ${submodule}) - string(STRIP ${GIT_DIR_RELATIVE} GIT_DIR_RELATIVE) - get_filename_component(SUBMODULE_DIR ${GIT_DIR} PATH) - get_filename_component(GIT_DIR ${SUBMODULE_DIR}/${GIT_DIR_RELATIVE} ABSOLUTE) - set(HEAD_SOURCE_FILE "${GIT_DIR}/HEAD") - else() - # GIT_DIR/CMAKE_CURRENT_SOURCE_DIR is in a worktree - file(READ ${GIT_DIR} worktree_ref) - # The .git directory contains a path to the worktree information directory - # inside the parent git repo of the worktree. - string(REGEX REPLACE "gitdir: (.*)$" "\\1" git_worktree_dir ${worktree_ref}) - string(STRIP ${git_worktree_dir} git_worktree_dir) - _git_find_closest_git_dir("${git_worktree_dir}" GIT_DIR) - set(HEAD_SOURCE_FILE "${git_worktree_dir}/HEAD") - endif() - else() - set(HEAD_SOURCE_FILE "${GIT_DIR}/HEAD") - endif() - if (NOT EXISTS "${HEAD_SOURCE_FILE}") - return() - endif() - - set(GIT_DATA "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/git-data") - if (NOT EXISTS "${GIT_DATA}") - file(MAKE_DIRECTORY "${GIT_DATA}") - endif() - set(HEAD_FILE "${GIT_DATA}/HEAD") - configure_file("${HEAD_SOURCE_FILE}" "${HEAD_FILE}" COPYONLY) - - configure_file("${_gitdescmoddir}/GetGitRevisionDescription.cmake.in" "${GIT_DATA}/grabRef.cmake" @ONLY) - include("${GIT_DATA}/grabRef.cmake") - - set(${_refspecvar} "${HEAD_REF}" PARENT_SCOPE) - set(${_hashvar} "${HEAD_HASH}" PARENT_SCOPE) -endfunction() diff --git a/third-party/td/td/CMake/GetGitRevisionDescription.cmake.in b/third-party/td/td/CMake/GetGitRevisionDescription.cmake.in deleted file mode 100644 index bfc1e54c15..0000000000 --- a/third-party/td/td/CMake/GetGitRevisionDescription.cmake.in +++ /dev/null @@ -1,43 +0,0 @@ -# -# Internal file for GetGitRevisionDescription.cmake -# -# Requires CMake 2.6 or newer (uses the 'function' command) -# -# Original Author: -# 2009-2010 Ryan Pavlik -# http://academic.cleardefinition.com -# Iowa State University HCI Graduate Program/VRAC -# -# Copyright 2009-2012, Iowa State University -# Copyright 2011-2015, Contributors -# Distributed under the Boost Software License, Version 1.0. -# (See accompanying file LICENSE_1_0.txt or copy at -# http://www.boost.org/LICENSE_1_0.txt) -# SPDX-License-Identifier: BSL-1.0 - -set(HEAD_HASH) - -file(READ "@HEAD_FILE@" HEAD_CONTENTS LIMIT 1024) - -string(STRIP "${HEAD_CONTENTS}" HEAD_CONTENTS) -if (HEAD_CONTENTS MATCHES "ref") - # named branch - string(REPLACE "ref: " "" HEAD_REF "${HEAD_CONTENTS}") - if (EXISTS "@GIT_DIR@/${HEAD_REF}") - configure_file("@GIT_DIR@/${HEAD_REF}" "@GIT_DATA@/head-ref" COPYONLY) - else() - configure_file("@GIT_DIR@/packed-refs" "@GIT_DATA@/packed-refs" COPYONLY) - file(READ "@GIT_DATA@/packed-refs" PACKED_REFS) - if (PACKED_REFS MATCHES "([0-9a-z]*) ${HEAD_REF}") - set(HEAD_HASH "${CMAKE_MATCH_1}") - endif() - endif() -else() - # detached HEAD - configure_file("@GIT_DIR@/HEAD" "@GIT_DATA@/head-ref" COPYONLY) -endif() - -if (NOT HEAD_HASH) - file(READ "@GIT_DATA@/head-ref" HEAD_HASH LIMIT 1024) - string(STRIP "${HEAD_HASH}" HEAD_HASH) -endif() diff --git a/third-party/td/td/CMake/PreventInSourceBuild.cmake b/third-party/td/td/CMake/PreventInSourceBuild.cmake deleted file mode 100644 index 1815e82a25..0000000000 --- a/third-party/td/td/CMake/PreventInSourceBuild.cmake +++ /dev/null @@ -1,14 +0,0 @@ -function(prevent_in_source_build) - get_filename_component(REAL_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}" REALPATH) - get_filename_component(REAL_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}" REALPATH) - - if (REAL_BINARY_DIR STREQUAL REAL_SOURCE_DIR) - message(" Out-of-source build must be used. Remove the files already") - message(" created by CMake and rerun CMake from a new directory:") - message(" rm -rf CMakeFiles CMakeCache.txt") - message(" mkdir build") - message(" cd build") - message(" cmake ..") - message(FATAL_ERROR "In-source build failed.") - endif() -endfunction() diff --git a/third-party/td/td/CMake/TdSetUpCompiler.cmake b/third-party/td/td/CMake/TdSetUpCompiler.cmake deleted file mode 100644 index a1937c2eb4..0000000000 --- a/third-party/td/td/CMake/TdSetUpCompiler.cmake +++ /dev/null @@ -1,185 +0,0 @@ -# Configures C++17 compiler, setting TDLib-specific compilation options. - -function(td_set_up_compiler) - set(CMAKE_EXPORT_COMPILE_COMMANDS 1 PARENT_SCOPE) - - set(CMAKE_POSITION_INDEPENDENT_CODE ON PARENT_SCOPE) - - include(illumos) - - if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") - set(GCC 1) - set(GCC 1 PARENT_SCOPE) - elseif (CMAKE_CXX_COMPILER_ID MATCHES "Clang") - set(CLANG 1) - set(CLANG 1 PARENT_SCOPE) - elseif (CMAKE_CXX_COMPILER_ID STREQUAL "Intel") - set(INTEL 1) - set(INTEL 1 PARENT_SCOPE) - elseif (NOT MSVC) - message(FATAL_ERROR "Compiler isn't supported") - endif() - - include(CheckCXXCompilerFlag) - - if (GCC OR CLANG OR INTEL) - if (WIN32 AND INTEL) - set(STD17_FLAG /Qstd=c++17) - else() - set(STD17_FLAG -std=c++17) - endif() - if (GCC AND (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 7.0)) - message(FATAL_ERROR "No C++17 support in the compiler. Please upgrade the compiler to at least GCC 7.0.") - endif() - if (CLANG AND (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.0)) - message(FATAL_ERROR "No C++17 support in the compiler. Please upgrade the compiler to at least clang 5.0.") - endif() - check_cxx_compiler_flag(${STD17_FLAG} HAVE_STD17) - elseif (MSVC) - set(HAVE_STD17 MSVC_VERSION>=1914) # MSVC 2017 version 15.7 - endif() - - if (NOT HAVE_STD17) - message(FATAL_ERROR "No C++17 support in the compiler. Please upgrade the compiler.") - endif() - - if (MSVC) - if (CMAKE_CXX_FLAGS_DEBUG MATCHES "/RTC1") - string(REPLACE "/RTC1" " " CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}") - endif() - add_definitions(-D_SCL_SECURE_NO_WARNINGS -D_CRT_SECURE_NO_WARNINGS) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /std:c++17 /utf-8 /GR- /W4 /wd4100 /wd4127 /wd4324 /wd4505 /wd4814 /wd4702 /bigobj") - elseif (CLANG OR GCC) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${STD17_FLAG} -fno-omit-frame-pointer -fno-exceptions -fno-rtti") - if (APPLE) - set(TD_LINKER_FLAGS "-Wl,-dead_strip") - if (NOT CMAKE_BUILD_TYPE MATCHES "Deb") - set(TD_LINKER_FLAGS "${TD_LINKER_FLAGS},-x,-S") - endif() - else() - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -ffunction-sections -fdata-sections") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ffunction-sections -fdata-sections") - if (CMAKE_SYSTEM_NAME STREQUAL "SunOS") - set(TD_LINKER_FLAGS "-Wl,-z,ignore") - elseif (EMSCRIPTEN) - set(TD_LINKER_FLAGS "-Wl,--gc-sections") - elseif (ANDROID) - set(TD_LINKER_FLAGS "-Wl,--gc-sections -Wl,--exclude-libs,ALL -Wl,--icf=safe") - else() - set(TD_LINKER_FLAGS "-Wl,--gc-sections -Wl,--exclude-libs,ALL") - endif() - endif() - set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${TD_LINKER_FLAGS}") - set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${TD_LINKER_FLAGS}") - - if (WIN32 OR CYGWIN) - if (GCC) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wa,-mbig-obj") - endif() - endif() - elseif (INTEL) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${STD17_FLAG}") - endif() - - if (WIN32) - add_definitions(-DNTDDI_VERSION=0x06020000 -DWINVER=0x0602 -D_WIN32_WINNT=0x0602 -DPSAPI_VERSION=1 -DNOMINMAX -DUNICODE -D_UNICODE -DWIN32_LEAN_AND_MEAN) - endif() - if (CYGWIN) - add_definitions(-D_DEFAULT_SOURCE=1 -DFD_SETSIZE=4096) - endif() - - # _FILE_OFFSET_BITS is broken in Android NDK r15, r15b and r17 and doesn't work prior to Android 7.0 - add_definitions(-D_FILE_OFFSET_BITS=64) - - # _GNU_SOURCE might not be defined by g++ - add_definitions(-D_GNU_SOURCE) - - if (CMAKE_SYSTEM_NAME STREQUAL "SunOS") - set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -lsocket -lnsl") - if (ILLUMOS) - add_definitions(-DTD_ILLUMOS=1) - endif() - endif() - - include(AddCXXCompilerFlag) - if (NOT MSVC) - add_cxx_compiler_flag("-Wall") - add_cxx_compiler_flag("-Wextra") - add_cxx_compiler_flag("-Wimplicit-fallthrough=2") - add_cxx_compiler_flag("-Wpointer-arith") - add_cxx_compiler_flag("-Wcast-qual") - add_cxx_compiler_flag("-Wsign-compare") - add_cxx_compiler_flag("-Wduplicated-branches") - add_cxx_compiler_flag("-Wduplicated-cond") - add_cxx_compiler_flag("-Walloc-zero") - add_cxx_compiler_flag("-Wlogical-op") - add_cxx_compiler_flag("-Wno-tautological-compare") - add_cxx_compiler_flag("-Wpointer-arith") - add_cxx_compiler_flag("-Wvla") - add_cxx_compiler_flag("-Wnon-virtual-dtor") - add_cxx_compiler_flag("-Wno-unused-parameter") - add_cxx_compiler_flag("-Wconversion") - add_cxx_compiler_flag("-Wno-sign-conversion") - add_cxx_compiler_flag("-Wc++17-compat-pedantic") - add_cxx_compiler_flag("-Wdeprecated") - add_cxx_compiler_flag("-Wno-unused-command-line-argument") - add_cxx_compiler_flag("-Qunused-arguments") - add_cxx_compiler_flag("-Wno-unknown-warning-option") - add_cxx_compiler_flag("-Wodr") - add_cxx_compiler_flag("-flto-odr-type-merging") - add_cxx_compiler_flag("-Wno-psabi") - add_cxx_compiler_flag("-Wunused-member-function") - add_cxx_compiler_flag("-Wunused-private-field") - - # add_cxx_compiler_flag("-Werror") - - # add_cxx_compiler_flag("-Wcast-align") - - #std::int32_t <-> int and off_t <-> std::size_t/std::int64_t - # add_cxx_compiler_flag("-Wuseless-cast") - - #external headers like openssl - # add_cxx_compiler_flag("-Wzero-as-null-pointer-constant") - endif() - - if (GCC) - add_cxx_compiler_flag("-Wno-maybe-uninitialized") # too many false positives - endif() - if (WIN32 AND GCC AND NOT (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 8.0)) - # warns about casts of function pointers returned by GetProcAddress - add_cxx_compiler_flag("-Wno-cast-function-type") - endif() - if (GCC AND NOT (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 9.0)) - # warns about a lot of "return std::move", which are not redundant for compilers without fix for DR 1579, i.e. GCC 4.9 or clang 3.8 - # see http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1579 - add_cxx_compiler_flag("-Wno-redundant-move") - endif() - if (GCC AND NOT (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 12.0)) - add_cxx_compiler_flag("-Wno-stringop-overflow") # some false positives - endif() - if (CLANG AND (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 3.5)) - # https://stackoverflow.com/questions/26744556/warning-returning-a-captured-reference-from-a-lambda - add_cxx_compiler_flag("-Wno-return-stack-address") - endif() - if (GCC AND (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 13.0)) - # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104030 - add_cxx_compiler_flag("-Wbidi-chars=none") - endif() - - if (MINGW) - add_cxx_compiler_flag("-ftrack-macro-expansion=0") - endif() - - #set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -isystem /usr/include/c++/v1") - #set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++") - #set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=thread") - #set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address") - #set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=undefined") - #set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=leak") - - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}" PARENT_SCOPE) - set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}" PARENT_SCOPE) - set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS}" PARENT_SCOPE) - set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS}" PARENT_SCOPE) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS}" PARENT_SCOPE) -endfunction() diff --git a/third-party/td/td/CMake/iOS.cmake b/third-party/td/td/CMake/iOS.cmake deleted file mode 100644 index 0bdbe7505a..0000000000 --- a/third-party/td/td/CMake/iOS.cmake +++ /dev/null @@ -1,278 +0,0 @@ -# This file is based off of the Platform/Darwin.cmake and Platform/UnixPaths.cmake -# files which are included with CMake 2.8.4 -# It has been altered for iOS development - -# Options: -# -# IOS_PLATFORM = OS (default) or SIMULATOR -# This decides if SDKS will be selected from the iPhoneOS.platform or iPhoneSimulator.platform folders -# OS - the default, used to build for iPhone and iPad physical devices, which have an arm arch. -# SIMULATOR - used to build for the Simulator platforms, which have an x86 arch. -# -# IOS_ARCH = automatic(default) or "arch1;arch2" (e.q. "x86_64;arm64") -# By default this value will be automatically chosen based on the IOS_PLATFORM value above. -# If set manually, it will override the default and force to build those architectures only. -# -# CMAKE_IOS_DEVELOPER_ROOT = automatic(default) or /path/to/platform/Developer folder -# By default this location is automatically chosen based on the IOS_PLATFORM value above. -# If set manually, it will override the default location and force the user of a particular Developer Platform -# -# CMAKE_IOS_SDK_ROOT = automatic(default) or /path/to/platform/Developer/SDKs/SDK folder -# By default this location is automatically chosen based on the CMAKE_IOS_DEVELOPER_ROOT value. -# In this case it will always be the most up-to-date SDK found in the CMAKE_IOS_DEVELOPER_ROOT path. -# If set manually, this will force the use of a specific SDK version - -# Macros: -# -# set_xcode_property (TARGET XCODE_PROPERTY XCODE_VALUE) -# A convenience macro for setting xcode specific properties on targets -# example: set_xcode_property (myioslib IPHONEOS_DEPLOYMENT_TARGET "3.1") -# -# find_host_package (PROGRAM ARGS) -# A macro used to find executable programs on the host system, not within the iOS environment. -# Thanks to the android-cmake project for providing the command - -# Standard settings -set (CMAKE_SYSTEM_NAME Darwin) -set (CMAKE_SYSTEM_VERSION 1) -set (UNIX True) -set (APPLE True) -set (IOS True) - -# Required as of cmake 2.8.10 -set (CMAKE_OSX_DEPLOYMENT_TARGET "" CACHE STRING "Force unset of the deployment target for iOS" FORCE) - -# Determine the cmake host system version so we know where to find the iOS SDKs -find_program (CMAKE_UNAME uname /bin /usr/bin /usr/local/bin) -if (CMAKE_UNAME) - execute_process(COMMAND uname -r OUTPUT_VARIABLE CMAKE_HOST_SYSTEM_VERSION OUTPUT_STRIP_TRAILING_WHITESPACE) - string (REGEX REPLACE "^([0-9]+)\\.([0-9]+).*$" "\\1" DARWIN_MAJOR_VERSION "${CMAKE_HOST_SYSTEM_VERSION}") -endif (CMAKE_UNAME) - -# Force the compilers to gcc for iOS -set (CMAKE_C_COMPILER /usr/bin/gcc) -set (CMAKE_CXX_COMPILER /usr/bin/g++) -set (CMAKE_AR ar CACHE FILEPATH "" FORCE) -set (CMAKE_RANLIB ranlib CACHE FILEPATH "" FORCE) -set (PKG_CONFIG_EXECUTABLE pkg-config CACHE FILEPATH "" FORCE) - -# Setup iOS platform unless specified manually with IOS_PLATFORM -if (NOT DEFINED IOS_PLATFORM) - set (IOS_PLATFORM "OS") -endif (NOT DEFINED IOS_PLATFORM) -set (IOS_PLATFORM ${IOS_PLATFORM} CACHE STRING "Type of iOS Platform") - -# Check the platform selection and setup for developer root -if (IOS_PLATFORM STREQUAL "OS") - set (IOS_PLATFORM_LOCATION "iPhoneOS.platform") - set (XCODE_IOS_PLATFORM ios) - - # This causes the installers to properly locate the output libraries - set (CMAKE_XCODE_EFFECTIVE_PLATFORMS "-iphoneos") - - set (APPLE_IOS True) -elseif (IOS_PLATFORM STREQUAL "SIMULATOR") - set (SIMULATOR_FLAG true) - set (IOS_PLATFORM_LOCATION "iPhoneSimulator.platform") - set (XCODE_IOS_PLATFORM ios-simulator) - - # This causes the installers to properly locate the output libraries - set (CMAKE_XCODE_EFFECTIVE_PLATFORMS "-iphonesimulator") - - set (APPLE_IOS True) -elseif (IOS_PLATFORM STREQUAL "WATCHOS") - set (IOS_PLATFORM_LOCATION "WatchOS.platform") - set (XCODE_IOS_PLATFORM watchos) - - # This causes the installers to properly locate the output libraries - set (CMAKE_XCODE_EFFECTIVE_PLATFORMS "-watchos") - - set (APPLE_WATCH True) -elseif (IOS_PLATFORM STREQUAL "WATCHSIMULATOR") - set (SIMULATOR_FLAG true) - set (IOS_PLATFORM_LOCATION "WatchSimulator.platform") - set (XCODE_IOS_PLATFORM watchos-simulator) - - # This causes the installers to properly locate the output libraries - set (CMAKE_XCODE_EFFECTIVE_PLATFORMS "-watchsimulator") - - set (APPLE_WATCH True) -elseif (IOS_PLATFORM STREQUAL "TVOS") - set (IOS_PLATFORM_LOCATION "AppleTvOS.platform") - set (XCODE_IOS_PLATFORM tvos) - - # This causes the installers to properly locate the output libraries - set (CMAKE_XCODE_EFFECTIVE_PLATFORMS "-appletvos") - - set (APPLE_TV True) -elseif (IOS_PLATFORM STREQUAL "TVSIMULATOR") - set (SIMULATOR_FLAG true) - set (IOS_PLATFORM_LOCATION "AppleTvSimulator.platform") - set (XCODE_IOS_PLATFORM tvos-simulator) - - # This causes the installers to properly locate the output libraries - set (CMAKE_XCODE_EFFECTIVE_PLATFORMS "-tvsimulator") - - set (APPLE_TV True) -elseif (IOS_PLATFORM STREQUAL "VISIONOS") - set (IOS_PLATFORM_LOCATION "XROS.platform") - set (XCODE_IOS_PLATFORM xros) - - # This causes the installers to properly locate the output libraries - set (CMAKE_XCODE_EFFECTIVE_PLATFORMS "-xros") - - set (APPLE_VISION True) -elseif (IOS_PLATFORM STREQUAL "VISIONSIMULATOR") - set (SIMULATOR_FLAG true) - set (IOS_PLATFORM_LOCATION "XRSimulator.platform") - set (XCODE_IOS_PLATFORM xros-simulator) - - # This causes the installers to properly locate the output libraries - set (CMAKE_XCODE_EFFECTIVE_PLATFORMS "-xrsimulator") - - set (APPLE_VISION True) -else (IOS_PLATFORM STREQUAL "OS") - message (FATAL_ERROR "Unsupported IOS_PLATFORM value selected. Please choose OS, SIMULATOR, or WATCHOS.") -endif () - -# All iOS/Darwin specific settings - some may be redundant -set (CMAKE_SHARED_LIBRARY_PREFIX "lib") -set (CMAKE_SHARED_LIBRARY_SUFFIX ".dylib") -set (CMAKE_SHARED_MODULE_PREFIX "lib") -set (CMAKE_SHARED_MODULE_SUFFIX ".so") -set (CMAKE_MODULE_EXISTS 1) -set (CMAKE_DL_LIBS "") - -set (CMAKE_C_OSX_COMPATIBILITY_VERSION_FLAG "-compatibility_version ") -set (CMAKE_C_OSX_CURRENT_VERSION_FLAG "-current_version ") -set (CMAKE_CXX_OSX_COMPATIBILITY_VERSION_FLAG "${CMAKE_C_OSX_COMPATIBILITY_VERSION_FLAG}") -set (CMAKE_CXX_OSX_CURRENT_VERSION_FLAG "${CMAKE_C_OSX_CURRENT_VERSION_FLAG}") - -if (IOS_DEPLOYMENT_TARGET) - set (XCODE_IOS_PLATFORM_VERSION_FLAGS "-m${XCODE_IOS_PLATFORM}-version-min=${IOS_DEPLOYMENT_TARGET}") -endif() - -set (CMAKE_SHARED_LINKER_FLAGS_INIT "-fapplication-extension") -set (CMAKE_C_FLAGS_INIT "${XCODE_IOS_PLATFORM_VERSION_FLAGS}") -# Hidden visibility is required for cxx on iOS -set (CMAKE_CXX_FLAGS_INIT "${XCODE_IOS_PLATFORM_VERSION_FLAGS} -fvisibility-inlines-hidden") - -set (CMAKE_C_LINK_FLAGS "${XCODE_IOS_PLATFORM_VERSION_FLAGS} -fapplication-extension -Wl,-search_paths_first ${CMAKE_C_LINK_FLAGS}") -set (CMAKE_CXX_LINK_FLAGS "${XCODE_IOS_PLATFORM_VERSION_FLAGS} -fapplication-extension -Wl,-search_paths_first ${CMAKE_CXX_LINK_FLAGS}") - -set (CMAKE_PLATFORM_HAS_INSTALLNAME 1) -set (CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS "-dynamiclib -headerpad_max_install_names") -set (CMAKE_SHARED_MODULE_CREATE_C_FLAGS "-bundle -headerpad_max_install_names") -set (CMAKE_SHARED_MODULE_LOADER_C_FLAG "-Wl,-bundle_loader,") -set (CMAKE_SHARED_MODULE_LOADER_CXX_FLAG "-Wl,-bundle_loader,") -set (CMAKE_FIND_LIBRARY_SUFFIXES ".dylib" ".so" ".a") - -# hack: if a new cmake (which uses CMAKE_INSTALL_NAME_TOOL) runs on an old build tree -# (where install_name_tool was hardcoded) and where CMAKE_INSTALL_NAME_TOOL isn't in the cache -# and still cmake didn't fail in CMakeFindBinUtils.cmake (because it isn't rerun) -# hardcode CMAKE_INSTALL_NAME_TOOL here to install_name_tool, so it behaves as it did before, Alex -if (NOT DEFINED CMAKE_INSTALL_NAME_TOOL) - find_program(CMAKE_INSTALL_NAME_TOOL install_name_tool) -endif (NOT DEFINED CMAKE_INSTALL_NAME_TOOL) - -# Setup iOS deployment target -set (IOS_DEPLOYMENT_TARGET ${IOS_DEPLOYMENT_TARGET} CACHE STRING "Minimum iOS version") - -# Setup iOS developer location unless specified manually with CMAKE_IOS_DEVELOPER_ROOT -# Note Xcode 4.3 changed the installation location, choose the most recent one available -execute_process(COMMAND /usr/bin/xcode-select -print-path OUTPUT_VARIABLE CMAKE_XCODE_DEVELOPER_DIR OUTPUT_STRIP_TRAILING_WHITESPACE) -set (XCODE_POST_43_ROOT "${CMAKE_XCODE_DEVELOPER_DIR}/Platforms/${IOS_PLATFORM_LOCATION}/Developer") -set (XCODE_PRE_43_ROOT "/Developer/Platforms/${IOS_PLATFORM_LOCATION}/Developer") -if (NOT DEFINED CMAKE_IOS_DEVELOPER_ROOT) - if (EXISTS ${XCODE_POST_43_ROOT}) - set (CMAKE_IOS_DEVELOPER_ROOT ${XCODE_POST_43_ROOT}) - elseif (EXISTS ${XCODE_PRE_43_ROOT}) - set (CMAKE_IOS_DEVELOPER_ROOT ${XCODE_PRE_43_ROOT}) - endif (EXISTS ${XCODE_POST_43_ROOT}) -endif (NOT DEFINED CMAKE_IOS_DEVELOPER_ROOT) -set (CMAKE_IOS_DEVELOPER_ROOT ${CMAKE_IOS_DEVELOPER_ROOT} CACHE PATH "Location of iOS Platform") - -# Find and use the most recent iOS sdk unless specified manually with CMAKE_IOS_SDK_ROOT -if (NOT DEFINED CMAKE_IOS_SDK_ROOT) - file (GLOB _CMAKE_IOS_SDKS "${CMAKE_IOS_DEVELOPER_ROOT}/SDKs/*") - if (_CMAKE_IOS_SDKS) - list (SORT _CMAKE_IOS_SDKS) - list (REVERSE _CMAKE_IOS_SDKS) - list (GET _CMAKE_IOS_SDKS 0 CMAKE_IOS_SDK_ROOT) - else (_CMAKE_IOS_SDKS) - message (FATAL_ERROR "No iOS SDK's found in default search path ${CMAKE_IOS_DEVELOPER_ROOT}. Manually set CMAKE_IOS_SDK_ROOT or install the iOS SDK.") - endif (_CMAKE_IOS_SDKS) - message (STATUS "Toolchain using default iOS SDK: ${CMAKE_IOS_SDK_ROOT}") -endif (NOT DEFINED CMAKE_IOS_SDK_ROOT) -set (CMAKE_IOS_SDK_ROOT ${CMAKE_IOS_SDK_ROOT} CACHE PATH "Location of the selected iOS SDK") - -# Set the sysroot default to the most recent SDK -set (CMAKE_OSX_SYSROOT ${CMAKE_IOS_SDK_ROOT} CACHE PATH "Sysroot used for iOS support") - -# Set the architectures unless specified manually with IOS_ARCH -if (NOT DEFINED IOS_ARCH) - if (IOS_PLATFORM STREQUAL "OS") - set (IOS_ARCH "arm64") - elseif (IOS_PLATFORM STREQUAL "SIMULATOR") - set (IOS_ARCH "x86_64;arm64") - elseif (IOS_PLATFORM STREQUAL "WATCHOS") - set (IOS_ARCH "armv7k;arm64_32;arm64") - - # Include C++ Standard Library for Xcode 15 builds. - include_directories(SYSTEM "${CMAKE_IOS_SDK_ROOT}/usr/include/c++/v1") - elseif (IOS_PLATFORM STREQUAL "WATCHSIMULATOR") - set (IOS_ARCH "x86_64;arm64") - - # Include C++ Standard Library for Xcode 15 builds. - include_directories(SYSTEM "${CMAKE_IOS_SDK_ROOT}/usr/include/c++/v1") - elseif (IOS_PLATFORM STREQUAL "TVOS") - set (IOS_ARCH "arm64") - elseif (IOS_PLATFORM STREQUAL "TVSIMULATOR") - set (IOS_ARCH "x86_64;arm64") - elseif (IOS_PLATFORM STREQUAL "VISIONOS") - set (IOS_ARCH "arm64") - elseif (IOS_PLATFORM STREQUAL "VISIONSIMULATOR") - set (IOS_ARCH "x86_64;arm64") - endif() -endif() -message (STATUS "The iOS architectures: ${IOS_ARCH}") - -set (CMAKE_OSX_ARCHITECTURES ${IOS_ARCH} CACHE STRING "Build architecture for iOS") - -# Set the find root to the iOS developer roots and to user defined paths -set (CMAKE_FIND_ROOT_PATH ${CMAKE_IOS_DEVELOPER_ROOT} ${CMAKE_IOS_SDK_ROOT} ${CMAKE_PREFIX_PATH} CACHE STRING "iOS find search path root") - -# default to searching for frameworks first -set (CMAKE_FIND_FRAMEWORK FIRST) - -# set up the default search directories for frameworks -set (CMAKE_SYSTEM_FRAMEWORK_PATH - ${CMAKE_IOS_SDK_ROOT}/System/Library/Frameworks - ${CMAKE_IOS_SDK_ROOT}/System/Library/PrivateFrameworks - ${CMAKE_IOS_SDK_ROOT}/Developer/Library/Frameworks -) - -# only search the iOS sdks, not the remainder of the host filesystem -set (CMAKE_FIND_ROOT_PATH_MODE_PROGRAM ONLY) -set (CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) -set (CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) - -# This little macro lets you set any Xcode specific property -macro (set_xcode_property TARGET XCODE_PROPERTY XCODE_VALUE) - set_property (TARGET ${TARGET} PROPERTY XCODE_ATTRIBUTE_${XCODE_PROPERTY} ${XCODE_VALUE}) -endmacro (set_xcode_property) - -# This macro lets you find executable programs on the host system -macro (find_host_package) - set (CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) - set (CMAKE_FIND_ROOT_PATH_MODE_LIBRARY NEVER) - set (CMAKE_FIND_ROOT_PATH_MODE_INCLUDE NEVER) - set (IOS FALSE) - - find_package(${ARGN}) - - set (IOS TRUE) - set (CMAKE_FIND_ROOT_PATH_MODE_PROGRAM ONLY) - set (CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) - set (CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) -endmacro (find_host_package) diff --git a/third-party/td/td/CMake/illumos.cmake b/third-party/td/td/CMake/illumos.cmake deleted file mode 100644 index 70583d1a82..0000000000 --- a/third-party/td/td/CMake/illumos.cmake +++ /dev/null @@ -1,10 +0,0 @@ -if (CMAKE_SYSTEM_NAME STREQUAL "SunOS") - # - # Determine if the host is running an illumos distribution: - # - execute_process(COMMAND /usr/bin/uname -o OUTPUT_VARIABLE UNAME_O OUTPUT_STRIP_TRAILING_WHITESPACE) - - if (UNAME_O STREQUAL "illumos") - set(ILLUMOS 1) - endif() -endif() diff --git a/third-party/td/td/CMakeLists.txt b/third-party/td/td/CMakeLists.txt deleted file mode 100644 index d6bbc903b6..0000000000 --- a/third-party/td/td/CMakeLists.txt +++ /dev/null @@ -1,1449 +0,0 @@ -cmake_minimum_required(VERSION 3.10 FATAL_ERROR) - -project(TDLib VERSION 1.8.46 LANGUAGES CXX C) - -if (NOT DEFINED CMAKE_MODULE_PATH) - set(CMAKE_MODULE_PATH "") -endif() -set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/CMake" "${CMAKE_MODULE_PATH}") - -if (NOT DEFINED CMAKE_INSTALL_LIBDIR) - set(CMAKE_INSTALL_LIBDIR "lib") -endif() -if (NOT DEFINED CMAKE_INSTALL_BINDIR) - set(CMAKE_INSTALL_BINDIR "bin") -endif() -if (NOT DEFINED CMAKE_INSTALL_INCLUDEDIR) - set(CMAKE_INSTALL_INCLUDEDIR "include") -endif() - -if (POLICY CMP0074) - # use environment variables to find libraries - cmake_policy(SET CMP0074 NEW) -endif() - -include(PreventInSourceBuild) -prevent_in_source_build() - -option(TD_INSTALL_STATIC_LIBRARIES "Enable installation of static libraries." ON) -option(TD_INSTALL_SHARED_LIBRARIES "Enable installation of shared libraries." ON) -option(TD_ENABLE_JNI "Use \"ON\" to enable JNI-compatible TDLib API.") -option(TD_ENABLE_DOTNET "Use \"ON\" to enable generation of C++/CLI or C++/CX TDLib API bindings.") -if (NOT CMAKE_CROSSCOMPILING) - option(TD_GENERATE_SOURCE_FILES "Use \"ON\" to just generate TDLib source files.") -endif() - -include(CTest) - -option(TD_ENABLE_LTO "Use \"ON\" to enable Link Time Optimization.") - -if (TD_ENABLE_LTO) - include(CheckIPOSupported) - check_ipo_supported(RESULT IPO_SUPPORTED) - if (IPO_SUPPORTED) - # set_property(DIRECTORY PROPERTY INTERPROCEDURAL_OPTIMIZATION TRUE) do not work? - string(REPLACE ";" " " CXX_FLAGS_IPO "${CMAKE_CXX_COMPILE_OPTIONS_IPO}") - message(STATUS "Use link time optimization CXX options: ${CXX_FLAGS_IPO}") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CXX_FLAGS_IPO}") - - string(REPLACE ";" " " C_FLAGS_IPO "${CMAKE_C_COMPILE_OPTIONS_IPO}") - message(STATUS "Use link time optimization C options: ${C_FLAGS_IPO}") - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${C_FLAGS_IPO}") - - string(REPLACE ";" " " LINK_FLAGS_IPO "${CMAKE_CXX_LINK_OPTIONS_IPO}") - message(STATUS "Use link time optimization linker options: ${LINK_FLAGS_IPO}") - set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${LINK_FLAGS_IPO}") - endif() -endif() - -# Configure Ccache if available -find_program(CCACHE_FOUND ccache) -#set(CCACHE_FOUND 0) -if (CCACHE_FOUND) - message(STATUS "Found ccache") - set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ccache) - set_property(GLOBAL PROPERTY RULE_LAUNCH_LINK ccache) -else() - message(STATUS "Could NOT find ccache (this is NOT an error)") -endif() - -set(MEMPROF "" CACHE STRING "Use one of \"ON\", \"FAST\" or \"SAFE\" to enable memory profiling. \ -Works under macOS and Linux when compiled using glibc. \ -In FAST mode stack is unwinded only using frame pointers, which may fail. \ -In SAFE mode stack is unwinded using backtrace function from execinfo.h, which may be very slow. \ -By default both methods are used to achieve the maximum speed and accuracy") - -if (EMSCRIPTEN) - # use prebuilt zlib - set(ZLIB_FOUND 1) - set(ZLIB_LIBRARIES) - set(ZLIB_INCLUDE_DIR) - - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -s ALLOW_MEMORY_GROWTH=1 -s MEMFS_APPEND_TO_TYPED_ARRAYS=1 -s USE_ZLIB=1 -s MODULARIZE=1 \ - -s EXPORT_NAME=\"'createTdwebModule'\" -s WEBSOCKET_URL=\"'wss:#'\" -s EXPORTED_RUNTIME_METHODS=\"['FS','cwrap']\" -lidbfs.js -lworkerfs.js") - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -s ALLOW_MEMORY_GROWTH=1 -s MEMFS_APPEND_TO_TYPED_ARRAYS=1 -s USE_ZLIB=1 -s MODULARIZE=1 \ - -s EXPORT_NAME=\"'createTdwebModule'\" -s WEBSOCKET_URL=\"'wss:#'\" -s EXPORTED_RUNTIME_METHODS=\"['FS','cwrap']\" -lidbfs.js -lworkerfs.js") - set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -s DEMANGLE_SUPPORT=1 -s ASSERTIONS=1") - set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -s DEMANGLE_SUPPORT=1 -s ASSERTIONS=1") - - set(TD_EMSCRIPTEN td_wasm) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -s WASM=1 --post-js ${CMAKE_CURRENT_SOURCE_DIR}/post.js") - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -s WASM=1") -endif() - -if (NOT TD_GENERATE_SOURCE_FILES) - if (NOT OPENSSL_FOUND) - find_package(OpenSSL) - endif() - if (OPENSSL_FOUND) - message(STATUS "Found OpenSSL: ${OPENSSL_INCLUDE_DIR} ${OPENSSL_LIBRARIES}") - endif() -endif() - -set(CMAKE_THREAD_PREFER_PTHREAD ON) -set(THREADS_PREFER_PTHREAD_FLAG ON) -find_package(Threads REQUIRED) - -if (THREADS_HAVE_PTHREAD_ARG) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread") -endif() - -include(TdSetUpCompiler) -td_set_up_compiler() - -if (MSVC) - option(TD_ENABLE_MULTI_PROCESSOR_COMPILATION "Use \"ON\" to enable multi-processor compilation.") - - if (TD_ENABLE_MULTI_PROCESSOR_COMPILATION) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP") - endif() - - if (TD_ENABLE_JNI) - # https://github.com/tdlib/td/issues/2912 - add_definitions(-D_DISABLE_CONSTEXPR_MUTEX_CONSTRUCTOR) - endif() -endif() - -if (CLANG OR GCC) - if (MEMPROF) - include(CheckCXXCompilerFlag) - check_cxx_compiler_flag(-no-pie CXX_NO_PIE_FLAG) - if (CXX_NO_PIE_FLAG) - set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -no-pie") - elseif (APPLE) - set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-no_pie") - endif() - include(AddCXXCompilerFlag) - add_cxx_compiler_flag("-static-libstdc++") - add_cxx_compiler_flag("-static-libgcc") - endif() -endif() - -include(GetGitRevisionDescription) -get_git_head_revision(TD_GIT_REFSPEC TD_GIT_COMMIT_HASH) -message(STATUS "Git state: ${TD_GIT_COMMIT_HASH}") - -configure_file("${CMAKE_CURRENT_SOURCE_DIR}/td/telegram/GitCommitHash.cpp.in" "${CMAKE_CURRENT_BINARY_DIR}/td/telegram/GitCommitHash.cpp" @ONLY) - -add_subdirectory(tdtl) - -if (TD_GENERATE_SOURCE_FILES) - set(TDUTILS_MIME_TYPE ON CACHE BOOL "" FORCE) - set(TDUTILS_USE_EXTERNAL_DEPENDENCIES OFF CACHE BOOL "" FORCE) -endif() -set(TDUTILS_ENABLE_INSTALL ${TD_INSTALL_STATIC_LIBRARIES} CACHE BOOL "" FORCE) -add_subdirectory(tdutils) - -add_subdirectory(td/generate) - -if (NOT CMAKE_CROSSCOMPILING) - set(TD_ALWAYS_GENERATE_SOURCE "") - if (TD_GENERATE_SOURCE_FILES) - set(TD_ALWAYS_GENERATE_SOURCE "ALL") - endif() - add_custom_target(prepare_cross_compiling ${TD_ALWAYS_GENERATE_SOURCE} DEPENDS tl_generate_mtproto tl_generate_common tdmime_auto tl_generate_json) - if (TD_ENABLE_DOTNET) - add_custom_target(remove_cpp_documentation - WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" - COMMAND remove_documentation ${TL_TD_API_AUTO_SOURCE} td/telegram/Client.h td/telegram/Log.h td/tl/TlObject.h - COMMENT "Remove C++ documentation from sources" - DEPENDS remove_documentation tl_generate_mtproto tl_generate_common generate_dotnet_api ${TL_TD_API_AUTO_SOURCE} td/telegram/Client.h td/telegram/Log.h td/tl/TlObject.h - ) - - add_dependencies(prepare_cross_compiling generate_dotnet_api remove_cpp_documentation) - endif() -endif() - -if (NOT OPENSSL_FOUND) - if (NOT TD_GENERATE_SOURCE_FILES) - message(WARNING "Can't find OpenSSL: stop TDLib building") - endif() - return() -endif() - -if (NOT ZLIB_FOUND) - find_package(ZLIB) -endif() -if (NOT ZLIB_FOUND) - message(WARNING "Can't find zlib: stop TDLib building") - return() -endif() - -if (NOT TDUTILS_MIME_TYPE OR NOT TDUTILS_USE_EXTERNAL_DEPENDENCIES) - message(WARNING "Option TDUTILS_MIME_TYPE and TDUTILS_USE_EXTERNAL_DEPENDENCIES must not be disabled: stop TDLib building") - return() -endif() - -set(TDACTOR_ENABLE_INSTALL ${TD_INSTALL_STATIC_LIBRARIES} CACHE BOOL "" FORCE) -add_subdirectory(tdactor) - -set(TDNET_ENABLE_INSTALL ${TD_INSTALL_STATIC_LIBRARIES} CACHE BOOL "" FORCE) -add_subdirectory(tdnet) - -set(TDSQLITE_ENABLE_INSTALL ${TD_INSTALL_STATIC_LIBRARIES} CACHE BOOL "" FORCE) -add_subdirectory(sqlite) - -set(TDDB_ENABLE_INSTALL ${TD_INSTALL_STATIC_LIBRARIES} CACHE BOOL "" FORCE) -add_subdirectory(tddb) - -if (BUILD_TESTING) - add_subdirectory(test) -endif() - -set(TDE2E_ENABLE_INSTALL ${TD_INSTALL_STATIC_LIBRARIES} CACHE BOOL "" FORCE) -add_subdirectory(tde2e) - -if (NOT CMAKE_CROSSCOMPILING) - add_subdirectory(benchmark) -endif() - - -get_directory_property(HAS_PARENT PARENT_DIRECTORY) -if (HAS_PARENT) - set(TL_TD_JSON_AUTO ${TL_TD_JSON_AUTO_SOURCE} PARENT_SCOPE) # used in tdbot - set(TD_TEST_SOURCE ${TD_TEST_SOURCE} PARENT_SCOPE) # used to build tests -endif() - - -# SOURCE SETS - -set_source_files_properties(${TL_TD_API_AUTO_SOURCE} PROPERTIES GENERATED TRUE) -if (TD_ENABLE_JNI OR ANDROID) - set(TL_JNI_OBJECT_SOURCE - td/tl/tl_jni_object.cpp - td/tl/tl_jni_object.h - ) -else() - set(TL_JNI_OBJECT_SOURCE) -endif() - -set(TL_TD_API_SOURCE - ${TL_TD_API_AUTO_SOURCE} - ${TL_JNI_OBJECT_SOURCE} - td/tl/TlObject.h -) - -set_source_files_properties(${TL_MTPROTO_AUTO_SOURCE} PROPERTIES GENERATED TRUE) - -set_source_files_properties(${TL_TD_AUTO_SOURCE} PROPERTIES GENERATED TRUE) - -set_source_files_properties(${TL_TD_JSON_AUTO_SOURCE} PROPERTIES GENERATED TRUE) -set(TL_TD_JSON_SOURCE - ${TL_TD_JSON_AUTO_SOURCE} - td/tl/tl_json.h -) - -set_source_files_properties(${TL_C_AUTO_SOURCE} PROPERTIES GENERATED TRUE) -set(TL_C_SCHEME_SOURCE - ${TL_C_AUTO_SOURCE} -) - -set_source_files_properties(${TL_DOTNET_AUTO_SOURCE} PROPERTIES GENERATED TRUE) -set(TL_DOTNET_SCHEME_SOURCE - ${TL_DOTNET_AUTO_SOURCE} - td/tl/tl_dotnet_object.h -) - -set(TD_MTPROTO_SOURCE - td/mtproto/AuthData.cpp - td/mtproto/ConnectionManager.cpp - td/mtproto/DhHandshake.cpp - td/mtproto/Handshake.cpp - td/mtproto/HandshakeActor.cpp - td/mtproto/HttpTransport.cpp - td/mtproto/IStreamTransport.cpp - td/mtproto/KDF.cpp - td/mtproto/Ping.cpp - td/mtproto/PingConnection.cpp - td/mtproto/ProxySecret.cpp - td/mtproto/RawConnection.cpp - td/mtproto/RSA.cpp - td/mtproto/SessionConnection.cpp - td/mtproto/TcpTransport.cpp - td/mtproto/TlsInit.cpp - td/mtproto/TlsReaderByteFlow.cpp - td/mtproto/Transport.cpp - td/mtproto/utils.cpp - - td/mtproto/AuthData.h - td/mtproto/AuthKey.h - td/mtproto/ConnectionManager.h - td/mtproto/CryptoStorer.h - td/mtproto/DhCallback.h - td/mtproto/DhHandshake.h - td/mtproto/Handshake.h - td/mtproto/HandshakeActor.h - td/mtproto/HandshakeConnection.h - td/mtproto/HttpTransport.h - td/mtproto/IStreamTransport.h - td/mtproto/KDF.h - td/mtproto/MessageId.h - td/mtproto/MtprotoQuery.h - td/mtproto/NoCryptoStorer.h - td/mtproto/PacketInfo.h - td/mtproto/PacketStorer.h - td/mtproto/Ping.h - td/mtproto/PingConnection.h - td/mtproto/ProxySecret.h - td/mtproto/RawConnection.h - td/mtproto/RSA.h - td/mtproto/SessionConnection.h - td/mtproto/TcpTransport.h - td/mtproto/TlsInit.h - td/mtproto/TlsReaderByteFlow.h - td/mtproto/Transport.h - td/mtproto/TransportType.h - td/mtproto/utils.h - - ${TL_MTPROTO_AUTO_SOURCE} - - td/tl/TlObject.h - td/tl/tl_object_parse.h - td/tl/tl_object_store.h -) - -set(TDLIB_SOURCE_PART1 - td/telegram/AccountManager.cpp - td/telegram/AffiliateType.cpp - td/telegram/AlarmManager.cpp - td/telegram/AnimationsManager.cpp - td/telegram/Application.cpp - td/telegram/AttachMenuManager.cpp - td/telegram/AudiosManager.cpp - td/telegram/AuthManager.cpp - td/telegram/AutoDownloadSettings.cpp - td/telegram/AutosaveManager.cpp - td/telegram/BackgroundInfo.cpp - td/telegram/BackgroundManager.cpp - td/telegram/BackgroundType.cpp - td/telegram/BaseTheme.cpp - td/telegram/Birthdate.cpp - td/telegram/BoostManager.cpp - td/telegram/BotCommand.cpp - td/telegram/BotCommandScope.cpp - td/telegram/BotInfoManager.cpp - td/telegram/BotMenuButton.cpp - td/telegram/BotQueries.cpp - td/telegram/BotRecommendationManager.cpp - td/telegram/BotVerification.cpp - td/telegram/BotVerifierSettings.cpp - td/telegram/BusinessAwayMessage.cpp - td/telegram/BusinessAwayMessageSchedule.cpp - td/telegram/BusinessBotManageBar.cpp - td/telegram/BusinessBotRights.cpp - td/telegram/BusinessChatLink.cpp - td/telegram/BusinessConnectedBot.cpp - td/telegram/BusinessConnectionManager.cpp - td/telegram/BusinessGreetingMessage.cpp - td/telegram/BusinessInfo.cpp - td/telegram/BusinessIntro.cpp - td/telegram/BusinessManager.cpp - td/telegram/BusinessRecipients.cpp - td/telegram/BusinessWorkHours.cpp - td/telegram/CallActor.cpp - td/telegram/CallbackQueriesManager.cpp - td/telegram/CallDiscardReason.cpp - td/telegram/CallManager.cpp - td/telegram/ChannelParticipantFilter.cpp - td/telegram/ChannelRecommendationManager.cpp - td/telegram/ChatManager.cpp - td/telegram/ChatReactions.cpp - td/telegram/ClientActor.cpp - td/telegram/CommonDialogManager.cpp - td/telegram/ConfigManager.cpp - td/telegram/ConnectionState.cpp - td/telegram/ConnectionStateManager.cpp - td/telegram/Contact.cpp - td/telegram/CountryInfoManager.cpp - td/telegram/DelayDispatcher.cpp - td/telegram/Dependencies.cpp - td/telegram/DeviceTokenManager.cpp - td/telegram/DhCache.cpp - td/telegram/DialogAction.cpp - td/telegram/DialogActionBar.cpp - td/telegram/DialogActionManager.cpp - td/telegram/DialogAdministrator.cpp - td/telegram/DialogDb.cpp - td/telegram/DialogEventLog.cpp - td/telegram/DialogFilter.cpp - td/telegram/DialogFilterInviteLink.cpp - td/telegram/DialogFilterManager.cpp - td/telegram/DialogId.cpp - td/telegram/DialogInviteLink.cpp - td/telegram/DialogInviteLinkManager.cpp - td/telegram/DialogLocation.cpp - td/telegram/DialogManager.cpp - td/telegram/DialogNotificationSettings.cpp - td/telegram/DialogParticipant.cpp - td/telegram/DialogParticipantFilter.cpp - td/telegram/DialogParticipantManager.cpp - td/telegram/DialogSource.cpp - td/telegram/Dimensions.cpp - td/telegram/DisallowedGiftsSettings.cpp - td/telegram/Document.cpp - td/telegram/DocumentsManager.cpp - td/telegram/DownloadManager.cpp - td/telegram/DownloadManagerCallback.cpp - td/telegram/DraftMessage.cpp - td/telegram/EmailVerification.cpp - td/telegram/EmojiGroup.cpp - td/telegram/EmojiGroupType.cpp - td/telegram/EmojiStatus.cpp - td/telegram/FactCheck.cpp - td/telegram/FileReferenceManager.cpp - td/telegram/files/FileBitmask.cpp - td/telegram/files/FileDb.cpp - td/telegram/files/FileDownloader.cpp - td/telegram/files/FileDownloadManager.cpp - td/telegram/files/FileEncryptionKey.cpp - td/telegram/files/FileFromBytes.cpp - td/telegram/files/FileGcParameters.cpp - td/telegram/files/FileGcWorker.cpp - td/telegram/files/FileGenerateManager.cpp - td/telegram/files/FileHashUploader.cpp - td/telegram/files/FileLoaderUtils.cpp - td/telegram/files/FileLoadManager.cpp - td/telegram/files/FileManager.cpp - td/telegram/files/FileStats.cpp - td/telegram/files/FileStatsWorker.cpp - td/telegram/files/FileType.cpp - td/telegram/files/FileUploader.cpp - td/telegram/files/FileUploadManager.cpp - td/telegram/files/PartsManager.cpp - td/telegram/files/ResourceManager.cpp - td/telegram/files/ResourceState.cpp - td/telegram/ForumTopic.cpp - td/telegram/ForumTopicEditedData.cpp - td/telegram/ForumTopicIcon.cpp - td/telegram/ForumTopicInfo.cpp - td/telegram/ForumTopicManager.cpp - td/telegram/Game.cpp - td/telegram/GameManager.cpp - td/telegram/GiveawayParameters.cpp - td/telegram/Global.cpp - td/telegram/GlobalPrivacySettings.cpp - td/telegram/GroupCallManager.cpp - td/telegram/GroupCallParticipant.cpp - td/telegram/GroupCallParticipantOrder.cpp - td/telegram/GroupCallVideoPayload.cpp - td/telegram/HashtagHints.cpp - td/telegram/InlineMessageManager.cpp - td/telegram/InlineQueriesManager.cpp - td/telegram/InputBusinessChatLink.cpp - td/telegram/InputDialogId.cpp - td/telegram/InputGroupCallId.cpp - td/telegram/InputInvoice.cpp - td/telegram/InputMessageText.cpp - td/telegram/JsonValue.cpp - td/telegram/LanguagePackManager.cpp - td/telegram/LinkManager.cpp - td/telegram/Location.cpp - td/telegram/logevent/LogEventHelper.cpp - td/telegram/Logging.cpp - td/telegram/MediaArea.cpp - td/telegram/MediaAreaCoordinates.cpp - td/telegram/MessageContent.cpp - td/telegram/MessageContentType.cpp - td/telegram/MessageDb.cpp - td/telegram/MessageEntity.cpp - td/telegram/MessageExtendedMedia.cpp - td/telegram/MessageForwardInfo.cpp - td/telegram/MessageId.cpp - td/telegram/MessageImportManager.cpp - td/telegram/MessageInputReplyTo.cpp - td/telegram/MessageOrigin.cpp - td/telegram/MessageQueryManager.cpp - td/telegram/MessageQuote.cpp - td/telegram/MessageReaction.cpp - td/telegram/MessageReactor.cpp - td/telegram/MessageReplyHeader.cpp - td/telegram/MessageReplyInfo.cpp - td/telegram/MessageSearchFilter.cpp - td/telegram/MessageSearchOffset.cpp - td/telegram/MessageSelfDestructType.cpp - td/telegram/MessageSender.cpp - td/telegram/MessagesInfo.cpp - td/telegram/MessagesManager.cpp - td/telegram/MessageSource.cpp - td/telegram/MessageThreadDb.cpp - td/telegram/MessageTtl.cpp - td/telegram/MessageViewer.cpp - td/telegram/misc.cpp - td/telegram/MissingInvitee.cpp -) -set(TDLIB_SOURCE_PART2 - td/telegram/net/AuthDataShared.cpp - td/telegram/net/ConnectionCreator.cpp - td/telegram/net/DcAuthManager.cpp - td/telegram/net/DcOptionsSet.cpp - td/telegram/net/MtprotoHeader.cpp - td/telegram/net/NetActor.cpp - td/telegram/net/NetQuery.cpp - td/telegram/net/NetQueryCreator.cpp - td/telegram/net/NetQueryDelayer.cpp - td/telegram/net/NetQueryDispatcher.cpp - td/telegram/net/NetQueryStats.cpp - td/telegram/net/NetQueryVerifier.cpp - td/telegram/net/NetStatsManager.cpp - td/telegram/net/Proxy.cpp - td/telegram/net/PublicRsaKeySharedCdn.cpp - td/telegram/net/PublicRsaKeySharedMain.cpp - td/telegram/net/PublicRsaKeyWatchdog.cpp - td/telegram/net/Session.cpp - td/telegram/net/SessionMultiProxy.cpp - td/telegram/net/SessionProxy.cpp - td/telegram/NewPasswordState.cpp - td/telegram/NotificationGroupInfo.cpp - td/telegram/NotificationGroupType.cpp - td/telegram/NotificationManager.cpp - td/telegram/NotificationSettingsManager.cpp - td/telegram/NotificationSettingsScope.cpp - td/telegram/NotificationSound.cpp - td/telegram/NotificationType.cpp - td/telegram/OnlineManager.cpp - td/telegram/OptionManager.cpp - td/telegram/OrderedMessage.cpp - td/telegram/OrderInfo.cpp - td/telegram/Outline.cpp - td/telegram/PaidReactionType.cpp - td/telegram/PasswordManager.cpp - td/telegram/Payments.cpp - td/telegram/PeerColor.cpp - td/telegram/PeopleNearbyManager.cpp - td/telegram/PhoneNumberManager.cpp - td/telegram/Photo.cpp - td/telegram/PhotoSize.cpp - td/telegram/PhotoSizeSource.cpp - td/telegram/PollManager.cpp - td/telegram/Premium.cpp - td/telegram/PremiumGiftOption.cpp - td/telegram/PrivacyManager.cpp - td/telegram/PromoDataManager.cpp - td/telegram/QueryCombiner.cpp - td/telegram/QueryMerger.cpp - td/telegram/QuickReplyManager.cpp - td/telegram/ReactionListType.cpp - td/telegram/ReactionManager.cpp - td/telegram/ReactionNotificationSettings.cpp - td/telegram/ReactionNotificationsFrom.cpp - td/telegram/ReactionType.cpp - td/telegram/RecentDialogList.cpp - td/telegram/ReferralProgramInfo.cpp - td/telegram/ReferralProgramManager.cpp - td/telegram/ReferralProgramParameters.cpp - td/telegram/ReferralProgramSortOrder.cpp - td/telegram/RepliedMessageInfo.cpp - td/telegram/ReplyMarkup.cpp - td/telegram/ReportReason.cpp - td/telegram/RequestedDialogType.cpp - td/telegram/Requests.cpp - td/telegram/RestrictionReason.cpp - td/telegram/SavedMessagesManager.cpp - td/telegram/SavedMessagesTopicId.cpp - td/telegram/ScopeNotificationSettings.cpp - td/telegram/SecretChatActor.cpp - td/telegram/SecretChatDb.cpp - td/telegram/SecretChatsManager.cpp - td/telegram/SecretInputMedia.cpp - td/telegram/SecureManager.cpp - td/telegram/SecureStorage.cpp - td/telegram/SecureValue.cpp - td/telegram/SendCodeHelper.cpp - td/telegram/SentEmailCode.cpp - td/telegram/SequenceDispatcher.cpp - td/telegram/SharedDialog.cpp - td/telegram/SpecialStickerSetType.cpp - td/telegram/SponsoredMessageManager.cpp - td/telegram/StarAmount.cpp - td/telegram/StarGift.cpp - td/telegram/StarGiftAttribute.cpp - td/telegram/StarGiftId.cpp - td/telegram/StarGiftManager.cpp - td/telegram/StarGiftSettings.cpp - td/telegram/StarManager.cpp - td/telegram/StarSubscription.cpp - td/telegram/StarSubscriptionPricing.cpp - td/telegram/StateManager.cpp - td/telegram/StatisticsManager.cpp - td/telegram/StickerFormat.cpp - td/telegram/StickerListType.cpp - td/telegram/StickerMaskPosition.cpp - td/telegram/StickerPhotoSize.cpp - td/telegram/StickerSetId.cpp - td/telegram/StickersManager.cpp - td/telegram/StickerType.cpp - td/telegram/StorageManager.cpp - td/telegram/StoryContent.cpp - td/telegram/StoryContentType.cpp - td/telegram/StoryDb.cpp - td/telegram/StoryForwardInfo.cpp - td/telegram/StoryInteractionInfo.cpp - td/telegram/StoryManager.cpp - td/telegram/StoryStealthMode.cpp - td/telegram/StoryViewer.cpp - td/telegram/SuggestedAction.cpp - td/telegram/SuggestedActionManager.cpp - td/telegram/Support.cpp - td/telegram/SynchronousRequests.cpp - td/telegram/TargetDialogTypes.cpp - td/telegram/Td.cpp - td/telegram/TdDb.cpp - td/telegram/TermsOfService.cpp - td/telegram/TermsOfServiceManager.cpp - td/telegram/ThemeManager.cpp - td/telegram/ThemeSettings.cpp - td/telegram/TimeZoneManager.cpp - td/telegram/TopDialogCategory.cpp - td/telegram/TopDialogManager.cpp - td/telegram/TranscriptionInfo.cpp - td/telegram/TranscriptionManager.cpp - td/telegram/TranslationManager.cpp - td/telegram/UpdatesManager.cpp - td/telegram/UserManager.cpp - td/telegram/Usernames.cpp - td/telegram/UserPrivacySetting.cpp - td/telegram/UserPrivacySettingRule.cpp - td/telegram/UserStarGift.cpp - td/telegram/Venue.cpp - td/telegram/VerificationStatus.cpp - td/telegram/VideoNotesManager.cpp - td/telegram/VideosManager.cpp - td/telegram/VoiceNotesManager.cpp - td/telegram/WebApp.cpp - td/telegram/WebAppManager.cpp - td/telegram/WebAppOpenParameters.cpp - td/telegram/WebPageBlock.cpp - td/telegram/WebPagesManager.cpp - - td/telegram/AccentColorId.h - td/telegram/AccessRights.h - td/telegram/AccountManager.h - td/telegram/AffectedHistory.h - td/telegram/AffiliateType.h - td/telegram/AlarmManager.h - td/telegram/AnimationsManager.h - td/telegram/Application.h - td/telegram/AttachMenuManager.h - td/telegram/AudiosManager.h - td/telegram/AuthManager.h - td/telegram/AutoDownloadSettings.h - td/telegram/AutosaveManager.h - td/telegram/BackgroundId.h - td/telegram/BackgroundInfo.h - td/telegram/BackgroundManager.h - td/telegram/BackgroundType.h - td/telegram/BaseTheme.h - td/telegram/Birthdate.h - td/telegram/BotVerification.h - td/telegram/BotVerifierSettings.h - td/telegram/BlockListId.h - td/telegram/BoostManager.h - td/telegram/BotCommand.h - td/telegram/BotCommandScope.h - td/telegram/BotInfoManager.h - td/telegram/BotMenuButton.h - td/telegram/BotQueries.h - td/telegram/BotRecommendationManager.h - td/telegram/BusinessAwayMessage.h - td/telegram/BusinessAwayMessageSchedule.h - td/telegram/BusinessBotManageBar.h - td/telegram/BusinessBotRights.h - td/telegram/BusinessChatLink.h - td/telegram/BusinessConnectedBot.h - td/telegram/BusinessConnectionId.h - td/telegram/BusinessConnectionManager.h - td/telegram/BusinessGreetingMessage.h - td/telegram/BusinessInfo.h - td/telegram/BusinessIntro.h - td/telegram/BusinessManager.h - td/telegram/BusinessRecipients.h - td/telegram/BusinessWorkHours.h - td/telegram/CallActor.h - td/telegram/CallbackQueriesManager.h - td/telegram/CallDiscardReason.h - td/telegram/CallId.h - td/telegram/CallManager.h - td/telegram/ChainId.h - td/telegram/ChannelId.h - td/telegram/ChannelParticipantFilter.h - td/telegram/ChannelRecommendationManager.h - td/telegram/ChannelType.h - td/telegram/ChatId.h - td/telegram/ChatManager.h - td/telegram/ChatReactions.h - td/telegram/ClientActor.h - td/telegram/CommonDialogManager.h - td/telegram/ConfigManager.h - td/telegram/ConnectionState.h - td/telegram/ConnectionStateManager.h - td/telegram/Contact.h - td/telegram/CountryInfoManager.h - td/telegram/CustomEmojiId.h - td/telegram/DelayDispatcher.h - td/telegram/Dependencies.h - td/telegram/DeviceTokenManager.h - td/telegram/DhCache.h - td/telegram/DhConfig.h - td/telegram/DialogAction.h - td/telegram/DialogActionBar.h - td/telegram/DialogActionManager.h - td/telegram/DialogAdministrator.h - td/telegram/DialogBoostLinkInfo.h - td/telegram/DialogDate.h - td/telegram/DialogDb.h - td/telegram/DialogEventLog.h - td/telegram/DialogFilter.h - td/telegram/DialogFilterDialogInfo.h - td/telegram/DialogFilterId.h - td/telegram/DialogFilterInviteLink.h - td/telegram/DialogFilterManager.h - td/telegram/DialogId.h - td/telegram/DialogInviteLink.h - td/telegram/DialogInviteLinkManager.h - td/telegram/DialogListId.h - td/telegram/DialogLocation.h - td/telegram/DialogManager.h - td/telegram/DialogNotificationSettings.h - td/telegram/DialogParticipant.h - td/telegram/DialogParticipantFilter.h - td/telegram/DialogParticipantManager.h - td/telegram/DialogSource.h - td/telegram/Dimensions.h - td/telegram/DisallowedGiftsSettings.h - td/telegram/Document.h - td/telegram/DocumentsManager.h - td/telegram/DownloadManager.h - td/telegram/DownloadManagerCallback.h - td/telegram/DraftMessage.h - td/telegram/EmailVerification.h - td/telegram/EmojiGroup.h - td/telegram/EmojiGroupType.h - td/telegram/EmojiStatus.h - td/telegram/EncryptedFile.h - td/telegram/FactCheck.h - td/telegram/FileReferenceManager.h - td/telegram/files/FileBitmask.h - td/telegram/files/FileData.h - td/telegram/files/FileDb.h - td/telegram/files/FileDbId.h - td/telegram/files/FileDownloader.h - td/telegram/files/FileDownloadManager.h - td/telegram/files/FileEncryptionKey.h - td/telegram/files/FileFromBytes.h - td/telegram/files/FileGcParameters.h - td/telegram/files/FileGcWorker.h - td/telegram/files/FileGenerateManager.h - td/telegram/files/FileHashUploader.h - td/telegram/files/FileId.h - td/telegram/files/FileLoaderActor.h - td/telegram/files/FileLoaderUtils.h - td/telegram/files/FileLoadManager.h - td/telegram/files/FileLocation.h - td/telegram/files/FileManager.h - td/telegram/files/FileSourceId.h - td/telegram/files/FileStats.h - td/telegram/files/FileStatsWorker.h - td/telegram/files/FileType.h - td/telegram/files/FileUploader.h - td/telegram/files/FileUploadId.h - td/telegram/files/FileUploadManager.h - td/telegram/files/PartsManager.h - td/telegram/files/ResourceManager.h - td/telegram/files/ResourceState.h - td/telegram/FolderId.h - td/telegram/ForumTopic.h - td/telegram/ForumTopicEditedData.h - td/telegram/ForumTopicIcon.h - td/telegram/ForumTopicInfo.h - td/telegram/ForumTopicManager.h - td/telegram/Game.h - td/telegram/GameManager.h - td/telegram/GitCommitHash.h - td/telegram/GiveawayParameters.h - td/telegram/Global.h - td/telegram/GlobalPrivacySettings.h - td/telegram/GroupCallId.h - td/telegram/GroupCallManager.h - td/telegram/GroupCallParticipant.h - td/telegram/GroupCallParticipantOrder.h - td/telegram/GroupCallVideoPayload.h - td/telegram/HashtagHints.h - td/telegram/InlineMessageManager.h - td/telegram/InlineQueriesManager.h - td/telegram/InputBusinessChatLink.h - td/telegram/InputDialogId.h - td/telegram/InputGroupCallId.h - td/telegram/InputInvoice.h - td/telegram/InputMessageText.h - td/telegram/JsonValue.h - td/telegram/LabeledPricePart.h - td/telegram/LanguagePackManager.h - td/telegram/LinkManager.h - td/telegram/Location.h - td/telegram/logevent/LogEvent.h - td/telegram/logevent/LogEventHelper.h - td/telegram/logevent/SecretChatEvent.h - td/telegram/Logging.h - td/telegram/MediaArea.h - td/telegram/MediaAreaCoordinates.h - td/telegram/MessageContent.h - td/telegram/MessageContentType.h - td/telegram/MessageCopyOptions.h - td/telegram/MessageDb.h - td/telegram/MessageEffectId.h - td/telegram/MessageEntity.h - td/telegram/MessageExtendedMedia.h - td/telegram/MessageForwardInfo.h - td/telegram/MessageFullId.h - td/telegram/MessageId.h - td/telegram/MessageImportManager.h - td/telegram/MessageInputReplyTo.h - td/telegram/MessageLinkInfo.h - td/telegram/MessageOrigin.h - td/telegram/MessageQueryManager.h - td/telegram/MessageQuote.h - td/telegram/MessageReaction.h - td/telegram/MessageReactor.h - td/telegram/MessageReplyHeader.h - td/telegram/MessageReplyInfo.h - td/telegram/MessageSearchFilter.h - td/telegram/MessageSearchOffset.h - td/telegram/MessageSelfDestructType.h - td/telegram/MessageSender.h - td/telegram/MessagesInfo.h - td/telegram/MessagesManager.h - td/telegram/MessageSource.h - td/telegram/MessageThreadDb.h - td/telegram/MessageThreadInfo.h - td/telegram/MessageTtl.h - td/telegram/MessageViewer.h - td/telegram/MinChannel.h - td/telegram/misc.h - td/telegram/MissingInvitee.h - td/telegram/net/AuthDataShared.h - td/telegram/net/AuthKeyState.h - td/telegram/net/ConnectionCreator.h - td/telegram/net/DcAuthManager.h - td/telegram/net/DcId.h - td/telegram/net/DcOptions.h - td/telegram/net/DcOptionsSet.h - td/telegram/net/MtprotoHeader.h - td/telegram/net/NetActor.h - td/telegram/net/NetQuery.h - td/telegram/net/NetQueryCounter.h - td/telegram/net/NetQueryCreator.h - td/telegram/net/NetQueryDelayer.h - td/telegram/net/NetQueryDispatcher.h - td/telegram/net/NetQueryStats.h - td/telegram/net/NetQueryVerifier.h - td/telegram/net/NetStatsManager.h - td/telegram/net/NetType.h - td/telegram/net/Proxy.h - td/telegram/net/PublicRsaKeySharedCdn.h - td/telegram/net/PublicRsaKeySharedMain.h - td/telegram/net/PublicRsaKeyWatchdog.h - td/telegram/net/Session.h - td/telegram/net/SessionMultiProxy.h - td/telegram/net/SessionProxy.h - td/telegram/net/TempAuthKeyWatchdog.h - td/telegram/NewPasswordState.h - td/telegram/Notification.h - td/telegram/NotificationGroupFromDatabase.h - td/telegram/NotificationGroupId.h - td/telegram/NotificationGroupInfo.h - td/telegram/NotificationGroupKey.h - td/telegram/NotificationGroupType.h - td/telegram/NotificationId.h - td/telegram/NotificationManager.h - td/telegram/NotificationObjectFullId.h - td/telegram/NotificationObjectId.h - td/telegram/NotificationSettingsManager.h - td/telegram/NotificationSettingsScope.h - td/telegram/NotificationSound.h - td/telegram/NotificationSoundType.h - td/telegram/NotificationType.h - td/telegram/OnlineManager.h - td/telegram/OptionManager.h - td/telegram/OrderedMessage.h - td/telegram/OrderInfo.h - td/telegram/Outline.h - td/telegram/PaidReactionType.h - td/telegram/PasswordManager.h - td/telegram/Payments.h - td/telegram/PeerColor.h - td/telegram/PeopleNearbyManager.h - td/telegram/PhoneNumberManager.h - td/telegram/Photo.h - td/telegram/PhotoFormat.h - td/telegram/PhotoSize.h - td/telegram/PhotoSizeSource.h - td/telegram/PhotoSizeType.h - td/telegram/PollId.h - td/telegram/PollManager.h - td/telegram/Premium.h - td/telegram/PremiumGiftOption.h - td/telegram/PrivacyManager.h - td/telegram/PromoDataManager.h - td/telegram/PtsManager.h - td/telegram/PublicDialogType.h - td/telegram/QueryCombiner.h - td/telegram/QueryMerger.h - td/telegram/QuickReplyManager.h - td/telegram/QuickReplyMessageFullId.h - td/telegram/QuickReplyShortcutId.h - td/telegram/ReactionListType.h - td/telegram/ReactionManager.h - td/telegram/ReactionNotificationSettings.h - td/telegram/ReactionNotificationsFrom.h - td/telegram/ReactionType.h - td/telegram/ReactionUnavailabilityReason.h - td/telegram/RecentDialogList.h - td/telegram/ReferralProgramInfo.h - td/telegram/ReferralProgramManager.h - td/telegram/ReferralProgramParameters.h - td/telegram/ReferralProgramSortOrder.h - td/telegram/RepliedMessageInfo.h - td/telegram/ReplyMarkup.h - td/telegram/ReportReason.h - td/telegram/RequestActor.h - td/telegram/RequestedDialogType.h - td/telegram/Requests.h - td/telegram/RestrictionReason.h - td/telegram/SavedMessagesManager.h - td/telegram/SavedMessagesTopicId.h - td/telegram/ScheduledServerMessageId.h - td/telegram/ScopeNotificationSettings.h - td/telegram/SecretChatActor.h - td/telegram/SecretChatDb.h - td/telegram/SecretChatId.h - td/telegram/SecretChatLayer.h - td/telegram/SecretChatsManager.h - td/telegram/SecretInputMedia.h - td/telegram/SecureManager.h - td/telegram/SecureStorage.h - td/telegram/SecureValue.h - td/telegram/SendCodeHelper.h - td/telegram/SentEmailCode.h - td/telegram/SequenceDispatcher.h - td/telegram/ServerMessageId.h - td/telegram/SetWithPosition.h - td/telegram/SharedDialog.h - td/telegram/SpecialStickerSetType.h - td/telegram/SponsoredMessageManager.h - td/telegram/StarAmount.h - td/telegram/StarGift.h - td/telegram/StarGiftAttribute.h - td/telegram/StarGiftId.h - td/telegram/StarGiftManager.h - td/telegram/StarGiftSettings.h - td/telegram/StarManager.h - td/telegram/StarSubscription.h - td/telegram/StarSubscriptionPricing.h - td/telegram/StateManager.h - td/telegram/StatisticsManager.h - td/telegram/StickerFormat.h - td/telegram/StickerListType.h - td/telegram/StickerMaskPosition.h - td/telegram/StickerPhotoSize.h - td/telegram/StickerSetId.h - td/telegram/StickersManager.h - td/telegram/StickerType.h - td/telegram/StorageManager.h - td/telegram/StoryContent.h - td/telegram/StoryContentType.h - td/telegram/StoryDb.h - td/telegram/StoryForwardInfo.h - td/telegram/StoryFullId.h - td/telegram/StoryId.h - td/telegram/StoryInteractionInfo.h - td/telegram/StoryListId.h - td/telegram/StoryManager.h - td/telegram/StoryNotificationSettings.h - td/telegram/StoryStealthMode.h - td/telegram/StoryViewer.h - td/telegram/SuggestedAction.h - td/telegram/SuggestedActionManager.h - td/telegram/Support.h - td/telegram/SynchronousRequests.h - td/telegram/TargetDialogTypes.h - td/telegram/Td.h - td/telegram/TdCallback.h - td/telegram/TdDb.h - td/telegram/TermsOfService.h - td/telegram/TermsOfServiceManager.h - td/telegram/ThemeManager.h - td/telegram/ThemeSettings.h - td/telegram/TimeZoneManager.h - td/telegram/TopDialogCategory.h - td/telegram/TopDialogManager.h - td/telegram/TranscriptionInfo.h - td/telegram/TranscriptionManager.h - td/telegram/TranslationManager.h - td/telegram/UniqueId.h - td/telegram/UpdatesManager.h - td/telegram/UserId.h - td/telegram/UserManager.h - td/telegram/Usernames.h - td/telegram/UserPrivacySetting.h - td/telegram/UserPrivacySettingRule.h - td/telegram/UserStarGift.h - td/telegram/Venue.h - td/telegram/VerificationStatus.h - td/telegram/Version.h - td/telegram/VideoNotesManager.h - td/telegram/VideosManager.h - td/telegram/VoiceNotesManager.h - td/telegram/WebApp.h - td/telegram/WebAppManager.h - td/telegram/WebAppOpenParameters.h - td/telegram/WebPageBlock.h - td/telegram/WebPageId.h - td/telegram/WebPagesManager.h - - td/telegram/AnimationsManager.hpp - td/telegram/AudiosManager.hpp - td/telegram/AuthManager.hpp - td/telegram/BackgroundInfo.hpp - td/telegram/BackgroundType.hpp - td/telegram/Birthdate.hpp - td/telegram/BotVerification.hpp - td/telegram/BotVerifierSettings.hpp - td/telegram/BusinessAwayMessage.hpp - td/telegram/BusinessAwayMessageSchedule.hpp - td/telegram/BusinessBotRights.hpp - td/telegram/BusinessConnectedBot.hpp - td/telegram/BusinessGreetingMessage.hpp - td/telegram/BusinessInfo.hpp - td/telegram/BusinessIntro.hpp - td/telegram/BusinessRecipients.hpp - td/telegram/BusinessWorkHours.hpp - td/telegram/ChatReactions.hpp - td/telegram/DialogFilter.hpp - td/telegram/DialogInviteLink.hpp - td/telegram/DialogNotificationSettings.hpp - td/telegram/Dimensions.hpp - td/telegram/DisallowedGiftsSettings.hpp - td/telegram/Document.hpp - td/telegram/DocumentsManager.hpp - td/telegram/DraftMessage.hpp - td/telegram/EmojiGroup.hpp - td/telegram/FactCheck.hpp - td/telegram/FileReferenceManager.hpp - td/telegram/files/FileData.hpp - td/telegram/files/FileId.hpp - td/telegram/files/FileLocation.hpp - td/telegram/files/FileManager.hpp - td/telegram/files/FileSourceId.hpp - td/telegram/ForumTopic.hpp - td/telegram/ForumTopicEditedData.hpp - td/telegram/ForumTopicIcon.hpp - td/telegram/ForumTopicInfo.hpp - td/telegram/Game.hpp - td/telegram/GiveawayParameters.hpp - td/telegram/InputInvoice.hpp - td/telegram/InputMessageText.hpp - td/telegram/MediaArea.hpp - td/telegram/MediaAreaCoordinates.hpp - td/telegram/MessageEntity.hpp - td/telegram/MessageExtendedMedia.hpp - td/telegram/MessageForwardInfo.hpp - td/telegram/MessageInputReplyTo.hpp - td/telegram/MessageOrigin.hpp - td/telegram/MessageQuote.hpp - td/telegram/MessageReaction.hpp - td/telegram/MessageReactor.hpp - td/telegram/MessageReplyInfo.hpp - td/telegram/MinChannel.hpp - td/telegram/NotificationGroupInfo.hpp - td/telegram/OrderInfo.hpp - td/telegram/PaidReactionType.hpp - td/telegram/Photo.hpp - td/telegram/PhotoSize.hpp - td/telegram/PhotoSizeSource.hpp - td/telegram/PhotoSizeType.hpp - td/telegram/PollId.hpp - td/telegram/PollManager.hpp - td/telegram/PremiumGiftOption.hpp - td/telegram/ReactionManager.hpp - td/telegram/ReactionNotificationSettings.hpp - td/telegram/ReactionNotificationsFrom.hpp - td/telegram/ReactionType.hpp - td/telegram/ReferralProgramInfo.hpp - td/telegram/ReferralProgramParameters.hpp - td/telegram/RepliedMessageInfo.hpp - td/telegram/ReplyMarkup.hpp - td/telegram/RequestedDialogType.hpp - td/telegram/ScopeNotificationSettings.hpp - td/telegram/SecureValue.hpp - td/telegram/SendCodeHelper.hpp - td/telegram/SharedDialog.hpp - td/telegram/StarAmount.hpp - td/telegram/StarGift.hpp - td/telegram/StarGiftAttribute.hpp - td/telegram/StarGiftId.hpp - td/telegram/StarGiftSettings.hpp - td/telegram/StarSubscriptionPricing.hpp - td/telegram/StickerMaskPosition.hpp - td/telegram/StickerPhotoSize.hpp - td/telegram/StickersManager.hpp - td/telegram/StoryForwardInfo.hpp - td/telegram/StoryInteractionInfo.hpp - td/telegram/StoryStealthMode.hpp - td/telegram/SuggestedAction.hpp - td/telegram/TermsOfService.hpp - td/telegram/ThemeSettings.hpp - td/telegram/TranscriptionInfo.hpp - td/telegram/VideoNotesManager.hpp - td/telegram/VideosManager.hpp - td/telegram/VoiceNotesManager.hpp - td/telegram/WebApp.hpp - - ${TL_TD_AUTO_SOURCE} - - td/tl/TlObject.h - td/tl/tl_object_parse.h - td/tl/tl_object_store.h - - ${CMAKE_CURRENT_BINARY_DIR}/td/telegram/GitCommitHash.cpp -) -set(TDLIB_SOURCE - ${TDLIB_SOURCE_PART1} - ${TDLIB_SOURCE_PART2} -) - -set(MEMPROF_SOURCE - memprof/memprof.cpp - memprof/memprof.h -) - -set(MEMPROF_STAT_SOURCE - memprof/memprof_stat.cpp - memprof/memprof_stat.h -) - -# LIBRARIES - -# memprof - simple library for memory usage profiling -add_library(memprof STATIC ${MEMPROF_SOURCE}) -target_include_directories(memprof PUBLIC $) -target_link_libraries(memprof PRIVATE tdutils) -if (MEMPROF) - target_compile_definitions(memprof PRIVATE -DUSE_MEMPROF=1) - if (MEMPROF STREQUAL "SAFE") - target_compile_definitions(memprof PRIVATE -DUSE_MEMPROF_SAFE=1) - elseif (MEMPROF STREQUAL "FAST") - target_compile_definitions(memprof PRIVATE -DUSE_MEMPROF_FAST=1) - elseif (NOT MEMPROF) - message(FATAL_ERROR "Unsupported MEMPROF value \"${MEMPROF}\"") - endif() -endif() - -add_library(memprof_stat EXCLUDE_FROM_ALL STATIC ${MEMPROF_STAT_SOURCE}) -target_include_directories(memprof_stat PUBLIC $) -target_link_libraries(memprof_stat PRIVATE tdutils) - - -add_library(tdapi STATIC ${TL_TD_API_SOURCE}) -target_include_directories(tdapi PUBLIC $ INTERFACE $) -target_link_libraries(tdapi PRIVATE tdutils) - -if (TD_ENABLE_JNI AND NOT ANDROID) # jni is available by default on Android - if (NOT JNI_FOUND) - find_package(JNI REQUIRED COMPONENTS JVM) - endif() - message(STATUS "Found JNI: ${JNI_INCLUDE_DIRS} ${JNI_LIBRARIES}") - target_include_directories(tdapi PUBLIC ${JAVA_INCLUDE_PATH} ${JAVA_INCLUDE_PATH2}) - target_link_libraries(tdapi PUBLIC ${JAVA_JVM_LIBRARY}) -endif() - -if (NOT CMAKE_CROSSCOMPILING) - add_dependencies(tdapi tl_generate_common) -endif() - -add_library(tdmtproto STATIC ${TD_MTPROTO_SOURCE}) -target_include_directories(tdmtproto PUBLIC $ $) -target_include_directories(tdmtproto SYSTEM PRIVATE ${OPENSSL_INCLUDE_DIR}) -target_link_libraries(tdmtproto PUBLIC tdactor tdnet tdutils PRIVATE ${OPENSSL_CRYPTO_LIBRARY} ${CMAKE_DL_LIBS} ${ZLIB_LIBRARIES}) -if (WIN32) - if (MINGW) - target_link_libraries(tdmtproto PRIVATE ws2_32 mswsock crypt32) - else() - target_link_libraries(tdmtproto PRIVATE ws2_32 Mswsock Crypt32) - endif() -endif() -if (NOT CMAKE_CROSSCOMPILING) - add_dependencies(tdmtproto tl_generate_mtproto) -endif() - -# tdcore - internal TDLib interface -if (MSVC AND TD_ENABLE_LTO) - add_library(tdcore_part1 STATIC ${TDLIB_SOURCE_PART1}) - target_include_directories(tdcore_part1 PUBLIC $ $) - target_link_libraries(tdcore_part1 PUBLIC tdapi tdnet tddb tdactor tde2e tdutils PRIVATE tdmtproto) - - add_library(tdcore_part2 STATIC ${TDLIB_SOURCE_PART2}) - target_include_directories(tdcore_part2 PUBLIC $ $) - target_link_libraries(tdcore_part2 PUBLIC tdapi tdnet tddb tdactor tde2e tdutils PRIVATE tdmtproto) - - add_library(tdcore INTERFACE) - target_link_libraries(tdcore INTERFACE tdcore_part1 tdcore_part2) - - set(TD_CORE_PART_TARGETS tdcore_part1 tdcore_part2) -else() - add_library(tdcore STATIC ${TDLIB_SOURCE}) - target_include_directories(tdcore PUBLIC $ $) - target_link_libraries(tdcore PUBLIC tdapi tdnet tddb tdactor tde2e tdutils PRIVATE tdmtproto) - - set(TD_CORE_PART_TARGETS) -endif() - -if (NOT CMAKE_CROSSCOMPILING) - add_dependencies(tdcore tl_generate_common) - if (TD_ENABLE_JNI) - add_dependencies(tdcore td_generate_java_api) - endif() - if (TD_ENABLE_DOTNET) - add_dependencies(tdcore remove_cpp_documentation) - endif() -endif() - -add_library(tdclient STATIC td/telegram/Client.cpp td/telegram/Client.h td/telegram/Log.cpp td/telegram/Log.h) -target_include_directories(tdclient PUBLIC - $ -) -target_link_libraries(tdclient PUBLIC tdapi PRIVATE tdcore) - -if (TD_ENABLE_DOTNET) - add_library(tddotnet SHARED - td/telegram/ClientDotNet.cpp - td/telegram/LogDotNet.cpp - ${TL_DOTNET_SCHEME_SOURCE} - ) - set_target_properties(tddotnet PROPERTIES OUTPUT_NAME Telegram.Td) - target_link_libraries(tddotnet PRIVATE tdclient tdutils) - target_include_directories(tddotnet PUBLIC - $ - ) - if (NOT CMAKE_CROSSCOMPILING) - add_dependencies(tddotnet generate_dotnet_api) - endif() - - target_compile_options(tddotnet PRIVATE "/doc") - if (CMAKE_SYSTEM_NAME STREQUAL "WindowsStore") - set_target_properties(tddotnet PROPERTIES VS_WINRT_COMPONENT "true") - target_compile_options(tddotnet PUBLIC "/ZW") - else() - set_target_properties(tddotnet PROPERTIES COMPILE_FLAGS "/GR /clr") - target_compile_options(tddotnet PUBLIC "/EHa") - endif() -endif() - -# tdc - TDLib interface in pure C -add_library(tdc STATIC EXCLUDE_FROM_ALL ${TL_C_SCHEME_SOURCE} td/telegram/td_c_client.cpp td/telegram/td_c_client.h) -target_include_directories(tdc PUBLIC - $ - $) -target_link_libraries(tdc PRIVATE tdclient tdutils) -if (NOT CMAKE_CROSSCOMPILING) - add_dependencies(tdc tl_generate_c) -endif() - -add_library(tdjson_private STATIC ${TL_TD_JSON_SOURCE} td/telegram/ClientJson.cpp td/telegram/ClientJson.h) -target_include_directories(tdjson_private PUBLIC - $ - $) -target_link_libraries(tdjson_private PUBLIC tdclient tdutils) -if (NOT CMAKE_CROSSCOMPILING) - add_dependencies(tdjson_private tl_generate_common tl_generate_json) - if (TD_ENABLE_DOTNET) - add_dependencies(tdjson_private remove_cpp_documentation) - endif() -endif() - -set(TD_JSON_HEADERS td/telegram/td_json_client.h td/telegram/td_log.h) -set(TD_JSON_SOURCE td/telegram/td_json_client.cpp td/telegram/td_log.cpp) - -include(GenerateExportHeader) - -add_library(tdjson SHARED ${TD_JSON_SOURCE} ${TD_JSON_HEADERS}) -target_link_libraries(tdjson PRIVATE tdjson_private) -generate_export_header(tdjson EXPORT_FILE_NAME ${CMAKE_CURRENT_BINARY_DIR}/td/telegram/tdjson_export.h) -target_include_directories(tdjson PUBLIC - $ - $) -if (APPLE) - set_target_properties(tdjson PROPERTIES LINK_FLAGS "-Wl,-exported_symbols_list,${CMAKE_CURRENT_SOURCE_DIR}/tdclientjson_export_list") -endif() - -add_library(tdjson_static STATIC ${TD_JSON_SOURCE} ${TD_JSON_HEADERS}) -target_link_libraries(tdjson_static PRIVATE tdjson_private) -target_compile_definitions(tdjson_static PUBLIC TDJSON_STATIC_DEFINE) -target_include_directories(tdjson_static PUBLIC - $ - $) - -# EXECUTABLES -if (EMSCRIPTEN) - set(TD_EMSCRIPTEN_SRC td/telegram/td_emscripten.cpp) - add_executable(${TD_EMSCRIPTEN} ${TD_EMSCRIPTEN_SRC}) - target_include_directories(${TD_EMSCRIPTEN} PUBLIC $) - target_link_libraries(${TD_EMSCRIPTEN} PRIVATE tdjson_static tdactor) -endif() - -if (NOT CMAKE_CROSSCOMPILING) - add_executable(tg_cli td/telegram/cli.cpp ${TL_TD_JSON_SOURCE}) - - if (NOT READLINE_FOUND) - find_package(Readline QUIET) - endif() - if (READLINE_FOUND) - message(STATUS "Found Readline: ${READLINE_INCLUDE_DIR} ${READLINE_LIBRARY}") - if (NOT USABLE_READLINE_FOUND) - set(CMAKE_REQUIRED_INCLUDES "${READLINE_INCLUDE_DIR}") - set(CMAKE_REQUIRED_LIBRARIES "${READLINE_LIBRARY}") - include(CheckCXXSourceCompiles) - unset(USABLE_READLINE_FOUND CACHE) - check_cxx_source_compiles("#include \n#include \nint main() { rl_free(0); }" USABLE_READLINE_FOUND) - if (NOT USABLE_READLINE_FOUND) - message(STATUS "Found Readline is too old, ignore it (this is NOT an error)") - unset(READLINE_INCLUDE_DIR CACHE) - unset(READLINE_LIBRARY CACHE) - endif() - endif() - if (USABLE_READLINE_FOUND) - target_link_libraries(tg_cli PRIVATE ${READLINE_LIBRARY}) - target_include_directories(tg_cli SYSTEM PRIVATE ${READLINE_INCLUDE_DIR}) - target_compile_definitions(tg_cli PRIVATE -DUSE_READLINE=1) - endif() - endif() - target_link_libraries(tg_cli PRIVATE memprof tdclient tdcore) - add_dependencies(tg_cli tl_generate_json) -endif() - -# Exported libraries -add_library(TdStatic INTERFACE) -target_link_libraries(TdStatic INTERFACE tdclient) - -add_library(TdJson INTERFACE) -target_link_libraries(TdJson INTERFACE tdjson) - -add_library(TdJsonStatic INTERFACE) -target_link_libraries(TdJsonStatic INTERFACE tdjson_static) - -add_library(Td::TdStatic ALIAS TdStatic) -add_library(Td::TdJson ALIAS TdJson) -add_library(Td::TdJsonStatic ALIAS TdJsonStatic) - -set(INSTALL_TARGETS tdjson TdJson) -set(INSTALL_STATIC_TARGETS tdjson_static TdJsonStatic tdjson_private "${TD_CORE_PART_TARGETS}" tdcore tdmtproto tdclient TdStatic tdapi) - -if (TD_INSTALL_SHARED_LIBRARIES) - install(TARGETS ${INSTALL_TARGETS} EXPORT TdTargets - LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" - ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" - RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" - INCLUDES DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}" - ) -endif() - -if (TD_INSTALL_STATIC_LIBRARIES) - install(TARGETS ${INSTALL_STATIC_TARGETS} EXPORT TdStaticTargets - LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" - ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" - INCLUDES DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}" - ) -endif() - -# generate pkg-config files -include(GeneratePkgConfig) - -if (TD_INSTALL_STATIC_LIBRARIES) - generate_pkgconfig(tdutils "Telegram Library - Utils") - generate_pkgconfig(tdactor "Telegram Library - Actor") - generate_pkgconfig(tde2e "Telegram Library - E2E") - generate_pkgconfig(tdnet "Telegram Library - Net") - generate_pkgconfig(tdsqlite "Telegram Library - SQLite") - generate_pkgconfig(tddb "Telegram Library - Database") - if (MEMPROF) - # generate_pkgconfig(memprof "memprof - simple library for memory usage profiling") - endif() - generate_pkgconfig(tdmtproto "Telegram Library - MTProto implementation") - generate_pkgconfig(tdcore "Telegram Library - Core") - generate_pkgconfig(tdclient "Telegram Library - C++ Interface") - if (TD_ENABLE_DOTNET) - # generate_pkgconfig(tddotnet "Telegram Library - C# Interface") - endif() - # generate_pkgconfig(tdc "Telegram Library - C interface") - generate_pkgconfig(tdapi "Telegram Library - API") - generate_pkgconfig(tdjson_private "Telegram Library - JSON interface (private)") - generate_pkgconfig(tdjson_static "Telegram Library - JSON interface (static)") -endif() -if (TD_INSTALL_SHARED_LIBRARIES) - generate_pkgconfig(tdjson "Telegram Library - JSON interface (shared)") -endif() - -if (TD_INSTALL_SHARED_LIBRARIES) - install(EXPORT TdTargets - FILE TdTargets.cmake - NAMESPACE Td:: - DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/Td" - ) -endif() - -if (TD_INSTALL_STATIC_LIBRARIES) - install(EXPORT TdStaticTargets - FILE TdStaticTargets.cmake - NAMESPACE Td:: - DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/Td" - ) -endif() - -if (TD_INSTALL_SHARED_LIBRARIES OR TD_INSTALL_STATIC_LIBRARIES) - # Install tdjson/tdjson_static: - install(FILES ${TD_JSON_HEADERS} "${CMAKE_CURRENT_BINARY_DIR}/td/telegram/tdjson_export.h" DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/td/telegram") -endif() -if (TD_INSTALL_STATIC_LIBRARIES) - # Install tdclient: - install(FILES td/telegram/Client.h td/telegram/Log.h DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/td/telegram") - # Install tdapi: - install(FILES td/tl/TlObject.h DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/td/tl") - install(FILES "${TL_TD_AUTO_INCLUDE_DIR}/td/telegram/td_api.h" "${TL_TD_AUTO_INCLUDE_DIR}/td/telegram/td_api.hpp" DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/td/telegram") -endif() -if (TD_ENABLE_JNI) - install(FILES td/tl/tl_jni_object.h DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/td/tl") -endif() -if (MSVC AND VCPKG_TOOLCHAIN) - install(DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/$/" DESTINATION "${CMAKE_INSTALL_BINDIR}" FILES_MATCHING PATTERN "*.dll") -endif() - -include(CMakePackageConfigHelpers) -write_basic_package_version_file("TdConfigVersion.cmake" - VERSION "${TDLib_VERSION}" - COMPATIBILITY ExactVersion -) -install(FILES "TdConfig.cmake" "${CMAKE_CURRENT_BINARY_DIR}/TdConfigVersion.cmake" - DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/Td" -) - -# Add SOVERSION to shared libraries -set_property(TARGET tdjson PROPERTY SOVERSION "${TDLib_VERSION}") diff --git a/third-party/td/td/Doxyfile b/third-party/td/td/Doxyfile deleted file mode 100644 index e9e26e2d5d..0000000000 --- a/third-party/td/td/Doxyfile +++ /dev/null @@ -1,2473 +0,0 @@ -# Doxyfile 1.8.13 - -# This file describes the settings to be used by the documentation system -# doxygen (www.doxygen.org) for a project. -# -# All text after a double hash (##) is considered a comment and is placed in -# front of the TAG it is preceding. -# -# All text after a single hash (#) is considered a comment and will be ignored. -# The format is: -# TAG = value [value, ...] -# For lists, items can also be appended using: -# TAG += value [value, ...] -# Values that contain spaces should be placed between quotes (\" \"). - -#--------------------------------------------------------------------------- -# Project related configuration options -#--------------------------------------------------------------------------- - -# This tag specifies the encoding used for all characters in the config file -# that follow. The default is UTF-8 which is also the encoding used for all text -# before the first occurrence of this tag. Doxygen uses libiconv (or the iconv -# built into libc) for the transcoding. See http://www.gnu.org/software/libiconv -# for the list of possible encodings. -# The default value is: UTF-8. - -DOXYFILE_ENCODING = UTF-8 - -# The PROJECT_NAME tag is a single word (or a sequence of words surrounded by -# double-quotes, unless you are using Doxywizard) that should identify the -# project for which the documentation is generated. This name is used in the -# title of most generated pages and in a few other places. -# The default value is: My Project. - -PROJECT_NAME = "TDLib" - -# The PROJECT_NUMBER tag can be used to enter a project or revision number. This -# could be handy for archiving the generated documentation or if some version -# control system is used. - -PROJECT_NUMBER = - -# Using the PROJECT_BRIEF tag one can provide an optional one line description -# for a project that appears at the top of each page and should give viewer a -# quick idea about the purpose of the project. Keep the description short. - -PROJECT_BRIEF = - -# With the PROJECT_LOGO tag one can specify a logo or an icon that is included -# in the documentation. The maximum height of the logo should not exceed 55 -# pixels and the maximum width should not exceed 200 pixels. Doxygen will copy -# the logo to the output directory. - -PROJECT_LOGO = - -# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path -# into which the generated documentation will be written. If a relative path is -# entered, it will be relative to the location where doxygen was started. If -# left blank the current directory will be used. - -OUTPUT_DIRECTORY = "docs" - -# If the CREATE_SUBDIRS tag is set to YES then doxygen will create 4096 sub- -# directories (in 2 levels) under the output directory of each output format and -# will distribute the generated files over these directories. Enabling this -# option can be useful when feeding doxygen a huge amount of source files, where -# putting all generated files in the same directory would otherwise causes -# performance problems for the file system. -# The default value is: NO. - -CREATE_SUBDIRS = NO - -# If the ALLOW_UNICODE_NAMES tag is set to YES, doxygen will allow non-ASCII -# characters to appear in the names of generated files. If set to NO, non-ASCII -# characters will be escaped, for example _xE3_x81_x84 will be used for Unicode -# U+3044. -# The default value is: NO. - -ALLOW_UNICODE_NAMES = NO - -# The OUTPUT_LANGUAGE tag is used to specify the language in which all -# documentation generated by doxygen is written. Doxygen will use this -# information to generate all constant output in the proper language. -# Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Catalan, Chinese, -# Chinese-Traditional, Croatian, Czech, Danish, Dutch, English (United States), -# Esperanto, Farsi (Persian), Finnish, French, German, Greek, Hungarian, -# Indonesian, Italian, Japanese, Japanese-en (Japanese with English messages), -# Korean, Korean-en (Korean with English messages), Latvian, Lithuanian, -# Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese, Romanian, Russian, -# Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish, Swedish, Turkish, -# Ukrainian and Vietnamese. -# The default value is: English. - -OUTPUT_LANGUAGE = English - -# If the BRIEF_MEMBER_DESC tag is set to YES, doxygen will include brief member -# descriptions after the members that are listed in the file and class -# documentation (similar to Javadoc). Set to NO to disable this. -# The default value is: YES. - -BRIEF_MEMBER_DESC = YES - -# If the REPEAT_BRIEF tag is set to YES, doxygen will prepend the brief -# description of a member or function before the detailed description -# -# Note: If both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the -# brief descriptions will be completely suppressed. -# The default value is: YES. - -REPEAT_BRIEF = YES - -# This tag implements a quasi-intelligent brief description abbreviator that is -# used to form the text in various listings. Each string in this list, if found -# as the leading text of the brief description, will be stripped from the text -# and the result, after processing the whole list, is used as the annotated -# text. Otherwise, the brief description is used as-is. If left blank, the -# following values are used ($name is automatically replaced with the name of -# the entity):The $name class, The $name widget, The $name file, is, provides, -# specifies, contains, represents, a, an and the. - -ABBREVIATE_BRIEF = "The $name class" \ - "The $name widget" \ - "The $name file" \ - is \ - provides \ - specifies \ - contains \ - represents \ - a \ - an \ - the - -# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then -# doxygen will generate a detailed section even if there is only a brief -# description. -# The default value is: NO. - -ALWAYS_DETAILED_SEC = NO - -# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all -# inherited members of a class in the documentation of that class as if those -# members were ordinary class members. Constructors, destructors and assignment -# operators of the base classes will not be shown. -# The default value is: NO. - -INLINE_INHERITED_MEMB = NO - -# If the FULL_PATH_NAMES tag is set to YES, doxygen will prepend the full path -# before files name in the file list and in the header files. If set to NO the -# shortest path that makes the file name unique will be used -# The default value is: YES. - -FULL_PATH_NAMES = YES - -# The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path. -# Stripping is only done if one of the specified strings matches the left-hand -# part of the path. The tag can be used to show relative paths in the file list. -# If left blank the directory from which doxygen is run is used as the path to -# strip. -# -# Note that you can specify absolute paths here, but also relative paths, which -# will be relative from the directory where doxygen is started. -# This tag requires that the tag FULL_PATH_NAMES is set to YES. - -STRIP_FROM_PATH = - -# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the -# path mentioned in the documentation of a class, which tells the reader which -# header file to include in order to use a class. If left blank only the name of -# the header file containing the class definition is used. Otherwise one should -# specify the list of include paths that are normally passed to the compiler -# using the -I flag. - -STRIP_FROM_INC_PATH = td/generate/auto/ . - -# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but -# less readable) file names. This can be useful is your file systems doesn't -# support long names like on DOS, Mac, or CD-ROM. -# The default value is: NO. - -SHORT_NAMES = NO - -# If the JAVADOC_AUTOBRIEF tag is set to YES then doxygen will interpret the -# first line (until the first dot) of a Javadoc-style comment as the brief -# description. If set to NO, the Javadoc-style will behave just like regular Qt- -# style comments (thus requiring an explicit @brief command for a brief -# description.) -# The default value is: NO. - -JAVADOC_AUTOBRIEF = NO - -# If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first -# line (until the first dot) of a Qt-style comment as the brief description. If -# set to NO, the Qt-style will behave just like regular Qt-style comments (thus -# requiring an explicit \brief command for a brief description.) -# The default value is: NO. - -QT_AUTOBRIEF = NO - -# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make doxygen treat a -# multi-line C++ special comment block (i.e. a block of //! or /// comments) as -# a brief description. This used to be the default behavior. The new default is -# to treat a multi-line C++ comment block as a detailed description. Set this -# tag to YES if you prefer the old behavior instead. -# -# Note that setting this tag to YES also means that rational rose comments are -# not recognized any more. -# The default value is: NO. - -MULTILINE_CPP_IS_BRIEF = NO - -# If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the -# documentation from any documented member that it re-implements. -# The default value is: YES. - -INHERIT_DOCS = YES - -# If the SEPARATE_MEMBER_PAGES tag is set to YES then doxygen will produce a new -# page for each member. If set to NO, the documentation of a member will be part -# of the file/class/namespace that contains it. -# The default value is: NO. - -SEPARATE_MEMBER_PAGES = NO - -# The TAB_SIZE tag can be used to set the number of spaces in a tab. Doxygen -# uses this value to replace tabs by spaces in code fragments. -# Minimum value: 1, maximum value: 16, default value: 4. - -TAB_SIZE = 4 - -# This tag can be used to specify a number of aliases that act as commands in -# the documentation. An alias has the form: -# name=value -# For example adding -# "sideeffect=@par Side Effects:\n" -# will allow you to put the command \sideeffect (or @sideeffect) in the -# documentation, which will result in a user-defined paragraph with heading -# "Side Effects:". You can put \n's in the value part of an alias to insert -# newlines. - -ALIASES = - -# This tag can be used to specify a number of word-keyword mappings (TCL only). -# A mapping has the form "name=value". For example adding "class=itcl::class" -# will allow you to use the command class in the itcl::class meaning. - -TCL_SUBST = - -# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources -# only. Doxygen will then generate output that is more tailored for C. For -# instance, some of the names that are used will be different. The list of all -# members will be omitted, etc. -# The default value is: NO. - -OPTIMIZE_OUTPUT_FOR_C = NO - -# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or -# Python sources only. Doxygen will then generate output that is more tailored -# for that language. For instance, namespaces will be presented as packages, -# qualified scopes will look different, etc. -# The default value is: NO. - -OPTIMIZE_OUTPUT_JAVA = NO - -# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran -# sources. Doxygen will then generate output that is tailored for Fortran. -# The default value is: NO. - -OPTIMIZE_FOR_FORTRAN = NO - -# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL -# sources. Doxygen will then generate output that is tailored for VHDL. -# The default value is: NO. - -OPTIMIZE_OUTPUT_VHDL = NO - -# Doxygen selects the parser to use depending on the extension of the files it -# parses. With this tag you can assign which parser to use for a given -# extension. Doxygen has a built-in mapping, but you can override or extend it -# using this tag. The format is ext=language, where ext is a file extension, and -# language is one of the parsers supported by doxygen: IDL, Java, Javascript, -# C#, C, C++, D, PHP, Objective-C, Python, Fortran (fixed format Fortran: -# FortranFixed, free formatted Fortran: FortranFree, unknown formatted Fortran: -# Fortran. In the later case the parser tries to guess whether the code is fixed -# or free formatted code, this is the default for Fortran type files), VHDL. For -# instance to make doxygen treat .inc files as Fortran files (default is PHP), -# and .f files as C (default is Fortran), use: inc=Fortran f=C. -# -# Note: For files without extension you can use no_extension as a placeholder. -# -# Note that for custom extensions you also need to set FILE_PATTERNS otherwise -# the files are not read by doxygen. - -EXTENSION_MAPPING = - -# If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments -# according to the Markdown format, which allows for more readable -# documentation. See http://daringfireball.net/projects/markdown/ for details. -# The output of markdown processing is further processed by doxygen, so you can -# mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in -# case of backward compatibilities issues. -# The default value is: YES. - -MARKDOWN_SUPPORT = YES - -# When the TOC_INCLUDE_HEADINGS tag is set to a non-zero value, all headings up -# to that level are automatically included in the table of contents, even if -# they do not have an id attribute. -# Note: This feature currently applies only to Markdown headings. -# Minimum value: 0, maximum value: 99, default value: 0. -# This tag requires that the tag MARKDOWN_SUPPORT is set to YES. - -TOC_INCLUDE_HEADINGS = 0 - -# When enabled doxygen tries to link words that correspond to documented -# classes, or namespaces to their corresponding documentation. Such a link can -# be prevented in individual cases by putting a % sign in front of the word or -# globally by setting AUTOLINK_SUPPORT to NO. -# The default value is: YES. - -AUTOLINK_SUPPORT = YES - -# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want -# to include (a tag file for) the STL sources as input, then you should set this -# tag to YES in order to let doxygen match functions declarations and -# definitions whose arguments contain STL classes (e.g. func(std::string); -# versus func(std::string) {}). This also make the inheritance and collaboration -# diagrams that involve STL classes more complete and accurate. -# The default value is: NO. - -BUILTIN_STL_SUPPORT = YES - -# If you use Microsoft's C++/CLI language, you should set this option to YES to -# enable parsing support. -# The default value is: NO. - -CPP_CLI_SUPPORT = NO - -# Set the SIP_SUPPORT tag to YES if your project consists of sip (see: -# http://www.riverbankcomputing.co.uk/software/sip/intro) sources only. Doxygen -# will parse them like normal C++ but will assume all classes use public instead -# of private inheritance when no explicit protection keyword is present. -# The default value is: NO. - -SIP_SUPPORT = NO - -# For Microsoft's IDL there are propget and propput attributes to indicate -# getter and setter methods for a property. Setting this option to YES will make -# doxygen to replace the get and set methods by a property in the documentation. -# This will only work if the methods are indeed getting or setting a simple -# type. If this is not the case, or you want to show the methods anyway, you -# should set this option to NO. -# The default value is: YES. - -IDL_PROPERTY_SUPPORT = YES - -# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC -# tag is set to YES then doxygen will reuse the documentation of the first -# member in the group (if any) for the other members of the group. By default -# all members of a group must be documented explicitly. -# The default value is: NO. - -DISTRIBUTE_GROUP_DOC = NO - -# If one adds a struct or class to a group and this option is enabled, then also -# any nested class or struct is added to the same group. By default this option -# is disabled and one has to add nested compounds explicitly via \ingroup. -# The default value is: NO. - -GROUP_NESTED_COMPOUNDS = NO - -# Set the SUBGROUPING tag to YES to allow class member groups of the same type -# (for instance a group of public functions) to be put as a subgroup of that -# type (e.g. under the Public Functions section). Set it to NO to prevent -# subgrouping. Alternatively, this can be done per class using the -# \nosubgrouping command. -# The default value is: YES. - -SUBGROUPING = YES - -# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and unions -# are shown inside the group in which they are included (e.g. using \ingroup) -# instead of on a separate page (for HTML and Man pages) or section (for LaTeX -# and RTF). -# -# Note that this feature does not work in combination with -# SEPARATE_MEMBER_PAGES. -# The default value is: NO. - -INLINE_GROUPED_CLASSES = NO - -# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and unions -# with only public data fields or simple typedef fields will be shown inline in -# the documentation of the scope in which they are defined (i.e. file, -# namespace, or group documentation), provided this scope is documented. If set -# to NO, structs, classes, and unions are shown on a separate page (for HTML and -# Man pages) or section (for LaTeX and RTF). -# The default value is: NO. - -INLINE_SIMPLE_STRUCTS = NO - -# When TYPEDEF_HIDES_STRUCT tag is enabled, a typedef of a struct, union, or -# enum is documented as struct, union, or enum with the name of the typedef. So -# typedef struct TypeS {} TypeT, will appear in the documentation as a struct -# with name TypeT. When disabled the typedef will appear as a member of a file, -# namespace, or class. And the struct will be named TypeS. This can typically be -# useful for C code in case the coding convention dictates that all compound -# types are typedef'ed and only the typedef is referenced, never the tag name. -# The default value is: NO. - -TYPEDEF_HIDES_STRUCT = NO - -# The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This -# cache is used to resolve symbols given their name and scope. Since this can be -# an expensive process and often the same symbol appears multiple times in the -# code, doxygen keeps a cache of pre-resolved symbols. If the cache is too small -# doxygen will become slower. If the cache is too large, memory is wasted. The -# cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range -# is 0..9, the default is 0, corresponding to a cache size of 2^16=65536 -# symbols. At the end of a run doxygen will report the cache usage and suggest -# the optimal cache size from a speed point of view. -# Minimum value: 0, maximum value: 9, default value: 0. - -LOOKUP_CACHE_SIZE = 0 - -#--------------------------------------------------------------------------- -# Build related configuration options -#--------------------------------------------------------------------------- - -# If the EXTRACT_ALL tag is set to YES, doxygen will assume all entities in -# documentation are documented, even if no documentation was available. Private -# class members and static file members will be hidden unless the -# EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES. -# Note: This will also disable the warnings about undocumented members that are -# normally produced when WARNINGS is set to YES. -# The default value is: NO. - -EXTRACT_ALL = NO - -# If the EXTRACT_PRIVATE tag is set to YES, all private members of a class will -# be included in the documentation. -# The default value is: NO. - -EXTRACT_PRIVATE = NO - -# If the EXTRACT_PACKAGE tag is set to YES, all members with package or internal -# scope will be included in the documentation. -# The default value is: NO. - -EXTRACT_PACKAGE = NO - -# If the EXTRACT_STATIC tag is set to YES, all static members of a file will be -# included in the documentation. -# The default value is: NO. - -EXTRACT_STATIC = NO - -# If the EXTRACT_LOCAL_CLASSES tag is set to YES, classes (and structs) defined -# locally in source files will be included in the documentation. If set to NO, -# only classes defined in header files are included. Does not have any effect -# for Java sources. -# The default value is: YES. - -EXTRACT_LOCAL_CLASSES = YES - -# This flag is only useful for Objective-C code. If set to YES, local methods, -# which are defined in the implementation section but not in the interface are -# included in the documentation. If set to NO, only methods in the interface are -# included. -# The default value is: NO. - -EXTRACT_LOCAL_METHODS = NO - -# If this flag is set to YES, the members of anonymous namespaces will be -# extracted and appear in the documentation as a namespace called -# 'anonymous_namespace{file}', where file will be replaced with the base name of -# the file that contains the anonymous namespace. By default anonymous namespace -# are hidden. -# The default value is: NO. - -EXTRACT_ANON_NSPACES = NO - -# If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all -# undocumented members inside documented classes or files. If set to NO these -# members will be included in the various overviews, but no documentation -# section is generated. This option has no effect if EXTRACT_ALL is enabled. -# The default value is: NO. - -HIDE_UNDOC_MEMBERS = NO - -# If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all -# undocumented classes that are normally visible in the class hierarchy. If set -# to NO, these classes will be included in the various overviews. This option -# has no effect if EXTRACT_ALL is enabled. -# The default value is: NO. - -HIDE_UNDOC_CLASSES = NO - -# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend -# (class|struct|union) declarations. If set to NO, these declarations will be -# included in the documentation. -# The default value is: NO. - -HIDE_FRIEND_COMPOUNDS = NO - -# If the HIDE_IN_BODY_DOCS tag is set to YES, doxygen will hide any -# documentation blocks found inside the body of a function. If set to NO, these -# blocks will be appended to the function's detailed documentation block. -# The default value is: NO. - -HIDE_IN_BODY_DOCS = NO - -# The INTERNAL_DOCS tag determines if documentation that is typed after a -# \internal command is included. If the tag is set to NO then the documentation -# will be excluded. Set it to YES to include the internal documentation. -# The default value is: NO. - -INTERNAL_DOCS = NO - -# If the CASE_SENSE_NAMES tag is set to NO then doxygen will only generate file -# names in lower-case letters. If set to YES, upper-case letters are also -# allowed. This is useful if you have classes or files whose names only differ -# in case and if your file system supports case sensitive file names. Windows -# and Mac users are advised to set this option to NO. -# The default value is: system dependent. - -CASE_SENSE_NAMES = NO - -# If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with -# their full class and namespace scopes in the documentation. If set to YES, the -# scope will be hidden. -# The default value is: NO. - -HIDE_SCOPE_NAMES = NO - -# If the HIDE_COMPOUND_REFERENCE tag is set to NO (default) then doxygen will -# append additional text to a page's title, such as Class Reference. If set to -# YES the compound reference will be hidden. -# The default value is: NO. - -HIDE_COMPOUND_REFERENCE= NO - -# If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of -# the files that are included by a file in the documentation of that file. -# The default value is: YES. - -SHOW_INCLUDE_FILES = YES - -# If the SHOW_GROUPED_MEMB_INC tag is set to YES then Doxygen will add for each -# grouped member an include statement to the documentation, telling the reader -# which file to include in order to use the member. -# The default value is: NO. - -SHOW_GROUPED_MEMB_INC = NO - -# If the FORCE_LOCAL_INCLUDES tag is set to YES then doxygen will list include -# files with double quotes in the documentation rather than with sharp brackets. -# The default value is: NO. - -FORCE_LOCAL_INCLUDES = NO - -# If the INLINE_INFO tag is set to YES then a tag [inline] is inserted in the -# documentation for inline members. -# The default value is: YES. - -INLINE_INFO = YES - -# If the SORT_MEMBER_DOCS tag is set to YES then doxygen will sort the -# (detailed) documentation of file and class members alphabetically by member -# name. If set to NO, the members will appear in declaration order. -# The default value is: YES. - -SORT_MEMBER_DOCS = YES - -# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief -# descriptions of file, namespace and class members alphabetically by member -# name. If set to NO, the members will appear in declaration order. Note that -# this will also influence the order of the classes in the class list. -# The default value is: NO. - -SORT_BRIEF_DOCS = NO - -# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the -# (brief and detailed) documentation of class members so that constructors and -# destructors are listed first. If set to NO the constructors will appear in the -# respective orders defined by SORT_BRIEF_DOCS and SORT_MEMBER_DOCS. -# Note: If SORT_BRIEF_DOCS is set to NO this option is ignored for sorting brief -# member documentation. -# Note: If SORT_MEMBER_DOCS is set to NO this option is ignored for sorting -# detailed member documentation. -# The default value is: NO. - -SORT_MEMBERS_CTORS_1ST = NO - -# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the hierarchy -# of group names into alphabetical order. If set to NO the group names will -# appear in their defined order. -# The default value is: NO. - -SORT_GROUP_NAMES = NO - -# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be sorted by -# fully-qualified names, including namespaces. If set to NO, the class list will -# be sorted only by class name, not including the namespace part. -# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. -# Note: This option applies only to the class list, not to the alphabetical -# list. -# The default value is: NO. - -SORT_BY_SCOPE_NAME = NO - -# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to do proper -# type resolution of all parameters of a function it will reject a match between -# the prototype and the implementation of a member function even if there is -# only one candidate or it is obvious which candidate to choose by doing a -# simple string match. By disabling STRICT_PROTO_MATCHING doxygen will still -# accept a match between prototype and implementation in such cases. -# The default value is: NO. - -STRICT_PROTO_MATCHING = NO - -# The GENERATE_TODOLIST tag can be used to enable (YES) or disable (NO) the todo -# list. This list is created by putting \todo commands in the documentation. -# The default value is: YES. - -GENERATE_TODOLIST = YES - -# The GENERATE_TESTLIST tag can be used to enable (YES) or disable (NO) the test -# list. This list is created by putting \test commands in the documentation. -# The default value is: YES. - -GENERATE_TESTLIST = YES - -# The GENERATE_BUGLIST tag can be used to enable (YES) or disable (NO) the bug -# list. This list is created by putting \bug commands in the documentation. -# The default value is: YES. - -GENERATE_BUGLIST = YES - -# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or disable (NO) -# the deprecated list. This list is created by putting \deprecated commands in -# the documentation. -# The default value is: YES. - -GENERATE_DEPRECATEDLIST= YES - -# The ENABLED_SECTIONS tag can be used to enable conditional documentation -# sections, marked by \if ... \endif and \cond -# ... \endcond blocks. - -ENABLED_SECTIONS = - -# The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the -# initial value of a variable or macro / define can have for it to appear in the -# documentation. If the initializer consists of more lines than specified here -# it will be hidden. Use a value of 0 to hide initializers completely. The -# appearance of the value of individual variables and macros / defines can be -# controlled using \showinitializer or \hideinitializer command in the -# documentation regardless of this setting. -# Minimum value: 0, maximum value: 10000, default value: 30. - -MAX_INITIALIZER_LINES = 30 - -# Set the SHOW_USED_FILES tag to NO to disable the list of files generated at -# the bottom of the documentation of classes and structs. If set to YES, the -# list will mention the files that were used to generate the documentation. -# The default value is: YES. - -SHOW_USED_FILES = YES - -# Set the SHOW_FILES tag to NO to disable the generation of the Files page. This -# will remove the Files entry from the Quick Index and from the Folder Tree View -# (if specified). -# The default value is: YES. - -SHOW_FILES = YES - -# Set the SHOW_NAMESPACES tag to NO to disable the generation of the Namespaces -# page. This will remove the Namespaces entry from the Quick Index and from the -# Folder Tree View (if specified). -# The default value is: YES. - -SHOW_NAMESPACES = YES - -# The FILE_VERSION_FILTER tag can be used to specify a program or script that -# doxygen should invoke to get the current version for each file (typically from -# the version control system). Doxygen will invoke the program by executing (via -# popen()) the command command input-file, where command is the value of the -# FILE_VERSION_FILTER tag, and input-file is the name of an input file provided -# by doxygen. Whatever the program writes to standard output is used as the file -# version. For an example see the documentation. - -FILE_VERSION_FILTER = - -# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed -# by doxygen. The layout file controls the global structure of the generated -# output files in an output format independent way. To create the layout file -# that represents doxygen's defaults, run doxygen with the -l option. You can -# optionally specify a file name after the option, if omitted DoxygenLayout.xml -# will be used as the name of the layout file. -# -# Note that if you run doxygen from a directory containing a file called -# DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE -# tag is left empty. - -LAYOUT_FILE = - -# The CITE_BIB_FILES tag can be used to specify one or more bib files containing -# the reference definitions. This must be a list of .bib files. The .bib -# extension is automatically appended if omitted. This requires the bibtex tool -# to be installed. See also http://en.wikipedia.org/wiki/BibTeX for more info. -# For LaTeX the style of the bibliography can be controlled using -# LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the -# search path. See also \cite for info how to create references. - -CITE_BIB_FILES = - -#--------------------------------------------------------------------------- -# Configuration options related to warning and progress messages -#--------------------------------------------------------------------------- - -# The QUIET tag can be used to turn on/off the messages that are generated to -# standard output by doxygen. If QUIET is set to YES this implies that the -# messages are off. -# The default value is: NO. - -QUIET = NO - -# The WARNINGS tag can be used to turn on/off the warning messages that are -# generated to standard error (stderr) by doxygen. If WARNINGS is set to YES -# this implies that the warnings are on. -# -# Tip: Turn warnings on while writing the documentation. -# The default value is: YES. - -WARNINGS = YES - -# If the WARN_IF_UNDOCUMENTED tag is set to YES then doxygen will generate -# warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag -# will automatically be disabled. -# The default value is: YES. - -WARN_IF_UNDOCUMENTED = YES - -# If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for -# potential errors in the documentation, such as not documenting some parameters -# in a documented function, or documenting parameters that don't exist or using -# markup commands wrongly. -# The default value is: YES. - -WARN_IF_DOC_ERROR = YES - -# This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that -# are documented, but have no documentation for their parameters or return -# value. If set to NO, doxygen will only warn about wrong or incomplete -# parameter documentation, but not about the absence of documentation. -# The default value is: NO. - -WARN_NO_PARAMDOC = NO - -# If the WARN_AS_ERROR tag is set to YES then doxygen will immediately stop when -# a warning is encountered. -# The default value is: NO. - -WARN_AS_ERROR = NO - -# The WARN_FORMAT tag determines the format of the warning messages that doxygen -# can produce. The string should contain the $file, $line, and $text tags, which -# will be replaced by the file and line number from which the warning originated -# and the warning text. Optionally the format may contain $version, which will -# be replaced by the version of the file (if it could be obtained via -# FILE_VERSION_FILTER) -# The default value is: $file:$line: $text. - -WARN_FORMAT = "$file:$line: $text" - -# The WARN_LOGFILE tag can be used to specify a file to which warning and error -# messages should be written. If left blank the output is written to standard -# error (stderr). - -WARN_LOGFILE = - -#--------------------------------------------------------------------------- -# Configuration options related to the input files -#--------------------------------------------------------------------------- - -# The INPUT tag is used to specify the files and/or directories that contain -# documented source files. You may enter file names like myfile.cpp or -# directories like /usr/src/myproject. Separate the files or directories with -# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING -# Note: If this tag is empty the current directory is searched. - -INPUT = td/generate/auto/td/telegram/td_api.h td/generate/auto/td/telegram/td_api.hpp td/tl/TlObject.h td/telegram/Client.h td/telegram/ClientActor.h td/telegram/Log.h td/telegram/TdCallback.h td/telegram/td_json_client.h td/telegram/td_log.h ./README.md - -# This tag can be used to specify the character encoding of the source files -# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses -# libiconv (or the iconv built into libc) for the transcoding. See the libiconv -# documentation (see: http://www.gnu.org/software/libiconv) for the list of -# possible encodings. -# The default value is: UTF-8. - -INPUT_ENCODING = UTF-8 - -# If the value of the INPUT tag contains directories, you can use the -# FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and -# *.h) to filter out the source-files in the directories. -# -# Note that for custom extensions or not directly supported extensions you also -# need to set EXTENSION_MAPPING for the extension otherwise the files are not -# read by doxygen. -# -# If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cpp, -# *.c++, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h, -# *.hh, *.hxx, *.hpp, *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc, -# *.m, *.markdown, *.md, *.mm, *.dox, *.py, *.pyw, *.f90, *.f95, *.f03, *.f08, -# *.f, *.for, *.tcl, *.vhd, *.vhdl, *.ucf and *.qsf. - -FILE_PATTERNS = *.c \ - *.cc \ - *.cxx \ - *.cpp \ - *.c++ \ - *.java \ - *.ii \ - *.ixx \ - *.ipp \ - *.i++ \ - *.inl \ - *.idl \ - *.ddl \ - *.odl \ - *.h \ - *.hh \ - *.hxx \ - *.hpp \ - *.h++ \ - *.cs \ - *.d \ - *.php \ - *.php4 \ - *.php5 \ - *.phtml \ - *.inc \ - *.m \ - *.markdown \ - *.md \ - *.mm \ - *.dox \ - *.py \ - *.pyw \ - *.f90 \ - *.f95 \ - *.f03 \ - *.f08 \ - *.f \ - *.for \ - *.tcl \ - *.vhd \ - *.vhdl \ - *.ucf \ - *.qsf - -# The RECURSIVE tag can be used to specify whether or not subdirectories should -# be searched for input files as well. -# The default value is: NO. - -RECURSIVE = NO - -# The EXCLUDE tag can be used to specify files and/or directories that should be -# excluded from the INPUT source files. This way you can easily exclude a -# subdirectory from a directory tree whose root is specified with the INPUT tag. -# -# Note that relative paths are relative to the directory from which doxygen is -# run. - -EXCLUDE = - -# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or -# directories that are symbolic links (a Unix file system feature) are excluded -# from the input. -# The default value is: NO. - -EXCLUDE_SYMLINKS = NO - -# If the value of the INPUT tag contains directories, you can use the -# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude -# certain files from those directories. -# -# Note that the wildcards are matched against the file with absolute path, so to -# exclude all test directories for example use the pattern */test/* - -EXCLUDE_PATTERNS = - -# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names -# (namespaces, classes, functions, etc.) that should be excluded from the -# output. The symbol name can be a fully qualified name, a word, or if the -# wildcard * is used, a substring. Examples: ANamespace, AClass, -# AClass::ANamespace, ANamespace::*Test -# -# Note that the wildcards are matched against the file with absolute path, so to -# exclude all test directories use the pattern */test/* - -EXCLUDE_SYMBOLS = - -# The EXAMPLE_PATH tag can be used to specify one or more files or directories -# that contain example code fragments that are included (see the \include -# command). - -EXAMPLE_PATH = - -# If the value of the EXAMPLE_PATH tag contains directories, you can use the -# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and -# *.h) to filter out the source-files in the directories. If left blank all -# files are included. - -EXAMPLE_PATTERNS = * - -# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be -# searched for input files to be used with the \include or \dontinclude commands -# irrespective of the value of the RECURSIVE tag. -# The default value is: NO. - -EXAMPLE_RECURSIVE = NO - -# The IMAGE_PATH tag can be used to specify one or more files or directories -# that contain images that are to be included in the documentation (see the -# \image command). - -IMAGE_PATH = - -# The INPUT_FILTER tag can be used to specify a program that doxygen should -# invoke to filter for each input file. Doxygen will invoke the filter program -# by executing (via popen()) the command: -# -# -# -# where is the value of the INPUT_FILTER tag, and is the -# name of an input file. Doxygen will then use the output that the filter -# program writes to standard output. If FILTER_PATTERNS is specified, this tag -# will be ignored. -# -# Note that the filter must not add or remove lines; it is applied before the -# code is scanned, but not when the output code is generated. If lines are added -# or removed, the anchors will not be placed correctly. -# -# Note that for custom extensions or not directly supported extensions you also -# need to set EXTENSION_MAPPING for the extension otherwise the files are not -# properly processed by doxygen. - -INPUT_FILTER = - -# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern -# basis. Doxygen will compare the file name with each pattern and apply the -# filter if there is a match. The filters are a list of the form: pattern=filter -# (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how -# filters are used. If the FILTER_PATTERNS tag is empty or if none of the -# patterns match the file name, INPUT_FILTER is applied. -# -# Note that for custom extensions or not directly supported extensions you also -# need to set EXTENSION_MAPPING for the extension otherwise the files are not -# properly processed by doxygen. - -FILTER_PATTERNS = - -# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using -# INPUT_FILTER) will also be used to filter the input files that are used for -# producing the source files to browse (i.e. when SOURCE_BROWSER is set to YES). -# The default value is: NO. - -FILTER_SOURCE_FILES = NO - -# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file -# pattern. A pattern will override the setting for FILTER_PATTERN (if any) and -# it is also possible to disable source filtering for a specific pattern using -# *.ext= (so without naming a filter). -# This tag requires that the tag FILTER_SOURCE_FILES is set to YES. - -FILTER_SOURCE_PATTERNS = - -# If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that -# is part of the input, its contents will be placed on the main page -# (index.html). This can be useful if you have a project on for instance GitHub -# and want to reuse the introduction page also for the doxygen output. - -USE_MDFILE_AS_MAINPAGE = ./README.md - -#--------------------------------------------------------------------------- -# Configuration options related to source browsing -#--------------------------------------------------------------------------- - -# If the SOURCE_BROWSER tag is set to YES then a list of source files will be -# generated. Documented entities will be cross-referenced with these sources. -# -# Note: To get rid of all source code in the generated output, make sure that -# also VERBATIM_HEADERS is set to NO. -# The default value is: NO. - -SOURCE_BROWSER = NO - -# Setting the INLINE_SOURCES tag to YES will include the body of functions, -# classes and enums directly into the documentation. -# The default value is: NO. - -INLINE_SOURCES = NO - -# Setting the STRIP_CODE_COMMENTS tag to YES will instruct doxygen to hide any -# special comment blocks from generated source code fragments. Normal C, C++ and -# Fortran comments will always remain visible. -# The default value is: YES. - -STRIP_CODE_COMMENTS = YES - -# If the REFERENCED_BY_RELATION tag is set to YES then for each documented -# function all documented functions referencing it will be listed. -# The default value is: NO. - -REFERENCED_BY_RELATION = NO - -# If the REFERENCES_RELATION tag is set to YES then for each documented function -# all documented entities called/used by that function will be listed. -# The default value is: NO. - -REFERENCES_RELATION = NO - -# If the REFERENCES_LINK_SOURCE tag is set to YES and SOURCE_BROWSER tag is set -# to YES then the hyperlinks from functions in REFERENCES_RELATION and -# REFERENCED_BY_RELATION lists will link to the source code. Otherwise they will -# link to the documentation. -# The default value is: YES. - -REFERENCES_LINK_SOURCE = YES - -# If SOURCE_TOOLTIPS is enabled (the default) then hovering a hyperlink in the -# source code will show a tooltip with additional information such as prototype, -# brief description and links to the definition and documentation. Since this -# will make the HTML file larger and loading of large files a bit slower, you -# can opt to disable this feature. -# The default value is: YES. -# This tag requires that the tag SOURCE_BROWSER is set to YES. - -SOURCE_TOOLTIPS = YES - -# If the USE_HTAGS tag is set to YES then the references to source code will -# point to the HTML generated by the htags(1) tool instead of doxygen built-in -# source browser. The htags tool is part of GNU's global source tagging system -# (see http://www.gnu.org/software/global/global.html). You will need version -# 4.8.6 or higher. -# -# To use it do the following: -# - Install the latest version of global -# - Enable SOURCE_BROWSER and USE_HTAGS in the config file -# - Make sure the INPUT points to the root of the source tree -# - Run doxygen as normal -# -# Doxygen will invoke htags (and that will in turn invoke gtags), so these -# tools must be available from the command line (i.e. in the search path). -# -# The result: instead of the source browser generated by doxygen, the links to -# source code will now point to the output of htags. -# The default value is: NO. -# This tag requires that the tag SOURCE_BROWSER is set to YES. - -USE_HTAGS = NO - -# If the VERBATIM_HEADERS tag is set the YES then doxygen will generate a -# verbatim copy of the header file for each class for which an include is -# specified. Set to NO to disable this. -# See also: Section \class. -# The default value is: YES. - -VERBATIM_HEADERS = YES - -#--------------------------------------------------------------------------- -# Configuration options related to the alphabetical class index -#--------------------------------------------------------------------------- - -# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index of all -# compounds will be generated. Enable this if the project contains a lot of -# classes, structs, unions or interfaces. -# The default value is: YES. - -ALPHABETICAL_INDEX = YES - -# The COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns in -# which the alphabetical index list will be split. -# Minimum value: 1, maximum value: 20, default value: 5. -# This tag requires that the tag ALPHABETICAL_INDEX is set to YES. - -COLS_IN_ALPHA_INDEX = 5 - -# In case all classes in a project start with a common prefix, all classes will -# be put under the same header in the alphabetical index. The IGNORE_PREFIX tag -# can be used to specify a prefix (or a list of prefixes) that should be ignored -# while generating the index headers. -# This tag requires that the tag ALPHABETICAL_INDEX is set to YES. - -IGNORE_PREFIX = - -#--------------------------------------------------------------------------- -# Configuration options related to the HTML output -#--------------------------------------------------------------------------- - -# If the GENERATE_HTML tag is set to YES, doxygen will generate HTML output -# The default value is: YES. - -GENERATE_HTML = YES - -# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. If a -# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of -# it. -# The default directory is: html. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_OUTPUT = html - -# The HTML_FILE_EXTENSION tag can be used to specify the file extension for each -# generated HTML page (for example: .htm, .php, .asp). -# The default value is: .html. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_FILE_EXTENSION = .html - -# The HTML_HEADER tag can be used to specify a user-defined HTML header file for -# each generated HTML page. If the tag is left blank doxygen will generate a -# standard header. -# -# To get valid HTML the header file that includes any scripts and style sheets -# that doxygen needs, which is dependent on the configuration options used (e.g. -# the setting GENERATE_TREEVIEW). It is highly recommended to start with a -# default header using -# doxygen -w html new_header.html new_footer.html new_stylesheet.css -# YourConfigFile -# and then modify the file new_header.html. See also section "Doxygen usage" -# for information on how to generate the default header that doxygen normally -# uses. -# Note: The header is subject to change so you typically have to regenerate the -# default header when upgrading to a newer version of doxygen. For a description -# of the possible markers and block names see the documentation. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_HEADER = - -# The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each -# generated HTML page. If the tag is left blank doxygen will generate a standard -# footer. See HTML_HEADER for more information on how to generate a default -# footer and what special commands can be used inside the footer. See also -# section "Doxygen usage" for information on how to generate the default footer -# that doxygen normally uses. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_FOOTER = - -# The HTML_STYLESHEET tag can be used to specify a user-defined cascading style -# sheet that is used by each HTML page. It can be used to fine-tune the look of -# the HTML output. If left blank doxygen will generate a default style sheet. -# See also section "Doxygen usage" for information on how to generate the style -# sheet that doxygen normally uses. -# Note: It is recommended to use HTML_EXTRA_STYLESHEET instead of this tag, as -# it is more robust and this tag (HTML_STYLESHEET) will in the future become -# obsolete. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_STYLESHEET = - -# The HTML_EXTRA_STYLESHEET tag can be used to specify additional user-defined -# cascading style sheets that are included after the standard style sheets -# created by doxygen. Using this option one can overrule certain style aspects. -# This is preferred over using HTML_STYLESHEET since it does not replace the -# standard style sheet and is therefore more robust against future updates. -# Doxygen will copy the style sheet files to the output directory. -# Note: The order of the extra style sheet files is of importance (e.g. the last -# style sheet in the list overrules the setting of the previous ones in the -# list). For an example see the documentation. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_EXTRA_STYLESHEET = - -# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or -# other source files which should be copied to the HTML output directory. Note -# that these files will be copied to the base HTML output directory. Use the -# $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these -# files. In the HTML_STYLESHEET file, use the file name only. Also note that the -# files will be copied as-is; there are no commands or markers available. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_EXTRA_FILES = - -# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen -# will adjust the colors in the style sheet and background images according to -# this color. Hue is specified as an angle on a colorwheel, see -# http://en.wikipedia.org/wiki/Hue for more information. For instance the value -# 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300 -# purple, and 360 is red again. -# Minimum value: 0, maximum value: 359, default value: 220. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_COLORSTYLE_HUE = 220 - -# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors -# in the HTML output. For a value of 0 the output will use grayscales only. A -# value of 255 will produce the most vivid colors. -# Minimum value: 0, maximum value: 255, default value: 100. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_COLORSTYLE_SAT = 100 - -# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to the -# luminance component of the colors in the HTML output. Values below 100 -# gradually make the output lighter, whereas values above 100 make the output -# darker. The value divided by 100 is the actual gamma applied, so 80 represents -# a gamma of 0.8, The value 220 represents a gamma of 2.2, and 100 does not -# change the gamma. -# Minimum value: 40, maximum value: 240, default value: 80. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_COLORSTYLE_GAMMA = 80 - -# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML -# page will contain the date and time when the page was generated. Setting this -# to YES can help to show when doxygen was last run and thus if the -# documentation is up to date. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_TIMESTAMP = NO - -# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML -# documentation will contain sections that can be hidden and shown after the -# page has loaded. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_DYNAMIC_SECTIONS = NO - -# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries -# shown in the various tree structured indices initially; the user can expand -# and collapse entries dynamically later on. Doxygen will expand the tree to -# such a level that at most the specified number of entries are visible (unless -# a fully collapsed tree already exceeds this amount). So setting the number of -# entries 1 will produce a full collapsed tree by default. 0 is a special value -# representing an infinite number of entries and will result in a full expanded -# tree by default. -# Minimum value: 0, maximum value: 9999, default value: 100. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_INDEX_NUM_ENTRIES = 100 - -# If the GENERATE_DOCSET tag is set to YES, additional index files will be -# generated that can be used as input for Apple's Xcode 3 integrated development -# environment (see: http://developer.apple.com/tools/xcode/), introduced with -# OSX 10.5 (Leopard). To create a documentation set, doxygen will generate a -# Makefile in the HTML output directory. Running make will produce the docset in -# that directory and running make install will install the docset in -# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at -# startup. See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html -# for more information. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTML is set to YES. - -GENERATE_DOCSET = NO - -# This tag determines the name of the docset feed. A documentation feed provides -# an umbrella under which multiple documentation sets from a single provider -# (such as a company or product suite) can be grouped. -# The default value is: Doxygen generated docs. -# This tag requires that the tag GENERATE_DOCSET is set to YES. - -DOCSET_FEEDNAME = "Doxygen generated docs" - -# This tag specifies a string that should uniquely identify the documentation -# set bundle. This should be a reverse domain-name style string, e.g. -# com.mycompany.MyDocSet. Doxygen will append .docset to the name. -# The default value is: org.doxygen.Project. -# This tag requires that the tag GENERATE_DOCSET is set to YES. - -DOCSET_BUNDLE_ID = org.doxygen.Project - -# The DOCSET_PUBLISHER_ID tag specifies a string that should uniquely identify -# the documentation publisher. This should be a reverse domain-name style -# string, e.g. com.mycompany.MyDocSet.documentation. -# The default value is: org.doxygen.Publisher. -# This tag requires that the tag GENERATE_DOCSET is set to YES. - -DOCSET_PUBLISHER_ID = org.doxygen.Publisher - -# The DOCSET_PUBLISHER_NAME tag identifies the documentation publisher. -# The default value is: Publisher. -# This tag requires that the tag GENERATE_DOCSET is set to YES. - -DOCSET_PUBLISHER_NAME = Publisher - -# If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three -# additional HTML index files: index.hhp, index.hhc, and index.hhk. The -# index.hhp is a project file that can be read by Microsoft's HTML Help Workshop -# (see: http://www.microsoft.com/en-us/download/details.aspx?id=21138) on -# Windows. -# -# The HTML Help Workshop contains a compiler that can convert all HTML output -# generated by doxygen into a single compiled HTML file (.chm). Compiled HTML -# files are now used as the Windows 98 help format, and will replace the old -# Windows help format (.hlp) on all Windows platforms in the future. Compressed -# HTML files also contain an index, a table of contents, and you can search for -# words in the documentation. The HTML workshop also contains a viewer for -# compressed HTML files. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTML is set to YES. - -GENERATE_HTMLHELP = NO - -# The CHM_FILE tag can be used to specify the file name of the resulting .chm -# file. You can add a path in front of the file if the result should not be -# written to the html output directory. -# This tag requires that the tag GENERATE_HTMLHELP is set to YES. - -CHM_FILE = - -# The HHC_LOCATION tag can be used to specify the location (absolute path -# including file name) of the HTML help compiler (hhc.exe). If non-empty, -# doxygen will try to run the HTML help compiler on the generated index.hhp. -# The file has to be specified with full path. -# This tag requires that the tag GENERATE_HTMLHELP is set to YES. - -HHC_LOCATION = - -# The GENERATE_CHI flag controls if a separate .chi index file is generated -# (YES) or that it should be included in the master .chm file (NO). -# The default value is: NO. -# This tag requires that the tag GENERATE_HTMLHELP is set to YES. - -GENERATE_CHI = NO - -# The CHM_INDEX_ENCODING is used to encode HtmlHelp index (hhk), content (hhc) -# and project file content. -# This tag requires that the tag GENERATE_HTMLHELP is set to YES. - -CHM_INDEX_ENCODING = - -# The BINARY_TOC flag controls whether a binary table of contents is generated -# (YES) or a normal table of contents (NO) in the .chm file. Furthermore it -# enables the Previous and Next buttons. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTMLHELP is set to YES. - -BINARY_TOC = NO - -# The TOC_EXPAND flag can be set to YES to add extra items for group members to -# the table of contents of the HTML help documentation and to the tree view. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTMLHELP is set to YES. - -TOC_EXPAND = NO - -# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and -# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that -# can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help -# (.qch) of the generated HTML documentation. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTML is set to YES. - -GENERATE_QHP = NO - -# If the QHG_LOCATION tag is specified, the QCH_FILE tag can be used to specify -# the file name of the resulting .qch file. The path specified is relative to -# the HTML output folder. -# This tag requires that the tag GENERATE_QHP is set to YES. - -QCH_FILE = - -# The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help -# Project output. For more information please see Qt Help Project / Namespace -# (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#namespace). -# The default value is: org.doxygen.Project. -# This tag requires that the tag GENERATE_QHP is set to YES. - -QHP_NAMESPACE = org.doxygen.Project - -# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt -# Help Project output. For more information please see Qt Help Project / Virtual -# Folders (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#virtual- -# folders). -# The default value is: doc. -# This tag requires that the tag GENERATE_QHP is set to YES. - -QHP_VIRTUAL_FOLDER = doc - -# If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom -# filter to add. For more information please see Qt Help Project / Custom -# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom- -# filters). -# This tag requires that the tag GENERATE_QHP is set to YES. - -QHP_CUST_FILTER_NAME = - -# The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the -# custom filter to add. For more information please see Qt Help Project / Custom -# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom- -# filters). -# This tag requires that the tag GENERATE_QHP is set to YES. - -QHP_CUST_FILTER_ATTRS = - -# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this -# project's filter section matches. Qt Help Project / Filter Attributes (see: -# http://qt-project.org/doc/qt-4.8/qthelpproject.html#filter-attributes). -# This tag requires that the tag GENERATE_QHP is set to YES. - -QHP_SECT_FILTER_ATTRS = - -# The QHG_LOCATION tag can be used to specify the location of Qt's -# qhelpgenerator. If non-empty doxygen will try to run qhelpgenerator on the -# generated .qhp file. -# This tag requires that the tag GENERATE_QHP is set to YES. - -QHG_LOCATION = - -# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be -# generated, together with the HTML files, they form an Eclipse help plugin. To -# install this plugin and make it available under the help contents menu in -# Eclipse, the contents of the directory containing the HTML and XML files needs -# to be copied into the plugins directory of eclipse. The name of the directory -# within the plugins directory should be the same as the ECLIPSE_DOC_ID value. -# After copying Eclipse needs to be restarted before the help appears. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTML is set to YES. - -GENERATE_ECLIPSEHELP = NO - -# A unique identifier for the Eclipse help plugin. When installing the plugin -# the directory name containing the HTML and XML files should also have this -# name. Each documentation set should have its own identifier. -# The default value is: org.doxygen.Project. -# This tag requires that the tag GENERATE_ECLIPSEHELP is set to YES. - -ECLIPSE_DOC_ID = org.doxygen.Project - -# If you want full control over the layout of the generated HTML pages it might -# be necessary to disable the index and replace it with your own. The -# DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) at top -# of each HTML page. A value of NO enables the index and the value YES disables -# it. Since the tabs in the index contain the same information as the navigation -# tree, you can set this option to YES if you also set GENERATE_TREEVIEW to YES. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTML is set to YES. - -DISABLE_INDEX = NO - -# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index -# structure should be generated to display hierarchical information. If the tag -# value is set to YES, a side panel will be generated containing a tree-like -# index structure (just like the one that is generated for HTML Help). For this -# to work a browser that supports JavaScript, DHTML, CSS and frames is required -# (i.e. any modern browser). Windows users are probably better off using the -# HTML help feature. Via custom style sheets (see HTML_EXTRA_STYLESHEET) one can -# further fine-tune the look of the index. As an example, the default style -# sheet generated by doxygen has an example that shows how to put an image at -# the root of the tree instead of the PROJECT_NAME. Since the tree basically has -# the same information as the tab index, you could consider setting -# DISABLE_INDEX to YES when enabling this option. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTML is set to YES. - -GENERATE_TREEVIEW = NO - -# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that -# doxygen will group on one line in the generated HTML documentation. -# -# Note that a value of 0 will completely suppress the enum values from appearing -# in the overview section. -# Minimum value: 0, maximum value: 20, default value: 4. -# This tag requires that the tag GENERATE_HTML is set to YES. - -ENUM_VALUES_PER_LINE = 4 - -# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be used -# to set the initial width (in pixels) of the frame in which the tree is shown. -# Minimum value: 0, maximum value: 1500, default value: 250. -# This tag requires that the tag GENERATE_HTML is set to YES. - -TREEVIEW_WIDTH = 250 - -# If the EXT_LINKS_IN_WINDOW option is set to YES, doxygen will open links to -# external symbols imported via tag files in a separate window. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTML is set to YES. - -EXT_LINKS_IN_WINDOW = NO - -# Use this tag to change the font size of LaTeX formulas included as images in -# the HTML documentation. When you change the font size after a successful -# doxygen run you need to manually remove any form_*.png images from the HTML -# output directory to force them to be regenerated. -# Minimum value: 8, maximum value: 50, default value: 10. -# This tag requires that the tag GENERATE_HTML is set to YES. - -FORMULA_FONTSIZE = 10 - -# Use the FORMULA_TRANPARENT tag to determine whether or not the images -# generated for formulas are transparent PNGs. Transparent PNGs are not -# supported properly for IE 6.0, but are supported on all modern browsers. -# -# Note that when changing this option you need to delete any form_*.png files in -# the HTML output directory before the changes have effect. -# The default value is: YES. -# This tag requires that the tag GENERATE_HTML is set to YES. - -FORMULA_TRANSPARENT = YES - -# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see -# http://www.mathjax.org) which uses client side Javascript for the rendering -# instead of using pre-rendered bitmaps. Use this if you do not have LaTeX -# installed or if you want to formulas look prettier in the HTML output. When -# enabled you may also need to install MathJax separately and configure the path -# to it using the MATHJAX_RELPATH option. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTML is set to YES. - -USE_MATHJAX = NO - -# When MathJax is enabled you can set the default output format to be used for -# the MathJax output. See the MathJax site (see: -# http://docs.mathjax.org/en/latest/output.html) for more details. -# Possible values are: HTML-CSS (which is slower, but has the best -# compatibility), NativeMML (i.e. MathML) and SVG. -# The default value is: HTML-CSS. -# This tag requires that the tag USE_MATHJAX is set to YES. - -MATHJAX_FORMAT = HTML-CSS - -# When MathJax is enabled you need to specify the location relative to the HTML -# output directory using the MATHJAX_RELPATH option. The destination directory -# should contain the MathJax.js script. For instance, if the mathjax directory -# is located at the same level as the HTML output directory, then -# MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax -# Content Delivery Network so you can quickly see the result without installing -# MathJax. However, it is strongly recommended to install a local copy of -# MathJax from http://www.mathjax.org before deployment. -# The default value is: http://cdn.mathjax.org/mathjax/latest. -# This tag requires that the tag USE_MATHJAX is set to YES. - -MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest - -# The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax -# extension names that should be enabled during MathJax rendering. For example -# MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols -# This tag requires that the tag USE_MATHJAX is set to YES. - -MATHJAX_EXTENSIONS = - -# The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces -# of code that will be used on startup of the MathJax code. See the MathJax site -# (see: http://docs.mathjax.org/en/latest/output.html) for more details. For an -# example see the documentation. -# This tag requires that the tag USE_MATHJAX is set to YES. - -MATHJAX_CODEFILE = - -# When the SEARCHENGINE tag is enabled doxygen will generate a search box for -# the HTML output. The underlying search engine uses javascript and DHTML and -# should work on any modern browser. Note that when using HTML help -# (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET) -# there is already a search function so this one should typically be disabled. -# For large projects the javascript based search engine can be slow, then -# enabling SERVER_BASED_SEARCH may provide a better solution. It is possible to -# search using the keyboard; to jump to the search box use + S -# (what the is depends on the OS and browser, but it is typically -# , /