Commit graph

30148 commits

Author SHA1 Message Date
isaac
e9d958809a Fix 2026-04-26 02:46:44 +04:00
isaac
2ac8a490b0 Postbox -> TelegramEngine waves 94-102 (squashed)
Adds AccountManagerResources facade in TelegramCore mirroring
TelegramEngine.Resources, drains the entire accountManager-side
mediaBox refactor across consumer modules, and validates the
Shape-C/D handle-migration pattern (account: Account ->
engine: TelegramEngine) on three classes.

Wave 94 (AccountManagerResources facade + 8 sites): new
AccountManagerResources class in TelegramCore with
storeResourceData, completedResourcePath (resource + id overloads),
status (with approximateSynchronousValue), moveResourceData,
fetch. Migrate EditThemeController (5 storeResourceData + 2
completedResourcePath) and WebBrowserSettingsController (1
storeResourceData).

Wave 95 (10 sites): WallpaperUtils.swift sweep, 5 distinct
storeResourceData patterns, replace_all on the two repeated ones.

Wave 96 (7 sites): theme controller triple — TPC (1 store + 2
moveResourceData), TPCN (1 status + 1 fetch + closure type
MediaResourceStatus -> EngineMediaResource.FetchStatus + rename
account local to engine), TAC (1 completedResourcePath + 1 store).

Wave 97 (9 sites): WallpaperGalleryController.swift, 4
completedResourcePath + 5 storeResourceData via replace_all.

Wave 98 (2 files): WallpaperGallery status-type cascade
Promise<MediaResourceStatus> -> Promise<EngineMediaResource.FetchStatus>
across WallpaperGalleryItem.swift + WallpaperGalleryController.swift.
Drops cosmetic `_asStatus()` unwrap.

Wave 99 (2 facade extensions + 7 sites): adds
AccountManagerResources.data() and approximateSynchronousValue
to engine.resources.status(). Migrates OpenResolvedUrl (data +
storeResourceData with .complete -> .isComplete cascade),
SettingsThemeWallpaperNode (paired engine + accountManager
status), WallpaperUploadManager, OpenChatMessage,
LiveChatReactionStreamView.

Wave 100 (Shape-C/D, free function): legacyWebSearchItem
account: Account -> engine: TelegramEngine. 4 files.

Wave 101 (Shape-C/D, small class): VerticalListContextResults
ChatInputPanelItem stored field migration. 2 files. Drops
`|> map(EngineMediaResource.FetchStatus.init)` redundancy.

Wave 102 (Shape-C/D, medium class with weak-context retention):
SharedMediaPlayer account: Account -> engine: TelegramEngine.
Engine field is intentionally a strong handle since the class
stores context as `weak var`. 2 files.

After this squash the accountManager-side mediaBox refactor is
essentially complete; only Postbox-protocol-blocked
cachedResourceRepresentation triple remains as the foundational
deferred item.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 02:46:44 +04:00
isaac
7ce00a00fa Merge commit '6df5f10973' 2026-04-25 20:50:35 +04:00
isaac
d1aa0db537 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>
2026-04-25 20:48:15 +04:00
Ilya Laktyushin
6df5f10973 Fix build 2026-04-25 18:35:36 +02:00
Ilya Laktyushin
5f7bcb7746 Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2026-04-25 17:41:48 +02:00
Ilya Laktyushin
9c15b8c27d Various improvements 2026-04-25 17:32:26 +02:00
isaac
6b7a23867c Postbox -> TelegramEngine wave 45
PeerInfoHeader* update(peer:) bundle: Peer? -> EnginePeer?.
Four update methods across PeerInfoHeaderNode, PeerInfoHeaderEditingContentNode,
PeerInfoEditingAvatarNode, PeerInfoEditingAvatarOverlayNode.
Drops wave-43 ADD-WRAP bridges (net ~-11 wraps). Stored
PeerInfoHeaderNode.peer: Peer? field stays raw (out of scope).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-25 00:02:22 +04:00
isaac
de21dedbe3 Fix offsets 2026-04-24 23:42:53 +04:00
isaac
4e192fda4d Fix reply panel animation 2026-04-24 23:24:20 +04:00
isaac
bd6523bb34 docs: log wave 44 outcome
Wave 44 (RenderedChannelParticipant.peers [PeerId: Peer] →
[EnginePeer.Id: EnginePeer]) landed as ca69fa8cbb. Closes the wave-41
RCP foundational-type ratchet. 14 files, 38 inserts / 38 deletes,
2-iteration convergence. Iteration-1 surfaced new.peers enum-destructure
binding (case let .participantSubscriptionExtended(prev, new)) at
ChatRecentActionsHistoryTransition:2272 — plan's participant.peers
pre-flight grep missed it. Widened lesson documented.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 23:21:05 +04:00
isaac
c0acc09cb1 Postbox -> TelegramEngine wave 44
Migrate RenderedChannelParticipant.peers from [PeerId: Peer] to
[EnginePeer.Id: EnginePeer]. Closes the wave-41 ratchet — the public
struct no longer leaks raw Peer types in any field (presences stays
Postbox-typed; separate migration).

Consumer-surface: -10 bridges. Dropped 6 EnginePeer(peer) read-wraps
at participant.peers[...] extraction sites across
ChannelAdminsController, ChannelMembersSearchContainerNode,
ChannelBlacklistController. Dropped 5 .mapValues({ $0._asPeer() })
constructor-unwrap transforms in ChannelAdminsController,
ChannelMembersSearchContainerNode, ChannelMembersSearchControllerNode.
Added 2 ._asPeer() unwraps in ChatRecentActionsHistoryTransition at
the two iteration sites (line 673 via participant.peers, line 2273
via new.peers in participantSubscriptionExtended) where the iterated
value is inserted into a raw-Peer SimpleDictionary.

TelegramCore producers: 8 files build the local peers dict inside
postbox.transaction and wrap at the insertion point. ChannelMembers,
RequestStartBot, ChannelOwnershipTransfer, JoinChannel, AddPeerMember,
PeerAdmins, ChannelBlacklist, Ranks.

2-iteration build convergence. Iteration-1 surfaced new.peers at
ChatRecentActionsHistoryTransition:2272 that the plan's participant.peers
pre-flight grep missed; wider grep now confirms the two iteration sites
are the complete surface.

No unit tests in this project; full Telegram/Telegram build verified
under configuration=debug_sim_arm64.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 23:21:05 +04:00
isaac
68a95f53f2 Various improvements 2026-04-24 23:21:05 +04:00
isaac
6c2f370a8f Fix fast-send morph starting position
The bubble-in-text-input morph ran concurrently with listNode's
scroll-to-item sublayerTransform animation, but its source rect was
computed via CALayer.convert which uses model transforms only and so
missed the pending additive sublayerTransform. The morph's `from`
ended up calibrated to the post-scroll state while playback started
from the pre-scroll state, offsetting the bubble at t=0.

Add convertAnimatingSourceRectFromWindow: walks the layer chain
top-down and at each parent->child step subtracts the parent's pending
additive sublayerTransform translation in the parent's bounds space
before descending, so the result reflects the t=0 presentation state
even through rotations/scales later in the chain. Parent
animatingItemNode under itemNode so listNode is on its ancestor chain
and its pending sublayerTransform is picked up.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 23:21:04 +04:00
isaac
493f3103b3 Postbox -> TelegramEngine waves 37-43 + wave 44 design/plan (squashed)
Squashes 20 commits — the implementation and outcome commits of
waves 37 through 43 plus wave 44's spec and implementation-plan
docs — into a single commit. Per-wave lessons remain recorded in
docs/superpowers/postbox-refactor-log.md. The unrelated "Add swift
svg" commit is preserved separately outside this squash.

Wave 37 — peerTokenTitle: peer Peer → EnginePeer (1 file)
Wave 38 — canSendMessagesToPeer: peer Peer → EnginePeer (12 files)
Wave 39 — AccountContext.makePeerInfoController: peer Peer → EnginePeer (52 files)
Wave 40 — makeChatQrCodeScreen + makeChatRecentActionsController bundle (8 files)
Wave 41 — RenderedChannelParticipant.peer: Peer → EnginePeer (28 files)
Wave 42 — PeerInfoScreenData.peer: Peer? → EnginePeer? (17 files)
Wave 43 — PeerInfoScreen 6 helpers: peer Peer? → EnginePeer? (12 files)
Wave 44 — RenderedChannelParticipant.peers design doc + implementation plan
         (impl and outcome land in subsequent commits, not part of squash)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 23:19:43 +04:00
isaac
e51fef57d8 Add swift svg 2026-04-24 23:19:15 +04:00
isaac
ce64d84013 docs: wave 37 design — peerTokenTitle peer parameter Peer → EnginePeer
Private free function in ContactMultiselectionController.swift. Five
_asPeer() bridges drop in one atomic single-file commit.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 11:29:25 +04:00
isaac
f5cb1391aa Merge commit '96b1432434' 2026-04-24 11:24:47 +04:00
isaac
97f8c53814 Various improvements 2026-04-24 11:24:14 +04:00
isaac
8408e0ae19 Postbox -> TelegramEngine waves 27-36
Consumer-sweep, facade-addition, and Peer→EnginePeer migrations:

- Wave 27: preferencesView consumer sweep
- Wave 28: resourceData consumer sweep
- Wave 29: resourceStatus consumer sweep
- Wave 30: _asStatus() bridge cleanup
- Wave 31: unused-import sweep re-run
- Wave 32: resourceStatus residue sweep
- Wave 33: loadedPeerWithId consumer sweep
- Wave 34: FoundPeer.peer Peer -> EnginePeer
- Wave 35: SendAsPeer.peer Peer -> EnginePeer
- Wave 36: ContactListPeer.peer Peer -> EnginePeer

Also includes per-wave specs, implementation plans, outcome logs, and
a CLAUDE.md wave-counter update.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 11:24:13 +04:00
isaac
9187fbb6db docs: reorganize CLAUDE.md — extract wave history and verbose guidance to log
Trims the Postbox-refactor section of CLAUDE.md from ~750 lines to ~160
by moving per-wave outcomes, the running tally of Postbox-free modules,
and verbose wave-selection guidance backstory into
docs/superpowers/postbox-refactor-log.md. Also adds a spec document for
the reorganization.

Kept in-place in CLAUDE.md: standing rules, engine typealias cheat sheet,
MediaResource consumer-migration patterns, TelegramEngine.Resources facade
inventory, and terse bullet-form guidance with log cross-references.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 11:20:55 +04:00
Ilya Laktyushin
96b1432434 Various improvements 2026-04-24 04:55:22 +02:00
Ilya Laktyushin
f41630083a Various improvements 2026-04-24 03:16:14 +02:00
Ilya Laktyushin
32b2ede5aa Fix data image sharing 2026-04-23 01:48:48 +02:00
Ilya Laktyushin
e3bf0cd30c Various fixes 2026-04-23 01:26:13 +02:00
Ilya Laktyushin
7d3a497db6 Fix build 2026-04-23 00:07:09 +02:00
Ilya Laktyushin
1fe13a7630 Fix build 2026-04-22 23:51:28 +02:00
Ilya Laktyushin
11af61f32e Fix build 2026-04-22 23:34:39 +02:00
Ilya Laktyushin
dbd40fe7d3 Various improvements 2026-04-22 23:03:51 +02:00
isaac
1dd23f6641 Bump version 2026-04-22 03:04:50 +04:00
isaac
f77eafacff Merge commit 'f185b602ea' 2026-04-22 00:32:48 +04:00
isaac
524c29cbe3 Various improvements 2026-04-22 00:32:34 +04:00
isaac
59dc46e0f5 docs: TextStyleEditScreen caret-tracking plan
Task-by-task implementation plan for the caret-tracking auto-scroll
design. Single-file change in TextStyleEditScreen.swift: tag both text
fields, walk the transition's TextFieldComponent.AnimationHint userData
on .textChanged, compute caret rect, and adjust the enclosing
ResizableSheetComponent scroll view's bounds.
2026-04-21 23:58:07 +04:00
isaac
bf74b055cf docs: TextStyleEditScreen caret-tracking spec
Design for auto-scrolling the ResizableSheetComponent scroll view on text
change so the caret in either ListMultilineTextFieldItemComponent stays
visible above the soft keyboard.
2026-04-21 23:55:09 +04:00
isaac
2dd07ef8cc TelegramApi: regenerate Api*/SecretApiLayer*.swift with safe flag unwrap
Mechanical regeneration after the SwiftTL fix. Every
'if Int(_N!) & Int(1 << K) != 0 {...}' gate and matching
'_cM = (Int(_N!) & ...) == 0) || ...' validation in parse_<ctor>
now reads 'Int(_N ?? 0)' instead of force-unwrapping. ~2168 sites
changed across the 41 flat Api*.swift files plus the 11 layered
SecretApiLayer*.swift files. No other content change.

Full Bazel build verified green with the regenerated sources.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-21 23:44:35 +04:00
isaac
90b2ba0bd4 SwiftTL: avoid trap when flags field fails to parse
Generated parse_<ctor>(...) for constructors with conditional fields
used to emit 'if Int(_N!) & Int(1 << K) != 0 { ... }' as the gate,
and 'let _cM = (Int(_N!) & Int(1 << K) == 0) || _M != nil' as the
per-field validation. Both force-unwrap _N (the flags field read)
before the bottom-of-function '_cN = _N != nil' validation runs,
so a buffer short enough to fail the flags read traps
deterministically instead of returning nil.

Replace the force-unwraps with (_N ?? 0). Missing flags then reads
as "all bits off": every gated branch is skipped, each flag-gated
_cM short-circuits to true via the '== 0' clause, and the flags
field's own _cN = _N != nil still fails so the overall constructor
validation falls through to return nil — matching the intended
"return nil on truncated buffer" contract.

Touches both generator emit paths (flat generateImplFile and layered
emitLayeredType). Regenerated Api*/SecretApiLayer*.swift follow in a
separate commit.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-21 23:44:26 +04:00
Mikhail Filimonov
f185b602ea ap update 2026-04-21 20:29:39 +01:00
isaac
3559ee9f1d TelegramApi: regenerate SecretApiLayer*.swift via SwiftTL
Replaces the hand-written layer 8/46/73/101/144 files with SwiftTL
output and adds the previously-unpublished layers 17/20/23/45/66/143.
Per-layer struct names (SecretApi8, SecretApi46, ...) and public
enum case signatures are unchanged for the consumers.

The regenerated cumulative snapshots now include every constructor
declared in secret_scheme.tl, including decryptedMessageActionTyping
(layer 17) which the hand-written files had elided. Switch statements
over DecryptedMessageAction in ProcessSecretChatIncomingDecryptedOperations
gain the missing case alongside .decryptedMessageActionNoop (both are
no-ops in the consumer-side state-machine).

BUILD uses glob("Sources/**/*.swift") so no BUILD update required.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-21 23:02:42 +04:00
isaac
e7956e0e70 Cleanup 2026-04-21 22:04:58 +04:00
isaac
da1629328f Fix resample 2026-04-21 22:04:47 +04:00
isaac
4464802051 Remove deprecated MTInputStream methods 2026-04-21 21:10:33 +04:00
isaac
2516f0005d CLAUDE.md: record full Make.py build command
Documents the actual build invocation (with codesigning + cache +
configuration arguments) at the top of the file, alongside the
existing notes that only Bazel + the codesigning env var were
mentioned. Removes the duplicate "Build environment quirk" footer
section since its content now lives at the top.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-21 16:05:12 +04:00
isaac
57bfe559ea SwiftTL: main.swift branches on ParsedSchema
Flat schemas keep the existing generate(...) pipeline. Layered
schemas iterate resolveLayeredTypes and write one
{apiPrefix}Layer{N}.swift per layer via generateLayered.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-21 15:56:05 +04:00
isaac
803bf23269 SwiftTL: add CodeGenerator.generateLayered for per-layer output
Emits one {apiPrefix}Layer{N}.swift file per layer: file-scope
dispatch table, public struct {apiPrefix}{N} with parse/parseVector/
serializeObject, nested public enums for each sum type using the
inline-args shape. Int256 dispatch entry emitted only when a layer's
constructors reference it. Reuses typeReferenceRepresentation /
generateFieldSerialization / generateFieldParsing unchanged, passing
the struct name as the apiPrefix so nested type refs render correctly.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-21 15:54:09 +04:00
isaac
10054efd81 SwiftTL: add Resolver.resolveLayeredTypes
Walks layer sections in order, threads a running constructor-name map
with last-wins semantics, and snapshots [SumType] at each layer
boundary. Constructors appearing only in later layers do not leak into
earlier layers' snapshots.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-21 15:46:48 +04:00
isaac
dba8a67bcb SwiftTL: add ParsedSchema + layered schema parsing
DescriptionParser.parse(data:) now returns ParsedSchema (.flat or
.layered) based on the presence of ===N=== markers. Layered schemas
split constructor lines per layer; pre-marker constructors attach to
the lowest-numbered layer; ---functions--- is rejected in layered
mode; non-ascending markers throw.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-21 15:36:09 +04:00
isaac
248c69a6d0 SwiftTL: plan for layered schema generation
Six-task implementation plan covering the parser / resolver / codegen
extension path described in the 2026-04-21 design spec. Tasks land
end-to-end, with a final Bazel build verification of the regenerated
SecretApiLayer*.swift files.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-21 15:25:19 +04:00
isaac
bb29084392 SwiftTL: thread apiPrefix, drop dead CLI flags and LegacyOrderParser
Preparation for layered schema generation. Threads apiPrefix: String
through CodeGenerator.generate / generateMainFile / generateImplFile
/ typeReferenceRepresentation so the output's namespace name can
come from the --api-prefix=<prefix> CLI flag rather than a hard-coded
"Api". Drops the --stub-functions and --print-constructors=N-M flags
(both unused) and the LegacyOrderParser.swift file (obsolete migration
helper that re-parsed hand-emitted Api0.swift).

No behavior change for the flat Api*.swift output when
--api-prefix=Api (the default). Enables the upcoming layered secret-
scheme pipeline to reuse the same generator helpers.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-21 15:24:14 +04:00
Mikhail Filimonov
365d44f03a Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2026-04-21 12:11:20 +01:00
Mikhail Filimonov
fe6836ab02 flag 2026-04-21 12:11:11 +01:00