Tags: Mercurygram/Mercurygram
Tags
[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.
[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.
[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
[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.
[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.
[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.
[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.
[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.
[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
[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.
PreviousNext