771 Commits
Author SHA1 Message Date
isaacandClaude Opus 4.8 0050cc7a08 Rich-message media in gallery/shared-media/preview pipelines via Message.effectiveMedia
Add Message/EngineMessage.effectiveMedia (= message.media when non-empty, else
richText.instantPage.allMedia()) and route the media-consuming sites through it
so a rich message's instant-page media participates in the same pipelines as
normal message.media: shared-media grids/file-rows, search media grid, gallery
open + item nodes + footer, the peer audio/voice playlist, secret-media preview,
resource-by-id resolution, recent downloads, downloaded-media store, delete-time
resource cleanup, cache-usage stats, the in-chat download manager, and the
context-menu / share actions (Save to Camera Roll, copy image, save audio/music
to files). For normal messages effectiveMedia == message.media, so each swap is
behavior-preserving; rich messages render their own bubble via
ChatMessageRichDataBubbleContentNode (not the text/file bubbles), so those paths
are deliberately untouched, as are the forward path (the attribute travels with
the forward) and the markdown-based rich-edit path. First-media scope for now.

See docs/instantpage-richtext.md for the full architecture + invariants.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-04 23:46:56 +02:00
isaacandClaude Opus 4.8 c95e014681 InstantPage rich messages: index embedded media into shared-media tags
Add InstantPage.allMedia() (recursive gatherer over the page's blocks —
audio/collage/cover/details/image/list/slideshow/video — resolving each via
the page's [MediaId: Media] dict) and feed it into tagsForStoreMessage, so a
rich message's instant-page media is indexed into MessageTags
(photo/photoOrVideo/video/gif/voice/file). Rich messages now appear in the
per-peer shared-media tabs and tag-queried surfaces.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-04 23:46:16 +02:00
isaacandClaude Opus 4.8 dce6a8bef7 Rich messages: "Show more" to load the full page for partial InstantPages
Server-sent rich messages can arrive partial (RichMessage isPartial ->
instantPage.isComplete == false). The bubble renders the partial page with
an inline "Show more" link; tapping it fetches the full page once and
expands in place.

- RichTextMessageAttribute keeps the partial instantPage and gains an
  optional fullInstantPage, filled by engine.messages.requestFullRichText
  via transaction.updateMessage. The seed-config merge preserves a fetched
  fullInstantPage across later server updates.
- ChatMessageRichDataBubbleContentNode: node-local, per-message expand
  state (collapsed on every fresh display, even when fullInstantPage is
  already cached); renders (expanded ? fullInstantPage : nil) ?? instantPage;
  gates the link on !expanded && !isComplete (+ not streaming, Cloud-only,
  not preview/messageOptions); expand state threaded through both layout
  caches; shimmer while fetching (instant when cached); bubble grows
  downward on expand via setInvertOffsetDirection.
- New localized string Chat.RichText.ShowMore; docs in
  docs/instantpage-richtext.md.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-04 20:18:15 +02:00
isaac a5825d5a67 Rich text wip 2026-06-04 15:54:27 +02:00
isaacandClaude Opus 4.8 a731f8bdc0 Implement textDate autoformatter for InstantPage V2 rich bubbles
Render RichText.textDate (API constructor textDate(flags, text, date)) as a
locale/timezone-correct, relative-aware, tappable date inside V2 rich-message
bubbles, reusing the existing stringForEntityFormattedDate autoformatter.

- Model: add RichText.textDate(text:date:format:) with Postbox coding,
  FlatBuffers schema (RichText.fbs; flatc regenerates), Equatable and plainText;
  parse flags->DateTimeFormat? at the API boundary (flags==0 => nil, matching
  the messageEntityFormattedDate convention) with a symmetric apiRichText()
  round-trip. The new case is handled in every exhaustive RichText switch
  (SyncCore, ApiUtils, InstantPageTextItem, InstantPageAnchorPath,
  InstantPagePreviewText, BrowserReadability, BrowserMarkdown).
- Render: attributedStringForRichText gains an optional formatDate closure;
  the V2 layout builds it from the message's strings/dateTimeFormat and threads
  it to every text-building call site, formatting the timestamp and tagging the
  run with TelegramTextAttributes.Date.
- Tappable: the Date attribute is added to linkSelectionRects hit-testing and
  mapped in the rich bubble's entityTapContent to the existing .date tap action
  (opens the date context menu).
- Live update: the V2 layout accumulates a page-wide formattedDateUpdatePeriod
  (>=10s) for relative dates; the rich bubble schedules a refresh timer on it,
  recreating it only when the period changes. The currentPageLayout cache is
  bypassed for relative-date pages so the timer-driven relayout actually
  re-formats the date.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-04 13:45:48 +02:00
isaacandClaude Opus 4.8 354e1c7a66 Implement InstantPageBlock.thinking (pageBlockThinking) parsing & serialization
Add a first-class InstantPageBlock.thinking(RichText) case mirroring .kicker:
- enum case + InstantPageBlockType.thinking = 30; Postbox coding & equality
- FlatBuffers InstantPageBlock_Thinking schema (appended last) + Swift codecs
- API parse at InstantPage.swift; output-only on send (apiInputBlock returns nil)
- no-op stubs in the two exhaustive switches (preview text, V2 layout)

Rendering is out of scope. Verified by a full Bazel build.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-29 16:07:09 +02:00
Ilya Laktyushin 4b2a826682 Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2026-05-29 10:01:53 +02:00
Ilya Laktyushin e0f4655cc5 Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2026-05-29 09:24:16 +02:00
isaacandClaude Opus 4.8 28763bb92d InstantPage blockQuote: nested-blocks payload
Upgrade InstantPageBlock.blockQuote from (text, caption) to
(blocks: [InstantPageBlock], caption). Legacy inbound shapes (API
pageBlockBlockquote, Postbox "t", FlatBuffers text) lift into
[.paragraph(text)]; outbound stays on the legacy wire constructor for
empty/single-paragraph quotes and uses pageBlockBlockquoteBlocks
otherwise. V1/V2 renderers recurse into child blocks with a fixed 10pt
inter-child gap; markdown forward/reverse, entity-expressibility, and
preview text updated. pullQuote is unchanged.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-29 01:00:47 +02:00
Mikhail Filimonov 366b85f770 guard bots 2026-05-28 15:17:57 +01:00
Ilya Laktyushin 21d5b4879b Various fixes 2026-05-27 19:05:44 +02:00
isaacandClaude Opus 4.7 81e3be1923 InstantPage list checkboxes (task-list style): parse, serialize, render
Add a first-class `checked: Bool?` to InstantPageListItem (orthogonal to the
ordered-list `num`), replacing the prior sentinel-string-in-num prototype.

- Data model: enum third associated value on .text/.blocks; Postbox + a new
  FlatBuffers `checkState` tri-state field (0=nil,1=unchecked,2=checked,
  backward-compatible); Equatable.
- Transmission: read/write the native API `checkbox`=flags.0 / `checked`=flags.1
  bits on all four PageListItem / PageListOrderedItem constructors, so checkbox
  state survives the server round-trip for sender and recipients.
- Markdown: forward parser routes detected `[ ]`/`[x]` into `checked` (keeping
  the real number for ordered items); reverse converter emits `- [ ]`/`- [x]`
  so editing a rich message round-trips.
- Display: V1 + V2 layout detect via `item.checked`; the V2 renderer draws real
  CheckNode artwork (was a placeholder); preview text shows a checkbox glyph
  instead of leaking the old sentinel.

Spec: docs/superpowers/specs/2026-05-27-instantpage-list-checkbox-design.md
Plan: docs/superpowers/plans/2026-05-27-instantpage-list-checkbox.md

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-27 16:44:47 +02:00
isaacandClaude Opus 4.7 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
isaacandClaude Opus 4.7 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
isaacandClaude Opus 4.7 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 3f09a1f325 WIP 2026-05-20 00:34:25 +08:00
isaac 13a153aff2 WIP 2026-05-20 00:33:08 +08:00
Ilya Laktyushin 91eb779ae2 Merge commit 'c64653ed37ce9fe2bc74e260e9e960fcf3ab5dc1' 2026-05-14 12:45:26 +02:00
Ilya Laktyushin 7a7333edab Various improvements 2026-05-05 14:57:06 +02:00
isaacandClaude Opus 4.7 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
Ilya Laktyushin d212968040 Update API 2026-04-28 20:35:06 +02:00
Ilya Laktyushin d574182374 Markdown improvements 2026-04-27 18:45:30 +02:00
Ilya Laktyushin f41630083a Various improvements 2026-04-24 03:16:14 +02:00
isaac f77eafacff Merge commit 'f185b602ea2769502268be6c3b2703d01ed179e4' 2026-04-22 00:32:48 +04:00
isaac 524c29cbe3 Various improvements 2026-04-22 00:32:34 +04:00
Mikhail Filimonov fe6836ab02 flag 2026-04-21 12:11:11 +01:00
IsaacandClaude Opus 4.7 d01bbc6529 TelegramCore: edit/delete AI text styles + AI webpage attribute
Adds TelegramEngine.Messages.editAITextStyle and deleteAITextStyle
facades and decodes webPageAttributeAiComposeTone into a new
TelegramMediaWebpageAITextStyleAttribute. Makes CloudStyle.prompt
optional and requires emojiFileId on create.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-19 23:45:18 +02:00
Isaac bf21bca206 Merge commit '31e3a7dc79a91d78d9dda66945f81c9fc3d62b8e'
# Conflicts:
#	submodules/TelegramCore/Sources/PendingMessages/PendingMessageUploadedContent.swift
#	submodules/TelegramCore/Sources/TelegramEngine/Messages/Polls.swift
#	submodules/TelegramCore/Sources/TelegramEngine/Messages/Translate.swift
2026-04-16 17:52:38 +02:00
Ilya Laktyushin 0df319742a Update API 2026-04-16 01:18:22 +02:00
Isaac 0095bfad39 Temp 2026-04-15 13:18:46 +02:00
Ilya Laktyushin 22df2dbdb9 Various fixes 2026-04-14 03:33:34 +02:00
Ilya Laktyushin f160fb99d9 Various improvements 2026-03-29 16:23:09 +02:00
Mikhail Filimonov 3c4af77ad2 Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2026-03-27 16:18:49 +01:00
Mikhail Filimonov b5973fed13 canManageBots flag 2026-03-27 16:18:42 +01:00
Isaac 2907ddbe46 Unseen polls 2026-03-27 18:30:01 +08:00
Ilya Laktyushin 6b6ba070c7 Update API 2026-03-26 09:26:15 +01:00
Mikhail Filimonov 010945d371 Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2026-03-24 09:26:24 +01:00
Mikhail Filimonov 84bc40e1f8 polls 2026-03-24 09:26:16 +01:00
Isaac 9c0e6f6151 Merge commit 'e11c9899e63f71ebd75986b792eb94a1b7754574' 2026-03-24 01:39:57 +08:00
Isaac 1a17e97a7c Temp 2026-03-23 23:37:31 +08:00
Ilya Laktyushin e11c9899e6 Various fixes 2026-03-23 15:03:50 +01:00
Mikhail Filimonov 7354bea3e6 pass iscreator 2026-03-23 10:45:34 +01:00
Ilya Laktyushin 5ed2f0ad1e Various fixes 2026-03-23 00:17:18 +01:00
Ilya Laktyushin 676f46d44d Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2026-03-20 12:48:12 +01:00
Ilya Laktyushin 34f5b9d4c2 Update API 2026-03-20 12:48:05 +01:00
Isaac 2c10093c5e Merge commit '1a08c3f0d0cab7b971ec737181d9f400731f2129'
# Conflicts:
#	submodules/TelegramCore/Sources/ApiUtils/StoreMessage_Telegram.swift
2026-03-18 00:27:47 +01:00
Isaac a2d5c530a5 Various improvements 2026-03-18 00:27:13 +01:00
Ilya Laktyushin 6519b5c84d [WIP] Polls 2026-03-17 11:12:58 +01:00
Ilya Laktyushin 2b9d97b944 Update API 2026-03-17 00:04:50 +01:00
Ilya Laktyushin b1a190f87a [WIP] Polls 2026-03-16 18:07:12 +01:00