Telegram github commits and releases
4.46K subscribers
601 files
20.9K links
Broadcast from the most important Telegram clients' repositories
Download Telegram
UnigramDev/Unigram/record-session • a9d5872 • 9 files, +1363/-1157
Give a recording an owner

The record button held four things: the gesture, the state of the recording, the
capture engine, and the decision of what to do with the result. The engine was a
thread-static singleton every loaded button subscribed to, so a recording started
in one chat drove the state of every other chat and story composer on the thread,
and QuantumProcessed was a single field that whichever button loaded last took
over and the first to unload set back to null.

ChatRecordSession now owns the state and the engine, one per button, which is one
per chat. What is left in the button is the press-and-hold gesture and its own
visuals.

Seven booleans and an integer interface state become three named states. The
fourth one - locked, then stopped - was only reachable through StopRecording(false),
which nothing ever called, so it went out along with the tri-state stop that
neither sent nor discarded what it recorded. Cancel and Complete say which they
are.

Elapsed comes off a monotonic clock rather than DateTime.Now, freezes while
paused, and starts when the capture device is actually open rather than when the
button was pressed. The pause state is reset when a recording ends instead of
leaking into the next one, and the bar detaches from the button on unload.

Permissions go through MediaDevicePermissions, which is what calls already use,
so granting access no longer costs the first press: the old check asked
DeviceAccessInformation and then returned false regardless, leaving the prompt as
the only thing that press did.

MediaCapture.Failed ends the recording instead of only logging it, and a press
too short to record now says so.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

#unigram
TGX-Android/Telegram-X/main • 4bdf4de • 1 files, +0/-1
Remove rudimentary logging

TGX-Android/Telegram-X/main • 93fda89 • 2 files, +6/-6
Update dependencies

TGX-Android/Telegram-X/main • a874e13 • 1 files, +1/-1
Update FFmpeg to FFmpeg/FFmpeg@e21e475

TGX-Android/Telegram-X/main • 283aa9e • 1 files, +1/-1
Do not use `-Xlint:-dangling-doc-comments`

TGX-Android/Telegram-X/main • c9798eb • 3 files, +27275/-26631
Update baseline profile

TGX-Android/Telegram-X/main • d2008bd • 1 files, +1/-1
Version bump to `1802`

#tgxandroid
🫡3
TGX-Android/Telegram-X/main • 7ada8e7 • 7 files, +89/-115
Update pre-latest flavors

TGX-Android/Telegram-X/main • c7e7825 • 1 files, +0/-35
Remove `update-dependencies.sh`

TGX-Android/Telegram-X/main • eff99a9 • 1 files, +4/-0
Add final cleanup after FFmpeg build

TGX-Android/Telegram-X/main • 3c9d9c9 • 1 files, +10/-0
Require JDK 21

TGX-Android/Telegram-X/main • 8369017 • 1 files, +1/-1
Version bump to `1802`

#tgxandroid
🫡3
TGX-Android/Telegram-X/main • e92c817 • 8 files, +67/-60
Improve build speed

TGX-Android/Telegram-X/main • 05c3831 • 16 files, +30/-17
Upgrade Gradle to `9.7.0`

TGX-Android/Telegram-X/main • 53301eb • 1 files, +1/-1
Version bump to `1802`

#tgxandroid
🫡3
TGX-Android/Telegram-X/main • cb3c194 • 1 files, +2/-3
Increase heap size + Enable caching

TGX-Android/Telegram-X/main • 920a83a • 1 files, +1/-1
Version bump to `1802`

#tgxandroid
🫡3
TGX-Android/Telegram-X/main • 48ebd44 • 3 files, +5/-5
Exclude `:baseline-profile` from default project configuration

TGX-Android/Telegram-X/main • ad5025c • 1 files, +1/-1
Version bump to `1802`

#tgxandroid
🫡3
TGX-Android/Telegram-X/main • 4608042 • 2 files, +28/-32
Improve build speed

TGX-Android/Telegram-X/main • 8177ad8 • 1 files, +1/-1
Version bump to `1802`

#tgxandroid
🫡3
telegramdesktop/tdesktop/nightly • b0d2935 • 2 files, +17/-5
[poll-view] Fixed cut emoji icon in add-option field at some scales.

telegramdesktop/tdesktop/nightly • 82e66c8 • 1 files, +49/-36
[poll-view] Fixed vertical alignment of answer media and text.

telegramdesktop/tdesktop/nightly • d910e4e • 4 files, +53/-15
[poll-view] Fixed answer media dropped for pending webpage.

telegramdesktop/tdesktop/nightly • 0ef0421 • 1 files, +44/-27
[poll-view] Slightly improved answer highlight.

#tdesktop
🫡3
UnigramDev/Unigram/tdlib-list-t • 828d784 • 2 files, +72/-30
Expose every TDLib vector to WinRT from the schema

SettingsStoragePage binds Statistics.ByChat to ItemsSource and threw
E_INVALIDARG. TG1001 cannot see it: a binding assigns through the declared
IList<T>, so the concrete type is only known at runtime. The schema does know
it, and both parsers materialise a vector as List<T>, so the generator emits
the registration for every one of them - 188, nested vectors included.

That also settles the arrays that were listed by hand. A vector is never an
array, so none of them could ever be reached, and removing them leaves TG1001
reporting exactly one: PremiumGiftPaymentOption[], which the app builds
itself.

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

UnigramDev/Unigram/tdlib-list-t • 636c91d • 2 files, +53/-7
Flag the collection expressions no registration can fix

Targeting a read-only interface, a collection expression compiles to a type
the compiler makes up, and nothing can generate a vtable for that. TG1001
never reaches it: the target is typed, so its reasoning says the generator has
the conversion covered - but the marshaller it emits still needs a CCW for
whatever concrete type turns up.

There are two of them and the element count picks which, so a call site that
works with two elements can break when one is removed. Measured rather than
assumed, along with the targets that are safe: List, IList and ICollection all
produce a real List, a mutable interface needing a mutable instance. That also
retires the reason the generated API used IList - new[] { x } is no longer the
only short spelling.

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

UnigramDev/Unigram/tdlib-list-t • 2c74f62 • 4 files, +285/-20
Expose the TDLib vector instantiations from real source

CsWinRT reads these attributes in its own generator, and a generator cannot
see what another generator wrote, so emitting them was a no-op: the storage
page still threw. TDAPI003 now compares the schema against the attributes
actually present, for the next time TDLib adds a vector.

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

UnigramDev/Unigram/tdlib-list-t • 224de7f • 25 files, +106/-67
Expose TDLib object vectors as List<T>

Objects are read - bound to ItemsSource, iterated per render - so List makes
the concrete type visible to the analyzer, stops foreach boxing an enumerator
and lets the indexer inline. Functions are only ever written and serialised,
and keep IList. Constructors take IList either way, so arrays and collection
expressions still bind, and a parsed response is cast rather than copied.

AnimatedImage draws no shimmer when Outline is null, hence the shared empty.

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

#unigram
UnigramDev/Unigram/tdlib-list-t • 4cbb362 • 1 files, +23/-1
Follow x:Bind into the setters the XAML compiler emits

A binding does not assign the property: it calls a Set_ on XamlBindingSetters,
which takes the value as object and belongs to this assembly, so nothing
flagged it. Following that one call reports 83 collections bound from XAML
with no CCW vtable - each one a page that throws when opened.

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

UnigramDev/Unigram/tdlib-list-t • 099bab6 • 82 files, +337/-313
Take List<T> in the generated constructors too

The parameter and the field are the same type now, so TdCollection.AsList is
gone. Call sites became [x] and [], which allocates less than it did: the
converter copied every array into a list.

Four needed more than a rewrite. TryGetColors and the two chat-list readers
fill by Add rather than by index, because a List's capacity is not its count.
TextStyleRun shares one empty list, since Array.Empty was free and these sit
on the render path - a shared mutable list is a footgun, and notes has the
plan for it.

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

#unigram
UnigramDev/Unigram/dragover-access-denied • 7a6aacc • 1 files, +13/-4
Refuse a drag whose data view cannot be inspected

IDataPackageView::Contains is a cross-process call into the process that
started the drag, and it can be denied, or fail because that process went
away mid-drag. Neither is something the app can act on, so the drop is
declined and the failure logged.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

#unigram
UnigramDev/Unigram/location-access-check • 7a24205 • 1 files, +8/-3
Guard the location access request in CheckDeviceAccessAsync

Geolocator.RequestAccessAsync is a call into the Windows Geolocation
Service and throws ERROR_SERVICE_DISABLED (0x80070422) when that service
is disabled, as the identical call in SendLocationPopup.FindLocation did
in the field. Treat a throw as access not being available, the way
StartTrackingAsync already does.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

#unigram
UnigramDev/Unigram/media-collection-loading • e9d2435 • 1 files, +21/-4
Handle errors and cancellation when loading media

An Error response fell through silently, and the cancellation token was
never checked, so an abandoned load still appended to the collection.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

#unigram
UnigramDev/Unigram/composer-readonly-enter • 447e1cc • 1 files, +7/-0
Don't run the editing shortcuts in a read-only composer

Enter without Shift wrote a vertical tab into the document, which
RichEdit rejects with E_ACCESSDENIED whenever the composer has been
made read-only because the user cannot post in the chat.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

#unigram
UnigramDev/Unigram/currency-formatter-fallback • cc19c38 • 2 files, +5/-1
Fall back to a plain currency format when globalization is unavailable

GetCurrencyFormatter treated GlobalizationPreferences as infallible, so a
denied system query escaped as an UnauthorizedAccessException through the
synchronous ContainerContentChanging callback that reaches it. FormatCurrency
already handled a null formatter, but nothing could ever return one.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

#unigram
💅1
UnigramDev/Unigram/delayed-file-source-null • 84c7b53 • 2 files, +8/-2
Tolerate a null file in DelayedFileSource

A sticker with no StickerValue leaves _file null, which every other member
of the hierarchy already supports, so hashing the source crashed on Id.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

#unigram
UnigramDev/Unigram/gallery-ad-click-race • bf2539b • 2 files, +18/-3
Stop the gallery ad taking clicks while it fades out

ShowHide(false) sets _collapsed immediately but only applies Visibility from the
scoped batch's Completed, so the button stays visible and hit-testable for the
whole fade - after the state its click handler needs is gone. Swiping to another
gallery item runs Dispose(), which reaches UpdateAdvertisement(null) and clears
_advertisement, and closing additionally drops the data context, so a click in
that window crashed on _advertisement.UniqueId (NullReferenceException, reported
by crash telemetry on 12.9.1).

The button now stops taking input when hiding starts rather than when the fade
ends, and the handler is guarded as well, because a focused button can still be
invoked from the keyboard or by automation, neither of which hit tests.

Also fix Unload() dropping the delegate before calling PlaybackStopped(), which
left UpdateAdvertisement(null) with nothing to call and the control holding a
stale advertisement.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

#unigram
UnigramDev/Unigram/tdlib-fatal-message • 1373931 • 1 files, +62/-0
Normalize TDLib fatal log lines before hashing

A LOG(FATAL) line becomes the crash report message, and its thread number,
scheduler tag, session index and printed values differ on every crash, so a
single assertion is hashed into a group per report. Keep the source location,
the actor name and the stringified condition, drop the rest.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

#unigram
TGX-Android/Telegram-X/main • ed3cad0 • 1 files, +2/-0
Disable `lintError`

TGX-Android/Telegram-X/main • 5309275 • 1 files, +1/-1
Version bump to `1803`

#tgxandroid
🫡3
UnigramDev/Unigram/develop • 09f6aca • 1 files, +86/-4
Report the marshalling failures nothing else can see

A managed exception thrown inside a CCW callback reaches neither unhandled
handler: CsWinRT converts it to an HRESULT at the ABI boundary, so the runtime
counts it as handled, and the fail-fast XAML raises on that HRESULT bypasses
the native filter as well. First chance is the only point it is still an
exception, and reports are written synchronously, so the record survives.

Narrow on purpose: the two types CsWinRT throws when it cannot marshal
something, one report per distinct message, eight a session. They draw on the
same token bucket as real crashes, and crash.id stays unwritten so a handled
exception does not mark the session as crashed.

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

UnigramDev/Unigram/develop • d2042c4 • 1 files, +5/-2
Spell out the kernel32 entry points

LibraryImport always generates ExactSpelling, so the bare name is looked up
verbatim and kernel32 only exports the W and A forms. DllImport found them by
probing, which it does because a CharSet leaves ExactSpelling false.

IsPasskeySupported went through GetModuleHandle behind a Lazy, so it threw
once and then threw forever.

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

UnigramDev/Unigram/develop • 51c712d • 1 files, +6/-1
Recognise the HRESULT suffix CsWinRT writes

.NET Native appends "(Exception from HRESULT: 0x80004005)", CsWinRT appends
"(0x80004005)". Matching only the first left the suffix attached to every
message on the AOT build, so no sentence matched the translation table and one
fault split into a group per language.

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

UnigramDev/Unigram/develop • f94f44c • 1 files, +5/-3
Produce a symbol package for the modern bundle

A sideload build does emit an .appxsym - Telegram.Msix has one beside every
bundle - and without it a tester's crash cannot be symbolicated at all, which
is what happened to the last one handed out.

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

UnigramDev/Unigram/develop • c3135cf • 1 files, +1/-1
Invalidate the load in flight when recycling

Recycling reset the generation to 0, so the next load took that same number
and an outstanding continuation still matched - painting its image over the
one now bound to the brush. Advance the counter instead.

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

#unigram
🫡1