[UnigramDev/Unigram/develop](https://github.com/UnigramDev/Unigram/tree/develop) • [4a14080](https://github.com/UnigramDev/Unigram/commit/4a14080e680b841f8fb1589c63ae4abb7fc78983) • _1 files, +4/-0_
Name the chart cards for the screen reader

A ListViewItem takes its name from the content ToString, which for a
ChartViewData is the type name, so every chart in the channel statistics
announced Telegram.ViewModels.Chats.ChartViewData. Give the container the
chart title, beside the header it already sets.

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

[UnigramDev/Unigram/develop](https://github.com/UnigramDev/Unigram/tree/develop) • [75177e5](https://github.com/UnigramDev/Unigram/commit/75177e573781de2cf553eaa4c74ed9447f1da223) • _4 files, +218/-3_
Reach the statistics charts from the keyboard

The chart is drawn, so its values exist as text only in the legend, which
followed the pointer and nothing else. Arrows step a point, page keys a tenth
of the visible range, Home and End the edges, Escape drops the selection, and
every move is announced through a notification; focus arriving from the
keyboard selects the most recent point, and leaving clears it.

Taking focus means being a Control, so the view moves off the Grid it was
ported onto, the canvas and the legend now sitting in its content, and gets a
peer that reports it focusable and hands out the selected point as its value.

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

[UnigramDev/Unigram/develop](https://github.com/UnigramDev/Unigram/tree/develop) • [47adb00](https://github.com/UnigramDev/Unigram/commit/47adb00201d8c283374c46a57e56e4f97a405695) • _1 files, +24/-1_
Select chart points on hover

A mouse reports moves with nothing pressed, which the touch original had no
notion of: the legend only followed a held button, and the branch that took
over tested the press position rather than the pointer, so after any click
inside the chart a hover kept dragging the selection along.

Hovering the chart area now selects and moving off it clears, a move with
nothing in contact ends a drag whose release was lost to a scroll or a flyout,
and clearing on pointer exit redraws, which it never did.

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

[UnigramDev/Unigram/develop](https://github.com/UnigramDev/Unigram/tree/develop) • [00bb9e8](https://github.com/UnigramDev/Unigram/commit/00bb9e84fcffeebdfec2aa42b75624c6850bffd1) • _10 files, +357/-214_
Don't search chats once per keystroke

The local half of the search ran on the keystroke itself, so typing a word sent
three TDLib requests and re-rendered the list per character; it now has its own
short debounce beside the online one. Its requests also go out together instead
of one after another, the message group is replaced in place rather than emptied
and refilled, and a row standing for the same chat is reused instead of rebuilt.

The four copies of ReplaceDiff became one extension, which is where the missing
UpdateItem call lands: a surviving row used to keep the query it was first found
by. Highlighters were also accumulating on recycled rows.

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

[UnigramDev/Unigram/develop](https://github.com/UnigramDev/Unigram/tree/develop) • [f2d33ae](https://github.com/UnigramDev/Unigram/commit/f2d33aecc8b6910e69752945c5465158c9abcd48) • _1 files, +8/-3_
Add a page of public posts once, not once per message

LoadMoreItemsAsync called AddRange inside a foreach over the same page, so
loading fifty posts appended two and a half thousand rows. Its staleness check
also read the _cancellation field, which a newer query replaces with a source
that is not cancelled.

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

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