[UnigramDev/Unigram/develop](https://github.com/UnigramDev/Unigram/tree/develop) • [95cca4f](https://github.com/UnigramDev/Unigram/commit/95cca4f8659715b2be3d37576b4a55bf6dc8bd4c) • _4 files, +97/-51_
Group SendFilesPopup the way the send path does

The popup grouped items into albums itself, splitting only on the ten item
limit. Sending groups them again with GetItemsView, which also splits a muted
video out, splits a WEBP document out to work around the server ignoring
force_file inside an album, and never mixes media with documents or audio. So
the albums on screen were not the messages that would be sent, and
Send_ContextRequested decided whether to offer "send without grouping" against
a third grouping, computed with a hardcoded albumAllowed and forceDocuments
rather than the popup's own.

GetItemsView is now the only place a StorageAlbum is constructed anywhere.
UpdateCollection calls it and adapts the result, because grouping to send and
grouping to draw are not quite the same question:

Documents and audio albums expand into rows. They are grouped for sending, but
there is no mosaic to draw for them, so the grouping is invisible either way
and the rows are what the popup always showed.

A standalone photo or video gets a one item album. GetItemsView leaves a muted
video bare because it is sent as its own message, and rendering that literally
would drop it out of the mosaic and into a document row the moment the user
hits mute. Sending cannot tell the difference: a one item album and a bare item
take the same path.

Permissions go in as allowed rather than as the chat's. GetItemsView silently
drops an item whose type is not permitted, which is right when sending and
wrong when drawing. Everything in Items already cleared the guard, and the edit
path has no guard at all, so filtering here could only blank out an item the
popup exists to show.

StorageAlbum carries its type now, so the popup can tell a mosaic from a row
without deriving it again.

Mute_Click never refreshed anything, which was harmless while the popup ignored
IsMuted and is not any more. Nothing binds IsMuted, so it has to ask. The rest
of what GetItemsView reads is either immutable or already refreshes: Items
through OnCollectionChanged, IsFilesSelected through ToggleIsFilesSelected and
MakeContentPaid, IsAlbum only from SendWithoutGrouping, which hides the popup.

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

[UnigramDev/Unigram/develop](https://github.com/UnigramDev/Unigram/tree/develop) • [8e488b9](https://github.com/UnigramDev/Unigram/commit/8e488b991ed0092311865eb6719e53478561ef3b) • _2 files, +16/-301_
Remove the video compression that never ran

StorageVideo carried a compression model ported from Android: Compression,
MaxCompression, CanCompress, GetEncodingAsync, both ToString overloads,
UpdateWidthHeightBitrateForCompression, and fifteen fields behind them.

Nothing outside the file referenced any of it, and it could not have worked
anyway. Every original* field it reads is assigned only in commented-out lines
in the constructor, so they are permanently zero: MaxCompression always
resolves to 1, CanCompress is always false, and ToString divides by a zero
duration. LoadPreview, called from the constructor, existed only to compute
those values.

What is left is Width and Height, TotalSeconds, Duration, IsMuted and
GetGeneration, which is the whole of what the app ever asked a StorageVideo
for.

IsMuted's setter was resetting Compression and raising CanCompress; it is now
just the set. That matters slightly more than it reads, since muting a video
now moves it out of its album and the refresh is done by the caller.

The commented-out assignments in the constructor go too. They set the original*
fields, so keeping them would describe members that no longer exist. Anyone
reviving video compression starts from the Android implementation rather than
from this.

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

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