Skip to content

Commit 449769c

Browse files
Fix launch white screen when chat list ready never fires
switchToFilter / updateAvailableFilters could drop completion when All Chats was hidden or the target folder was missing, so ApplicationContext never attached the root controller (white host view). Always complete the switch, pick a real fallback folder, set mainReady even if the switch stalls, and time out isReady after 2.5s. Co-authored-by: D3C0Y <decoder-dev@users.noreply.github.com>
1 parent a64aa24 commit 449769c

5 files changed

Lines changed: 46 additions & 18 deletions

File tree

‎CHANGELOG.md‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,13 @@
44
Тег релиза = `v{app}-{tagSuffix}` (например `v12.9.2-3845`); CI кладёт секцию тега в GitHub Release notes.
55
Теги `*-pre` публикуются как GitHub **pre-release** (не Latest).
66

7+
## [v12.9.2-3854-pre] — 2026-08-18
8+
9+
Pre-release: фикс белого экрана при запуске. Sideload smoke, не Latest.
10+
11+
### Fixed
12+
- Запуск больше не зависает на белом экране, если чат-лист не успевает стать ready (скрытие «Все чаты» / смена папки / `switchToFilter` без completion). Через 2.5 с UI всё равно показывается.
13+
714
## [v12.9.2-3853-pre] — 2026-08-18
815

916
Pre-release: Extra по разделам + фичи из Swiftgram. Sideload smoke, не Latest.

‎submodules/ChatListUI/Sources/ChatListController.swift‎

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4088,14 +4088,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
40884088
resolvedItems = []
40894089
}
40904090

4091-
let firstItem = countAndFilterItems.1.first?.0 ?? .allChats
4092-
let firstItemEntryId: ChatListFilterTabEntryId
4093-
switch firstItem {
4094-
case .allChats:
4095-
firstItemEntryId = .all
4096-
case let .filter(id, _, _, _):
4097-
firstItemEntryId = .filter(id)
4098-
}
4091+
let firstItemEntryId = resolvedItems.first?.id ?? .all
40994092

41004093
var selectedEntryId = !strongSelf.initializedFilters ? firstItemEntryId : strongSelf.chatListDisplayNode.mainContainerNode.currentItemFilter
41014094
if !strongSelf.initializedFilters, ForkExtrasHotFlags.rememberLastFolder {
@@ -4163,16 +4156,24 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
41634156
if isPremium == nil && items.isEmpty {
41644157
strongSelf.mainReady.set(strongSelf.chatListDisplayNode.mainContainerNode.currentItemNode.ready)
41654158
} else if !strongSelf.initializedFilters {
4166-
if selectedEntryId != strongSelf.chatListDisplayNode.mainContainerNode.currentItemFilter {
4167-
strongSelf.chatListDisplayNode.mainContainerNode.switchToFilter(id: selectedEntryId, animated: false, completion: { [weak self] in
4168-
if let strongSelf = self {
4169-
strongSelf.mainReady.set(strongSelf.chatListDisplayNode.mainContainerNode.currentItemNode.ready)
4170-
}
4159+
strongSelf.initializedFilters = true
4160+
let setMainReady: () -> Void = { [weak strongSelf] in
4161+
guard let strongSelf else {
4162+
return
4163+
}
4164+
strongSelf.mainReady.set(strongSelf.chatListDisplayNode.mainContainerNode.currentItemNode.ready)
4165+
}
4166+
let currentFilter = strongSelf.chatListDisplayNode.mainContainerNode.currentItemFilter
4167+
if selectedEntryId != currentFilter, availableFilters.contains(where: { $0.id == selectedEntryId }) {
4168+
strongSelf.chatListDisplayNode.mainContainerNode.switchToFilter(id: selectedEntryId, animated: false, completion: {
4169+
setMainReady()
4170+
})
4171+
Queue.mainQueue().after(1.0, {
4172+
setMainReady()
41714173
})
41724174
} else {
4173-
strongSelf.mainReady.set(strongSelf.chatListDisplayNode.mainContainerNode.currentItemNode.ready)
4175+
setMainReady()
41744176
}
4175-
strongSelf.initializedFilters = true
41764177
}
41774178

41784179
let animated = strongSelf.didSetupTabs

‎submodules/ChatListUI/Sources/ChatListControllerNode.swift‎

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -850,9 +850,14 @@ public final class ChatListContainerNode: ASDisplayNode, ASGestureRecognizerDele
850850
}
851851
}
852852
if !availableFilters.contains(where: { $0.id == self.selectedId }) {
853-
self.switchToFilter(id: .all, completion: {
853+
let fallbackId = availableFilters.first?.id ?? .all
854+
if fallbackId != self.selectedId, availableFilters.contains(where: { $0.id == fallbackId }) {
855+
self.switchToFilter(id: fallbackId, animated: false, completion: {
856+
apply()
857+
})
858+
} else {
854859
apply()
855-
})
860+
}
856861
} else {
857862
apply()
858863
}
@@ -874,6 +879,9 @@ public final class ChatListContainerNode: ASDisplayNode, ASGestureRecognizerDele
874879
if id != self.selectedId, let index = self.availableFilters.firstIndex(where: { $0.id == id }) {
875880
if let itemNode = self.itemNodes[id] {
876881
guard let (layout, navigationBarHeight, visualNavigationHeight, originalNavigationHeight, cleanNavigationBarHeight, insets, isReorderingFilters, isEditing, inlineNavigationLocation, inlineNavigationTransitionFraction, storiesInset) = self.validLayout else {
882+
self.selectedId = id
883+
self.applyItemNodeAsCurrent(id: id, itemNode: itemNode)
884+
completion?()
877885
return
878886
}
879887

@@ -1006,7 +1014,11 @@ public final class ChatListContainerNode: ASDisplayNode, ASGestureRecognizerDele
10061014
}
10071015
return
10081016
}
1017+
} else {
1018+
completion?()
10091019
}
1020+
} else {
1021+
completion?()
10101022
}
10111023
}
10121024

‎submodules/TelegramUI/Sources/ApplicationContext.swift‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -257,7 +257,8 @@ final class AuthorizedApplicationContext {
257257
|> map { $0 && $1 }
258258
|> filter { $0 }
259259
|> take(1)
260-
self.isReady.set(combinedReady)
260+
self.isReady.set(combinedReady
261+
|> timeout(2.5, queue: Queue.mainQueue(), alternate: .single(true)))
261262
} else {
262263
self.isReady.set(.single(true))
263264
}

‎submodules/TelegramUI/Sources/TelegramRootController.swift‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -252,10 +252,17 @@ public final class TelegramRootController: NavigationController, TelegramRootCon
252252
self.rootTabController = tabBarController
253253
self.pushViewController(tabBarController, animated: false)
254254
self.hideTabBarDisposable?.dispose()
255+
var appliedHideTabBar = false
255256
self.hideTabBarDisposable = (forkExtrasSettings(accountManager: self.context.sharedContext.accountManager)
256257
|> map { $0.hideTabBar }
257258
|> distinctUntilChanged
258259
|> deliverOnMainQueue).startStrict(next: { [weak self] hidden in
260+
if !appliedHideTabBar {
261+
appliedHideTabBar = true
262+
if !hidden {
263+
return
264+
}
265+
}
259266
(self?.rootTabController as? TabBarControllerImpl)?.updateIsTabBarHidden(hidden, transition: .animated(duration: 0.25, curve: .easeInOut))
260267
})
261268
}

0 commit comments

Comments
 (0)