Telegram github commits and releases
4.55K subscribers
601 files
20.3K links
Broadcast from the most important Telegram clients' repositories
Download Telegram
morethanwords/tweb/masterb6d3b0510 files, +281/-15
Support chat-specific hashtag and cashtag search

morethanwords/tweb/master293cb458 files, +233/-9
Stop a stalled spoiler renderer from bricking a chat

A chat with a media spoiler in it could become permanently impossible to open:
the container went active but the topbar and input kept their `hide` class, the
bubbles stayed in a detached `chatInner`, and nothing was logged anywhere.

The chain started at the shader fetch. `DotRendererCore.shaderTexts[url] ??= fetch(url)`
memoized the request forever, so once it stalled every later attempt inherited the
same dead promise; `init()` memoized its failure the same way. The worker only posts
`media-inited` after `init()` resolves, so `DotRenderer.mediaWorkerReady` — a static
deferred, with `mediaInited` latched true and no retry — stayed pending for the rest
of the session. `wrapMediaSpoiler` awaits it, so that bubble's render promise never
settled, and `processBatch`'s `Promise.all(...).catch(noop)` waited on it forever:
`.catch` covers a rejection, never an answer that simply does not arrive. Behind it
queued `performHistoryResult` and then `Chat.setPeerPromise`, and `setPeer`'s early
return on a pending `setPeerPromise` turned every retry into a silent no-op.

Bound each step so no single stuck promise can latch permanently:

* never memoize a failed shader fetch or a failed `init()`, and give the fetch a
timeout, so the next spoiler retries instead of inheriting a dead promise
* give up on the worker's `*-inited` answer after a deadline: resolve the deferred
(the spoiler degrades to its blurred thumbnail, which still covers the media) and
unlatch `*Inited` so the next spoiler re-sends the init
* bound `wrapMediaSpoiler`'s wait on the dot canvas — it is decoration on top of an
already-covering thumbnail and must never hold up the message batch
* bound the batch's media `Promise.all`; the bubbles are already built, so at worst
some media finishes loading after mount instead of before it
* expire the in-flight peer-change dedupe, so an abandoned change stops swallowing
every attempt to reopen the chat

Also fixes a null deref in `replaceSharedMediaTab`, which threw on `tab.container`
when both the previous tab and the new one were undefined, aborting the peer change
that called it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

morethanwords/tweb/master12fbb852 files, +119/-2
Isolate fastRaf callbacks so one throw cannot poison the batch

Callbacks batched into a single frame are unrelated to each other, but `fastRaf`
ran them with a bare `forEach`, so the first one to throw cancelled every callback
queued behind it. `fastRafPromise` resolves from a callback queued in exactly that
way and caches its promise in a module-level variable that is only cleared once the
promise resolves — losing that resolve leaves it pending forever, and every later
`fastRafPromise()` hands out the same dead promise. Awaiting one is enough to park
a render path for the lifetime of the tab, silently.

`fastRafConventional` had the same hazard with an extra edge: a throw escaping its
loop also left the queue non-empty and `processing` stuck true, degrading every
later call to synchronous execution.

Run each callback in isolation and log what it threw, so a broken callback fails
alone instead of taking the frame's other work with it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

#webk
🫡3
morethanwords/tweb/master12718821 files, +8/-8
Stop a read receipt from leaving two check marks on one message

An outgoing message in a group could end up rendering its sent and its read
status side by side — "18:11 ✓✓ ✓" — with the thread reply counter that used to
sit next to them gone.

setBubbleSendingStatus asked whether a status was already there with a
descendant query (`element.querySelector('.time-sending-status')`) but then
wrote over `element.firstElementChild`, which is only the same node while
nothing has been prepended in front of it. setBubbleRepliesCount prepends
exactly there: a message that gains its first thread reply after its bubble was
rendered gets `.time-replies` pushed ahead of the status. The next status change
— the read receipt — then replaced the counter instead of the old icon, and the
old icon stayed. Both carry `order: 5` against the time's `0`, so they line up
after the time in DOM order, newest first. The `!status` branch had the mirror
of the same bug: it removed the first child and left the status alone.

The two lookups now name the node they intend to touch, so a status replaces a
status and a missing one is prepended. setBubbleRepliesCount gets the same
direct-child scope: once the status bug had eaten the outer `.time`'s counter,
its descendant query found the copy inside `.time-inner`, concluded the counter
was already mounted and never restored it — leaving the hidden spacer that
reserves the footer's width one element short of what is drawn.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

morethanwords/tweb/mastera5a90e74 files, +64/-2
Keep tag search input focused

#webk
🫡3
morethanwords/tweb/master3501e7611 files, +107/-23
Take a frame's url and height as input rather than at face value

Three values a hosted frame — a mini app, a payment provider, an Instant View
embed — hands the client were used as given.

`path_full` from a `web_app_open_tg_link` event was pasted onto the bare host,
so a value that does not open with a slash landed in the host instead of the
path: '.evil.com/x' built https://t.me.evil.com/x. It walks out of the
registrable domain but not out of the client, because wrapUrl's t.me regexp is
not anchored at its end and matches the result anyway, handing it to the `im`
handler, which reads the parsed path and never the href — so the link opens a
username. Both call sites build it through `getWebViewTgLink` now, which anchors
the path.

`resize_frame` from an Instant View embed set the block height with no ceiling.
The event is the embed's own way of asking for the room its content needs, and
the document that sends it is third party by definition — after a navigation
away, not even the one the block asked for — so the height is capped at four
viewports.

`keyboardButtonUrlAuth.url` reached `window.open()` raw, the one url in the
client that skipped `safeWindowOpen`; the server rejects a non-https button url
today, which is what kept it out of reach. Its local `openWindow` wrapper is
gone. The helper it now shares, meanwhile, repeated wrapUrl's protocol filter
for none of its callers, and most of them pass a url straight off the wire — a
web app event, a gift's listing url, a bot's privacy policy. The filter lives in
`normalizeUrlProtocol` and runs there too, replacing the three hand-rolled
copies of it.

Untouched: the bridge still authorizes an inbound message by WindowProxy
identity alone unless the server asked for `same_origin`, and still answers a
frame it is not bound to at '*'. Binding it by default would break the
cross-origin hops the opt-in exists to permit — a 3DS redirect, an OAuth leg.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

#webk
🫡3
UnigramDev/Unigram/build-from-scratche4c521d4 files, +113/-28
Give each vcpkg triplet its own install root

UnigramDev/Unigram/build-from-scratche7241051 files, +24/-2
Accept a separated -arch list in the TDLib build script

UnigramDev/Unigram/build-from-scratchc6662062 files, +24/-0
Name the npm command when editor.html is missing

UnigramDev/Unigram/build-from-scratchedba7a42 files, +13/-2
Restore packages.config projects from the build scripts

UnigramDev/Unigram/build-from-scratch1d275bb1 files, +2/-0
Build the native components before Telegram.Modern

UnigramDev/Unigram/build-from-scratch8d2a2ea1 files, +2/-1
Drop the Alternative manifest from an Original build

UnigramDev/Unigram/build-from-scratch022acc11 files, +18/-0
Package the language resource maps in the Modern bundle

UnigramDev/Unigram/build-from-scratch62fb3791 files, +14/-0
Scope the store build mode to the packaging project

UnigramDev/Unigram/build-from-scratch1e1054811 files, +16/-22
Keep one signing certificate at the repository root

UnigramDev/Unigram/build-from-scratch0b2c1991 files, +1/-1
Point Build.ps1 at the renamed solution

UnigramDev/Unigram/build-from-scratchd878c1d1 files, +0/-4
Stop warning that ARM64 has never been through ILC

UnigramDev/Unigram/build-from-scratchbcfb2e92 files, +15/-12
Record what the from-scratch build verified

#unigram
🫡2
UnigramDev/Unigram/build-from-scratcha0da4142 files, +13/-2
Restore packages.config projects from the build scripts

UnigramDev/Unigram/build-from-scratch32e629c1 files, +2/-0
Build the native components before Telegram.Modern

UnigramDev/Unigram/build-from-scratch3200fb61 files, +2/-1
Drop the Alternative manifest from an Original build

UnigramDev/Unigram/build-from-scratchb41af381 files, +18/-0
Package the language resource maps in the Modern bundle

UnigramDev/Unigram/build-from-scratch03ebf6a1 files, +14/-0
Scope the store build mode to the packaging project

UnigramDev/Unigram/build-from-scratch36ffdcd11 files, +16/-22
Keep one signing certificate at the repository root

UnigramDev/Unigram/build-from-scratch37a822a1 files, +1/-1
Point Build.ps1 at the renamed solution

UnigramDev/Unigram/build-from-scratch3bdfcd81 files, +0/-4
Stop warning that ARM64 has never been through ILC

UnigramDev/Unigram/build-from-scratch8587bfd2 files, +15/-12
Record what the from-scratch build verified

UnigramDev/Unigram/build-from-scratch11424be4 files, +411/-1
Check in the assembled editor.html

#unigram
🫡1
telegramdesktop/tdesktop/public-canarye547b2b1 files, +29/-1
Fixed missing ATL breaking breakpad build in canary Windows job.

#tdesktop
🫡3
UnigramDev/Unigram/group-call-participants6c609077 files, +510/-383
Split group call participants into a model and a windowed view

#unigram
UnigramDev/Unigram/streaming-download-buttons3dc54fc14 files, +112/-112
Rename MessageContentState to FileButtonState

UnigramDev/Unigram/streaming-download-buttons244c0bf3 files, +73/-0
Track the files a reader is streaming

UnigramDev/Unigram/streaming-download-buttonsf09c9d314 files, +197/-138
Hide a download that only feeds a reader from the file buttons

#unigram
UnigramDev/Unigram/group-call-participantseed9d177 files, +510/-382
Split group call participants into a model and a windowed view

#unigram
UnigramDev/Unigram/animatedimage-imagesourcef1e08a61 files, +46/-30
Read the animated frame from the presenter, not from ImageBrush.ImageSource

#unigram
UnigramDev/Unigram/developa769cb224 files, +56/-0
TEMP: trace LoadMoreItemsAsync

UnigramDev/Unigram/developb6e32f94 files, +113/-28
Give each vcpkg triplet its own install root

UnigramDev/Unigram/developff1820e1 files, +24/-2
Accept a separated -arch list in the TDLib build script

UnigramDev/Unigram/develop811b1f82 files, +13/-2
Restore packages.config projects from the build scripts

UnigramDev/Unigram/develop7a64fb41 files, +2/-0
Build the native components before Telegram.Modern

UnigramDev/Unigram/developed6cffa1 files, +2/-1
Drop the Alternative manifest from an Original build

UnigramDev/Unigram/develop910d6791 files, +18/-0
Package the language resource maps in the Modern bundle

UnigramDev/Unigram/develop6a15dea1 files, +14/-0
Scope the store build mode to the packaging project

UnigramDev/Unigram/develop306b59011 files, +16/-22
Keep one signing certificate at the repository root

UnigramDev/Unigram/develop0b0d0ac1 files, +1/-1
Point Build.ps1 at the renamed solution

UnigramDev/Unigram/developb7523df1 files, +0/-4
Stop warning that ARM64 has never been through ILC

UnigramDev/Unigram/developc2d4d342 files, +15/-12
Record what the from-scratch build verified

UnigramDev/Unigram/develop08ea0a14 files, +411/-1
Check in the assembled editor.html

#unigram
telegramdesktop/tdesktop/devaef8afe4 files, +247/-106
Moved out corner status from view gif to separated module.

telegramdesktop/tdesktop/dev4c2bde65 files, +169/-71
Moved out video message seek ring from view gif to separated module.

telegramdesktop/tdesktop/devd0c45c85 files, +205/-46
Added seek ring with handle to paused video messages.

telegramdesktop/tdesktop/dev59442864 files, +101/-15
Added frame preview while seeking in video messages.

telegramdesktop/tdesktop/devfdf96618 files, +1143/-14
[iv-editor] Added slash menu with list of insertable blocks.

telegramdesktop/tdesktop/dev47d26f32 files, +24/-1
[iv-editor] Added caret restore after inline button and formula edit.

Related commits: 3cb72867d6, 6b970dfee9.

telegramdesktop/tdesktop/dev5291c5c2 files, +68/-5
[iv-editor] Added restore of trimmed spaces on inline field commit.

Related commit: 4ddd36665b.

telegramdesktop/tdesktop/dev838c6ca1 files, +1/-1
Fixed macOS libraries prune dropping pkg-config files for FFmpeg build.

telegramdesktop/tdesktop/devb9255282 files, +54/-0
Added cache of participant ban state to chat participants API.

telegramdesktop/tdesktop/dev52cd64b2 files, +53/-0
Added ban and unban of monoforum peer to sublist menus.

telegramdesktop/tdesktop/dev8c53eef3 files, +25/-0
[thanos] Fixed lost collapse animation on delete in new chat view.

telegramdesktop/tdesktop/dev5a507f51 files, +21/-0
[thanos] Moved collapse gaps with content in history view list widget.

telegramdesktop/tdesktop/dev36f43911 files, +3/-0
[thanos] Added scroll pin after list resize during collapse.

#tdesktop
🫡3
telegramdesktop/tdesktop/dev3f6639c1 files, +1/-1
[thanos] Replaced direct scroll with syntetic one during collapse.

telegramdesktop/tdesktop/dev0ea3ac93 files, +8/-1
[thanos] Fixed lost collapse for all but first of deleted messages.

telegramdesktop/tdesktop/dev00cb5fd4 files, +75/-43
[thanos] Replaced assumed collapse gap height with measured one.

telegramdesktop/tdesktop/devad1e5671 files, +20/-1
Fixed rich paste toast offering editor for plain text lists.

Related commit: 98591aa959.

telegramdesktop/tdesktop/dev415efce5 files, +37/-24
Fixed rich paste toast offering formatting restore for markdown.

Related commit: 3605382c0d.

telegramdesktop/tdesktop/devc6370871 files, +1/-1
Replaced bold with italic for double underscore in markdown import.

Related commit: 4076184532.

telegramdesktop/tdesktop/deva2f030a7 files, +181/-45
Added offer to apply pasted markdown in message field.

Related commit: 3605382c0d.

telegramdesktop/tdesktop/dev6c10c0a2 files, +98/-66
Replaced paint flag with single action for Gif icon and click.

Related commit: 41985c0a5f.

telegramdesktop/tdesktop/devc5c3f4a2 files, +0/-7
Fix chat closing and removing from list on restricted self receive.

I hope this fixes #31172, fixes #31174.

#tdesktop
🫡3
telegramdesktop/tdesktop/devcb817841 files, +1/-1
Added deferral of back click handling in history view top bar widget.

telegramdesktop/tdesktop/dev97367901 files, +3/-0
Fixed slide animation swallowing back clicks in chat section.

telegramdesktop/tdesktop/devea53b551 files, +1/-1
Added marking as read on Enter with empty field in chat section.

Related commit: b978bc4876.

telegramdesktop/tdesktop/devb8126b92 files, +34/-21
Added marking as read on Enter without compose field in chat section.

Related commit: b978bc4876.

#tdesktop
🫡3
telegramdesktop/tdesktop/public-canarya793d4c1 files, +50/-20
Install ATL for the pinned Windows toolset

#tdesktop
🫡3
UnigramDev/Unigram/develop31264421 files, +4/-4
Guard for disconnected window

UnigramDev/Unigram/developf70ee903 files, +67/-39
Safely cast to ICompositionVisualSurfacePartner

UnigramDev/Unigram/develop466e8af1 files, +1/-1
Pass the right xaml root to gallery

UnigramDev/Unigram/develop9a289f81 files, +17/-8
Fix share window initialization

UnigramDev/Unigram/develop3baac566 files, +560/-22
Make the Win32 window answer for what a UWP one does

UnigramDev/Unigram/develop35d5a166 files, +292/-3
Put Mica behind the Win32 windows

UnigramDev/Unigram/developec1089f1 files, +4/-0
Translate more errors

#unigram
UnigramDev/Unigram/animatedimage-imagesourceb85ce691 files, +42/-26
Hand the frame geometry over instead of the buffer

#unigram
telegramdesktop/tdesktop/public-canary0cbbae83 files, +0/-0
Delete unused account_check icon rasters

Task: 2026/08/18/delete-orphaned-account-check-icon

telegramdesktop/tdesktop/public-canary980ea852 files, +11/-2
Correct shared media index writes and viewer counts

Task: 2026/08/18/repair-shared-media-index-and-count-bookkeeping

telegramdesktop/tdesktop/public-canaryc161ac61 files, +16/-3
Re-index a sent message only when its thread moves

Task: 2026/08/18/repair-shared-media-index-and-count-bookkeeping

telegramdesktop/tdesktop/public-canary03fe6f32 files, +60/-6
Derive the pinned bar's topic root from the thread

Task: 2026/08/19/align-replies-thread-shared-media-attribution

telegramdesktop/tdesktop/public-canaryd0c1c032 files, +1/-1
Pair the uploaded media edit's shared media removal

Task: 2026/08/19/pair-media-edit-removal-with-index-add

telegramdesktop/tdesktop/public-canary7802c831 files, +20/-5
Drop a sent message from the shared media lists it left

Task: 2026/08/19/match-sent-message-removal-to-written-mask

telegramdesktop/tdesktop/public-canary64940be1 files, +3/-3
Don't keep a media reference across rich page changes

Task: 2026/08/19/refetch-saved-media-after-rich-page-changes

telegramdesktop/tdesktop/public-canaryc9d3ebc5 files, +30/-13
Don't lower shared media counts for unindexed messages

Task: 2026/08/20/stop-unmatched-removal-lowering-shared-media-counts

telegramdesktop/tdesktop/public-canary55ec45c7 files, +40/-56
Tie stored pinned index writes to the pinned flag

Task: 2026/08/19/unify-pinned-index-writers

telegramdesktop/tdesktop/public-canary2c01caa2 files, +52/-1
Write the pinned thread index only in forum peers

Task: 2026/08/20/stop-orphaning-general-id-shared-media-lists

telegramdesktop/tdesktop/public-canaryc001c722 files, +5/-2
Give a saved sublist its own pinned message list

Task: 2026/08/19/make-saved-sublist-pinned-bar-read-one-list

#tdesktop
🫡3
telegramdesktop/tdesktop/public-canary1848f291 files, +6/-0
Retire shared media of a deleted topic with no object

Task: 2026/08/20/retire-forum-media-lists-without-topic-objects

telegramdesktop/tdesktop/public-canary6464b815 files, +31/-0
Retire all topic shared media when a forum is destroyed

Task: 2026/08/20/retire-stranded-forum-media-keys-on-forum-teardown

telegramdesktop/tdesktop/public-canarya55a9291 files, +6/-4
Guard the live-topic media unload against a zero root

Task: 2026/08/20/guard-live-topic-unload-against-zero-root

telegramdesktop/tdesktop/public-canary2833aba1 files, +6/-4
Guard the forum teardown media unload against a zero root

Task: 2026/08/20/guard-forum-teardown-unload-against-zero-root

telegramdesktop/tdesktop/public-canaryddd4ed12 files, +4/-4
Resolve the self peer sublist in the shared resolver

Task: 2026/08/20/resolve-self-peer-sublist-in-shared-resolver

telegramdesktop/tdesktop/public-canarycf34af62 files, +0/-2
Drop the write-only monoforum id from top controls

Task: 2026/08/20/retire-write-only-top-controls-monoforum-peer-id

telegramdesktop/tdesktop/public-canary679a20a1 files, +1/-1
Read the inbox when a sublist has no parent chat

Task: 2026/08/20/restore-read-inbox-on-parentless-sublist-send

telegramdesktop/tdesktop/public-canaryfff93ae1 files, +2/-8
Use the shared sublist resolver in the player panel

Task: 2026/08/20/collapse-player-panel-sublist-onto-shared-resolver

telegramdesktop/tdesktop/public-canary4f343be4 files, +35/-0
Request pinned messages when a pin is not loaded

Task: 2026/08/20/reach-unloaded-pin-on-complete-pinned-slice

telegramdesktop/tdesktop/public-canary36367696 files, +21/-10
Open a saved sublist's own shared media page

Task: 2026/08/20/open-saved-sublist-own-info-media-page

#tdesktop
🫡3
telegramdesktop/tdesktop/public-canary43d9b1a9 files, +63/-43
Align sublist media count, query and window keys

Task: 2026/08/21/align-sublist-media-count-query-and-window-keys

telegramdesktop/tdesktop/public-canary2ac8f4d4 files, +55/-3
Keep Info pages on their topic or sublist

Task: 2026/08/21/preserve-info-thread-identity-and-lifetime

telegramdesktop/tdesktop/public-canary8f706531 files, +12/-10
Tear down Info after a sublist is destroyed

Task: 2026/08/21/preserve-info-thread-identity-and-lifetime

telegramdesktop/tdesktop/public-canary9f2b4511 files, +14/-12
Clear Info immediately when its sublist dies

Task: 2026/08/21/preserve-info-thread-identity-and-lifetime

telegramdesktop/tdesktop/public-canary15d31621 files, +9/-13
Always drop an Info wrap when its sublist dies

Task: 2026/08/21/preserve-info-thread-identity-and-lifetime

telegramdesktop/tdesktop/public-canary392e20d6 files, +90/-34
Reach unloaded pins on thread keys and updates

Task: 2026/08/21/reach-unloaded-pins-across-thread-and-update-paths

telegramdesktop/tdesktop/public-canarya8e41c83 files, +11/-4
Rebind Info wrap teardown when a sublist is replaced

Task: 2026/08/21/resubscribe-info-wrap-teardown-on-replaced-sublist

telegramdesktop/tdesktop/public-canarydc3edf32 files, +14/-10
Tear down Layer Info instantly when its sublist dies

Task: 2026/08/21/resubscribe-info-wrap-teardown-on-replaced-sublist

telegramdesktop/tdesktop/public-canaryc6c538f2 files, +17/-14
Queue Info wrap teardown off sublist destroyed()

Task: 2026/08/21/resubscribe-info-wrap-teardown-on-replaced-sublist

telegramdesktop/tdesktop/public-canary2a7abec3 files, +19/-21
Hide Layer Info before its sublist is erased

Task: 2026/08/21/resubscribe-info-wrap-teardown-on-replaced-sublist

telegramdesktop/tdesktop/public-canary8b579dc2 files, +15/-18
Preserve teardown stream across Info wrap removal

Task: 2026/08/21/resubscribe-info-wrap-teardown-on-replaced-sublist

#tdesktop
🫡3
telegramdesktop/tdesktop/public-canarye6ffaa21 files, +0/-1
Remove stale Info teardown implementation note

Task: 2026/08/21/resubscribe-info-wrap-teardown-on-replaced-sublist

telegramdesktop/tdesktop/public-canarya4bb3611 files, +3/-2
Keep saved sublists alive through item teardown

Task: 2026/08/21/finish-info-wrap-sublist-teardown-past-item-destroy

telegramdesktop/tdesktop/public-canaryaed8ff54 files, +39/-20
Align sublist media counts, windows and titles

Task: 2026/08/21/align-sublist-media-count-window-and-title

telegramdesktop/tdesktop/public-canaryb8b2b2c1 files, +7/-5
Show the new window tooltip only on entries that have one

Task: 2026/08/23/verify-saved-sublist-media-surfaces-and-gate-tooltip

telegramdesktop/tdesktop/public-canaryd431e374 files, +90/-67
Unify sublist media window ids and persisted titles

Task: 2026/08/23/unify-sublist-separate-id-and-window-naming-rulings

telegramdesktop/tdesktop/public-canarycbc1eea3 files, +26/-7
[ai] Refuse implausible test watchdog values

Task: 2026/08/23/refuse-implausible-test-watchdog-values

telegramdesktop/tdesktop/public-canary47f965c1 files, +2/-2
Limit media topic context to forum chats

telegramdesktop/tdesktop/public-canaryc8ec5884 files, +7/-0
Add public keys for canary channel.

telegramdesktop/tdesktop/public-canaryc4a2f0a9 files, +1279/-0
Add v2 update verification core and build channels

telegramdesktop/tdesktop/public-canarye45bbea3 files, +672/-0
Support v2 channel packing in the Packer

telegramdesktop/tdesktop/public-canary2a39af07 files, +662/-141
Verify, fetch and install v2 updates in the client

telegramdesktop/tdesktop/public-canary267242a2 files, +9/-1
Show canary version and skip changelogs on canary

#tdesktop
🫡3