Telegram github commits and releases
4.54K subscribers
601 files
20.3K links
Broadcast from the most important Telegram clients' repositories
Download Telegram
telegramdesktop/tdesktop/dev1c1a5381 files, +15/-0
Fix accessible focus on filters refresh.

#tdesktop
🫡3
UnigramDev/Unigram/developff09a2f1 files, +1/-11
Undo style

UnigramDev/Unigram/develop9e4cc271 files, +5/-2
Fix null ref

UnigramDev/Unigram/develop9aa25503 files, +225/-17
Improve custom text selection

UnigramDev/Unigram/developb3099416 files, +52/-27
Break MessageSelector reference cycle

UnigramDev/Unigram/develop703b2fd11 files, +199/-85
Fix playback service unsubscribe

UnigramDev/Unigram/develop1188ad41 files, +8/-2
Access violation guard

UnigramDev/Unigram/develop9d86f1b9 files, +738/-298
Break FormattedTextBlock into pieces, add MessageTextBlock, support expandable quotes

UnigramDev/Unigram/develop8e4368b1 files, +17/-8
Fix text selection manager events registration

UnigramDev/Unigram/developf3a06d32 files, +29/-0
Add missing interface methods

UnigramDev/Unigram/develop1d66e252 files, +43/-3
Handle custom text selection in chat history

UnigramDev/Unigram/developdbfee715 files, +42/-74
Support translating formatted text

UnigramDev/Unigram/developdc5dd1d1 files, +21/-186
Improve quotes in rich messages

UnigramDev/Unigram/developaab94f72 files, +13/-5
Use new text block in gallery

UnigramDev/Unigram/develop333b44b1 files, +4/-1
Disable interactions on album children

UnigramDev/Unigram/develop19714bb1 files, +4/-0
Don't stackalloc in debug to avoid recompiling every time

#unigram
🫡2
TGX-Android/Telegram-X/maincea514d37 files, +2744/-318
Add `marshmallow` flavor

TGX-Android/Telegram-X/main6c144101 files, +8/-1
Sync `.gitignore` with `translations.telegram.org`

#tgxandroid
🫡3
morethanwords/tweb/masterceb516011 files, +19/-48
Address AI Editor review findings

- Fix: removing a saved tone was blocked at the saved-tones limit — the
ViewTonePopup unsave path fell through to Promise.reject(), showing an
error toast instead of unsaving. Allow unsave regardless of capacity.
- Bound the composed-message cache (was an unbounded module-level Map).
- Drop duplicate AICOMPOSE_*/TONE_NOT_FOUND literals in ServerErrorType.
- customEmoji renderer: pass the callback to unobserveResize so it removes
only its own resize callback (the new array-based observeResize allows
multiple callbacks per element).
- Remove dead code: simulateDelay/DEBUG scaffolding in styleTab, autoHeight
duration/easing props, inputFieldMessage containerRef prop, and the
byte-identical unused viewTonePopup/limits.ts.
- wrapRichText: wrap the messageEntityDiffReplace case body in a block.
- getMessageEntityFromDocIdOrEmoji: use the @lib alias import.
- lang: "Used by %d persons" -> "people".

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

morethanwords/tweb/masterea7e91b300 files, +15781/-2628
Merge branch 'master' into feature/ai-editor

Resolved conflicts:
- Icon font (icons.ts, _variables/_style.scss, tgico.svg/ttf/woff): kept the
PR's regenerated set so the new AI icons work. Re-added master's
`privacypolicy` glyph to icons.ts/_variables.scss as a placeholder
(codepoint eab3) so the tree builds — it renders blank until the icon font
is regenerated (`pnpm generate-icons`) from the union of SVG sources
(privacypolicy.svg + the AI icons are both present in assets/icons/).
- inputFieldMessage.tsx: union of imports (PR's AI-editor imports + master's
getOverlayRoot).

Production build passes.

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

morethanwords/tweb/master40846ea116 files, +6147/-1857
Merge pull request #665 from H7GhosT/feature/ai-editor

AI Editor

morethanwords/tweb/master3a0099f3 files, +3/-3
Merge pull request #676 from prdsrm/master

fix: update nodejs version #675

#webk
🫡3🤨1
TGX-Android/Telegram-X/main3bb31c215 files, +245/-152
Migrate to `Firebase Installation ID` on Android 6 (Marshmallow) and higher

#tgxandroid
🫡3
morethanwords/tweb/master29e12726 files, +351/-350
Regenerate icons

morethanwords/tweb/master3853912300 files, +934/-818
Build

#webk
🫡3
Ajaxy/telegram-tt/master2b0f5d93 files, +4/-4
12.0.31

Ajaxy/telegram-tt/master297afa41 files, +5/-2
Message List: Fix random scroll to bottom on open (#7055)

Ajaxy/telegram-tt/master5d4d2371 files, +5/-1
Bot: Hide info immediately when starting new chat (#7056)

Ajaxy/telegram-tt/master1dc28e32 files, +11/-3
Polls: Add line break for poll action messages (#7051)

Ajaxy/telegram-tt/master81ee4be34 files, +1444/-873
Poll: Support more creation options (#7033)

Ajaxy/telegram-tt/master72557c26 files, +91/-115
Poll Answer Results: Redesign (#7057)

Ajaxy/telegram-tt/masteracebf111 files, +12/-0
Media Viewer: Fix closing MV on Esc (#7062)

Ajaxy/telegram-tt/master46fa67810 files, +669/-0
Message: Support read metrics (#7060)

Ajaxy/telegram-tt/master78990981 files, +1/-0
Middle Column: Fix visibility after unlock (#7065)

Ajaxy/telegram-tt/master7f3f7ff4 files, +18/-10
Middle Header: Fix middle header panel styles (#7063)

Ajaxy/telegram-tt/masterd97d4da94 files, +207/-193
[Build]

#webz
🫡2
morethanwords/tweb/masteref8c3801 files, +2/-4
Merge branch 'feature/ai-editor' of github.com:H7GhosT/private-tweb into feature/ai-editor

morethanwords/tweb/master50bb529300 files, +10771/-2264
Merge branch 'master' into feature/ai-editor

morethanwords/tweb/masterd88da871 files, +2/-5
Change comment

morethanwords/tweb/masterc381bf71 files, +2/-2
Prevent EmojiDocumentIcon rerendering when color changes

morethanwords/tweb/master1d339ba5 files, +125/-49
Make inner content scrollable

morethanwords/tweb/masterdc3cec81 files, +1/-5
Change arrow bg hover color

morethanwords/tweb/master8b0c60e1 files, +5/-1
Fix skeleton color on light theme

morethanwords/tweb/mastere4d53642 files, +21/-4
Recompose message when editing currently selected tone

morethanwords/tweb/master299f8ab1 files, +8/-7
Move create style button to the end of the list

morethanwords/tweb/master8fedf413 files, +22/-3
Fade original and result scrollables edges when scrolled

morethanwords/tweb/master17438073 files, +17/-2
Hide thumb when original is collapsed

morethanwords/tweb/master68c84cc3 files, +6/-6
Show created by you in view tone popup

morethanwords/tweb/master4d9db4b2 files, +21/-25
Fix formatting

morethanwords/tweb/masterd25787e4 files, +128/-21
Add send menu to the send button

morethanwords/tweb/masterd3d34f319 files, +880/-684
Remake the translation popup to be like the AI Editor popup

#webk
🫡3
morethanwords/tweb/master7f76e503 files, +17/-8
Rethrow error for copyTextToClipboard

morethanwords/tweb/master3dfc6322 files, +0/-2
Remove unnecessary instance check

morethanwords/tweb/masterf15ee7b3 files, +16/-22
Small refactor. Fix Original's overlay fading when appearing first time

morethanwords/tweb/master0cf0e023 files, +69/-12
Add animation to scrollable's mask. Trigger onSizeChange when scrollable
is added to DOM.

morethanwords/tweb/master42815691 files, +7/-4
AI editor: don't leak composer's pending silent/schedule/effect into sends

getMessageSendingParams() carries the chat input's live silent/scheduleDate/
scheduleRepeatPeriod/effect (e.g. restored from a draft). The AI editor manages
these via its own send menu, so override them outright instead of merging —
otherwise a message sent from the editor inherits state the editor never showed.

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

morethanwords/tweb/masterf382c9932 files, +1260/-777
Merge pull request #678 from H7GhosT/feature/ai-editor

Ai Editor improvements

#webk
🫡3
morethanwords/tweb/mastere9ea7d01 files, +4/-0
Ignore clicks on pinned gifts when profile avatar is expanded

The pinned-gifts layer paints on top of the avatar and was only hidden
via opacity:0 when the header is expanded, which leaves it catching
clicks meant for the avatar underneath. Make it pointer-events:none in
the expanded state so clicks fall through to the avatar handler.

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

morethanwords/tweb/master0b2e4a51 files, +9/-2
Fix player menus invisible in fullscreen

Playback-rate / quality / live menus open via ButtonMenuToggle, which
portals the menu to document.body. While the player wrapper is the
fullscreen element the browser paints only its subtree (top layer), so a
menu in document.body never shows. Mount the menu inside the fullscreen
element when the trigger lives there; falls back to the overlay root
otherwise.

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

morethanwords/tweb/masterbc0fe183 files, +27/-19
Chat preview: apply per-chat theme to outgoing bubbles + fix bubble width

A preview Chat sets isPreview, so Chat.handleBackgrounds() short-circuits and
applyContainerTheme() never runs — the per-chat theme's outgoing-bubble vars
(--message-out-*) were missing on the container, so outgoing bubbles fell back
to the global :root palette ("theme only partially applied"). Apply the
resolved theme to the preview's chat container, re-firing on day/night toggle,
mirroring Chat._handleBackgrounds.

Also scope the bubbles scroll-area negative inset-inline rule to #column-center
so it no longer widens the preview popup's bubbles, and drop the now-redundant
inset-inline: 0 override in _chatPreview.scss.

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

morethanwords/tweb/master2010d643 files, +56/-0
Close global search and left-sidebar tabs when switching folders

Switching a chat folder now dismisses an open global search and closes any
stacked left-sidebar tabs, mirroring closeEverythingInside. Tabs close the
natural way (as if via the back arrow), so a tab that needs confirmation
still asks; if the user declines, the folder switch is cancelled. Both folder
UIs (the horizontal tabs and the vertical folders sidebar) funnel through
selectFolderByIndex, so a single hook covers both.

Adds SidebarSlider.closeAllTabsNaturally (close tabs top-down honoring each
tab's isConfirmationNeededOnClose) and AppSidebarLeft.closeEverythingInsideNaturally.

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

#webk
🫡3
morethanwords/tweb/masterd2322741 files, +10/-12
Fix voice waveform dropped for non-standard (62-byte) waveforms

decodeWaveform read each 5-bit sample via DataView.getUint16, which
over-reads one byte past the needed one. For a 62-byte / 99-sample
waveform the last sample's read landed out of bounds, threw a
RangeError, and the catch returned an empty array — so the whole
waveform silently failed to render (flat line). Standard 63-byte
waveforms have a spare trailing byte and happened to work.

Read the two bytes manually with a bounds-guarded high byte instead;
output is bit-identical for 63-byte waveforms and now correct for
shorter ones. Also fixes the latent byteOffset bug in the old
new DataView(waveform.buffer) on view-backed arrays.

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

morethanwords/tweb/master29ce0b65 files, +106/-16
Pause video avatars when not visible (incl. right sidebar closed)

Video avatars kept animating while off-screen and, notably, while sitting in
the right sidebar after it was slid closed — the column is hidden with a
transform but stays mounted, so an IntersectionObserver never reports it as
hidden.

- avatarNew: register avatar <video>s with animationIntersector instead of an
ad-hoc IntersectionObserver (pauses on off-screen / blur / idle / lite-mode,
resumes when visible, survives Document-PiP). Covers both the chat-list /
topbar overlay and the profile-carousel / service-bubble path, which had no
visibility gating at all.
- animationIntersector: add toggleVideosUnder(element, paused) to pause+lock
(or resume) every registered video inside a container.
- sidebarRight: pause/resume the column's avatar videos on hide()/show(), since
the transform-based hide is invisible to the observer.
- peerProfileAvatars: self-suspend the tab-progress rAF loop when the active
video isn't advancing (restart on a captured 'play' / carousel nav), and free
the carousel's registered videos on cleanup so a video locked while the
sidebar was closed can't leak when the profile is torn down.
- createLoopingMutedVideo: set autoplay only after the start-frame seek so the
clip isn't briefly flashed from frame 0.

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

morethanwords/tweb/master388a8b432 files, +1260/-777
Merge branch 'master' of https://github.com/morethanwords/tweb

#webk
🫡4
morethanwords/tweb/mastere8c9dca1 files, +2/-2
Skip post-send handling when no message was actually sent

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

morethanwords/tweb/master64efd761 files, +1/-1
Wrap long bot verification text in peer profile

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

morethanwords/tweb/master330ca411 files, +8/-1
Show profile Edit button for any admin, not only change_info

The Edit (pencil) button in group/channel info was gated solely on the
change_info right, so an admin who could manage members/permissions/admins
but lacked change_info couldn't reach the edit screen — even though that
screen already gates each section on its own rights and merely locks the
name field when change_info is missing.

Mirror tdesktop's EditPeerInfoBox::Available: show the button to any admin
(channel: just_admin || change_info, excluding monoforums; basic group:
change_info || change_permissions).

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

#webk
🫡4💅1
morethanwords/tweb/master6cb2df21 files, +2/-2
Don't append live messages to the pinned-messages view

The history_append/history_multiappend handlers guarded against the
Scheduled/Static/Logs chat types but not Pinned. The pinned view shares the
chat's messagesStorageKey and, once fully loaded, has loadedAll.bottom === true,
so a regular incoming message fell through every guard and got rendered as a
bubble in the pinned list. Exclude Pinned from both append handlers, matching
the existing pattern; history_delete is left intact so deleted/unpinned messages
still disappear from the view.

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

morethanwords/tweb/master5d5c3ef3 files, +49/-3
Read mention/reaction when jumping to an already-visible message

The unread mention/reaction corner button only scrolled to the target via
setMessageId; the actual read is driven solely by the intersection observer,
which fires only on an intersection CHANGE. When the target is already on
screen — typical for reactions, which sit on our own recent messages — the
programmatic scroll is a no-op, so no callback ever fires: the reaction stays
unread and the badge never clears.

Fix it by re-arming the observer for the focused bubble after it is rendered
and scrolled into view, forcing a fresh intersection entry. It still reads
only if the bubble is actually intersecting, so "read == seen" holds.

- SuperIntersectionObserver.reobserve(target): re-deliver an entry for an
already-observed target (handles bubbles with multiple callbacks, e.g. a
mention that also carries the history observer); no-op while frozen.
- ChatBubbles.reobserveUnreadContent(peerId, mid): guarded re-arm, only acts
on a bubble still pending unread content (idempotent with the natural flow).
- ChatInput: await the inner render/scroll promise before re-arming; poll
votes keep their own read flow in goToNextMention.

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

#webk
🫡3
morethanwords/tweb/masterfcdcb043 files, +338/-0
Refresh chat-folder membership on unread-mark toggle and message deletion

Chat-folder membership is driven by a cached index (dialog[index_N] /
folder.dialogs) that is written only by dialogsStorage.processDialogForFilters
— separate from the folder unread counters. Two update handlers mutated a
dialog's unread state without re-processing filters, so a dialog could go stale
in an exclude_read ("Unread") folder: it showed in the list with no badge (the
badge reads the live unread_count, already 0) and only vanished when opened
(open -> readHistory -> processDialogForFilters).

- onUpdateDialogUnreadMark: marking a read chat unread didn't add it to an
exclude_read folder, and clearing the mark (e.g. from another client) left it
stranded there.
- onUpdateDeleteMessages: deleting a channel's unread posts drops unread_count
to 0 but left the channel stuck in the folder.

Both fixed by calling processDialogForFilters after releaseUnreadCount, matching
the readHistory ordering (release -> processDialogForFilters -> dispatch). No
counter double-count: the unread*PeerIds sets are idempotent and the additive
unreadMessagesCount nets to zero (release covers folders that matched before the
change; the membership-change modify uses the post-mutate count).

Adds synthetic regression tests:
- unreadMarkFilterStale.test.ts: mark/clear maintains the index, counters net-zero.
- channelMuteFilter.test.ts: muting alone is correct in isolation; deleting a
channel's unread posts must drop it from exclude_read.

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

morethanwords/tweb/masterf9eb2de8 files, +350/-12
Fix forum topic open, invite-tab, and cross-account propagation bugs

- Opening a just-created topic in a cold (not-yet-warm) forum dropped the
threadId and showed the forum root: Chat.setPeer set isForum only in the
async onChangePeer, so a chat_update mid-transition compared against a stale
isForum and reset the peer. Set isForum synchronously in setPeer.

- Joining a forum via an invite link didn't open the topics tab. Route both
PopupJoinChatInvite.openChat and internalLinkProcessor's already-joined
(chatInviteAlready/Peek) path through appImManager.open() instead of
setInnerPeer(), so forums go through op() and open the sidebar topics tab.

- A topic created on another account never appeared in an open/cached topic
list, and stayed hidden even after reopening or receiving messages, until a
full reload. Replication-lag race: the topic-create arrives before the topic
is queryable by id, messages.getForumTopicsByID returns forumTopicDeleted,
and getForumTopicById blacklisted it permanently in deletedTopics. Build the
topic locally from the messageActionTopicCreate action (it carries title,
icon and id) instead of fetching it, and only blacklist a topic when the
server explicitly returns forumTopicDeleted (not on errors/omissions).

- Guard canManageTopic and the generic-animations sticker preload against null.

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

#webk
🫡3
morethanwords/tweb/mastere95fe521 files, +5/-1
Keep personal account in paid-reaction send-as list

channels.getSendAs(for_paid_reactions=true) omits the personal account;
the client injects it as the default peer. But this.sendAsPeers — the
canonical pool every click handler rebuilds the menu from — was sliced
before that injection, so the personal account was missing from it. The
menu rendered correctly on first open (built from the local list), but
the first selection regenerated it from this.sendAsPeers and dropped the
personal account permanently. Save this.sendAsPeers after folding in the
current/default peer.

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

morethanwords/tweb/master07f72889 files, +214/-51
Notify when another user posts a story

Add a local notification when a peer you follow posts a new story, mirroring the message-notification pipeline: the worker dispatches a notificationBuild task carrying a story payload (discriminated union) and the main thread builds and shows it. Respects the existing per-peer/global stories_muted setting, skips own/out/already-read stories, and covers the uncached-peer path so a peer's very first story still notifies.

Story notifications play no sound and don't bump the tab-title counter (noIncrement). Clicking opens the peer's stories at the first unread (matching Android and the avatar tap): in-page directly, on the service-worker/background-push path via a custom.story_id marker, and cross-account via a new 'story' hash param.

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

#webk
🫡3
telegramdesktop/tdesktop/dev4943c419 files, +16/-38
Get rid of new Q_OS_LINUX

telegramdesktop/tdesktop/dev34470201 files, +3/-2
Make macOS packaged cache key more stable

telegramdesktop/tdesktop/dev22143a81 files, +15/-3
Per-week cache key for ccache on Linux action

telegramdesktop/tdesktop/dev734d7093 files, +32/-1
Allow to override ffmpeg thread count for debugging purposes

#tdesktop
🫡3
telegramdesktop/tdesktop/devd6f2e4c1 files, +2/-4
Simplify the use of new ffmpeg thread option

#tdesktop
🫡2
telegramdesktop/tdesktop/dev5e1a05f1 files, +1/-1
Fix crash when removing pinned chats during folder changes.

#tdesktop
🫡2
telegramdesktop/tdesktop/dev24ccd1c1 files, +6/-1
Fix crash when finishing the appearing text animation

textAppearCheckLine() runs synchronously from inside the width and
height animation tick callbacks (textAppearWidthCallback /
textAppearHeightCallback). Calling RemoveComponents(TextAppearing::Bit())
there destroys those very animations (and their Ui::Animations::Simple
data) while the animations manager is still iterating them, leading to a
use-after-free / null _data dereference in Simple::value().

Defer the component removal to the next main loop iteration so the
running tick can unwind first.

#tdesktop
🫡2
telegramdesktop/tdesktop/dev7f8c6901 files, +0/-1
Remove duplicate QT_NO_PRIVATE_MODULE_WARNING from root CMakeLists.txt

It now lives in cmake/external/qt/package.cmake

#tdesktop
🫡2
telegramdesktop/tdesktop/devdf268f34 files, +10/-10
Bump actions/cache from 5 to 6

Bumps [actions/cache](https://github.com/actions/cache) from 5 to 6.
- [Release notes](https://github.com/actions/cache/releases)
- [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md)
- [Commits](https://github.com/actions/cache/compare/v5...v6)

---
updated-dependencies:
- dependency-name: actions/cache
dependency-version: '6'
dependency-type: direct:production
update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>

#tdesktop
🫡2