[UnigramDev/Unigram/develop](https://github.com/UnigramDev/Unigram/tree/develop) • [dc192a3](https://github.com/UnigramDev/Unigram/commit/dc192a33316458179922b3b93618161c4f13f058) • _2 files, +12/-8_
Time the typing indicator with ticks, not the clock

It ran DateTime.Now twice on every keystroke. Now resolves the local time zone
on each call, which Logger.cs already documents, but the bigger point is that
this measures an interval: the clock can jump backwards on an NTP correction,
and the gate would then stay shut until it caught up. Logger.TickCount is
milliseconds since boot, read once.

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

[UnigramDev/Unigram/develop](https://github.com/UnigramDev/Unigram/tree/develop) • [9c8aa44](https://github.com/UnigramDev/Unigram/commit/9c8aa4409202f1220630c409772efed0252e915d) • _2 files, +14/-7_
Ask for the quick reply shortcuts once, not per typed character

GetCommands runs for every autocomplete query that doesn't match the previous
one, so typing /start sent six identical loadQuickReplyShortcuts requests.

Answering the TODO that sat on the line: it is needed. GetQuickReplyShortcuts
returns empty until the update this asks for arrives, and the only other caller
is the business replies page, which a user may never open. So it stays - once
per box rather than once per character.

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

[UnigramDev/Unigram/develop](https://github.com/UnigramDev/Unigram/tree/develop) • [dc1f251](https://github.com/UnigramDev/Unigram/commit/dc1f251c4cb6f0afc1c09b7592cc05dec4e5c55d) • _4 files, +22/-11_
Track the quick reply shortcuts request in the service

Following up 9c8aa44: the flag belongs next to the state it guards, not in one
of the callers. LoadQuickReplyShortcuts is an IClientService method now, so the
business replies page gets the same treatment, and Clear() resets it with the
shortcuts it goes with.

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

[UnigramDev/Unigram/develop](https://github.com/UnigramDev/Unigram/tree/develop) • [99d1ad7](https://github.com/UnigramDev/Unigram/commit/99d1ad7f08ef1dc86f342e1f26d5bea408895c2b) • _3 files, +39/-14_
Don't allocate a cancellation source just to cancel

CancelEmoji cancelled the pending emoji query and allocated a replacement in
the same breath, and SetAutocomplete calls it on nearly every keystroke - with
nothing to hand the new token to. It also dropped the cancelled source without
disposing it, unlike CancelInlineBotToken next door.

Cancelling and starting are separate now. CaptionTextBox carries a copy of the
same code, so it gets the same split.

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

[#unigram](?q=%23unigram)