Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios

This commit is contained in:
Ilya Laktyushin 2023-03-13 13:21:55 +04:00
commit b4f359a8e7
3 changed files with 219 additions and 31 deletions

View File

@ -552,7 +552,22 @@ public final class AuthorizationSequenceController: NavigationController, MFMail
if nextType == nil { if nextType == nil {
if MFMailComposeViewController.canSendMail(), let controller = controller { if MFMailComposeViewController.canSendMail(), let controller = controller {
let formattedNumber = formatPhoneNumber(number) let formattedNumber = formatPhoneNumber(number)
strongSelf.presentEmailComposeController(address: "sms@telegram.org", subject: strongSelf.presentationData.strings.Login_EmailCodeSubject(formattedNumber).string, body: strongSelf.presentationData.strings.Login_EmailCodeBody(formattedNumber).string, from: controller)
var emailBody = ""
emailBody.append(strongSelf.presentationData.strings.Login_EmailCodeBody(formattedNumber).string)
emailBody.append("\n\n")
let appVersion = (Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String) ?? "unknown"
let systemVersion = UIDevice.current.systemVersion
let locale = Locale.current.identifier
let carrier = CTCarrier()
let mnc = carrier.mobileNetworkCode ?? "none"
emailBody.append("Telegram: \(appVersion)\n")
emailBody.append("OS: \(systemVersion)\n")
emailBody.append("Locale: \(locale)\n")
emailBody.append("MNC: \(mnc)")
strongSelf.presentEmailComposeController(address: "sms@telegram.org", subject: strongSelf.presentationData.strings.Login_EmailCodeSubject(formattedNumber).string, body: emailBody, from: controller)
} else { } else {
controller?.present(standardTextAlertController(theme: AlertControllerTheme(presentationData: strongSelf.presentationData), title: nil, text: strongSelf.presentationData.strings.Login_EmailNotConfiguredError, actions: [TextAlertAction(type: .defaultAction, title: strongSelf.presentationData.strings.Common_OK, action: {})]), in: .window(.root)) controller?.present(standardTextAlertController(theme: AlertControllerTheme(presentationData: strongSelf.presentationData), title: nil, text: strongSelf.presentationData.strings.Login_EmailNotConfiguredError, actions: [TextAlertAction(type: .defaultAction, title: strongSelf.presentationData.strings.Common_OK, action: {})]), in: .window(.root))
} }

View File

@ -268,7 +268,18 @@ enum HistoryViewAnchor {
case lowerBound case lowerBound
case index(MessageIndex) case index(MessageIndex)
func isLower(than otherIndex: MessageIndex) -> Bool { func isLower(than otherIndex: MessageIndex, peerId: PeerId, namespace: MessageId.Namespace) -> Bool {
switch self {
case .upperBound:
return false
case .lowerBound:
return true
case let .index(index):
return index.withPeerId(peerId).withNamespace(namespace) < otherIndex.withPeerId(peerId).withNamespace(namespace)
}
}
func internal_isLower(than otherIndex: MessageIndex) -> Bool {
switch self { switch self {
case .upperBound: case .upperBound:
return false return false
@ -279,18 +290,40 @@ enum HistoryViewAnchor {
} }
} }
func isEqualOrLower(than otherIndex: MessageIndex) -> Bool { func isEqualOrLower(than otherIndex: MessageIndex, peerId: PeerId, namespace: MessageId.Namespace) -> Bool {
switch self { switch self {
case .upperBound: case .upperBound:
return false return false
case .lowerBound: case .lowerBound:
return true return true
case let .index(index): case let .index(index):
return index <= otherIndex return index.withPeerId(peerId).withNamespace(namespace) <= otherIndex.withPeerId(peerId).withNamespace(namespace)
} }
} }
func isGreater(than otherIndex: MessageIndex) -> Bool { func isGreater(than otherIndex: MessageIndex, peerId: PeerId, namespace: MessageId.Namespace) -> Bool {
switch self {
case .upperBound:
return true
case .lowerBound:
return false
case let .index(index):
return index.withPeerId(peerId).withNamespace(namespace) > otherIndex.withPeerId(peerId).withNamespace(namespace)
}
}
func isEqualOrGreater(than otherIndex: MessageIndex, peerId: PeerId, namespace: MessageId.Namespace) -> Bool {
switch self {
case .upperBound:
return true
case .lowerBound:
return false
case let .index(index):
return index.withPeerId(peerId).withNamespace(namespace) >= otherIndex.withPeerId(peerId).withNamespace(namespace)
}
}
func internal_isGreater(than otherIndex: MessageIndex) -> Bool {
switch self { switch self {
case .upperBound: case .upperBound:
return true return true
@ -300,28 +333,17 @@ enum HistoryViewAnchor {
return index > otherIndex return index > otherIndex
} }
} }
func isEqualOrGreater(than otherIndex: MessageIndex) -> Bool {
switch self {
case .upperBound:
return true
case .lowerBound:
return false
case let .index(index):
return index >= otherIndex
}
}
} }
private func binaryInsertionIndex(_ inputArr: [MutableMessageHistoryEntry], searchItem: HistoryViewAnchor) -> Int { private func binaryInsertionIndex(_ inputArr: [MutableMessageHistoryEntry], searchItem: HistoryViewAnchor, peerId: PeerId, namespace: MessageId.Namespace) -> Int {
var lo = 0 var lo = 0
var hi = inputArr.count - 1 var hi = inputArr.count - 1
while lo <= hi { while lo <= hi {
let mid = (lo + hi) / 2 let mid = (lo + hi) / 2
let value = inputArr[mid] let value = inputArr[mid]
if searchItem.isGreater(than: value.index) { if searchItem.isGreater(than: value.index, peerId: peerId, namespace: namespace) {
lo = mid + 1 lo = mid + 1
} else if searchItem.isLower(than: value.index) { } else if searchItem.isLower(than: value.index, peerId: peerId, namespace: namespace) {
hi = mid - 1 hi = mid - 1
} else { } else {
return mid return mid
@ -330,14 +352,46 @@ private func binaryInsertionIndex(_ inputArr: [MutableMessageHistoryEntry], sear
return lo return lo
} }
func binaryIndexOrLower(_ inputArr: [MessageHistoryEntry], _ searchItem: HistoryViewAnchor, peerId: PeerId, namespace: MessageId.Namespace) -> Int {
var lo = 0
var hi = inputArr.count - 1
while lo <= hi {
let mid = (lo + hi) / 2
if searchItem.isGreater(than: inputArr[mid].index, peerId: peerId, namespace: namespace) {
lo = mid + 1
} else if searchItem.isLower(than: inputArr[mid].index, peerId: peerId, namespace: namespace) {
hi = mid - 1
} else {
return mid
}
}
return hi
}
func binaryIndexOrLower(_ inputArr: [MessageHistoryEntry], _ searchItem: HistoryViewAnchor) -> Int { func binaryIndexOrLower(_ inputArr: [MessageHistoryEntry], _ searchItem: HistoryViewAnchor) -> Int {
var lo = 0 var lo = 0
var hi = inputArr.count - 1 var hi = inputArr.count - 1
while lo <= hi { while lo <= hi {
let mid = (lo + hi) / 2 let mid = (lo + hi) / 2
if searchItem.isGreater(than: inputArr[mid].index) { if searchItem.internal_isGreater(than: inputArr[mid].index) {
lo = mid + 1 lo = mid + 1
} else if searchItem.isLower(than: inputArr[mid].index) { } else if searchItem.internal_isLower(than: inputArr[mid].index) {
hi = mid - 1
} else {
return mid
}
}
return hi
}
func binaryIndexOrLower(_ inputArr: [MessageHistoryMessageEntry], _ searchItem: HistoryViewAnchor, peerId: PeerId, namespace: MessageId.Namespace) -> Int {
var lo = 0
var hi = inputArr.count - 1
while lo <= hi {
let mid = (lo + hi) / 2
if searchItem.isGreater(than: inputArr[mid].message.index, peerId: peerId, namespace: namespace) {
lo = mid + 1
} else if searchItem.isLower(than: inputArr[mid].message.index, peerId: peerId, namespace: namespace) {
hi = mid - 1 hi = mid - 1
} else { } else {
return mid return mid
@ -351,9 +405,9 @@ func binaryIndexOrLower(_ inputArr: [MessageHistoryMessageEntry], _ searchItem:
var hi = inputArr.count - 1 var hi = inputArr.count - 1
while lo <= hi { while lo <= hi {
let mid = (lo + hi) / 2 let mid = (lo + hi) / 2
if searchItem.isGreater(than: inputArr[mid].message.index) { if searchItem.internal_isGreater(than: inputArr[mid].message.index) {
lo = mid + 1 lo = mid + 1
} else if searchItem.isLower(than: inputArr[mid].message.index) { } else if searchItem.internal_isLower(than: inputArr[mid].message.index) {
hi = mid - 1 hi = mid - 1
} else { } else {
return mid return mid
@ -362,14 +416,14 @@ func binaryIndexOrLower(_ inputArr: [MessageHistoryMessageEntry], _ searchItem:
return hi return hi
} }
private func binaryIndexOrLower(_ inputArr: [MutableMessageHistoryEntry], _ searchItem: HistoryViewAnchor) -> Int { private func binaryIndexOrLower(_ inputArr: [MutableMessageHistoryEntry], _ searchItem: HistoryViewAnchor, peerId: PeerId, namespace: MessageId.Namespace) -> Int {
var lo = 0 var lo = 0
var hi = inputArr.count - 1 var hi = inputArr.count - 1
while lo <= hi { while lo <= hi {
let mid = (lo + hi) / 2 let mid = (lo + hi) / 2
if searchItem.isGreater(than: inputArr[mid].index) { if searchItem.isGreater(than: inputArr[mid].index, peerId: peerId, namespace: namespace) {
lo = mid + 1 lo = mid + 1
} else if searchItem.isLower(than: inputArr[mid].index) { } else if searchItem.isLower(than: inputArr[mid].index, peerId: peerId, namespace: namespace) {
hi = mid - 1 hi = mid - 1
} else { } else {
return mid return mid
@ -778,12 +832,19 @@ struct HistoryViewHoles {
} }
struct OrderedHistoryViewEntries { struct OrderedHistoryViewEntries {
private let spacePeerId: PeerId
private let spaceNamespace: MessageId.Namespace
private let anchor: HistoryViewAnchor
private(set) var lowerOrAtAnchor: [MutableMessageHistoryEntry] private(set) var lowerOrAtAnchor: [MutableMessageHistoryEntry]
private(set) var higherThanAnchor: [MutableMessageHistoryEntry] private(set) var higherThanAnchor: [MutableMessageHistoryEntry]
private(set) var reverseAssociatedIndices: [MessageId: [MessageIndex]] = [:] private(set) var reverseAssociatedIndices: [MessageId: [MessageIndex]] = [:]
fileprivate init(lowerOrAtAnchor: [MutableMessageHistoryEntry], higherThanAnchor: [MutableMessageHistoryEntry]) { fileprivate init(spacePeerId: PeerId, spaceNamespace: MessageId.Namespace, anchor: HistoryViewAnchor, lowerOrAtAnchor: [MutableMessageHistoryEntry], higherThanAnchor: [MutableMessageHistoryEntry]) {
self.spacePeerId = spacePeerId
self.spaceNamespace = spaceNamespace
self.anchor = anchor
self.lowerOrAtAnchor = lowerOrAtAnchor self.lowerOrAtAnchor = lowerOrAtAnchor
self.higherThanAnchor = higherThanAnchor self.higherThanAnchor = higherThanAnchor
@ -805,6 +866,20 @@ struct OrderedHistoryViewEntries {
} }
} }
} }
#if DEBUG
for entry in self.lowerOrAtAnchor {
assert(self.anchor.isEqualOrGreater(than: entry.index, peerId: self.spacePeerId, namespace: self.spaceNamespace))
}
for entry in self.higherThanAnchor {
assert(!self.anchor.isEqualOrGreater(than: entry.index, peerId: self.spacePeerId, namespace: self.spaceNamespace))
}
if !self.lowerOrAtAnchor.isEmpty && !self.higherThanAnchor.isEmpty {
let lowerMax = self.lowerOrAtAnchor.map(\.index.id.id).max()!
let upperMin = self.higherThanAnchor.map(\.index.id.id).min()!
assert(upperMin > lowerMax)
}
#endif
} }
mutating func setLowerOrAtAnchorAtArrayIndex(_ index: Int, to value: MutableMessageHistoryEntry) { mutating func setLowerOrAtAnchorAtArrayIndex(_ index: Int, to value: MutableMessageHistoryEntry) {
@ -830,6 +905,20 @@ struct OrderedHistoryViewEntries {
} }
} }
} }
#if DEBUG
for entry in self.lowerOrAtAnchor {
assert(self.anchor.isEqualOrGreater(than: entry.index, peerId: self.spacePeerId, namespace: self.spaceNamespace))
}
for entry in self.higherThanAnchor {
assert(!self.anchor.isEqualOrGreater(than: entry.index, peerId: self.spacePeerId, namespace: self.spaceNamespace))
}
if !self.lowerOrAtAnchor.isEmpty && !self.higherThanAnchor.isEmpty {
let lowerMax = self.lowerOrAtAnchor.map(\.index.id.id).max()!
let upperMin = self.higherThanAnchor.map(\.index.id.id).min()!
assert(upperMin > lowerMax)
}
#endif
} }
mutating func setHigherThanAnchorAtArrayIndex(_ index: Int, to value: MutableMessageHistoryEntry) { mutating func setHigherThanAnchorAtArrayIndex(_ index: Int, to value: MutableMessageHistoryEntry) {
@ -855,6 +944,20 @@ struct OrderedHistoryViewEntries {
} }
} }
} }
#if DEBUG
for entry in self.lowerOrAtAnchor {
assert(self.anchor.isEqualOrGreater(than: entry.index, peerId: self.spacePeerId, namespace: self.spaceNamespace))
}
for entry in self.higherThanAnchor {
assert(!self.anchor.isEqualOrGreater(than: entry.index, peerId: self.spacePeerId, namespace: self.spaceNamespace))
}
if !self.lowerOrAtAnchor.isEmpty && !self.higherThanAnchor.isEmpty {
let lowerMax = self.lowerOrAtAnchor.map(\.index.id.id).max()!
let upperMin = self.higherThanAnchor.map(\.index.id.id).min()!
assert(upperMin > lowerMax)
}
#endif
} }
mutating func insertLowerOrAtAnchorAtArrayIndex(_ index: Int, value: MutableMessageHistoryEntry) { mutating func insertLowerOrAtAnchorAtArrayIndex(_ index: Int, value: MutableMessageHistoryEntry) {
@ -867,6 +970,20 @@ struct OrderedHistoryViewEntries {
self.reverseAssociatedIndices[id]!.append(value.index) self.reverseAssociatedIndices[id]!.append(value.index)
} }
} }
#if DEBUG
for entry in self.lowerOrAtAnchor {
assert(self.anchor.isEqualOrGreater(than: entry.index, peerId: self.spacePeerId, namespace: self.spaceNamespace))
}
for entry in self.higherThanAnchor {
assert(!self.anchor.isEqualOrGreater(than: entry.index, peerId: self.spacePeerId, namespace: self.spaceNamespace))
}
if !self.lowerOrAtAnchor.isEmpty && !self.higherThanAnchor.isEmpty {
let lowerMax = self.lowerOrAtAnchor.map(\.index.id.id).max()!
let upperMin = self.higherThanAnchor.map(\.index.id.id).min()!
assert(upperMin > lowerMax)
}
#endif
} }
mutating func insertHigherThanAnchorAtArrayIndex(_ index: Int, value: MutableMessageHistoryEntry) { mutating func insertHigherThanAnchorAtArrayIndex(_ index: Int, value: MutableMessageHistoryEntry) {
@ -879,6 +996,20 @@ struct OrderedHistoryViewEntries {
self.reverseAssociatedIndices[id]!.append(value.index) self.reverseAssociatedIndices[id]!.append(value.index)
} }
} }
#if DEBUG
for entry in self.lowerOrAtAnchor {
assert(self.anchor.isEqualOrGreater(than: entry.index, peerId: self.spacePeerId, namespace: self.spaceNamespace))
}
for entry in self.higherThanAnchor {
assert(!self.anchor.isEqualOrGreater(than: entry.index, peerId: self.spacePeerId, namespace: self.spaceNamespace))
}
if !self.lowerOrAtAnchor.isEmpty && !self.higherThanAnchor.isEmpty {
let lowerMax = self.lowerOrAtAnchor.map(\.index.id.id).max()!
let upperMin = self.higherThanAnchor.map(\.index.id.id).min()!
assert(upperMin > lowerMax)
}
#endif
} }
mutating func removeLowerOrAtAnchorAtArrayIndex(_ index: Int) { mutating func removeLowerOrAtAnchorAtArrayIndex(_ index: Int) {
@ -891,6 +1022,20 @@ struct OrderedHistoryViewEntries {
} }
self.lowerOrAtAnchor.remove(at: index) self.lowerOrAtAnchor.remove(at: index)
#if DEBUG
for entry in self.lowerOrAtAnchor {
assert(self.anchor.isEqualOrGreater(than: entry.index, peerId: self.spacePeerId, namespace: self.spaceNamespace))
}
for entry in self.higherThanAnchor {
assert(!self.anchor.isEqualOrGreater(than: entry.index, peerId: self.spacePeerId, namespace: self.spaceNamespace))
}
if !self.lowerOrAtAnchor.isEmpty && !self.higherThanAnchor.isEmpty {
let lowerMax = self.lowerOrAtAnchor.map(\.index.id.id).max()!
let upperMin = self.higherThanAnchor.map(\.index.id.id).min()!
assert(upperMin > lowerMax)
}
#endif
} }
mutating func removeHigherThanAnchorAtArrayIndex(_ index: Int) { mutating func removeHigherThanAnchorAtArrayIndex(_ index: Int) {
@ -903,6 +1048,20 @@ struct OrderedHistoryViewEntries {
} }
self.higherThanAnchor.remove(at: index) self.higherThanAnchor.remove(at: index)
#if DEBUG
for entry in self.lowerOrAtAnchor {
assert(self.anchor.isEqualOrGreater(than: entry.index, peerId: self.spacePeerId, namespace: self.spaceNamespace))
}
for entry in self.higherThanAnchor {
assert(!self.anchor.isEqualOrGreater(than: entry.index, peerId: self.spacePeerId, namespace: self.spaceNamespace))
}
if !self.lowerOrAtAnchor.isEmpty && !self.higherThanAnchor.isEmpty {
let lowerMax = self.lowerOrAtAnchor.map(\.index.id.id).max()!
let upperMin = self.higherThanAnchor.map(\.index.id.id).min()!
assert(upperMin > lowerMax)
}
#endif
} }
mutating func fixMonotony() { mutating func fixMonotony() {
@ -945,6 +1104,20 @@ struct OrderedHistoryViewEntries {
self.lowerOrAtAnchor.sort(by: { $0.index.id.id < $1.index.id.id }) self.lowerOrAtAnchor.sort(by: { $0.index.id.id < $1.index.id.id })
self.higherThanAnchor.sort(by: { $0.index.id.id < $1.index.id.id }) self.higherThanAnchor.sort(by: { $0.index.id.id < $1.index.id.id })
} }
#if DEBUG
for entry in self.lowerOrAtAnchor {
assert(self.anchor.isEqualOrGreater(than: entry.index, peerId: self.spacePeerId, namespace: self.spaceNamespace))
}
for entry in self.higherThanAnchor {
assert(!self.anchor.isEqualOrGreater(than: entry.index, peerId: self.spacePeerId, namespace: self.spaceNamespace))
}
if !self.lowerOrAtAnchor.isEmpty && !self.higherThanAnchor.isEmpty {
let lowerMax = self.lowerOrAtAnchor.map(\.index.id.id).max()!
let upperMin = self.higherThanAnchor.map(\.index.id.id).min()!
assert(upperMin > lowerMax)
}
#endif
} }
func find(index: MessageIndex) -> MutableMessageHistoryEntry? { func find(index: MessageIndex) -> MutableMessageHistoryEntry? {
@ -1133,7 +1306,7 @@ final class HistoryViewLoadedState {
assert(lowerOrAtAnchorMessages.count <= self.halfLimit) assert(lowerOrAtAnchorMessages.count <= self.halfLimit)
assert(higherThanAnchorMessages.count <= self.halfLimit) assert(higherThanAnchorMessages.count <= self.halfLimit)
var entries = OrderedHistoryViewEntries(lowerOrAtAnchor: lowerOrAtAnchorMessages, higherThanAnchor: higherThanAnchorMessages) var entries = OrderedHistoryViewEntries(spacePeerId: space.peerId, spaceNamespace: space.namespace, anchor: self.anchor, lowerOrAtAnchor: lowerOrAtAnchorMessages, higherThanAnchor: higherThanAnchorMessages)
if case .automatic = self.input, self.statistics.contains(.combinedLocation), let first = entries.first { if case .automatic = self.input, self.statistics.contains(.combinedLocation), let first = entries.first {
let messageIndex = first.index let messageIndex = first.index
@ -1294,7 +1467,7 @@ final class HistoryViewLoadedState {
let space = PeerIdAndNamespace(peerId: entry.index.id.peerId, namespace: entry.index.id.namespace) let space = PeerIdAndNamespace(peerId: entry.index.id.peerId, namespace: entry.index.id.namespace)
if self.orderedEntriesBySpace[space] == nil { if self.orderedEntriesBySpace[space] == nil {
self.orderedEntriesBySpace[space] = OrderedHistoryViewEntries(lowerOrAtAnchor: [], higherThanAnchor: []) self.orderedEntriesBySpace[space] = OrderedHistoryViewEntries(spacePeerId: space.peerId, spaceNamespace: space.namespace, anchor: self.anchor, lowerOrAtAnchor: [], higherThanAnchor: [])
} }
var updated = false var updated = false
@ -1313,7 +1486,7 @@ final class HistoryViewLoadedState {
} }
} }
if self.anchor.isEqualOrGreater(than: entry.index) { if self.anchor.isEqualOrGreater(than: entry.index, peerId: space.peerId, namespace: space.namespace) {
let insertionIndex = binaryInsertionIndex(self.orderedEntriesBySpace[space]!.lowerOrAtAnchor, extract: { $0.index }, searchItem: entry.index) let insertionIndex = binaryInsertionIndex(self.orderedEntriesBySpace[space]!.lowerOrAtAnchor, extract: { $0.index }, searchItem: entry.index)
if insertionIndex < self.orderedEntriesBySpace[space]!.lowerOrAtAnchor.count { if insertionIndex < self.orderedEntriesBySpace[space]!.lowerOrAtAnchor.count {

View File

@ -343,7 +343,7 @@ class ChatMessageActionBubbleContentNode: ChatMessageBubbleContentNode {
if item.controllerInteraction.presentationContext.backgroundNode?.hasExtraBubbleBackground() == true { if item.controllerInteraction.presentationContext.backgroundNode?.hasExtraBubbleBackground() == true {
strongSelf.backgroundColorNode.isHidden = true strongSelf.backgroundColorNode.isHidden = true
} else { } else {
strongSelf.backgroundColorNode.isHidden = false strongSelf.backgroundColorNode.isHidden = true
} }
} else { } else {
if strongSelf.backgroundMaskNode.supernode == nil { if strongSelf.backgroundMaskNode.supernode == nil {