Skip to content

Tags: Mercurygram/Mercurygram

Tags

12.10.6.1

Toggle 12.10.6.1's commit message
[MG] fix the notification permission prompt returning on every launch

When the POST_NOTIFICATIONS permission is missing, DialogsActivity shows
NotificationPermissionDialog at startup, gated by shouldAsk() and a back-off
of 1, 3, 7 and then 30 days that askLater() advances. Dismissing the dialog
called askLater(), but accepting it did not: the dialog then sends the user
to the system prompt or to Android settings, and if they left without
granting, nothing was recorded and the next launch asked again (#44).

Call askLater() when the dialog is accepted too. If the permission is then
granted, shouldAsk() returns false on its own, so the back-off only matters
when it was not.

12.10.6.0.4

Toggle 12.10.6.0.4's commit message
[MG] fix the notification permission prompt returning on every launch

When the POST_NOTIFICATIONS permission is missing, DialogsActivity shows
NotificationPermissionDialog at startup, gated by shouldAsk() and a back-off
of 1, 3, 7 and then 30 days that askLater() advances. Dismissing the dialog
called askLater(), but accepting it did not: the dialog then sends the user
to the system prompt or to Android settings, and if they left without
granting, nothing was recorded and the next launch asked again (#44).

Call askLater() when the dialog is accepted too. If the permission is then
granted, shouldAsk() returns false on its own, so the back-off only matters
when it was not.

12.10.6.0.3

Toggle 12.10.6.0.3's commit message
[MG] add a chat menu item to jump to the first message

Add "Go to first message" to the chat header menu, next to Search. It
reuses jumpToDate() with a date before Telegram existed (August 2013),
so topics, threads and migrated supergroups load from their oldest
message. Hidden in secret chats, where there is no remote history.

Closes #80

12.10.6.0.2

Toggle 12.10.6.0.2's commit message
[MG] fix duplicate GREASE extensions in the fake TLS ClientHello

The GREASE dedup loop in the TLSHello constructor compares slot i with
slot i + 1, so it pairs (1,2), (3,4), (5,6) and reads past the array at
(7,8). The two GREASE extension slots are 2 and 3, which the loop never
compares, so one hello in sixteen carries the same GREASE extension type
twice. BoringSSL servers reject a ClientHello with a duplicate extension
with a decode_error alert, which is what www.google.com does and why the
TlsHelloHandshakeTest instrumentation test failed at random in CI.

Compare slot i with i - 1 like TDLib does, so the pairs are (0,1), (2,3),
(4,5), (6,7) and the out-of-bounds read goes away. 150 generated hellos
in a row now get a ServerHello from www.google.com; before the fix 5 of
60 were rejected.

12.10.6.0.1

Toggle 12.10.6.0.1's commit message
[MG] fix duplicate GREASE extensions in the fake TLS ClientHello

The GREASE dedup loop in the TLSHello constructor compares slot i with
slot i + 1, so it pairs (1,2), (3,4), (5,6) and reads past the array at
(7,8). The two GREASE extension slots are 2 and 3, which the loop never
compares, so one hello in sixteen carries the same GREASE extension type
twice. BoringSSL servers reject a ClientHello with a duplicate extension
with a decode_error alert, which is what www.google.com does and why the
TlsHelloHandshakeTest instrumentation test failed at random in CI.

Compare slot i with i - 1 like TDLib does, so the pairs are (0,1), (2,3),
(4,5), (6,7) and the out-of-bounds read goes away. 150 generated hellos
in a row now get a ServerHello from www.google.com; before the fix 5 of
60 were rejected.

12.10.5.1.1

Toggle 12.10.5.1.1's commit message
[MG] fix duplicate GREASE extensions in the fake TLS ClientHello

The GREASE dedup loop in the TLSHello constructor compares slot i with
slot i + 1, so it pairs (1,2), (3,4), (5,6) and reads past the array at
(7,8). The two GREASE extension slots are 2 and 3, which the loop never
compares, so one hello in sixteen carries the same GREASE extension type
twice. BoringSSL servers reject a ClientHello with a duplicate extension
with a decode_error alert, which is what www.google.com does and why the
TlsHelloHandshakeTest instrumentation test failed at random in CI.

Compare slot i with i - 1 like TDLib does, so the pairs are (0,1), (2,3),
(4,5), (6,7) and the out-of-bounds read goes away. 150 generated hellos
in a row now get a ServerHello from www.google.com; before the fix 5 of
60 were rejected.

12.10.5.1

Toggle 12.10.5.1's commit message
[MG] fix duplicate GREASE extensions in the fake TLS ClientHello

The GREASE dedup loop in the TLSHello constructor compares slot i with
slot i + 1, so it pairs (1,2), (3,4), (5,6) and reads past the array at
(7,8). The two GREASE extension slots are 2 and 3, which the loop never
compares, so one hello in sixteen carries the same GREASE extension type
twice. BoringSSL servers reject a ClientHello with a duplicate extension
with a decode_error alert, which is what www.google.com does and why the
TlsHelloHandshakeTest instrumentation test failed at random in CI.

Compare slot i with i - 1 like TDLib does, so the pairs are (0,1), (2,3),
(4,5), (6,7) and the out-of-bounds read goes away. 150 generated hellos
in a row now get a ServerHello from www.google.com; before the fix 5 of
60 were rejected.

12.10.5.0.3

Toggle 12.10.5.0.3's commit message
[MG] fix the pin limit check on folder tabs

Pinning a chat on a folder tab was refused long before the folder was full.
Upstream caps the pins of a folder tab at 100 minus the size of alwaysShow,
then compares that against the pins already there plus the new one. But the
pinned chats of a server folder already sit in alwaysShow (pinDialog adds
them there, and MessagesStorage folds pinned_peers into alwaysShow when the
folder comes from the server), so every pin counted twice. The count of
existing pins is also the leading pinned run of the All chats list, which
since "pin more chats in All chats" can be 100 long instead of 5, so a folder
whose pins are also pinned in All chats hit the refusal with half the
folder still free.

The rule the server enforces is alwaysShow plus the chats the pin would add
against the chats-per-folder limit, 100 or 200 with Premium; upstream
hardcoded 100 there too. MgFolders.maxPinned returns the cap in the unit the
two checks in DialogsActivity compare against, so the existing pin count
cancels out and the miscount above stops mattering. A Mercurygram folder has
no chat limit, only the pin cap, where the upstream formula went negative
once the folder held more than 100 chats.

Inugram carries the same fix inlined into DialogsActivity
(bugfix/correct-folder-pin-count.patch); this one keeps the cap in
MgFolders next to the other folder limits.

12.10.5.0.2

Toggle 12.10.5.0.2's commit message
[MG] add QR code login

Log in by scanning a QR code from a device where the account is already
logged in, the way Telegram Desktop does. A "Log in by QR code" link under
the phone number field opens a dialog showing tg://login?token=..., which
the other phone scans from Settings > Devices. No SMS or login code is
involved, which helps where Telegram insists on a paid or SMS-only code.

The token comes from auth.exportLoginToken, with the accounts already
logged in here passed as except_ids, and is exported again shortly before
it expires. Acceptance is pushed as updateLoginToken, on which the export
is repeated and answers loginTokenSuccess, or loginTokenMigrateTo when the
account lives on another DC (switch the default DC, then
auth.importLoginToken). SESSION_PASSWORD_NEEDED opens the usual password
page, as the passkey path does.

The logic lives in MgQrLogin. LoginActivity only gets the link hook and
the visibility needed to finish the login (onAuthSuccess, VIEW_*), and
MessagesController forwards updateShort to it.

Closes #146

12.10.5.0.1

Toggle 12.10.5.0.1's commit message
[MG] fix a chat notification sound reset by opening its Sound screen

A custom notification sound set on a contact or a chat was often not kept: it
took several attempts before it stuck, and it could revert later on its own.

loadTones() resolves the stored tone against the uploaded tones and the
RingtoneManager cursor built at that moment. When nothing matched it fell back
to Default and marked the selection as changed, and onFragmentDestroy persists
the selection and pushes it to the server whenever that flag is set. So merely
opening the Sound screen and leaving it rewrote sound_<key>/sound_path_<key> to
Default and sent notificationSoundDefault for that peer.

A match fails whenever the stored URI is not in the cursor right then, which a
media rescan after an install or a reboot causes by reassigning the id of a
system tone.

Keep the fallback as a display default and stop marking it as changed, so only
picking a tone (or deleting the picked one) writes the setting. Nothing is lost
by keeping an unresolvable value: playback already falls back to Default on its
own, and the value starts matching again after the next rescan.