Postbox -> TelegramEngine waves 46-93 (squashed)

Squash of 63 commits spanning waves 46-93 (plus interspersed docs commits)
of the gradual Postbox->TelegramEngine consumer-side migration.

Scope: 139 files changed, 2123 insertions(+), 452 deletions(-).

## Themes by wave-block

**Waves 46-58 — Peer field migrations + facade additions**
Foundational EnginePeer convenience init additions (PeerReference, RenderedPeer,
SelectivePrivacyPeer). Multiple `peer: Peer` field migrations across PeerInfo,
ChatList, and SettingsUI components.

**Waves 59-73 — peer field cascade + EnginePeer wrap drops**
Series of single- to two-file peer-field migrations; consumer-side wrap
removal (`EnginePeer(peer)` -> direct EnginePeer use); `as? TelegramUser`
cast conversion to `case let .user(...)` enum match. Wave 64: RenderedPeer
convenience init. Wave 68: SelectivePrivacyPeer convenience init.

**Waves 74-83 — controller-Node bridge cleanup + small migrations**
Wave-71 shadow-pattern cleanup at controller->Node bridges. Migrations of
ChatRecentActionsController.peer (74), PeerInfoMember (75), MentionChatInputPanelItem
(76), PassportUI SecureIdAuthController (77), AccountWithInfo + ShareController
(78), peerInputActivitiesPromise (79), InactiveChannel (80), BlockedPeers (81),
openHashtag resolveSignal (82), NotificationExceptionsList (83).

**Waves 84-90 — TelegramEngine.Resources facade migrations**
Per-method Shape-A/B sweeps converting `<ctx>.account.postbox.mediaBox.X(...)`
to `<ctx>.engine.resources.X(...)`. Wave 90 was a single-commit big sweep:
40 fetchedMediaResource sites in 25 files migrated to engine.resources.fetch
facade in one atomic pass with first-pass-clean build.

Methods covered: storeResourceData, completedResourcePath, cancelInteractiveResourceFetch,
resourceRangesStatus, resourceStatus, fetch (fetchedMediaResource).

**Waves 91-92 — additional type migrations**
Wave 91: ItemListWebsiteItem.peer + RecentSessionsController enum-case payload
+ openWebSession callback Peer? -> EnginePeer?.
Wave 92: ChatListController StateHolder.EntryContext status type
MediaResourceStatus -> EngineMediaResource.FetchStatus.

**Wave 93 — speculative `import Postbox` drop sweep**
Drop import from 7 wave-touched files where it became unused; restore in 5
files where bare PeerId/Message/MediaId/StoryId references escaped the
pre-flight regex. Includes one MediaId(...) -> EngineMedia.Id(...) swap in
InAppPurchaseManager to unlock its import drop.

## Build state

Final state at squash: clean Telegram/Telegram build at debug_sim_arm64.

## Persistent-state notes

- Pre-existing WIP unchanged across the squashed range:
  - build-system/bazel-rules/sourcekit-bazel-bsp submodule marker
  - Untracked: build-system/tulsi/, submodules/TgVoip/, third-party/libx264/

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
isaac 2026-04-25 20:48:15 +04:00
parent 6b7a23867c
commit d1aa0db537
139 changed files with 2124 additions and 453 deletions

View file

@ -205,7 +205,7 @@ private enum StatsEntry: ItemListNodeEntry {
case instantPageInteractionsGraph(PresentationTheme, PresentationStrings, PresentationDateTimeFormat, StatsGraph, ChartType)
case postsTitle(PresentationTheme, String)
case post(Int32, PresentationTheme, PresentationStrings, PresentationDateTimeFormat, Peer, StatsPostItem, ChannelStatsPostInteractions)
case post(Int32, PresentationTheme, PresentationStrings, PresentationDateTimeFormat, EnginePeer, StatsPostItem, ChannelStatsPostInteractions)
case boostLevel(PresentationTheme, Int32, Int32, CGFloat)
@ -636,7 +636,7 @@ private enum StatsEntry: ItemListNodeEntry {
return false
}
case let .post(lhsIndex, lhsTheme, lhsStrings, lhsDateTimeFormat, lhsPeer, lhsPost, lhsInteractions):
if case let .post(rhsIndex, rhsTheme, rhsStrings, rhsDateTimeFormat, rhsPeer, rhsPost, rhsInteractions) = rhs, lhsIndex == rhsIndex, lhsTheme === rhsTheme, lhsStrings === rhsStrings, lhsDateTimeFormat == rhsDateTimeFormat, arePeersEqual(lhsPeer, rhsPeer), lhsPost == rhsPost, lhsInteractions == rhsInteractions {
if case let .post(rhsIndex, rhsTheme, rhsStrings, rhsDateTimeFormat, rhsPeer, rhsPost, rhsInteractions) = rhs, lhsIndex == rhsIndex, lhsTheme === rhsTheme, lhsStrings === rhsStrings, lhsDateTimeFormat == rhsDateTimeFormat, lhsPeer == rhsPeer, lhsPost == rhsPost, lhsInteractions == rhsInteractions {
return true
} else {
return false
@ -960,7 +960,7 @@ private enum StatsEntry: ItemListNodeEntry {
}, sectionId: self.section, style: .blocks)
case let .post(_, _, _, _, peer, post, interactions):
return StatsMessageItem(context: arguments.context, presentationData: presentationData, peer: peer, item: post, views: interactions.views, reactions: interactions.reactions, forwards: interactions.forwards, sectionId: self.section, style: .blocks, action: {
arguments.openPostStats(EnginePeer(peer), post)
arguments.openPostStats(peer, post)
}, openStory: { sourceView in
if case let .story(_, story) = post {
arguments.openStory(story, sourceView)
@ -1426,11 +1426,11 @@ private func statsEntries(
switch post {
case let .message(message):
if let interactions = interactions[.message(id: message.id)] {
entries.append(.post(index, presentationData.theme, presentationData.strings, presentationData.dateTimeFormat, peer._asPeer(), post, interactions))
entries.append(.post(index, presentationData.theme, presentationData.strings, presentationData.dateTimeFormat, peer, post, interactions))
}
case let .story(_, story):
if let interactions = interactions[.story(peerId: peer.id, id: story.id)] {
entries.append(.post(index, presentationData.theme, presentationData.strings, presentationData.dateTimeFormat, peer._asPeer(), post, interactions))
entries.append(.post(index, presentationData.theme, presentationData.strings, presentationData.dateTimeFormat, peer, post, interactions))
}
}
index += 1

View file

@ -198,10 +198,10 @@ private enum StatsEntry: ItemListNodeEntry {
var reactions: Int32 = 0
var isStory = false
let peer: Peer
let peer: EnginePeer
switch item {
case let .message(message):
peer = message.peers[message.id.peerId]!
peer = EnginePeer(message.peers[message.id.peerId]!)
for attribute in message.attributes {
if let viewsAttribute = attribute as? ViewCountMessageAttribute {
views = Int32(viewsAttribute.count)
@ -214,7 +214,7 @@ private enum StatsEntry: ItemListNodeEntry {
}
}
case let .story(peerValue, story):
peer = peerValue._asPeer()
peer = peerValue
views = Int32(story.views?.seenCount ?? 0)
forwards = Int32(story.views?.forwardCount ?? 0)
reactions = Int32(story.views?.reactedCount ?? 0)

View file

@ -19,7 +19,7 @@ public class StatsMessageItem: ListViewItem, ItemListItem {
let context: AccountContext
let presentationData: ItemListPresentationData
let systemStyle: ItemListSystemStyle
let peer: Peer
let peer: EnginePeer
let item: StatsPostItem
let views: Int32
let reactions: Int32
@ -31,7 +31,7 @@ public class StatsMessageItem: ListViewItem, ItemListItem {
let openStory: (UIView) -> Void
let contextAction: ((ASDisplayNode, ContextGesture?) -> Void)?
init(context: AccountContext, presentationData: ItemListPresentationData, systemStyle: ItemListSystemStyle = .glass, peer: Peer, item: StatsPostItem, views: Int32, reactions: Int32, forwards: Int32, isPeer: Bool = false, sectionId: ItemListSectionId, style: ItemListStyle, action: (() -> Void)?, openStory: @escaping (UIView) -> Void, contextAction: ((ASDisplayNode, ContextGesture?) -> Void)?) {
init(context: AccountContext, presentationData: ItemListPresentationData, systemStyle: ItemListSystemStyle = .glass, peer: EnginePeer, item: StatsPostItem, views: Int32, reactions: Int32, forwards: Int32, isPeer: Bool = false, sectionId: ItemListSectionId, style: ItemListStyle, action: (() -> Void)?, openStory: @escaping (UIView) -> Void, contextAction: ((ASDisplayNode, ContextGesture?) -> Void)?) {
self.context = context
self.presentationData = presentationData
self.systemStyle = systemStyle
@ -351,7 +351,7 @@ final class StatsMessageItemNode: ListViewItemNode, ItemListItemNode {
}
if item.isPeer {
text = EnginePeer(item.peer).displayTitle(strings: item.presentationData.strings, displayOrder: item.presentationData.nameDisplayOrder)
text = item.peer.displayTitle(strings: item.presentationData.strings, displayOrder: item.presentationData.nameDisplayOrder)
} else {
text = foldLineBreaks(text)
}
@ -476,7 +476,7 @@ final class StatsMessageItemNode: ListViewItemNode, ItemListItemNode {
strongSelf.offsetContainerNode.addSubnode(avatarNode)
strongSelf.avatarNode = avatarNode
}
avatarNode.setPeer(context: item.context, theme: item.presentationData.theme, peer: EnginePeer(item.peer))
avatarNode.setPeer(context: item.context, theme: item.presentationData.theme, peer: item.peer)
if case .story = item.item {
contentImageInset += 3.0