Skip to content

Commit 909303a

Browse files
committed
Merge CryZFix dec/zalupa-mess: WEB proxy carriers, foreground lifecycle, unread diagnostics
Co-authored-by: D3C0Y <decoder-dev@users.noreply.github.com>
2 parents dd2ac18 + d1a02c6 commit 909303a

9 files changed

Lines changed: 1382 additions & 123 deletions

File tree

‎submodules/TelegramCore/Sources/Settings/ProxySettings.swift‎

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -75,14 +75,14 @@ func applySharedProxySettingsToNetwork(settings: ProxySettings, network: Network
7575
if let resolvedProxySettings = resolvedProxySettings {
7676
updated = resolvedProxySettings
7777
} else if let current = current {
78-
// Sidecar failed while switching proxies — keep the previous endpoint
79-
// rather than falling back to a direct connection.
78+
// Sidecar not ready yet (bootstrap / resume) — keep the previous endpoint.
79+
// Never fall through to 127.0.0.1:1: that port produces Connection-refused
80+
// storms and has correlated with SIGABRT under MtProto reconnect pressure.
8081
updated = current
81-
} else if let activeServer = activeServer, case let .web(secret) = activeServer.connection {
82-
// First enable with a dead sidecar: route to an unreachable loopback port
83-
// with the MTProxy code path so traffic never goes out unproxied.
84-
updated = MTSocksProxySettings(ip: "127.0.0.1", port: 1, username: nil, password: nil, secret: secret)
8582
} else {
83+
// First enable while the sidecar is still booting: leave socks settings
84+
// unchanged (nil). MtProto stays offline until the sidecar event re-applies
85+
// a real loopback port — preferred over advertising a dead :1 sink.
8686
updated = nil
8787
}
8888
} else {

‎submodules/TelegramUI/Sources/AppDelegate.swift‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ import NavigationBarImpl
4646
import ContextUI
4747
import ContextControllerImpl
4848
import ProxyServerPreviewScreen
49+
import WebProxyTransport
4950

5051
#if canImport(AppCenter)
5152
import AppCenter
@@ -2065,6 +2066,8 @@ private func extractAccountManagerState(records: AccountRecordsView<TelegramAcco
20652066
UIApplication.shared.endBackgroundTask(taskId)
20662067
}
20672068
})
2069+
2070+
WebProxyManager.shared.applicationDidEnterBackground()
20682071
}
20692072

20702073
/// The app had no answer to a memory warning: a search of the tree turns up exactly one
@@ -2111,6 +2114,8 @@ private func extractAccountManagerState(records: AccountRecordsView<TelegramAcco
21112114
self.runForegroundTasks()
21122115

21132116
SharedDisplayLinkDriver.shared.updateForegroundState(self.isActiveValue)
2117+
2118+
WebProxyManager.shared.applicationDidBecomeActive()
21142119
}
21152120

21162121
func runForegroundTasks() {
@@ -2155,6 +2160,8 @@ private func extractAccountManagerState(records: AccountRecordsView<TelegramAcco
21552160
}
21562161

21572162
//cancelWindowPanGestures(view: self.mainWindow.hostView.containerView)
2163+
2164+
WebProxyManager.shared.applicationDidBecomeActive()
21582165
}
21592166

21602167
func applicationWillTerminate(_ application: UIApplication) {

‎submodules/TelegramUI/Sources/ChatHistoryListNode.swift‎

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -490,6 +490,10 @@ public final class ChatHistoryListNodeImpl: ASDisplayNode, ChatHistoryNode, Chat
490490

491491
var enableUnreadAlignment: Bool = true
492492
var areContentAnimationsEnabled: Bool = false
493+
// A layout pass can arrive immediately after the initial unread scroll, e.g. when the input
494+
// panel changes its bottom inset. Do not let that pass replace the first-unread anchor with
495+
// the unread divider before the user has seen the initial position.
496+
private var suppressUnreadAlignmentUntil: Double = 0.0
493497

494498
private var historyView: ChatHistoryView?
495499
public var originalHistoryView: MessageHistoryView? {
@@ -3926,6 +3930,14 @@ public final class ChatHistoryListNodeImpl: ASDisplayNode, ChatHistoryNode, Chat
39263930
}
39273931
self.hasActiveTransition = true
39283932
let transition = self.enqueuedHistoryViewTransitions.removeFirst()
3933+
if case .Initial = transition.reason, transition.scrollToItem != nil, transition.historyView.filteredEntries.contains(where: { entry in
3934+
if case .UnreadEntry = entry {
3935+
return true
3936+
}
3937+
return false
3938+
}) {
3939+
self.suppressUnreadAlignmentUntil = CACurrentMediaTime() + 1.0
3940+
}
39293941

39303942
var expiredMessageStableIds = Set<UInt32>()
39313943
if let previousHistoryView = self.historyView, transition.options.contains(.AnimateInsertion) {
@@ -4078,6 +4090,16 @@ public final class ChatHistoryListNodeImpl: ASDisplayNode, ChatHistoryNode, Chat
40784090

40794091
let completion: (Bool, ListViewDisplayedItemRange) -> Void = { [weak self] wasTransformed, visibleRange in
40804092
if let strongSelf = self {
4093+
if let scrollToItem = transition.scrollToItem {
4094+
var visibleMessages: [String] = []
4095+
strongSelf.forEachVisibleMessageItemNode { itemNode in
4096+
if let item = itemNode.item {
4097+
visibleMessages.append("\(Int(itemNode.frame.minY)):\(item.message.index)")
4098+
}
4099+
}
4100+
let visibleMessageSummary = visibleMessages.joined(separator: ",")
4101+
Logger.shared.log("ChatUnreadPosition", "list-applied peer=\(String(describing: strongSelf.chatLocation.peerId)) targetListIndex=\(scrollToItem.index) targetPosition=\(scrollToItem.position) reason=\(transition.reason) visibleRange=\(visibleRange) visibleMessages=\(visibleMessageSummary)")
4102+
}
40814103
strongSelf.currentAppliedDeleteAnimationCorrelationIds.removeAll()
40824104

40834105
var newIncomingReactions: [MessageId: (value: MessageReaction.Reaction, isLarge: Bool)] = [:]
@@ -4685,12 +4707,16 @@ public final class ChatHistoryListNodeImpl: ASDisplayNode, ChatHistoryNode, Chat
46854707
var postScrollToItem: ListViewScrollToItem?
46864708
if scrollToTop, case .known = self.visibleContentOffset() {
46874709
scrollToItem = ListViewScrollToItem(index: 0, position: .top(0.0), animated: true, curve: .Spring(duration: updateSizeAndInsets.duration), directionHint: .Up)
4710+
} else if self.enableUnreadAlignment, CACurrentMediaTime() < self.suppressUnreadAlignmentUntil, updateSizeAndInsets.insets.bottom != self.insets.bottom {
4711+
Logger.shared.log("ChatUnreadPosition", "layout-realign-unread-suppressed peer=\(String(describing: self.chatLocation.peerId)) oldBottomInset=\(self.insets.bottom) newBottomInset=\(updateSizeAndInsets.insets.bottom)")
4712+
self.suppressUnreadAlignmentUntil = 0.0
46884713
} else if self.enableUnreadAlignment {
46894714
if updateSizeAndInsets.insets.bottom != self.insets.bottom {
46904715
self.forEachVisibleItemNode { itemNode in
46914716
if let itemNode = itemNode as? ChatUnreadItemNode, let index = itemNode.index {
46924717
if abs(itemNode.frame.maxY - (self.listView.visibleSize.height - self.insets.bottom + 6.0)) < 1.0 {
46934718
postScrollToItem = ListViewScrollToItem(index: index, position: .bottom(0.0), animated: updateSizeAndInsets.duration != 0.0, curve: updateSizeAndInsets.curve, directionHint: .Up)
4719+
Logger.shared.log("ChatUnreadPosition", "layout-realign-unread peer=\(String(describing: self.chatLocation.peerId)) listIndex=\(index) oldBottomInset=\(self.insets.bottom) newBottomInset=\(updateSizeAndInsets.insets.bottom) unreadMaxY=\(itemNode.frame.maxY) visibleHeight=\(self.listView.visibleSize.height)")
46944720
}
46954721
}
46964722
}

‎submodules/TelegramUI/Sources/ChatHistoryViewForLocation.swift‎

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,17 @@ func chatHistoryViewForLocation(
136136
|> map { viewData, isPossibleIntroLoaded -> ChatHistoryViewUpdate in
137137
let (view, updateType, initialData) = viewData
138138
var effectiveIsAddedToChatList = view.isAddedToChatList
139+
140+
// Temporary diagnostics for chats that open away from the unread boundary.
141+
// Keep the actual indexes (rather than message text) so entries can be
142+
// correlated with the Postbox read-state trace without exposing content.
143+
let peerDebugId = chatLocation.peerId.map { String(describing: $0) } ?? "none"
144+
let entriesRange = "\(String(describing: view.entries.first?.message.index))...\(String(describing: view.entries.last?.message.index))"
145+
let firstIncomingUnreadIndex: MessageIndex? = view.maxReadIndex.flatMap { maxReadIndex in
146+
return view.entries.first(where: { entry in
147+
return !entry.message.flags.intersection(.IsIncomingMask).isEmpty && entry.message.index > maxReadIndex
148+
})?.message.index
149+
}
139150

140151
let (cachedData, cachedDataMessages, readStateData, peers) = extractAdditionalData(view: view, chatLocation: chatLocation)
141152
if case let .peer(peerId) = chatLocation, let channel = peers[peerId] as? TelegramChannel, let linkedCommunityId = channel.linkedCommunityId, let community = peers[linkedCommunityId] as? TelegramCommunity {
@@ -147,16 +158,20 @@ func chatHistoryViewForLocation(
147158
let combinedInitialData = ChatHistoryCombinedInitialData(initialData: initialData, buttonKeyboardMessage: view.topTaggedMessages.first, cachedData: cachedData, cachedDataMessages: cachedDataMessages, readStateData: readStateData)
148159

149160
if !isPossibleIntroLoaded {
161+
Logger.shared.log("ChatUnreadPosition", "loading peer=\(peerDebugId) reason=businessIntro update=\(updateType) maxRead=\(String(describing: view.maxReadIndex)) firstIncomingUnread=\(String(describing: firstIncomingUnreadIndex)) anchor=\(view.anchorIndex) entries=\(entriesRange) holes=\(view.holeEarlier)/\(view.holeLater)")
150162
return .Loading(initialData: combinedInitialData, type: .Generic(type: updateType))
151163
}
152164

153165
if preloaded {
166+
Logger.shared.log("ChatUnreadPosition", "update-after-initial peer=\(peerDebugId) update=\(updateType) maxRead=\(String(describing: view.maxReadIndex)) firstIncomingUnread=\(String(describing: firstIncomingUnreadIndex)) anchor=\(view.anchorIndex) entries=\(entriesRange) holes=\(view.holeEarlier)/\(view.holeLater)")
154167
return .HistoryView(view: view, type: .Generic(type: updateType), scrollPosition: nil, flashIndicators: false, originalScrollPosition: nil, initialData: combinedInitialData, id: location.id)
155168
} else {
156169
if view.isLoading || (view.entries.isEmpty && (view.holeEarlier || view.holeLater)) {
170+
Logger.shared.log("ChatUnreadPosition", "loading peer=\(peerDebugId) reason=history update=\(updateType) maxRead=\(String(describing: view.maxReadIndex)) firstIncomingUnread=\(String(describing: firstIncomingUnreadIndex)) anchor=\(view.anchorIndex) entries=\(entriesRange) holes=\(view.holeEarlier)/\(view.holeLater)")
157171
return .Loading(initialData: combinedInitialData, type: .Generic(type: updateType))
158172
}
159173
var scrollPosition: ChatHistoryViewScrollPosition?
174+
var scrollDecision = "default"
160175

161176
let canScrollToRead: Bool
162177
if case let .replyThread(message) = chatLocation, !message.isForumPost, !message.isMonoforumPost {
@@ -176,12 +191,14 @@ func chatHistoryViewForLocation(
176191
if tag == nil, case let .replyThread(message) = chatLocation, message.isForumPost, view.maxReadIndex == nil {
177192
if case let .message(index) = view.anchorIndex {
178193
scrollPosition = .index(subject: MessageHistoryScrollToSubject(index: .message(index), quote: nil), position: .bottom(0.0), directionHint: .Up, animated: false, highlight: false, displayLink: false, setupReply: false)
194+
scrollDecision = "forum-anchor"
179195
}
180196
}
181197

182198
if let maxReadIndex = view.maxReadIndex, tag == nil, canScrollToRead {
183199
let aroundIndex = maxReadIndex
184200
scrollPosition = .unread(index: maxReadIndex)
201+
scrollDecision = "unread"
185202

186203
if let _ = chatLocation.peerId {
187204
var targetIndex = 0
@@ -196,11 +213,13 @@ func chatHistoryViewForLocation(
196213
let minIndex = targetIndex - 40
197214
if minIndex <= 0 && view.holeEarlier {
198215
fadeIn = true
216+
Logger.shared.log("ChatUnreadPosition", "loading peer=\(peerDebugId) reason=missing-earlier-near-unread maxRead=\(maxReadIndex) firstIncomingUnread=\(String(describing: firstIncomingUnreadIndex)) anchor=\(view.anchorIndex) entries=\(entriesRange) holes=\(view.holeEarlier)/\(view.holeLater)")
199217
return .Loading(initialData: combinedInitialData, type: .Generic(type: updateType))
200218
}
201219
if maxIndex >= view.entries.count {
202220
if view.holeLater {
203221
fadeIn = true
222+
Logger.shared.log("ChatUnreadPosition", "loading peer=\(peerDebugId) reason=missing-later-near-unread maxRead=\(maxReadIndex) firstIncomingUnread=\(String(describing: firstIncomingUnreadIndex)) anchor=\(view.anchorIndex) entries=\(entriesRange) holes=\(view.holeEarlier)/\(view.holeLater)")
204223
return .Loading(initialData: combinedInitialData, type: .Generic(type: updateType))
205224
}
206225
if view.holeEarlier {
@@ -213,13 +232,15 @@ func chatHistoryViewForLocation(
213232
if case let .peer(peerId) = chatLocation, let combinedReadStates = view.fixedReadStates, case let .peer(readStates) = combinedReadStates, let readState = readStates[peerId], readState.count == incomingCount {
214233
} else {
215234
fadeIn = true
235+
Logger.shared.log("ChatUnreadPosition", "loading peer=\(peerDebugId) reason=missing-earlier-unread-count maxRead=\(maxReadIndex) firstIncomingUnread=\(String(describing: firstIncomingUnreadIndex)) anchor=\(view.anchorIndex) entries=\(entriesRange) holes=\(view.holeEarlier)/\(view.holeLater)")
216236
return .Loading(initialData: combinedInitialData, type: .Generic(type: updateType))
217237
}
218238
}
219239
}
220240
}
221241
} else if effectiveIsAddedToChatList, tag == nil, let historyScrollState = (initialData?.storedInterfaceState).flatMap(_internal_decodeStoredChatInterfaceState).flatMap(ChatInterfaceState.parse)?.historyScrollState {
222242
scrollPosition = .positionRestoration(index: historyScrollState.messageIndex, relativeOffset: CGFloat(historyScrollState.relativeOffset))
243+
scrollDecision = "saved-position"
223244
} else {
224245
if let _ = chatLocation.peerId, !effectiveIsAddedToChatList {
225246
if view.holeEarlier && view.entries.count <= 2 {
@@ -233,6 +254,7 @@ func chatHistoryViewForLocation(
233254
}
234255
}
235256

257+
Logger.shared.log("ChatUnreadPosition", "initial peer=\(peerDebugId) decision=\(scrollDecision) canScrollToRead=\(canScrollToRead) update=\(updateType) maxRead=\(String(describing: view.maxReadIndex)) firstIncomingUnread=\(String(describing: firstIncomingUnreadIndex)) anchor=\(view.anchorIndex) entries=\(entriesRange) holes=\(view.holeEarlier)/\(view.holeLater)")
236258
preloaded = true
237259
return .HistoryView(view: view, type: .Initial(fadeIn: fadeIn), scrollPosition: scrollPosition, flashIndicators: false, originalScrollPosition: nil, initialData: ChatHistoryCombinedInitialData(initialData: initialData, buttonKeyboardMessage: view.topTaggedMessages.first, cachedData: cachedData, cachedDataMessages: cachedDataMessages, readStateData: readStateData), id: location.id)
238260
}

0 commit comments

Comments
 (0)