Commit graph

30308 commits

Author SHA1 Message Date
isaac
a9f8b0d067 Make rich messages editable via InstantPage↔markdown round-trip
Reconstruct markdown source from a stored InstantPage to populate the edit
field, then re-classify on save (the inverse of the send path). Adds the
InstantPageToMarkdown converter, edit-field population and save-time
re-classification in ChatControllerLoadDisplayNode, and a shared InstantPage
previewText surfaced through MessageContentKind for reply/pinned/forward
previews. Documented in CLAUDE.md.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 23:10:48 +02:00
isaac
e1b48665a8 Auto-detect rich vs. entity markdown on send
Classify typed markdown on send: structure the message-entity set can't
represent (headings, lists, tables) is sent as a rich message
(RichTextMessageAttribute carrying an InstantPage); everything else takes
the existing entity path. Adds the parse-then-inspect classifier in
BrowserMarkdown, gates it in ChatControllerNode.sendCurrentMessage
(replacing the debugRichText flag), drops formulas/dividers as triggers,
and cleans up heading blocks for the chat path. Documented in CLAUDE.md.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 23:10:15 +02:00
isaac
38464954b0 Update API 2026-05-24 00:24:21 +04:00
isaac
8b9f498d53 RichText.textSpoiler: dust overlay + tap-to-reveal in rich-data bubbles
Add the RichText.textSpoiler case end-to-end: model + Postbox coding,
FlatBuffers schema/codec, and Api.RichText parsing/serialization (lossless).
Display attaches the spoiler attribute, collects per-line spoiler rects in
the V2 layout, clips obscured glyphs and draws an energy-gated dust overlay
in the V2 text view, propagates the reveal flag across the nested V2 tree
(building dust for freshly-created text views), and wires tap-to-reveal
routing in the rich-data bubble.

Also seeds the streaming reveal cursor across chunk rebuilds and refines
status date positioning.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-23 22:12:47 +04:00
isaac
99e4c41b24 RichText: entity cases (mention / hashtag / cashtag / bot command / bank card / auto link)
Implement the nine message-entity RichText cases (textMention,
textMentionName, textHashtag, textCashtag, textBotCommand, textBankCard,
textAutoUrl, textAutoEmail, textAutoPhone): model + Postbox coding,
FlatBuffers schema/codec, Api.RichText parsing/serialization (lossless),
InstantPage display attaching the matching TelegramTextAttributes keys, and
tap routing in the rich-data bubble mirroring ChatMessageTextBubbleContentNode.
mentionName display resolves via EnginePeer.Id (PeerId not in scope).

Also lets rich-data text selection reach a line's trailing edge and fixes
the date/status node positioning to match TextBubble.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-23 22:12:47 +04:00
isaac
b48b96ecd9 RichText.textCustomEmoji: inline animated custom emoji in rich-data bubbles
Add the RichText.textCustomEmoji(fileId:alt:) case end-to-end: model +
Postbox coding, FlatBuffers schema/codec, and Api.RichText
parsing/serialization (lossless), plus display in the InstantPage V2
renderer. The emoji renders as an InlineStickerItemLayer that participates
in the streaming reveal (pops in as the reveal cursor crosses it) and is
gated by the bubble's visibility rect, propagated recursively through the
nested V2 view tree. Also frees the CTRunDelegate extent buffers for the
image/formula/custom-emoji attachment arms and documents the feature in
CLAUDE.md.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-23 22:12:47 +04:00
isaac
ded413ae74 Add design spec: RichText.textCustomEmoji parsing, serialization & display
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-22 17:02:47 +08:00
isaac
3c939d0c87 Update xcodebuildmcp config 2026-05-20 00:34:25 +08:00
isaac
dd9adeeaf2 Update gitignore 2026-05-20 00:34:25 +08:00
isaac
3f09a1f325 WIP 2026-05-20 00:34:25 +08:00
isaac
562de27c30 InstantPage V2: AI streaming animation for rich-data bubbles
Spec, plan, and full implementation of the AI-message streaming
animation in ChatMessageRichDataBubbleContentNode. Extracts
TextRevealController into a shared StreamingTextReveal submodule;
precomputes per-character rects in V2 layout (RTL-safe, glyph-ink
bounds); splits InstantPageV2TextView into render container + render
view with a reveal mask layer; implements mask + snippet pop-in
reveal; adds a per-text-view reveal cost map + applyReveal extension;
switches reveal cost to a width-based unit; sizes / clips the bubble
to the revealed prefix during streaming; aligns the Thinking… header
with TextBubble; floors table cell reveal cost at cell frame width;
includes layout closing pad in revealedContentSize; documents the
non-obvious invariants in CLAUDE.md.
2026-05-20 00:34:07 +08:00
isaac
a53ef1f299 InstantPage V2: inline-formula baseline alignment
Snapshot list marker subviews/sublayers before iteration, anchor
strike/underline drawing to item frame height, baseline-align inline
text, images, and formulas. Also: implementation plan and two spec
refreshes (clarify extraDescent nudge removal; refresh stale line
numbers).
2026-05-20 00:33:55 +08:00
isaac
8dbbf0f715 Rich-bubble text selection (post-V2 fix)
Design and plan, then implementation: include the details title in
selectableTextItems, restore V2 text selection in the rich bubble,
drop the InstantPageMultiTextAdapter init parameter-name split, and
split LinkHighlightingNode modern-path groups on disjoint rects.
Also includes the IP V2 inline-formula baseline alignment design doc.
2026-05-20 00:33:47 +08:00
isaac
3a22e7c81b Fix clipping 2026-05-20 00:33:32 +08:00
isaac
e2da230af6 InstantPage V2: media rendering (image / video / map / cover)
Design and plan, then the implementation: extract a shared
openInstantPageMedia helper for V1+V2 reuse, add typed media item
cases + allMedias() helper, introduce InstantPageV2RenderContext and
thread it through the view tree, add four media wrapper views, route
layout dispatch through typed media items, let the chat bubble build
the render context so real media renders, wire gallery tap routing,
cache V2View by message id + stableVersion, add stable-id identity +
per-class update(item:theme:), reuse item views on re-layouts via
stable-id harvest, preserve TextView clipping inset on reuse, and let
the use site control media-reference construction.
2026-05-20 00:33:28 +08:00
isaac
0a3030deed InstantPage V2: formula display
Design, plan, and implementation. Adds .formula item case +
InstantPageV2FormulaView, bumps InstantPageMathAttachment fields to
public, routes block and inline formulas through .formula items,
aligns the scroll view with V1 (alwaysBounceHorizontal = false), and
reports narrow block formula natural width so the fitToWidth bubble
shrinks.
2026-05-20 00:33:18 +08:00
isaac
6a0c8d9e07 Fix gif rendering issues 2026-05-20 00:33:11 +08:00
isaac
13a153aff2 WIP 2026-05-20 00:33:08 +08:00
isaac
50da64adfa InstantPage V2: TextView clipping inset
Design and plan, then the implementation: grow InstantPageV2TextView
frame by 4pt on each side to avoid clipping descenders and italic
overhangs.
2026-05-20 00:33:04 +08:00
isaac
c32ef046b7 InstantPage V2: implementation
Initial design, plan, scaffold, and the full incremental implementation
of InstantPage V2 used by ChatMessageRichDataBubbleContentNode: layout
data types and driver, shared text helpers, text view / divider /
anchor, lists, code blocks, block/pull quotes, media placeholders,
details (with recursion), tables, hit-test / selection / last-line
helpers, V1→V2 swap in the rich-data bubble, and post-swap fix-ups
(cache key, RTL paragraphs, list geometry, lazy pageView construction,
fitToWidth horizontal inset, V2View.update() no longer writes
self.frame).
2026-05-20 00:32:44 +08:00
isaac
cea2846249 Reveal pacing: switch to predicted-arrival algorithm
Adds the V2 reveal-pacing simulator and switches the live pacing
controller from the EWMA inter-arrival approach to a predicted-arrival
algorithm.
2026-05-20 00:32:08 +08:00
isaac
e06e154396 Rich bubble: add statusNode
Spec, plan, and implementation of the date / checks / reactions /
effects status node on ChatMessageRichDataBubbleContentNode. Hoists
layout work out of the inner closure and anchors the status frame top
at text maxY.
2026-05-20 00:30:48 +08:00
isaac
39d33d998c Fix audio route button 2026-05-20 00:30:43 +08:00
isaac
9e3c16cde5 Live typing draft reveal pacing
Smooth-pace reveal of incoming live typing drafts. Adds the design
doc, implementation plan, the EWMA inter-arrival → velocity-smoothed
cursor core, handling for text shrink / item loss, and debug logs.
2026-05-20 00:30:39 +08:00
isaac
b8ee5493d9 Postbox refactor waves 427-437: combinedView → engine.data migrations
Squashed batch of 14 consumer-side migrations from Postbox
combinedView/subscribe patterns to TelegramEngine.data.subscribe /
.get, plus two engine-data-item additions.

- Wave 427: DataAndStorageSettingsController preferences subscribe
- Wave 428: SaveIncomingMediaController inner preferences subscribe
- Wave 429: SaveIncomingMediaController top-level preferences subscribe
- Wave 430 (reverted + retried as 430-retry):
    initial TabBarChatListFilterController globalNotifications attempt
    landed and was reverted; replaced by ChatControllerContentData
    messageAndTopic collapse via additive Messages.MessageCount
    handleThreads/namespace parameter
- Wave 431: ChatControllerContentData savedMessagesPeer collapse via
    new Peer.MainPeer(id:) engine data item
- Wave 432 (+ followup): 6 messageHistoryThreadInfo sites to
    Messages.ThreadInfo
- Wave 433: ChatListController cachedPeerData → engine.data.get
- Wave 434: 8 orderedItemList sites to Collections.Featured*Packs
- Wave 435: StorageUsageExceptionsScreen preferences combinedView
- Wave 436: FeaturedStickersScreen 2 itemCollectionInfos sites
- Wave 437: extends Messages.PeerUnreadCount with handleThreads
    parameter + migrates AccountContext unreadCount site
2026-05-20 00:18:15 +08:00
isaac
c64653ed37 Bump version 2026-05-07 07:40:39 +02:00
isaac
4107263747 Postbox refactor waves 358-426
Squashed range bf01b4c..a66739c (70 commits) covering 69 waves of the
Postbox -> TelegramEngine consumer migration plus a few BUILD-dep
followups.

Notable additions to TelegramCore in this range:
- Engine typealiases: EngineRawPeerPresence, EngineRawValueBoxKey,
  EngineSimpleDictionary, EngineRawPeerView, EngineRawPostboxViewKey,
  EngineRawPreferencesView, EngineRawMessageHistoryView (+ entry/attrs/
  read-state), EngineMessageIdNamespaces, EngineHistoryViewInputAnchor,
  EngineRawUnreadMessageCountsItem, EngineRawMessageHistorySavedMessages
  IndexView, EngineRawChatInterfaceStateView, EngineRawOrderedItemList
  View, EngineRawMessageHistoryThreadIndexView, EngineRawCombinedRead
  StateView, EngineRawMessageHistoryThreadInfoView, EngineRawBasicPeer
  View, EngineRawCachedPeerDataView, EngineMessageHistoryThreadData,
  EngineViewUpdateType, EngineInitialMessageHistoryData,
  EnginePeerGroupId, EngineChatLocationInput, EngineHistoryViewInputTag.
- Engine data items: Peer.CachedData, ItemCollections.InstalledPackInfos,
  ItemCollections.InstalledPackIds.
- Engine facade: TelegramEngine.ItemCollections.allItems(namespace:).
- Free function: engineAreMediaArraysEqual forwarder.

Net effect: 65+ consumer modules drop "import Postbox"; 131 files
changed (+1386 / -1493). Build green at HEAD.
2026-05-07 07:36:30 +02:00
isaac
bf01b4c858 Postbox refactor wave 357: drop orphan //submodules/Postbox BUILD deps
Sweep 14 BUILD files whose modules no longer have any source file with
`import Postbox`. All targets are ChatMessage*BubbleContentNode subclasses
plus WallpaperPreviewMedia — modules whose Swift sources stopped importing
Postbox in earlier waves but whose BUILD deps were not cleaned up.

Pre-flight: for each `BUILD` containing `"//submodules/Postbox"`, verified
no source file under `<module>/Sources` matches `^import Postbox$`. 14
modules met the criterion.

Build: 15s warm-cache verify, 0 errors.

Modules:
- ChatMessageActionBubbleContentNode
- ChatMessageEventLogPreviousDescriptionContentNode
- ChatMessageEventLogPreviousLinkContentNode
- ChatMessageEventLogPreviousMessageContentNode
- ChatMessageFileBubbleContentNode
- ChatMessageGameBubbleContentNode
- ChatMessageInvoiceBubbleContentNode
- ChatMessageMapBubbleContentNode
- ChatMessageMediaBubbleContentNode
- ChatMessageProfilePhotoSuggestionContentNode
- ChatMessageStoryMentionContentNode
- ChatMessageWallpaperBubbleContentNode
- ChatMessageWebpageBubbleContentNode
- WallpaperPreviewMedia

Pre-wave attempt failure note: tried 5 source-side `import Postbox` drops
first (StatsMessageItem, StarsAvatarComponent, PeerListItemComponent,
WebAppMessagePreviewScreen, OpenChatMessage). All 5 hit hidden bare
`Media`/`Message`/`PeerStoryStats`/`areMediaArraysEqual` references that
the prior pre-flight regex missed. Reverted source edits; only the
risk-free BUILD-dep sweep survives in this commit.

Lesson: pre-flight regex MUST include bare Postbox protocols
`\bMedia\b`, `\bMessage\b`, `\bPeer\b`, plus the Postbox helper
`areMediaArraysEqual` and the `PeerStoryStats` type. The previous
identifier-typealias-only regex was insufficient.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 21:01:48 +02:00
isaac
71ac72d463 Upate webrtc 2026-05-05 20:32:33 +02:00
isaac
05fe27d0f7 Update tgcalls 2026-05-05 20:28:43 +02:00
isaac
3e9b0742d1 Fix custom emoji 2026-05-05 20:23:06 +02:00
isaac
05f1f19ab0 Context controller portal-view transition 2026-05-05 20:26:25 +02:00
isaac
3051b1f3e4 Add implementation plan: context controller portal-view transition
Eight-task plan covering ContextUI struct field additions,
PortalTransitionStaging helper, CCEPN animateIn/animateOut wiring,
ChatControllerNode contextTransitionContainer, two adopter sources,
and manual visual verification.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 17:26:09 +02:00
isaac
4de5eeccd2 Various improvements 2026-05-05 16:53:47 +02:00
isaac
aafe6d8dab Add implementation plan for ShimmeringMaskView
Three task plan: (1) trim ShimmeringMask BUILD deps, (2) replace stub
with full reveal-mask CAGradientLayer implementation, (3) wrap
streamingStatusTextNode in ChatMessageTextBubbleContentNode. Plus a
manual-verification task since the project has no unit-test harness.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 16:53:13 +02:00
isaac
797326d669 Add design spec for ShimmeringMaskView
Reusable view that applies a moving alpha-mask shimmer (rest=1.0,
dip=peakAlpha) to its contentView. First consumer: the streaming-status
text node in ChatMessageTextBubbleContentNode for ChatGPT-style
"thinking" effect.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 16:41:05 +02:00
isaac
f7dcf20f69 Add design spec: context controller portal-view transition
Replaces CCEPN's manual visible-area clipping with a portal-based
transition mirroring CMTN's primitive. Adds optional
sourceTransitionSurface to TakeViewInfo/PutBackInfo; chat is the
first adopter.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 16:27:20 +02:00
isaac
e918b353ec Postbox refactor waves 278-356: squash
Squashes 79 sequential refactor waves into a single commit.

Highlights:
- Drop `import Postbox` (and matching `//submodules/Postbox` BUILD deps) from a wide swath of consumer files: ChatList, ChatMessage*BubbleContentNode subclasses, ListMessageNode/ListMessageItem, GalleryData, ChatHistorySearchContainerNode, ChatPanelInterfaceInteraction, ChatControllerInteraction, ChatMessageStickerItemNode, ChatMessageReplyInfoNode, ChatMessageInstantVideoItemNode, ChatPresentationInterfaceState, BrowserMarkdown/Readability, MediaResources, LocalMediaResources, ICloudResources, FetchManager, ShareController, OpenChatMessage, GalleryController, GroupStickerSearchContainerNode, GroupStickerPackCurrentItem, ChatPinnedMessageTitlePanelNode, OverlayAudioPlayerController, PresentationThemeSettings, StatisticsUI/StoryIconNode, TextFormat/StringWithAppliedEntities, GalleryUI/VideoAdComponent, StickerPackPreviewUI, WallpaperPreviewMedia, WallpaperResources, YoutubeEmbedImplementation, InstantPageExternalMediaResource, PlatformRestrictionMatching, TelegramUIDeclareEncodables, ChatListNode/ChatListSearchContainerNode.
- Add `TelegramEngine` facades: `Themes.wallpapers`, `Themes.themes`, `AccountData.addAppLogEvent`.
- Add `EngineMessageHistoryEntryLocation` wrapper.
- Add `EngineRaw*` escape-hatch typealiases (`EngineRawMessage`, `EngineRawPeer`, `EngineRawMedia`, `EngineRawMediaResource`, `EngineRawMediaResourceData`, `EngineRawItemCollectionItem`, `EngineRawItemCollectionInfo`) and `engineDeclareEncodable` forwarder.
- Drop unused `account:`/`postbox:`/`network:` parameters from several public functions and delete the dead overloads/types/functions left over: `automaticThemeShouldSwitchNow`, `cancelFreeMediaFileInteractiveFetch`, `legacyEnqueueVideoMessage`, `TelegramMediaFileReference`, plus assorted dead public TelegramCore/AccountContext SecureId entry points.
- Delete entire dead modules: `LegacyDataImport`, `TonBinding`, `SpotlightSupport`, `SvgRendering`, third-party `AppCenter`/`VectorPlus`/`SwiftColor`/`SwiftSVG`.
- Drop orphan `//submodules/Postbox` BUILD deps across 3 cleanup rounds.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 14:11:06 +02:00
isaac
ea0f6a685c Postbox refactor wave 277: cachedWallpaper(account:) → cachedWallpaper(engine:network:)
Migrate `cachedWallpaper(account: Account, ...)` in WallpaperCache.swift to
take `(engine: TelegramEngine, network: Network, ...)` instead of the umbrella
Account parameter. Body drops the local `let engine = TelegramEngine(account:)`
since engine is now a parameter; `account.network` is now `network`.

19 context-based callers (`account: context.account` /
`self.context.account` / `component.context.account`) update via perl
sweep to pass `engine: context.engine, network: context.account.network`.

3 internal-Account-typed callers (WallpaperResources.swift × 2,
ThemeUpdateManager.swift × 1) bridge with adhoc
`engine: TelegramEngine(account: account), network: account.network`
since they're inside functions that still take `account: Account` and have
heavier Postbox uses we can't migrate yet.

Drops `import Postbox` from WallpaperCache.swift since the only remaining
Postbox-ish identifier was `ValueBoxKey`, which swaps to `EngineDataBuffer`.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 00:54:26 +02:00
isaac
ab7fc69e16 Merge commit '93244da737' 2026-05-05 00:45:32 +02:00
isaac
69bfc65da7 Postbox refactor waves 138–276: 168-commit squash
Consolidates 137 wave commits + 31 supporting commits (CLAUDE.md bump,
typealias additions, AnyObject→EngineMedia restoration) into one squashed
commit. Migrates dozens of consumer-side public APIs, struct fields,
protocol methods, and enum payloads from Postbox protocols/structs to
TelegramEngine engine wrappers and typealiases. Drops `import Postbox`
from many files. Adds new TelegramCore typealiases and one
TelegramEngineUnauthorized facade.

Notable changes by category:

**TelegramCore typealias additions** (rule 2 — narrow utility typealiases):
- EngineChatListIndex, EngineTempBoxFile, EngineItemCollectionItemIndex,
  EngineItemCollectionViewEntryIndex, EngineValueBoxEncryptionParameters,
  EngineMessageAndThreadId, EnginePeerStoryStats, EngineMessageHistoryAnchorIndex,
  EngineChatListTotalUnreadStateCategory, EngineChatListTotalUnreadStateStats,
  EnginePeerSummaryCounterTags, EngineChatListTotalUnreadState,
  EngineItemCacheEntryId, EngineHashFunctions,
  EngineCachedMediaResourceRepresentationResult,
  EngineMediaResourceDataFetchResult, EngineMediaResourceDataFetchError,
  EngineMediaResourceStatus, EngineCachedPeerData

**TelegramCore engine extensions/forwarders**:
- EngineMessage.engineMedia, EngineMessage.enginePeers,
  EngineMessage.adAttribute, EngineMessage.effectivelyIncoming
- engineFileSize forwarder
- TelegramEngine.Resources.clearCachedMediaResources(mediaResourceIds: Set<EngineMediaResource.Id>)
- TelegramEngine.Resources.fetchStatus(id:resourceSize:)
- TelegramEngineUnauthorized.UnauthorizedResources facade with storeResourceData

**Public API/struct migrations to engine types**:
- ChatAvailableMessageActions.banAuthor/banAuthors → EnginePeer?/[EnginePeer]
- WebSessionsContextState.peers → [EnginePeer.Id: EnginePeer]
- CacheUsageStats.peers → [EnginePeer.Id: EnginePeer]
- PeerCommand.peer → EnginePeer
- PeerInfoControllerMode.calls(messages:) → [EngineMessage]
- CallControllerNodeProtocol.updatePeer → EnginePeer params
- ChatHistoryListNode.messageInCurrentHistoryView (and 4 variants) → EngineMessage?
- ChatHistorySearchContainerNode.messageForGallery → EngineMessage?
- PeerInfoPaneNode.findLoadedMessage / ensureMessageIsVisible /
  transitionNodeForGallery → engine-typed
- GalleryHiddenMediaTarget.getTransitionInfo /
  GalleryHiddenMediaManager.findTarget → engine-typed
- ChatPanelInterfaceInteraction.presentReactionDeletionOptions /
  presentBan*MessageOptions → EnginePeer
- DrawingMessageRenderer.messages → [EngineMessage]
- ChatVideoGalleryItemScrubberView.setFetchStatusSignal →
  EngineMediaResource.FetchStatus
- ChannelDiscussionGroupActionSheetItem.peer, VoiceChatPeerEntry.peer,
  VoiceChatFullscreenParticipantItem.peer, MediaStreamComponent.chatPeer,
  MediaStreamVideoComponent.callPeer, ChatMessageContactBubbleContentNode.contactPeer,
  ChatMessageForwardInfoNode.peer, ChatMessageCommentFooterContentNode.replyPeers,
  ChatReportPeerTitlePanelNode.peer, ChatMessageActionUrlAuthController.bot,
  PeerMediaCollectionInterfaceState.peer, ChatMessageCallBubbleContentNode.peopleAvatars,
  ChatLoadingNode.renderedPeer (→ EngineRenderedPeer) — all to engine types

**Wave-71-shadow stored-field migrations** (Postbox Peer/Message → Engine wrapper):
- LegacyCallControllerNode.peer
- CallStatusBarNode.currentPeer

**Dead-code / dead-field removals**:
- CallController.peer, CallControllerNodeV2.account,
  ContactMultiselectionController PeerNameIndex fields,
  preparedChatListNodeViewTransition account: Account param,
  FetchResource.swift entirely (unused function)

**Module-level Postbox import drops**: 30+ files including TelegramRootController,
EditStories, GiftViewScreen, AnimatedStickerUtils, FetchPhotoLibraryImageResource,
PeerInfoGiftsPaneNode, PeerInfoPaneContainerNode, PresentAddMembers,
PeerInfoProfileItems, ChatControllerAdminBanUsers, PresentationData typealiases,
DefaultDayPresentationTheme, ChatListViewTransition, GalleryHiddenMediaManager,
RecentSessionsController, GifContext, AuthorizationSequenceController,
PeerInfoHeaderEditingContentNode, PeerInfoHeaderNode,
PeerAllowedReactionListController, CallControllerNodeV2, and 6 PeerInfo pane files.

**AnyObject restoration**: rule 8 added (never substitute Postbox protocols
with Any/AnyObject) — undid previous AnyObject substitutions in waves 141/143
back to EngineMedia.

Doc maintenance: CLAUDE.md updated to reflect new typealiases and forwarders.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 00:44:27 +02:00
isaac
631df15f40 Refactoring 2026-05-03 10:31:22 +02:00
isaac
86d1456552 Postbox -> TelegramEngine waves 107-137 (squashed)
31 waves of consumer-side migration from `import Postbox` to TelegramEngine
typealiases. Net: 173 import drops + 39 BUILD-dep drops + 1 new typealias
(`EngineStoryId = StoryId`, wave 113).

Wave shapes used:
- Orphan-import sweeps (107, 108, 128): drop `import Postbox` from files
  whose only Postbox-symbol reference was the import line itself, then
  resolve build failures. Methodology requires token-level (`grep -oE`)
  filtering, not line-level, to avoid masking real Postbox usage on lines
  that also contain `Namespaces.X` references.
- Identifier-swap mini-waves (109-127, 129-134, 136-137): rename
  Postbox-typealiased identifiers to engine equivalents
  (PeerId -> EnginePeer.Id, MessageId -> EngineMessage.Id,
  MediaId -> EngineMedia.Id, MessageIndex -> EngineMessage.Index,
  StoryId -> EngineStoryId, ItemCollectionId -> EngineItemCollectionId,
  PreferencesEntry -> EnginePreferencesEntry,
  FetchResourceSourceType/Error -> EngineFetchResourceSourceType/Error,
  MemoryBuffer -> EngineMemoryBuffer, MessageTags -> EngineMessage.Tags,
  MessageAttribute -> EngineMessage.Attribute,
  TempBox -> EngineTempBox).
- Asset-string FP-only orphans (124).
- Typealias addition + drain (113): added `EngineStoryId` typealias to
  TelegramCore, then drained 3+11 consumer sites.

Hard blockers identified during these waves (must restore `import Postbox`
when present): MediaResource[A-Za-z]* (any suffix -- the literal
`MediaResource` matches don't catch MediaResourceData/MediaResourceId/etc.),
Postbox/MediaBox/MediaResource raw types, PostboxCoding/PostboxEncoder/
PostboxDecoder, TempBoxFile, ValueBoxKey, PostboxView, combinedView,
HashFunctions, postboxLog, openPostbox, declareEncodable, PeerView,
MessageHistoryView, MessageHistoryThreadData, CachedPeerData, RenderedPeer,
SelectivePrivacyPeer, SimpleDictionary, ItemCollectionInfosView,
ItemCollectionItem, ItemCollectionItemIndex, ItemCollectionViewEntryIndex,
ChatListIndex, ChatListEntrySummaryComponents, CodableEntry,
MessageHistoryThread, MessageHistoryAnchorIndex,
MessageHistoryEntryLocation, PeerStoryStats, PeerNameIndex,
PeerSummaryCounterTags, ChatListTotalUnreadStateCategory/Stats,
arePeersEqual. Protocol-shape blockers: bare `Peer`/`Message`/`Media`
in function signatures, generic args, enum-case payloads, or dict value
types (e.g., `[PeerId: Peer]`, `case messages([Message])`,
`Signal<(Peer?, ...), NoError>`).

`replace_all PeerId -> EnginePeer.Id` is dangerous: mangles compound
names like `failedPeerId`, `ContactListPeerId`, `nextRemoteMediaId`,
`replyToMessageId`. Pre-flight grep `\b[a-z][a-zA-Z]*PeerId\b` and only
replace_all if 0 matches.

Also removes unneeded design/plan docs from a separate (link-highlighting)
feature branch:
- docs/superpowers/plans/2026-05-02-link-highlighting-modern-path-fixes.md
- docs/superpowers/specs/2026-05-02-link-highlighting-modern-path-fixes-design.md

Squashed commits: 6d82c2980d..e6de5d53a3 (59 commits, including
per-wave content commits and per-wave CLAUDE.md bumps).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-03 10:28:50 +02:00
Mikhail Filimonov
93244da737 macos 2026-05-02 11:56:45 +01:00
isaac
b1aab0839c LinkHighlightingNode: ceil instead of floor for stair-step radii
drawRectsImageContent's modern path computed nextRadius and
prevRadius as min(outerRadius, floor(|Δx| * 0.5)). When |Δx| < 2
the floor produces 0 and the addArc call becomes a no-op,
leaving an unsmoothed corner at the stair-step. Replace floor
with ceil so any non-zero edge mismatch rounds up to at least
1 px. Exact-equality cases (Δx == 0) are unaffected — they take
the else branch with a straight addLine.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-02 11:46:38 +02:00
isaac
d1c5d66bd3 LinkHighlightingNode: fix X-edge snap unreachable after midY snap
In drawRectsImageContent's modern path the snap loop runs midY
trimming first, leaving rects[i].maxY == rects[i+1].minY for
adjacent line rects. The X-edge snap guard then evaluated
rects[i].insetBy(dx: 0.0, dy: 1.0).intersects(rects[i+1]) — but
positive dy shrinks the rect, so after the trim the guarded
rectangle no longer intersects its neighbor (CGRect.intersects
requires positive-area overlap). Flip dy to -1.0 so the temp
rect grows and touching neighbors satisfy the guard.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-02 11:44:05 +02:00
isaac
6e318f314e Add implementation plan: modern path link-highlighting fixes (#3, #7)
Plan covers two single-line edits in LinkHighlightingNode.swift's
modern branch (X-snap dy direction; floor → ceil for stair-step
fillet radii), each landed as its own commit, with a final
full-project build for validation since this repo has no tests.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-02 11:37:29 +02:00
isaac
42498cd06c Add design spec: modern path link-highlighting fixes (#3, #7)
Document the analysis and intended fixes for two bugs in
LinkHighlightingNode's modern path branch: the X-edge snap is
unreachable after the midY snap (positive dy in insetBy shrinks
rect[i] so it can't intersect the touching neighbor), and the
floor() in nextRadius/prevRadius can produce zero-radius arcs.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-02 11:32:04 +02:00
Mikhail Filimonov
5b56675b06 Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios
# Conflicts:
#	submodules/MetalEngine/Sources/MetalEngine.swift
2026-05-02 10:10:18 +01:00
Mikhail Filimonov
5b8e5e0f95 metal transaction 2026-05-02 10:07:13 +01:00