Telegram-iOS
Find a file
isaac 1d82735d61 InstantPage V2: render inline RichText images
Renders `RichText.image(id:, dimensions:)` runs as real fetched images
inside `ChatMessageRichDataBubbleContentNode` / `InstantPageV2View`,
replacing the gray `InstantPageV2MediaPlaceholderView`. Source is
whatever populates `instantPage.media[id]` (server-pushed webpage
InstantPages); the markdown converter is unchanged
(`markdownImageParsingEnabled` stays false).

Architecture mirrors inline custom emoji: inline images are NOT
top-level `InstantPageV2LaidOutItem`s. `InstantPageV2View` walks each
text view's `line.imageItems`, resolves each MediaId against
`layout.media`, and creates `InstantPageV2InlineImageView` children
inside a new `imageContainerView` on each `InstantPageV2TextView`
(sibling of `renderContainer`, above the reveal mask, below
`emojiContainerView`).

Streaming reveal participation: image cells contribute their full
width to the per-line character rects (mirrors emoji), so the cost map
charges the cursor by the image's width when crossing it. When the
cursor crosses the cell, `updateImageReveal` pops the view in
(opacity 0→1 + scale 0.1→1.0 over 0.2s ease-out), matching
`updateEmojiReveal` exactly. `applyReveal` calls both alongside each
other.

Non-interactive (V1 parity): `isUserInteractionEnabled = false` lets
URL-wrapping `RichText.url(text: .image(...))` route taps through to
the underlying text view's URL handler.

Key files:
- New `InstantPageV2InlineImageView.swift`: lightweight
  `TransformImageNode`-backed view. Picks the fetch signal by
  EngineMedia kind (.image → chatMessagePhoto; image-mime .file →
  instantPageImageFile; video .file → chatMessageVideo single frame).
  `MetaDisposable` cancels fetches on dealloc.
- `InstantPageV2Layout.swift`: `media`/`webpage` fields on the layout
  struct; image cells contribute to char rects; the gray-placeholder
  branch in `layoutTextItem` is removed; the dead `media`/`webpage`
  params on `layoutTextItem` are dropped along with their 13 call
  sites.
- `InstantPageRenderer.swift`: `imageContainerView` on text view
  (sibling of `renderContainer`, between it and `emojiContainerView`);
  `InlineImageKey` + `InstantPageInlineImageData` types;
  `updateInlineImages()` + `updateImageReveal()` on
  `InstantPageV2View`; wired into `update(layout:theme:animation:)`.
- `InstantPageV2RevealCost.swift`: `applyReveal` calls
  `updateImageReveal` next to `updateEmojiReveal` in both the
  clear-path branch and the entry-walking branch.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-28 14:21:25 +02:00
.github Add CONTRIBUTING.md 2023-12-03 14:23:34 +04:00
.vscode Temp 2026-03-13 09:00:55 +01:00
.xcodebuildmcp Update xcodebuildmcp config 2026-05-20 00:34:25 +08:00
build-system Update signing 2026-05-27 01:06:41 +02:00
buildbox Working state 2022-08-11 00:39:11 +04:00
docs Fix build command path in list-checkbox plan (Make/Make.py) 2026-05-27 16:45:06 +02:00
scripts Temp 2026-03-13 09:00:55 +01:00
submodules InstantPage V2: render inline RichText images 2026-05-28 14:21:25 +02:00
Telegram Optimize watch building 2026-05-28 02:45:47 +02:00
Tests Refactoring 2026-04-07 11:31:22 +02:00
third-party Upate webrtc 2026-05-05 20:32:33 +02:00
tools Extract tgcalls helpers into tgcalls 2026-04-30 22:13:55 +02:00
.bazelrc feat: tgcalls CLI test tool with group SFU, video, and adaptation 2026-04-30 18:28:43 +02:00
.cursorignore Build system 2025-05-05 17:58:19 +02:00
.gitattributes Various fixes 2021-02-11 22:51:56 +04:00
.gitignore Update gitignore 2026-05-20 00:34:25 +08:00
.gitlab-ci.yml Update CI 2026-05-26 23:24:45 +02:00
.gitmodules Update submodules 2026-02-23 11:17:26 +01:00
BUILD.bazel Temp 2026-03-13 09:00:55 +01:00
build_number_offset Fix chat title update 2026-02-10 10:52:53 +04:00
CLAUDE.md Optimize watch building 2026-05-28 02:45:47 +02:00
MODULE.bazel Extract tgcalls helpers into tgcalls 2026-04-30 22:13:55 +02:00
MODULE.bazel.lock Update instructions and fix build 2026-05-01 00:49:47 +02:00
Random.txt Trigger build 2026-04-07 21:44:48 +02:00
README.md Update readme 2023-10-07 00:32:58 +04:00
versions.json Bump version 2026-05-27 00:06:37 +02:00
WORKSPACE Cleanup 2025-05-17 02:34:15 +08:00

Telegram iOS Source Code Compilation Guide

We welcome all developers to use our API and source code to create applications on our platform. There are several things we require from all developers for the moment.

Creating your Telegram Application

  1. Obtain your own api_id for your application.
  2. Please do not use the name Telegram for your app — or make sure your users understand that it is unofficial.
  3. Kindly do not use our standard logo (white paper plane in a blue circle) as your app's logo.
  4. Please study our security guidelines and take good care of your users' data and privacy.
  5. Please remember to publish your code too in order to comply with the licences.

Quick Compilation Guide

Get the Code

git clone --recursive -j8 https://github.com/TelegramMessenger/Telegram-iOS.git

Setup Xcode

Install Xcode (directly from https://developer.apple.com/download/applications or using the App Store).

Adjust Configuration

  1. Generate a random identifier:
openssl rand -hex 8
  1. Create a new Xcode project. Use Telegram as the Product Name. Use org.{identifier from step 1} as the Organization Identifier.
  2. Open Keychain Access and navigate to Certificates. Locate Apple Development: your@email.address (XXXXXXXXXX) and double tap the certificate. Under Details, locate Organizational Unit. This is the Team ID.
  3. Edit build-system/template_minimal_development_configuration.json. Use data from the previous steps.

Generate an Xcode project

python3 build-system/Make/Make.py \
    --cacheDir="$HOME/telegram-bazel-cache" \
    generateProject \
    --configurationPath=build-system/template_minimal_development_configuration.json \
    --xcodeManagedCodesigning

Advanced Compilation Guide

Xcode

  1. Copy and edit build-system/appstore-configuration.json.
  2. Copy build-system/fake-codesigning. Create and download provisioning profiles, using the profiles folder as a reference for the entitlements.
  3. Generate an Xcode project:
python3 build-system/Make/Make.py \
    --cacheDir="$HOME/telegram-bazel-cache" \
    generateProject \
    --configurationPath=configuration_from_step_1.json \
    --codesigningInformationPath=directory_from_step_2

IPA

  1. Repeat the steps from the previous section. Use distribution provisioning profiles.
  2. Run:
python3 build-system/Make/Make.py \
    --cacheDir="$HOME/telegram-bazel-cache" \
    build \
    --configurationPath=...see previous section... \
    --codesigningInformationPath=...see previous section... \
    --buildNumber=100001 \
    --configuration=release_arm64

FAQ

Xcode is stuck at "build-request.json not updated yet"

Occasionally, you might observe the following message in your build log:

"/Users/xxx/Library/Developer/Xcode/DerivedData/Telegram-xxx/Build/Intermediates.noindex/XCBuildData/xxx.xcbuilddata/build-request.json" not updated yet, waiting...

Should this occur, simply cancel the ongoing build and initiate a new one.

Telegram_xcodeproj: no such package

Following a system restart, the auto-generated Xcode project might encounter a build failure accompanied by this error:

ERROR: Skipping '@rules_xcodeproj_generated//generator/Telegram/Telegram_xcodeproj:Telegram_xcodeproj': no such package '@rules_xcodeproj_generated//generator/Telegram/Telegram_xcodeproj': BUILD file not found in directory 'generator/Telegram/Telegram_xcodeproj' of external repository @rules_xcodeproj_generated. Add a BUILD file to a directory to mark it as a package.

If you encounter this issue, re-run the project generation steps in the README.

Tips

Codesigning is not required for simulator-only builds

Add --disableProvisioningProfiles:

python3 build-system/Make/Make.py \
    --cacheDir="$HOME/telegram-bazel-cache" \
    generateProject \
    --configurationPath=path-to-configuration.json \
    --codesigningInformationPath=path-to-provisioning-data \
    --disableProvisioningProfiles

Versions

Each release is built using a specific Xcode version (see versions.json). The helper script checks the versions of the installed software and reports an error if they don't match the ones specified in versions.json. It is possible to bypass these checks:

python3 build-system/Make/Make.py --overrideXcodeVersion build ... # Don't check the version of Xcode