diff --git a/Telegram/CMakeLists.txt b/Telegram/CMakeLists.txt index 4db06b26f..29d434847 100644 --- a/Telegram/CMakeLists.txt +++ b/Telegram/CMakeLists.txt @@ -531,6 +531,10 @@ PRIVATE data/business/data_business_info.h data/business/data_shortcut_messages.cpp data/business/data_shortcut_messages.h + data/components/scheduled_messages.cpp + data/components/scheduled_messages.h + data/components/sponsored_messages.cpp + data/components/sponsored_messages.h data/notify/data_notify_settings.cpp data/notify/data_notify_settings.h data/notify/data_peer_notify_settings.cpp @@ -648,14 +652,10 @@ PRIVATE data/data_send_action.h data/data_session.cpp data/data_session.h - data/data_scheduled_messages.cpp - data/data_scheduled_messages.h data/data_shared_media.cpp data/data_shared_media.h data/data_sparse_ids.cpp data/data_sparse_ids.h - data/data_sponsored_messages.cpp - data/data_sponsored_messages.h data/data_statistics.h data/data_stories.cpp data/data_stories.h @@ -1530,8 +1530,6 @@ PRIVATE ui/image/image_location.h ui/image/image_location_factory.cpp ui/image/image_location_factory.h - ui/widgets/level_meter.cpp - ui/widgets/level_meter.h ui/countryinput.cpp ui/countryinput.h ui/dynamic_thumbnails.cpp @@ -1547,6 +1545,8 @@ PRIVATE ui/search_field_controller.h ui/text/format_song_document_name.cpp ui/text/format_song_document_name.h + ui/widgets/label_with_custom_emoji.cpp + ui/widgets/label_with_custom_emoji.h ui/unread_badge.cpp ui/unread_badge.h window/main_window.cpp diff --git a/Telegram/Resources/langs/lang.strings b/Telegram/Resources/langs/lang.strings index 00e0bcf7c..2c2009edd 100644 --- a/Telegram/Resources/langs/lang.strings +++ b/Telegram/Resources/langs/lang.strings @@ -309,7 +309,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL "lng_edit_limit_reached#one" = "You've reached the message text limit. Please make the text shorter by {count} character."; "lng_edit_limit_reached#other" = "You've reached the message text limit. Please make the text shorter by {count} characters."; "lng_edit_message" = "Edit message"; -"lng_edit_message_text" = "New message text..."; +"lng_edit_message_text" = "Caption"; "lng_deleted" = "Deleted Account"; "lng_deleted_message" = "Deleted message"; "lng_deleted_story" = "Deleted story"; @@ -734,6 +734,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL "lng_settings_sensitive_disable_filtering" = "Disable filtering"; "lng_settings_sensitive_about" = "Display sensitive media in public channels on all your Telegram devices."; "lng_settings_security_bots" = "Bots and websites"; +"lng_settings_file_confirmations" = "File open confirmations"; +"lng_settings_edit_extensions" = "Extensions whitelist"; +"lng_settings_edit_extensions_about" = "Open files with the following extensions without additional confirmation."; +"lng_settings_edit_ip_confirm" = "IP reveal warning"; +"lng_settings_edit_ip_confirm_about" = "Show confirmation when opening files that may reveal your IP address."; "lng_settings_clear_payment_info" = "Clear Payment and Shipping Info"; "lng_settings_logged_in" = "Connected websites"; "lng_settings_logged_in_title" = "Logged in with Telegram"; @@ -4480,10 +4485,14 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL "lng_translate_settings_about" = "The 'Translate' button will appear when you open a context menu on a text message."; "lng_translate_settings_one" = "Please choose at least one language so that it can be used as the \"Translate to\" language."; -"lng_launch_exe_warning" = "This file has a {extension} extension.\nAre you sure you want to run it?"; +"lng_launch_exe_warning" = "This file has {extension} extension.\nAre you sure you want to run it?"; +"lng_launch_other_warning" = "This file has {extension} extension.\nAre you sure you want to open it?"; "lng_launch_svg_warning" = "Opening this file can potentially expose your IP address to its sender. Continue?"; "lng_launch_exe_sure" = "Run"; +"lng_launch_other_sure" = "Open"; "lng_launch_exe_dont_ask" = "Don't ask me again"; +"lng_launch_dont_ask" = "Remember for this file type"; +"lng_launch_dont_ask_settings" = "You can later edit trusted file types in Settings > Privacy and Security > File open confirmations."; "lng_polls_anonymous" = "Anonymous Poll"; "lng_polls_public" = "Poll"; diff --git a/Telegram/Resources/uwp/AppX/AppxManifest.xml b/Telegram/Resources/uwp/AppX/AppxManifest.xml index 3488163e5..734a63bc4 100644 --- a/Telegram/Resources/uwp/AppX/AppxManifest.xml +++ b/Telegram/Resources/uwp/AppX/AppxManifest.xml @@ -10,7 +10,7 @@ <Identity Name="TelegramMessengerLLP.TelegramDesktop" ProcessorArchitecture="ARCHITECTURE" Publisher="CN=536BC709-8EE1-4478-AF22-F0F0F26FF64A" - Version="4.16.6.0" /> + Version="4.16.8.0" /> <Properties> <DisplayName>Telegram Desktop</DisplayName> <PublisherDisplayName>Telegram Messenger LLP</PublisherDisplayName> diff --git a/Telegram/Resources/winrc/Telegram.rc b/Telegram/Resources/winrc/Telegram.rc index 07be79162..481b83cfb 100644 --- a/Telegram/Resources/winrc/Telegram.rc +++ b/Telegram/Resources/winrc/Telegram.rc @@ -44,8 +44,8 @@ IDI_ICON1 ICON "..\\art\\icon256.ico" // VS_VERSION_INFO VERSIONINFO - FILEVERSION 4,16,6,0 - PRODUCTVERSION 4,16,6,0 + FILEVERSION 4,16,8,0 + PRODUCTVERSION 4,16,8,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -62,10 +62,10 @@ BEGIN BEGIN VALUE "CompanyName", "Radolyn Labs" VALUE "FileDescription", "AyuGram Desktop" - VALUE "FileVersion", "4.16.6.0" + VALUE "FileVersion", "4.16.8.0" VALUE "LegalCopyright", "Copyright (C) 2014-2024" VALUE "ProductName", "AyuGram Desktop" - VALUE "ProductVersion", "4.16.6.0" + VALUE "ProductVersion", "4.16.8.0" END END BLOCK "VarFileInfo" diff --git a/Telegram/Resources/winrc/Updater.rc b/Telegram/Resources/winrc/Updater.rc index 88221f475..208fdf399 100644 --- a/Telegram/Resources/winrc/Updater.rc +++ b/Telegram/Resources/winrc/Updater.rc @@ -35,8 +35,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US // VS_VERSION_INFO VERSIONINFO - FILEVERSION 4,16,6,0 - PRODUCTVERSION 4,16,6,0 + FILEVERSION 4,16,8,0 + PRODUCTVERSION 4,16,8,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -53,10 +53,10 @@ BEGIN BEGIN VALUE "CompanyName", "Radolyn Labs" VALUE "FileDescription", "AyuGram Desktop Updater" - VALUE "FileVersion", "4.16.6.0" + VALUE "FileVersion", "4.16.8.0" VALUE "LegalCopyright", "Copyright (C) 2014-2024" VALUE "ProductName", "AyuGram Desktop" - VALUE "ProductVersion", "4.16.6.0" + VALUE "ProductVersion", "4.16.8.0" END END BLOCK "VarFileInfo" diff --git a/Telegram/SourceFiles/api/api_bot.cpp b/Telegram/SourceFiles/api/api_bot.cpp index 706b7a7cb..0284ae719 100644 --- a/Telegram/SourceFiles/api/api_bot.cpp +++ b/Telegram/SourceFiles/api/api_bot.cpp @@ -236,14 +236,14 @@ void SendBotCallbackDataWithPassword( } else { return; } - const auto box = std::make_shared<QPointer<PasscodeBox>>(); auto fields = PasscodeBox::CloudFields::From(state); fields.customTitle = tr::lng_bots_password_confirm_title(); fields.customDescription = tr::lng_bots_password_confirm_description(tr::now); fields.customSubmitButton = tr::lng_passcode_submit(); fields.customCheckCallback = [=]( - const Core::CloudPasswordResult &result) { + const Core::CloudPasswordResult &result, + QPointer<PasscodeBox> box) { if (const auto button = getButton()) { if (button->requestId) { return; @@ -257,18 +257,17 @@ void SendBotCallbackDataWithPassword( return; } SendBotCallbackData(strongController, item, row, column, result, [=] { - if (*box) { - (*box)->closeBox(); + if (box) { + box->closeBox(); } }, [=](const QString &error) { - if (*box) { - (*box)->handleCustomCheckError(error); + if (box) { + box->handleCustomCheckError(error); } }); } }; auto object = Box<PasscodeBox>(session, fields); - *box = Ui::MakeWeak(object.data()); show->showBox(std::move(object), Ui::LayerOption::CloseOther); }, *lifetime); } diff --git a/Telegram/SourceFiles/api/api_chat_participants.cpp b/Telegram/SourceFiles/api/api_chat_participants.cpp index 6761d2fff..745e0b883 100644 --- a/Telegram/SourceFiles/api/api_chat_participants.cpp +++ b/Telegram/SourceFiles/api/api_chat_participants.cpp @@ -112,8 +112,8 @@ void ApplyLastList( channel->mgInfo->lastAdmins.clear(); channel->mgInfo->lastRestricted.clear(); channel->mgInfo->lastParticipants.clear(); - channel->mgInfo->lastParticipantsStatus = - MegagroupInfo::LastParticipantsUpToDate + channel->mgInfo->lastParticipantsStatus + = MegagroupInfo::LastParticipantsUpToDate | MegagroupInfo::LastParticipantsOnceReceived; auto botStatus = channel->mgInfo->botStatus; diff --git a/Telegram/SourceFiles/api/api_earn.cpp b/Telegram/SourceFiles/api/api_earn.cpp index e8f38e06b..d6425ef69 100644 --- a/Telegram/SourceFiles/api/api_earn.cpp +++ b/Telegram/SourceFiles/api/api_earn.cpp @@ -58,25 +58,33 @@ void HandleWithdrawalButton( state->loading = false; auto fields = PasscodeBox::CloudFields::From(pass); - fields.customTitle = - tr::lng_channel_earn_balance_password_title(); - fields.customDescription = - tr::lng_channel_earn_balance_password_description(tr::now); + fields.customTitle + = tr::lng_channel_earn_balance_password_title(); + fields.customDescription + = tr::lng_channel_earn_balance_password_description(tr::now); fields.customSubmitButton = tr::lng_passcode_submit(); fields.customCheckCallback = crl::guard(button, [=]( - const Core::CloudPasswordResult &result) { + const Core::CloudPasswordResult &result, + QPointer<PasscodeBox> box) { + const auto done = [=](const QString &result) { + if (!result.isEmpty()) { + UrlClickHandler::Open(result); + if (box) { + box->closeBox(); + } + } + }; + const auto fail = [=](const QString &error) { + show->showToast(error); + }; session->api().request( MTPstats_GetBroadcastRevenueWithdrawalUrl( channel->inputChannel, result.result )).done([=](const MTPstats_BroadcastRevenueWithdrawalUrl &r) { - const auto url = qs(r.data().vurl()); - - if (!url.isEmpty()) { - UrlClickHandler::Open(url); - } + done(qs(r.data().vurl())); }).fail([=](const MTP::Error &error) { - show->showToast(error.type()); + fail(error.type()); }).send(); }); show->show(Box<PasscodeBox>(session, fields)); diff --git a/Telegram/SourceFiles/api/api_editing.cpp b/Telegram/SourceFiles/api/api_editing.cpp index 84f0cbfff..f91a73579 100644 --- a/Telegram/SourceFiles/api/api_editing.cpp +++ b/Telegram/SourceFiles/api/api_editing.cpp @@ -12,12 +12,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "api/api_text_entities.h" #include "ui/boxes/confirm_box.h" #include "data/business/data_shortcut_messages.h" +#include "data/components/scheduled_messages.h" #include "data/data_histories.h" -#include "data/data_scheduled_messages.h" #include "data/data_session.h" #include "data/data_web_page.h" #include "history/history.h" -#include "history/history_item.h" #include "lang/lang_keys.h" #include "main/main_session.h" #include "mtproto/mtproto_response.h" @@ -29,20 +28,20 @@ namespace { using namespace rpl::details; template <typename T> -constexpr auto WithId = - is_callable_plain_v<T, Fn<void()>, mtpRequestId>; +constexpr auto WithId + = is_callable_plain_v<T, Fn<void()>, mtpRequestId>; template <typename T> -constexpr auto WithoutId = - is_callable_plain_v<T, Fn<void()>>; +constexpr auto WithoutId + = is_callable_plain_v<T, Fn<void()>>; template <typename T> -constexpr auto WithoutCallback = - is_callable_plain_v<T>; +constexpr auto WithoutCallback + = is_callable_plain_v<T>; template <typename T> -constexpr auto ErrorWithId = - is_callable_plain_v<T, QString, mtpRequestId>; +constexpr auto ErrorWithId + = is_callable_plain_v<T, QString, mtpRequestId>; template <typename T> -constexpr auto ErrorWithoutId = - is_callable_plain_v<T, QString>; +constexpr auto ErrorWithoutId + = is_callable_plain_v<T, QString>; template <typename DoneCallback, typename FailCallback> mtpRequestId EditMessage( @@ -95,7 +94,7 @@ mtpRequestId EditMessage( : emptyFlag); const auto id = item->isScheduled() - ? session->data().scheduledMessages().lookupId(item) + ? session->scheduledMessages().lookupId(item) : item->isBusinessShortcut() ? session->data().shortcutMessages().lookupId(item) : item->id; diff --git a/Telegram/SourceFiles/api/api_statistics.cpp b/Telegram/SourceFiles/api/api_statistics.cpp index 9bc31c483..7139c5ebb 100644 --- a/Telegram/SourceFiles/api/api_statistics.cpp +++ b/Telegram/SourceFiles/api/api_statistics.cpp @@ -860,6 +860,7 @@ void EarnStatistics::requestHistory( .token = Data::EarnHistorySlice::OffsetToken(nextToken), }); }).fail([=] { + done({}); _requestId = 0; }).send(); } diff --git a/Telegram/SourceFiles/api/api_updates.cpp b/Telegram/SourceFiles/api/api_updates.cpp index b5deb99ae..97b2f7529 100644 --- a/Telegram/SourceFiles/api/api_updates.cpp +++ b/Telegram/SourceFiles/api/api_updates.cpp @@ -21,6 +21,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "mtproto/mtproto_config.h" #include "mtproto/mtproto_dc_options.h" #include "data/business/data_shortcut_messages.h" +#include "data/components/scheduled_messages.h" #include "data/notify/data_notify_settings.h" #include "data/stickers/data_stickers.h" #include "data/data_saved_messages.h" @@ -37,7 +38,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "data/data_histories.h" #include "data/data_folder.h" #include "data/data_forum.h" -#include "data/data_scheduled_messages.h" #include "data/data_send_action.h" #include "data/data_stories.h" #include "data/data_message_reactions.h" @@ -98,7 +98,7 @@ void ProcessScheduledMessageWithElapsedTime( // Note that when a message is scheduled until online // while the recipient is already online, the server sends // an ordinary new message with skipped "from_scheduled" flag. - session->data().scheduledMessages().checkEntitiesAndUpdate(data); + session->scheduledMessages().checkEntitiesAndUpdate(data); } } @@ -1472,7 +1472,9 @@ void Updates::applyUpdates( if (const auto id = owner.messageIdByRandomId(randomId)) { const auto local = owner.message(id); if (local && local->isScheduled()) { - owner.scheduledMessages().sendNowSimpleMessage(d, local); + session().scheduledMessages().sendNowSimpleMessage( + d, + local); } } const auto wasAlready = (lookupMessage() != nullptr); @@ -1569,7 +1571,7 @@ void Updates::feedUpdate(const MTPUpdate &update) { auto &owner = session().data(); if (const auto local = owner.message(id)) { if (local->isScheduled()) { - session().data().scheduledMessages().apply(d, local); + session().scheduledMessages().apply(d, local); } else if (local->isBusinessShortcut()) { session().data().shortcutMessages().apply(d, local); } else { @@ -1779,12 +1781,12 @@ void Updates::feedUpdate(const MTPUpdate &update) { case mtpc_updateNewScheduledMessage: { const auto &d = update.c_updateNewScheduledMessage(); - session().data().scheduledMessages().apply(d); + session().scheduledMessages().apply(d); } break; case mtpc_updateDeleteScheduledMessages: { const auto &d = update.c_updateDeleteScheduledMessages(); - session().data().scheduledMessages().apply(d); + session().scheduledMessages().apply(d); } break; case mtpc_updateQuickReplies: { diff --git a/Telegram/SourceFiles/api/api_user_privacy.cpp b/Telegram/SourceFiles/api/api_user_privacy.cpp index b27580aaa..d0c17fa6b 100644 --- a/Telegram/SourceFiles/api/api_user_privacy.cpp +++ b/Telegram/SourceFiles/api/api_user_privacy.cpp @@ -307,8 +307,8 @@ void UserPrivacy::reload(Key key) { } void UserPrivacy::pushPrivacy(Key key, const TLRules &rules) { - const auto &saved = (_privacyValues[key] = - TLToRules(rules, _session->data())); + const auto &saved + = (_privacyValues[key] = TLToRules(rules, _session->data())); const auto i = _privacyChanges.find(key); if (i != end(_privacyChanges)) { i->second.fire_copy(saved); diff --git a/Telegram/SourceFiles/apiwrap.cpp b/Telegram/SourceFiles/apiwrap.cpp index ab030fb57..057b7629f 100644 --- a/Telegram/SourceFiles/apiwrap.cpp +++ b/Telegram/SourceFiles/apiwrap.cpp @@ -35,6 +35,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "api/api_user_names.h" #include "api/api_websites.h" #include "data/business/data_shortcut_messages.h" +#include "data/components/scheduled_messages.h" #include "data/notify/data_notify_settings.h" #include "data/data_changes.h" #include "data/data_web_page.h" @@ -43,7 +44,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "data/data_forum.h" #include "data/data_saved_sublist.h" #include "data/data_search_controller.h" -#include "data/data_scheduled_messages.h" #include "data/data_session.h" #include "data/data_channel.h" #include "data/data_chat.h" @@ -559,7 +559,7 @@ void ApiWrap::sendMessageFail( } } } else if (error == u"SCHEDULE_STATUS_PRIVATE"_q) { - auto &scheduled = _session->data().scheduledMessages(); + auto &scheduled = _session->scheduledMessages(); Assert(peer->isUser()); if (const auto item = scheduled.lookupItem(peer->id, itemId.msg)) { scheduled.removeSending(item); @@ -1573,8 +1573,8 @@ void ApiWrap::saveStickerSets( writeRecent = true; } - const auto isAttached = - (removedSetId == Data::Stickers::CloudRecentAttachedSetId); + const auto isAttached + = (removedSetId == Data::Stickers::CloudRecentAttachedSetId); const auto flags = isAttached ? MTPmessages_ClearRecentStickers::Flag::f_attached : MTPmessages_ClearRecentStickers::Flags(0); @@ -2480,8 +2480,8 @@ void ApiWrap::refreshFileReference( _session->data().peer(storyId.peer)->input, MTP_vector<MTPint>(1, MTP_int(storyId.story)))); } else if (item->isScheduled()) { - const auto &scheduled = _session->data().scheduledMessages(); - const auto realId = scheduled.lookupId(item); + const auto realId = _session->scheduledMessages().lookupId( + item); request(MTPmessages_GetScheduledMessages( item->history()->peer->input, MTP_vector<MTPint>(1, MTP_int(realId)))); @@ -2527,8 +2527,8 @@ void ApiWrap::refreshFileReference( }, [&](Data::FileOriginPeerPhoto data) { fail(); }, [&](Data::FileOriginStickerSet data) { - const auto isRecentAttached = - (data.setId == Data::Stickers::CloudRecentAttachedSetId); + const auto isRecentAttached + = (data.setId == Data::Stickers::CloudRecentAttachedSetId); if (data.setId == Data::Stickers::CloudRecentSetId || data.setId == Data::Stickers::RecentSetId || isRecentAttached) { diff --git a/Telegram/SourceFiles/boxes/add_contact_box.cpp b/Telegram/SourceFiles/boxes/add_contact_box.cpp index ba35e8d98..45d4b1e99 100644 --- a/Telegram/SourceFiles/boxes/add_contact_box.cpp +++ b/Telegram/SourceFiles/boxes/add_contact_box.cpp @@ -605,8 +605,8 @@ void GroupInfoBox::prepare() { _navigation->session().api().selfDestruct().reload(); const auto top = addTopButton(st::infoTopBarMenu); - const auto menu = - top->lifetime().make_state<base::unique_qptr<Ui::PopupMenu>>(); + const auto menu + = top->lifetime().make_state<base::unique_qptr<Ui::PopupMenu>>(); top->setClickedCallback([=] { *menu = base::make_unique_q<Ui::PopupMenu>( top, @@ -1306,8 +1306,8 @@ void SetupChannelBox::handleChange() { && (ch < 'a' || ch > 'z') && (ch < '0' || ch > '9') && ch != '_') { - const auto badSymbols = - tr::lng_create_channel_link_bad_symbols(tr::now); + const auto badSymbols + = tr::lng_create_channel_link_bad_symbols(tr::now); if (_errorText != badSymbols) { _errorText = badSymbols; update(); @@ -1317,8 +1317,8 @@ void SetupChannelBox::handleChange() { } } if (name.size() < Ui::EditPeer::kMinUsernameLength) { - const auto tooShort = - tr::lng_create_channel_link_too_short(tr::now); + const auto tooShort + = tr::lng_create_channel_link_too_short(tr::now); if (_errorText != tooShort) { _errorText = tooShort; update(); diff --git a/Telegram/SourceFiles/boxes/delete_messages_box.cpp b/Telegram/SourceFiles/boxes/delete_messages_box.cpp index 0a939ace6..1def53870 100644 --- a/Telegram/SourceFiles/boxes/delete_messages_box.cpp +++ b/Telegram/SourceFiles/boxes/delete_messages_box.cpp @@ -232,8 +232,8 @@ void DeleteMessagesBox::prepare() { if (hasScheduledMessages()) { } else if (auto revoke = revokeText(peer)) { const auto &settings = Core::App().settings(); - const auto revokeByDefault = - !settings.rememberedDeleteMessageOnlyForYou(); + const auto revokeByDefault + = !settings.rememberedDeleteMessageOnlyForYou(); _revoke.create( this, revoke->checkbox, diff --git a/Telegram/SourceFiles/boxes/gift_premium_box.cpp b/Telegram/SourceFiles/boxes/gift_premium_box.cpp index b107af7c9..10ad9409d 100644 --- a/Telegram/SourceFiles/boxes/gift_premium_box.cpp +++ b/Telegram/SourceFiles/boxes/gift_premium_box.cpp @@ -16,7 +16,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "boxes/peers/prepare_short_info_box.h" #include "boxes/peers/replace_boost_box.h" // BoostsForGift. #include "boxes/premium_preview_box.h" // ShowPremiumPreviewBox. -#include "core/ui_integration.h" // Core::MarkedTextContext. #include "data/data_boosts.h" #include "data/data_changes.h" #include "data/data_channel.h" @@ -48,6 +47,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "ui/toast/toast.h" #include "ui/widgets/checkbox.h" #include "ui/widgets/gradient_round_button.h" +#include "ui/widgets/label_with_custom_emoji.h" #include "ui/wrap/padding_wrap.h" #include "ui/wrap/slide_wrap.h" #include "ui/wrap/table_layout.h" @@ -319,21 +319,20 @@ void GiftBox( std::move(titleLabel)), st::premiumGiftTitlePadding); - auto textLabel = object_ptr<Ui::FlatLabel>(box, st::premiumPreviewAbout); - tr::lng_premium_gift_about( - lt_user, - user->session().changes().peerFlagsValue( - user, - Data::PeerUpdate::Flag::Name - ) | rpl::map([=] { return TextWithEntities{ user->firstName }; }), - Ui::Text::RichLangValue - ) | rpl::map( - BoostsForGiftText({ user }) - ) | rpl::start_with_next([ - raw = textLabel.data(), - session = &user->session()](const TextWithEntities &t) { - raw->setMarkedText(t, Core::MarkedTextContext{ .session = session }); - }, textLabel->lifetime()); + auto textLabel = Ui::CreateLabelWithCustomEmoji( + box, + tr::lng_premium_gift_about( + lt_user, + user->session().changes().peerFlagsValue( + user, + Data::PeerUpdate::Flag::Name + ) | rpl::map([=] { return TextWithEntities{ user->firstName }; }), + Ui::Text::RichLangValue + ) | rpl::map( + BoostsForGiftText({ user }) + ), + { .session = &user->session() }, + st::premiumPreviewAbout); textLabel->setTextColorOverride(stTitle.textFg->c); textLabel->resizeToWidth(available); box->addRow( @@ -536,14 +535,12 @@ void GiftsBox( const auto label = box->addRow( object_ptr<Ui::CenterWrap<Ui::FlatLabel>>( box, - object_ptr<Ui::FlatLabel>(box, st::premiumPreviewAbout)), + Ui::CreateLabelWithCustomEmoji( + box, + std::move(text), + { .session = session }, + st::premiumPreviewAbout)), padding)->entity(); - std::move( - text - ) | rpl::start_with_next([=](const TextWithEntities &t) { - using namespace Core; - label->setMarkedText(t, MarkedTextContext{ .session = session }); - }, label->lifetime()); label->setTextColorOverride(stTitle.textFg->c); label->resizeToWidth(available); } diff --git a/Telegram/SourceFiles/boxes/passcode_box.cpp b/Telegram/SourceFiles/boxes/passcode_box.cpp index e320b434f..840e4872d 100644 --- a/Telegram/SourceFiles/boxes/passcode_box.cpp +++ b/Telegram/SourceFiles/boxes/passcode_box.cpp @@ -740,7 +740,7 @@ void PasscodeBox::submitOnlyCheckCloudPassword(const QString &oldPassword) { void PasscodeBox::sendOnlyCheckCloudPassword(const QString &oldPassword) { checkPassword(oldPassword, [=](const Core::CloudPasswordResult &check) { if (const auto onstack = _cloudFields.customCheckCallback) { - onstack(check); + onstack(check, Ui::MakeWeak(this)); } else { Assert(_cloudFields.turningOff); sendClearCloudPassword(check); diff --git a/Telegram/SourceFiles/boxes/passcode_box.h b/Telegram/SourceFiles/boxes/passcode_box.h index 684da859a..b651cda64 100644 --- a/Telegram/SourceFiles/boxes/passcode_box.h +++ b/Telegram/SourceFiles/boxes/passcode_box.h @@ -51,7 +51,10 @@ public: TimeId pendingResetDate = 0; // Check cloud password for some action. - Fn<void(const Core::CloudPasswordResult &)> customCheckCallback; + using CustomCheck = Fn<void( + const Core::CloudPasswordResult &, + QPointer<PasscodeBox>)>; + CustomCheck customCheckCallback; rpl::producer<QString> customTitle; std::optional<QString> customDescription; rpl::producer<QString> customSubmitButton; diff --git a/Telegram/SourceFiles/boxes/peers/edit_participant_box.cpp b/Telegram/SourceFiles/boxes/peers/edit_participant_box.cpp index c1c086ad1..39389d1d5 100644 --- a/Telegram/SourceFiles/boxes/peers/edit_participant_box.cpp +++ b/Telegram/SourceFiles/boxes/peers/edit_participant_box.cpp @@ -598,19 +598,17 @@ void EditAdminBox::requestTransferPassword(not_null<ChannelData*> channel) { ) | rpl::take( 1 ) | rpl::start_with_next([=](const Core::CloudPasswordState &state) { - const auto box = std::make_shared<QPointer<PasscodeBox>>(); auto fields = PasscodeBox::CloudFields::From(state); fields.customTitle = tr::lng_rights_transfer_password_title(); fields.customDescription = tr::lng_rights_transfer_password_description(tr::now); fields.customSubmitButton = tr::lng_passcode_submit(); fields.customCheckCallback = crl::guard(this, [=]( - const Core::CloudPasswordResult &result) { - sendTransferRequestFrom(*box, channel, result); + const Core::CloudPasswordResult &result, + QPointer<PasscodeBox> box) { + sendTransferRequestFrom(box, channel, result); }); - *box = getDelegate()->show(Box<PasscodeBox>( - &channel->session(), - fields)); + getDelegate()->show(Box<PasscodeBox>(&channel->session(), fields)); }, lifetime()); } diff --git a/Telegram/SourceFiles/boxes/peers/edit_peer_history_visibility_box.cpp b/Telegram/SourceFiles/boxes/peers/edit_peer_history_visibility_box.cpp index 9086dfce8..8883ad0a5 100644 --- a/Telegram/SourceFiles/boxes/peers/edit_peer_history_visibility_box.cpp +++ b/Telegram/SourceFiles/boxes/peers/edit_peer_history_visibility_box.cpp @@ -9,6 +9,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "lang/lang_keys.h" #include "ui/layers/generic_box.h" +#include "ui/widgets/buttons.h" #include "ui/widgets/checkbox.h" #include "ui/widgets/labels.h" #include "styles/style_layers.h" @@ -23,6 +24,17 @@ void EditPeerHistoryVisibilityBox( Ui::RadioenumGroup<HistoryVisibility> >(historyVisibilitySavedValue); + const auto addButton = [=]( + not_null<Ui::RpWidget*> inner, + HistoryVisibility v) { + const auto button = Ui::CreateChild<Ui::AbstractButton>(inner.get()); + inner->sizeValue( + ) | rpl::start_with_next([=](const QSize &s) { + button->resize(s); + }, button->lifetime()); + button->setClickedCallback([=] { historyVisibility->setValue(v); }); + }; + box->setTitle(tr::lng_manage_history_visibility_title()); box->addButton(tr::lng_settings_save(), [=] { savedCallback(historyVisibility->current()); @@ -31,32 +43,36 @@ void EditPeerHistoryVisibilityBox( box->addButton(tr::lng_cancel(), [=] { box->closeBox(); }); box->addSkip(st::editPeerHistoryVisibilityTopSkip); - box->addRow(object_ptr<Ui::Radioenum<HistoryVisibility>>( + const auto visible = box->addRow(object_ptr<Ui::VerticalLayout>(box)); + visible->add(object_ptr<Ui::Radioenum<HistoryVisibility>>( box, historyVisibility, HistoryVisibility::Visible, tr::lng_manage_history_visibility_shown(tr::now), st::defaultBoxCheckbox)); - box->addRow( + visible->add( object_ptr<Ui::FlatLabel>( box, tr::lng_manage_history_visibility_shown_about(), st::editPeerPrivacyLabel), - st::editPeerPreHistoryLabelMargins + st::boxRowPadding); + st::editPeerPreHistoryLabelMargins); + addButton(visible, HistoryVisibility::Visible); box->addSkip(st::editPeerHistoryVisibilityTopSkip); - box->addRow(object_ptr<Ui::Radioenum<HistoryVisibility>>( + const auto hidden = box->addRow(object_ptr<Ui::VerticalLayout>(box)); + hidden->add(object_ptr<Ui::Radioenum<HistoryVisibility>>( box, historyVisibility, HistoryVisibility::Hidden, tr::lng_manage_history_visibility_hidden(tr::now), st::defaultBoxCheckbox)); - box->addRow( + hidden->add( object_ptr<Ui::FlatLabel>( box, (isLegacy ? tr::lng_manage_history_visibility_hidden_legacy : tr::lng_manage_history_visibility_hidden_about)(), st::editPeerPrivacyLabel), - st::editPeerPreHistoryLabelMargins + st::boxRowPadding); + st::editPeerPreHistoryLabelMargins); + addButton(hidden, HistoryVisibility::Hidden); } diff --git a/Telegram/SourceFiles/boxes/peers/edit_peer_info_box.cpp b/Telegram/SourceFiles/boxes/peers/edit_peer_info_box.cpp index 31faabec1..a1ee68248 100644 --- a/Telegram/SourceFiles/boxes/peers/edit_peer_info_box.cpp +++ b/Telegram/SourceFiles/boxes/peers/edit_peer_info_box.cpp @@ -983,8 +983,8 @@ void Controller::fillHistoryVisibilityButton() { : HistoryVisibility::Visible; _channelHasLocationOriginalValue = channel && channel->hasLocation(); - const auto updateHistoryVisibility = - std::make_shared<rpl::event_stream<HistoryVisibility>>(); + const auto updateHistoryVisibility + = std::make_shared<rpl::event_stream<HistoryVisibility>>(); const auto boxCallback = crl::guard(this, [=](HistoryVisibility checked) { updateHistoryVisibility->fire(std::move(checked)); @@ -1698,8 +1698,8 @@ void Controller::saveUsernamesOrder() { channel->setUsernames(ranges::views::all( newUsernames ) | ranges::views::transform([&](QString username) { - const auto editable = - (channel->editableUsername() == username); + const auto editable + = (channel->editableUsername() == username); return Data::Username{ .username = std::move(username), .active = true, diff --git a/Telegram/SourceFiles/boxes/peers/edit_peer_invite_link.cpp b/Telegram/SourceFiles/boxes/peers/edit_peer_invite_link.cpp index 7b80e2652..8f67b6ba4 100644 --- a/Telegram/SourceFiles/boxes/peers/edit_peer_invite_link.cpp +++ b/Telegram/SourceFiles/boxes/peers/edit_peer_invite_link.cpp @@ -227,9 +227,9 @@ QImage QrExact(const Qr::Data &data, int pixel, QColor color) { p.drawImage( skip, skip, - Intro::details::TelegramLogoImage().scaled( - logoSize * style::DevicePixelRatio(), - logoSize * style::DevicePixelRatio(), + Window::LogoNoMargin().scaled( + logoSize, + logoSize, Qt::IgnoreAspectRatio, Qt::SmoothTransformation)); } diff --git a/Telegram/SourceFiles/boxes/premium_preview_box.cpp b/Telegram/SourceFiles/boxes/premium_preview_box.cpp index 67e402da5..da1ab9064 100644 --- a/Telegram/SourceFiles/boxes/premium_preview_box.cpp +++ b/Telegram/SourceFiles/boxes/premium_preview_box.cpp @@ -1240,8 +1240,8 @@ void DecorateListPromoBox( box->setStyle(st::premiumPreviewDoubledLimitsBox); box->widthValue( ) | rpl::start_with_next([=](int width) { - const auto &padding = - st::premiumPreviewDoubledLimitsBox.buttonPadding; + const auto &padding + = st::premiumPreviewDoubledLimitsBox.buttonPadding; button->resizeToWidth(width - padding.left() - padding.right()); diff --git a/Telegram/SourceFiles/boxes/ringtones_box.cpp b/Telegram/SourceFiles/boxes/ringtones_box.cpp index d8097222e..4c299c162 100644 --- a/Telegram/SourceFiles/boxes/ringtones_box.cpp +++ b/Telegram/SourceFiles/boxes/ringtones_box.cpp @@ -90,7 +90,7 @@ QString ExtractRingtoneName(not_null<DocumentData*> document) { } const auto name = document->filename(); if (!name.isEmpty()) { - const auto extension = Data::FileExtension(name); + const auto extension = Core::FileExtension(name); if (extension.isEmpty()) { return name; } else if (name.size() > extension.size() + 1) { diff --git a/Telegram/SourceFiles/boxes/sticker_set_box.cpp b/Telegram/SourceFiles/boxes/sticker_set_box.cpp index 9e30ebded..09efc7dfe 100644 --- a/Telegram/SourceFiles/boxes/sticker_set_box.cpp +++ b/Telegram/SourceFiles/boxes/sticker_set_box.cpp @@ -611,8 +611,8 @@ void StickerSetBox::updateButtons() { if (!_inner->shortName().isEmpty()) { const auto top = addTopButton(st::infoTopBarMenu); - const auto menu = - std::make_shared<base::unique_qptr<Ui::PopupMenu>>(); + const auto menu + = std::make_shared<base::unique_qptr<Ui::PopupMenu>>(); top->setClickedCallback([=] { *menu = base::make_unique_q<Ui::PopupMenu>( top, @@ -656,8 +656,8 @@ void StickerSetBox::updateButtons() { _show->showBox(std::move(box)); } }; - const auto menu = - std::make_shared<base::unique_qptr<Ui::PopupMenu>>(); + const auto menu + = std::make_shared<base::unique_qptr<Ui::PopupMenu>>(); top->setClickedCallback([=] { *menu = base::make_unique_q<Ui::PopupMenu>( top, diff --git a/Telegram/SourceFiles/calls/calls_call.cpp b/Telegram/SourceFiles/calls/calls_call.cpp index c3cbe68d6..d30c49a04 100644 --- a/Telegram/SourceFiles/calls/calls_call.cpp +++ b/Telegram/SourceFiles/calls/calls_call.cpp @@ -945,8 +945,8 @@ void Call::createAndStartController(const MTPDphoneCall &call) { tgcalls::Descriptor descriptor = { .version = versionString, .config = tgcalls::Config{ - .initializationTimeout = - serverConfig.callConnectTimeoutMs / 1000., + .initializationTimeout + = serverConfig.callConnectTimeoutMs / 1000., .receiveTimeout = serverConfig.callPacketTimeoutMs / 1000., .dataSaving = tgcalls::DataSaving::Never, .enableP2P = call.is_p2p_allowed(), diff --git a/Telegram/SourceFiles/calls/calls_call.h b/Telegram/SourceFiles/calls/calls_call.h index 55f48237a..0a99c8067 100644 --- a/Telegram/SourceFiles/calls/calls_call.h +++ b/Telegram/SourceFiles/calls/calls_call.h @@ -277,11 +277,11 @@ private: MTP::Sender _api; Type _type = Type::Outgoing; rpl::variable<State> _state = State::Starting; - rpl::variable<RemoteAudioState> _remoteAudioState = - RemoteAudioState::Active; + rpl::variable<RemoteAudioState> _remoteAudioState + = RemoteAudioState::Active; rpl::variable<Webrtc::VideoState> _remoteVideoState; - rpl::variable<RemoteBatteryState> _remoteBatteryState = - RemoteBatteryState::Normal; + rpl::variable<RemoteBatteryState> _remoteBatteryState + = RemoteBatteryState::Normal; rpl::event_stream<Error> _errors; FinishType _finishAfterRequestingCall = FinishType::None; bool _answerAfterDhConfigReceived = false; diff --git a/Telegram/SourceFiles/calls/calls_panel.h b/Telegram/SourceFiles/calls/calls_panel.h index f6c8666d8..11c6dceae 100644 --- a/Telegram/SourceFiles/calls/calls_panel.h +++ b/Telegram/SourceFiles/calls/calls_panel.h @@ -162,8 +162,8 @@ private: object_ptr<Ui::FlatLabel> _status; object_ptr<Ui::RpWidget> _fingerprint = { nullptr }; object_ptr<Ui::PaddingWrap<Ui::FlatLabel>> _remoteAudioMute = { nullptr }; - object_ptr<Ui::PaddingWrap<Ui::FlatLabel>> _remoteLowBattery = - { nullptr }; + object_ptr<Ui::PaddingWrap<Ui::FlatLabel>> _remoteLowBattery + = { nullptr }; std::unique_ptr<Userpic> _userpic; std::unique_ptr<VideoBubble> _outgoingVideoBubble; QPixmap _bottomShadow; diff --git a/Telegram/SourceFiles/calls/group/calls_volume_item.cpp b/Telegram/SourceFiles/calls/group/calls_volume_item.cpp index 5942a97e7..d34a51060 100644 --- a/Telegram/SourceFiles/calls/group/calls_volume_item.cpp +++ b/Telegram/SourceFiles/calls/group/calls_volume_item.cpp @@ -25,8 +25,8 @@ const auto kSpeakerThreshold = std::vector<float>{ 50.0f / kMaxVolumePercent, 150.0f / kMaxVolumePercent }; -constexpr auto kVolumeStickedValues = - std::array<std::pair<float64, float64>, 7>{{ +constexpr auto kVolumeStickedValues + = std::array<std::pair<float64, float64>, 7>{{ { 25. / kMaxVolumePercent, 2. / kMaxVolumePercent }, { 50. / kMaxVolumePercent, 2. / kMaxVolumePercent }, { 75. / kMaxVolumePercent, 2. / kMaxVolumePercent }, @@ -93,8 +93,8 @@ MenuVolumeItem::MenuVolumeItem( const auto volume = _localMuted ? 0 : base::SafeRound(_slider->value() * kMaxVolumePercent); - const auto muteProgress = - _crossLineAnimation.value((!volume) ? 1. : 0.); + const auto muteProgress + = _crossLineAnimation.value((!volume) ? 1. : 0.); const auto selected = isSelected(); p.fillRect(clip, selected ? st.itemBgOver : st.itemBg); @@ -174,8 +174,8 @@ MenuVolumeItem::MenuVolumeItem( return; } if (_waitingForUpdateVolume) { - const auto localVolume = - base::SafeRound(_slider->value() * _maxVolume); + const auto localVolume + = base::SafeRound(_slider->value() * _maxVolume); if ((localVolume != newVolume) && (_cloudVolume == newVolume)) { _changeVolumeRequests.fire(int(localVolume)); diff --git a/Telegram/SourceFiles/chat_helpers/field_autocomplete.cpp b/Telegram/SourceFiles/chat_helpers/field_autocomplete.cpp index e82ab9b9f..9bc6e88f2 100644 --- a/Telegram/SourceFiles/chat_helpers/field_autocomplete.cpp +++ b/Telegram/SourceFiles/chat_helpers/field_autocomplete.cpp @@ -437,8 +437,8 @@ void FieldAutocomplete::updateFiltered(bool resetScroll) { auto filterNotPassedByUsername = [this](UserData *user) -> bool { if (PrimaryUsername(user).startsWith(_filter, Qt::CaseInsensitive)) { - const auto exactUsername = - (PrimaryUsername(user).size() == _filter.size()); + const auto exactUsername + = (PrimaryUsername(user).size() == _filter.size()); return exactUsername; } return true; @@ -446,8 +446,9 @@ void FieldAutocomplete::updateFiltered(bool resetScroll) { auto filterNotPassedByName = [&](UserData *user) -> bool { for (const auto &nameWord : user->nameWords()) { if (nameWord.startsWith(_filter, Qt::CaseInsensitive)) { - const auto exactUsername = - (PrimaryUsername(user).compare(_filter, Qt::CaseInsensitive) == 0); + const auto exactUsername = PrimaryUsername(user).compare( + _filter, + Qt::CaseInsensitive) == 0; return exactUsername; } } diff --git a/Telegram/SourceFiles/core/application.cpp b/Telegram/SourceFiles/core/application.cpp index 9e3997a42..6f82c252e 100644 --- a/Telegram/SourceFiles/core/application.cpp +++ b/Telegram/SourceFiles/core/application.cpp @@ -933,8 +933,8 @@ void Application::handleAppDeactivated() { } rpl::producer<bool> Application::appDeactivatedValue() const { - const auto &app = - static_cast<QGuiApplication*>(QCoreApplication::instance()); + const auto &app + = static_cast<QGuiApplication*>(QCoreApplication::instance()); return rpl::single( app->applicationState() ) | rpl::then( diff --git a/Telegram/SourceFiles/core/core_cloud_password.cpp b/Telegram/SourceFiles/core/core_cloud_password.cpp index 3a65f24d5..a835112dc 100644 --- a/Telegram/SourceFiles/core/core_cloud_password.cpp +++ b/Telegram/SourceFiles/core/core_cloud_password.cpp @@ -313,8 +313,8 @@ CloudPasswordState ParseCloudPasswordState( ParseCloudPasswordAlgo(data.vnew_algo())); result.mtp.newSecureSecret = ValidateNewSecureSecretAlgo( ParseSecureSecretAlgo(data.vnew_secure_algo())); - result.unconfirmedPattern = - qs(data.vemail_unconfirmed_pattern().value_or_empty()); + result.unconfirmedPattern = qs( + data.vemail_unconfirmed_pattern().value_or_empty()); result.pendingResetDate = data.vpending_reset_date().value_or_empty(); result.outdatedClient = [&] { diff --git a/Telegram/SourceFiles/core/core_settings.cpp b/Telegram/SourceFiles/core/core_settings.cpp index bbff44551..c8297e668 100644 --- a/Telegram/SourceFiles/core/core_settings.cpp +++ b/Telegram/SourceFiles/core/core_settings.cpp @@ -160,6 +160,10 @@ QByteArray Settings::serialize() const { const auto &recentEmojiPreloadData = _recentEmojiPreload.empty() ? recentEmojiPreloadGenerated : _recentEmojiPreload; + const auto noWarningExtensions = QStringList( + begin(_noWarningExtensions), + end(_noWarningExtensions) + ).join(' '); auto size = Serialize::bytearraySize(themesAccentColors) + sizeof(qint32) * 5 @@ -216,7 +220,8 @@ QByteArray Settings::serialize() const { + Serialize::stringSize(_captureDeviceId.current()) + Serialize::stringSize(_callPlaybackDeviceId.current()) + Serialize::stringSize(_callCaptureDeviceId.current()) - + Serialize::bytearraySize(ivPosition); + + Serialize::bytearraySize(ivPosition) + + Serialize::stringSize(noWarningExtensions); auto result = QByteArray(); result.reserve(size); @@ -256,7 +261,7 @@ QByteArray Settings::serialize() const { << qint32(_sendSubmitWay) << qint32(_includeMutedCounter ? 1 : 0) << qint32(_countUnreadMessages ? 1 : 0) - << qint32(_exeLaunchWarning ? 1 : 0) + << qint32(1) // legacy exe launch warning << qint32(_notifyAboutPinned.current() ? 1 : 0) << qint32(_loopAnimatedStickers ? 1 : 0) << qint32(_largeEmoji.current() ? 1 : 0) @@ -361,7 +366,8 @@ QByteArray Settings::serialize() const { << _captureDeviceId.current() << _callPlaybackDeviceId.current() << _callCaptureDeviceId.current() - << ivPosition; + << ivPosition + << noWarningExtensions; } Ensures(result.size() == size); @@ -412,7 +418,8 @@ void Settings::addFromSerialized(const QByteArray &serialized) { qint32 sendSubmitWay = static_cast<qint32>(_sendSubmitWay); qint32 includeMutedCounter = _includeMutedCounter ? 1 : 0; qint32 countUnreadMessages = _countUnreadMessages ? 1 : 0; - qint32 exeLaunchWarning = _exeLaunchWarning ? 1 : 0; + std::optional<QString> noWarningExtensions; + qint32 legacyExeLaunchWarning = 1; qint32 notifyAboutPinned = _notifyAboutPinned.current() ? 1 : 0; qint32 loopAnimatedStickers = _loopAnimatedStickers ? 1 : 0; qint32 largeEmoji = _largeEmoji.current() ? 1 : 0; @@ -519,7 +526,7 @@ void Settings::addFromSerialized(const QByteArray &serialized) { >> sendSubmitWay >> includeMutedCounter >> countUnreadMessages - >> exeLaunchWarning + >> legacyExeLaunchWarning >> notifyAboutPinned >> loopAnimatedStickers >> largeEmoji @@ -761,6 +768,10 @@ void Settings::addFromSerialized(const QByteArray &serialized) { if (!stream.atEnd()) { stream >> ivPosition; } + if (!stream.atEnd()) { + noWarningExtensions = QString(); + stream >> *noWarningExtensions; + } if (stream.status() != QDataStream::Ok) { LOG(("App Error: " "Bad data for Core::Settings::constructFromSerialized()")); @@ -824,7 +835,12 @@ void Settings::addFromSerialized(const QByteArray &serialized) { } _includeMutedCounter = (includeMutedCounter == 1); _countUnreadMessages = (countUnreadMessages == 1); - _exeLaunchWarning = (exeLaunchWarning == 1); + if (noWarningExtensions) { + const auto list = noWarningExtensions->mid(0, 10240) + .split(' ', Qt::SkipEmptyParts) + .mid(0, 1024); + _noWarningExtensions = base::flat_set<QString>(list.begin(), list.end()); + } _ipRevealWarning = (ipRevealWarning == 1); _notifyAboutPinned = (notifyAboutPinned == 1); _loopAnimatedStickers = (loopAnimatedStickers == 1); @@ -1290,7 +1306,7 @@ void Settings::resetOnLastLogout() { //_sendSubmitWay = Ui::InputSubmitSettings::Enter; _soundOverrides = {}; - _exeLaunchWarning = true; + _noWarningExtensions.clear(); _ipRevealWarning = true; _loopAnimatedStickers = true; _largeEmoji = true; diff --git a/Telegram/SourceFiles/core/core_settings.h b/Telegram/SourceFiles/core/core_settings.h index bc40e39e0..e1ff616ec 100644 --- a/Telegram/SourceFiles/core/core_settings.h +++ b/Telegram/SourceFiles/core/core_settings.h @@ -404,11 +404,12 @@ public: } [[nodiscard]] QString getSoundPath(const QString &key) const; - [[nodiscard]] bool exeLaunchWarning() const { - return _exeLaunchWarning; + [[nodiscard]] auto noWarningExtensions() const + -> const base::flat_set<QString> & { + return _noWarningExtensions; } - void setExeLaunchWarning(bool warning) { - _exeLaunchWarning = warning; + void setNoWarningExtensions(base::flat_set<QString> extensions) { + _noWarningExtensions = std::move(extensions); } [[nodiscard]] bool ipRevealWarning() const { return _ipRevealWarning; @@ -939,7 +940,7 @@ private: Ui::SendFilesWay _sendFilesWay = Ui::SendFilesWay(); Ui::InputSubmitSettings _sendSubmitWay = Ui::InputSubmitSettings(); base::flat_map<QString, QString> _soundOverrides; - bool _exeLaunchWarning = true; + base::flat_set<QString> _noWarningExtensions; bool _ipRevealWarning = true; bool _loopAnimatedStickers = true; rpl::variable<bool> _largeEmoji = true; @@ -990,8 +991,8 @@ private: #else // Q_OS_MAC bool _hardwareAcceleratedVideo = false; #endif // Q_OS_MAC - HistoryView::DoubleClickQuickAction _chatQuickAction = - HistoryView::DoubleClickQuickAction(); + HistoryView::DoubleClickQuickAction _chatQuickAction + = HistoryView::DoubleClickQuickAction(); bool _translateButtonEnabled = false; rpl::variable<bool> _translateChatEnabled = true; rpl::variable<int> _translateToRaw = 0; diff --git a/Telegram/SourceFiles/core/mime_type.cpp b/Telegram/SourceFiles/core/mime_type.cpp index 8ba1b6494..7467145cf 100644 --- a/Telegram/SourceFiles/core/mime_type.cpp +++ b/Telegram/SourceFiles/core/mime_type.cpp @@ -37,6 +37,12 @@ namespace { && data->hasImage(); } +[[nodiscard]] base::flat_set<QString> SplitExtensions( + const QString &joined) { + const auto list = joined.split(' '); + return base::flat_set<QString>(list.begin(), list.end()); +} + } // namespace MimeType::MimeType(const QMimeType &type) : _typeStruct(type) { @@ -162,22 +168,9 @@ bool IsMimeAcceptedForPhotoVideoAlbum(const QString &mime) { } bool FileIsImage(const QString &name, const QString &mime) { - QString lowermime = mime.toLower(), namelower = name.toLower(); - if (lowermime.startsWith(u"image/"_q)) { - return true; - } else if (namelower.endsWith(u".bmp"_q) - || namelower.endsWith(u".jpg"_q) - || namelower.endsWith(u".jpeg"_q) - || namelower.endsWith(u".gif"_q) - || namelower.endsWith(u".webp"_q) - || namelower.endsWith(u".tga"_q) - || namelower.endsWith(u".tiff"_q) - || namelower.endsWith(u".tif"_q) - || namelower.endsWith(u".psd"_q) - || namelower.endsWith(u".png"_q)) { - return true; - } - return false; + return name.isEmpty() + ? mime.toLower().startsWith(u"image/"_q) + : (DetectNameType(name) == NameType::Image); } std::shared_ptr<QMimeData> ShareMimeMediaData( @@ -194,10 +187,10 @@ std::shared_ptr<QMimeData> ShareMimeMediaData( result->setData(u"application/x-td-use-jpeg"_q, "1"); result->setData(u"image/jpeg"_q, original->data(u"image/jpeg"_q)); } - if (auto list = Core::ReadMimeUrls(original); !list.isEmpty()) { + if (auto list = ReadMimeUrls(original); !list.isEmpty()) { result->setUrls(std::move(list)); } - result->setText(Core::ReadMimeText(original)); + result->setText(ReadMimeText(original)); return result; } @@ -240,4 +233,116 @@ bool CanSendFiles(not_null<const QMimeData*> data) { return false; } +QString FileExtension(const QString &filepath) { + const auto reversed = ranges::views::reverse(filepath); + const auto last = ranges::find_first_of(reversed, ".\\/"); + if (last == reversed.end() || *last != '.') { + return QString(); + } + return QString(last.base(), last - reversed.begin()); +} + +NameType DetectNameType(const QString &filepath) { + static const auto kImage = SplitExtensions(u"\ +afdesign ai avif bmp dng gif heic icns ico jfif jpeg jpg jpg-large nef png \ +png-large psd raw sketch svg tga tif tiff webp"_q); + static const auto kVideo = SplitExtensions(u"\ +3g2 3gp 3gpp aep avi flv h264 m4s m4v mkv mov mp4 mpeg mpg ogv srt tgs tgv \ +vob webm wmv"_q); + static const auto kAudio = SplitExtensions(u"\ +aac ac3 aif amr caf cda cue flac m4a m4b mid midi mp3 ogg opus wav wma"_q); + static const auto kDocument = SplitExtensions(u"\ +pdf doc docx ppt pptx pps ppsx xls xlsx txt rtf odt ods odp csv text log tl \ +tex xspf xml djvu diag ps ost kml pub epub mobi cbr cbz fb2 prc ris pem p7b \ +m3u m3u8 wpd wpl htm html xhtml key"_q); + static const auto kArchive = SplitExtensions(u"\ +7z arj bz2 gz rar tar xz z zip zst"_q); + static const auto kThemeFile = SplitExtensions(u"\ +tdesktop-theme tdesktop-palette tgios-theme attheme"_q); + static const auto kOtherBenign = SplitExtensions(u"\ +c cc cpp cxx h m mm swift cs ts class java css ninja cmake patch diff plist \ +gyp gitignore strings asoundrc torrent csr json xaml md keylayout sql \ +sln xib mk \ +\ +dmg img iso vcd \ +\ +pdb eot ics ips ipa core mem pcap ovpn part pcapng dmp pkpass dat zxp crash \ +file bak gbr plain dlc fon fnt otf ttc ttf gpx db rss cur \ +\ +tdesktop-endpoints"_q); + + static const auto kExecutable = SplitExtensions( +#ifdef Q_OS_WIN + u"\ +ad ade adp ahk app application appref-ms asp aspx asx bas bat bin cab cdxml \ +cer cfg cgi chi chm cmd cnt com conf cpl crt csh der diagcab dll drv eml \ +exe fon fxp gadget grp hlp hpj hta htt inf ini ins inx isp isu its jar jnlp \ +job js jse jsp key ksh lexe library-ms lnk local lua mad maf mag mam \ +manifest maq mar mas mat mau mav maw mcf mda mdb mde mdt mdw mdz mht mhtml \ +mjs mmc mof msc msg msh msh1 msh2 msh1xml msh2xml mshxml msi msp mst ops \ +osd paf pcd phar php php3 php4 php5 php7 phps php-s pht phtml pif pl plg pm \ +pod prf prg ps1 ps2 ps1xml ps2xml psc1 psc2 psd1 psm1 pssc pst py py3 pyc \ +pyd pyi pyo pyw pyzw pyz rb reg rgs scf scr sct search-ms settingcontent-ms \ +sh shb shs slk sys swf t tmp u3p url vb vbe vbp vbs vbscript vdx vsmacros \ +vsd vsdm vsdx vss vssm vssx vst vstm vstx vsw vsx vtx website wlua ws wsc \ +wsf wsh xbap xll xlsm xnk xs"_q +#elif defined Q_OS_MAC // Q_OS_MAC + u"\ +applescript action app bin command csh osx workflow terminal url caction \ +mpkg pkg scpt scptd xhtm xhtml webarchive"_q +#else // Q_OS_WIN || Q_OS_MAC + u"bin csh deb desktop ksh out pet pkg pup rpm run sh shar slp zsh"_q +#endif // !Q_OS_WIN && !Q_OS_MAC + ); + + const auto extension = FileExtension(filepath).toLower(); + if (kExecutable.contains(extension)) { + return NameType::Executable; + } else if (kImage.contains(extension)) { + return NameType::Image; + } else if (kVideo.contains(extension)) { + return NameType::Video; + } else if (kAudio.contains(extension)) { + return NameType::Audio; + } else if (kDocument.contains(extension)) { + return NameType::Document; + } else if (kArchive.contains(extension)) { + return NameType::Archive; + } else if (kThemeFile.contains(extension)) { + return NameType::ThemeFile; + } else if (kOtherBenign.contains(extension)) { + return NameType::OtherBenign; + } + return NameType::Unknown; +} + +bool NameTypeAllowsThumbnail(NameType type) { + return type == NameType::Image + || type == NameType::Video + || type == NameType::Audio + || type == NameType::Document + || type == NameType::ThemeFile; +} + +bool IsIpRevealingPath(const QString &filepath) { + static const auto kExtensions = [] { + const auto joined = u"htm html svg m4v m3u8 xhtml"_q; + const auto list = joined.split(' '); + return base::flat_set<QString>(list.begin(), list.end()); + }(); + static const auto kMimeTypes = [] { + const auto joined = u"text/html image/svg+xml"_q; + const auto list = joined.split(' '); + return base::flat_set<QString>(list.begin(), list.end()); + }(); + + return ranges::binary_search( + kExtensions, + FileExtension(filepath).toLower() + ) || ranges::binary_search( + kMimeTypes, + QMimeDatabase().mimeTypeForFile(QFileInfo(filepath)).name() + ); +} + } // namespace Core diff --git a/Telegram/SourceFiles/core/mime_type.h b/Telegram/SourceFiles/core/mime_type.h index 3271adafe..ebf4db64b 100644 --- a/Telegram/SourceFiles/core/mime_type.h +++ b/Telegram/SourceFiles/core/mime_type.h @@ -69,4 +69,21 @@ struct MimeImageData { [[nodiscard]] QList<QUrl> ReadMimeUrls(not_null<const QMimeData*> data); [[nodiscard]] bool CanSendFiles(not_null<const QMimeData*> data); +enum class NameType : uchar { + Unknown, + Executable, + Image, + Video, + Audio, + Document, + Archive, + ThemeFile, + OtherBenign, +}; + +[[nodiscard]] QString FileExtension(const QString &filepath); +[[nodiscard]] NameType DetectNameType(const QString &filepath); +[[nodiscard]] bool NameTypeAllowsThumbnail(NameType type); +[[nodiscard]] bool IsIpRevealingPath(const QString &filepath); + } // namespace Core diff --git a/Telegram/SourceFiles/core/sandbox.cpp b/Telegram/SourceFiles/core/sandbox.cpp index 6feacdb5b..3daf91784 100644 --- a/Telegram/SourceFiles/core/sandbox.cpp +++ b/Telegram/SourceFiles/core/sandbox.cpp @@ -82,7 +82,6 @@ bool Sandbox::QuitOnStartRequested = false; Sandbox::Sandbox(int &argc, char **argv) : QApplication(argc, argv) , _mainThreadId(QThread::currentThreadId()) { - setQuitOnLastWindowClosed(false); } int Sandbox::start() { diff --git a/Telegram/SourceFiles/core/sandbox.h b/Telegram/SourceFiles/core/sandbox.h index 4c15c2828..dfb1fe4a6 100644 --- a/Telegram/SourceFiles/core/sandbox.h +++ b/Telegram/SourceFiles/core/sandbox.h @@ -107,6 +107,7 @@ private: void readClients(); void removeClients(); + QEventLoopLocker _eventLoopLocker; const Qt::HANDLE _mainThreadId = nullptr; int _eventNestingLevel = 0; int _loopNestingLevel = 0; diff --git a/Telegram/SourceFiles/core/shortcuts.cpp b/Telegram/SourceFiles/core/shortcuts.cpp index 08d8cc59b..43ccc4f8a 100644 --- a/Telegram/SourceFiles/core/shortcuts.cpp +++ b/Telegram/SourceFiles/core/shortcuts.cpp @@ -230,8 +230,24 @@ void WriteDefaultCustomFile() { const auto path = CustomFilePath(); auto input = QFile(":/misc/default_shortcuts-custom.json"); auto output = QFile(path); - if (input.open(QIODevice::ReadOnly) && output.open(QIODevice::WriteOnly)) { + if (input.open(QIODevice::ReadOnly) + && output.open(QIODevice::WriteOnly)) { +#ifdef Q_OS_MAC + auto text = qs(input.readAll()); + const auto note = R"( +// Note: +// On Apple platforms, reference to "ctrl" corresponds to the Command keys )" + + QByteArray() + + R"(on the Macintosh keyboard. +// On Apple platforms, reference to "meta" corresponds to the Control keys. + +[ +)"; + text.replace(u"\n\n["_q, QString(note)); + output.write(text.toUtf8()); +#else output.write(input.readAll()); +#endif // !Q_OS_MAC } } diff --git a/Telegram/SourceFiles/core/ui_integration.cpp b/Telegram/SourceFiles/core/ui_integration.cpp index 5f0c200a7..75a4d9e8a 100644 --- a/Telegram/SourceFiles/core/ui_integration.cpp +++ b/Telegram/SourceFiles/core/ui_integration.cpp @@ -13,9 +13,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "core/application.h" #include "core/sandbox.h" #include "core/click_handler_types.h" +#include "data/components/sponsored_messages.h" #include "data/stickers/data_custom_emoji.h" #include "data/data_session.h" -#include "data/data_sponsored_messages.h" #include "iv/iv_instance.h" #include "ui/text/text_custom_emoji.h" #include "ui/basic_click_handlers.h" @@ -303,7 +303,7 @@ bool UiIntegration::allowClickHandlerActivation( const ClickContext &context) { const auto my = context.other.value<ClickHandlerContext>(); if (const auto window = my.sessionWindow.get()) { - window->session().data().sponsoredMessages().clicked(my.itemId); + window->session().sponsoredMessages().clicked(my.itemId); } return true; } diff --git a/Telegram/SourceFiles/core/version.h b/Telegram/SourceFiles/core/version.h index ffbc3b76c..4230495a6 100644 --- a/Telegram/SourceFiles/core/version.h +++ b/Telegram/SourceFiles/core/version.h @@ -22,7 +22,7 @@ constexpr auto AppId = "{53F49750-6209-4FBF-9CA8-7A333C87D666}"_cs; constexpr auto AppNameOld = "AyuGram for Windows"_cs; constexpr auto AppName = "AyuGram Desktop"_cs; constexpr auto AppFile = "AyuGram"_cs; -constexpr auto AppVersion = 4016006; -constexpr auto AppVersionStr = "4.16.6"; +constexpr auto AppVersion = 4016008; +constexpr auto AppVersionStr = "4.16.8"; constexpr auto AppBetaVersion = false; constexpr auto AppAlphaVersion = TDESKTOP_ALPHA_VERSION; diff --git a/Telegram/SourceFiles/data/data_scheduled_messages.cpp b/Telegram/SourceFiles/data/components/scheduled_messages.cpp similarity index 98% rename from Telegram/SourceFiles/data/data_scheduled_messages.cpp rename to Telegram/SourceFiles/data/components/scheduled_messages.cpp index ffe4ab436..92e0da880 100644 --- a/Telegram/SourceFiles/data/data_scheduled_messages.cpp +++ b/Telegram/SourceFiles/data/components/scheduled_messages.cpp @@ -5,7 +5,7 @@ the official desktop application for the Telegram messaging service. For license and copyright information please follow this link: https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL */ -#include "data/data_scheduled_messages.h" +#include "data/components/scheduled_messages.h" #include "base/unixtime.h" #include "data/data_forum_topic.h" @@ -101,10 +101,10 @@ bool IsScheduledMsgId(MsgId id) { return (id > ServerMaxMsgId) && (id < ScheduledMaxMsgId); } -ScheduledMessages::ScheduledMessages(not_null<Session*> owner) -: _session(&owner->session()) +ScheduledMessages::ScheduledMessages(not_null<Main::Session*> session) +: _session(session) , _clearTimer([=] { clearOldRequests(); }) { - owner->itemRemoved( + _session->data().itemRemoved( ) | rpl::filter([](not_null<const HistoryItem*> item) { return item->isScheduled(); }) | rpl::start_with_next([=](not_null<const HistoryItem*> item) { @@ -113,9 +113,16 @@ ScheduledMessages::ScheduledMessages(not_null<Session*> owner) } ScheduledMessages::~ScheduledMessages() { - for (const auto &request : _requests) { + Expects(_data.empty()); + Expects(_requests.empty()); +} + +void ScheduledMessages::clear() { + _lifetime.destroy(); + for (const auto &request : base::take(_requests)) { _session->api().request(request.second.requestId).cancel(); } + base::take(_data); } void ScheduledMessages::clearOldRequests() { diff --git a/Telegram/SourceFiles/data/data_scheduled_messages.h b/Telegram/SourceFiles/data/components/scheduled_messages.h similarity index 97% rename from Telegram/SourceFiles/data/data_scheduled_messages.h rename to Telegram/SourceFiles/data/components/scheduled_messages.h index 5daacd099..90d5b0415 100644 --- a/Telegram/SourceFiles/data/data_scheduled_messages.h +++ b/Telegram/SourceFiles/data/components/scheduled_messages.h @@ -18,14 +18,13 @@ class Session; namespace Data { -class Session; struct MessagesSlice; [[nodiscard]] bool IsScheduledMsgId(MsgId id); class ScheduledMessages final { public: - explicit ScheduledMessages(not_null<Session*> owner); + explicit ScheduledMessages(not_null<Main::Session*> session); ScheduledMessages(const ScheduledMessages &other) = delete; ScheduledMessages &operator=(const ScheduledMessages &other) = delete; ~ScheduledMessages(); @@ -56,6 +55,8 @@ public: [[nodiscard]] Data::MessagesSlice list( not_null<const Data::ForumTopic*> topic) const; + void clear(); + private: using OwnedItem = std::unique_ptr<HistoryItem, HistoryItem::Destroyer>; struct List { diff --git a/Telegram/SourceFiles/data/data_sponsored_messages.cpp b/Telegram/SourceFiles/data/components/sponsored_messages.cpp similarity index 99% rename from Telegram/SourceFiles/data/data_sponsored_messages.cpp rename to Telegram/SourceFiles/data/components/sponsored_messages.cpp index c22cce33a..23d4e1e45 100644 --- a/Telegram/SourceFiles/data/data_sponsored_messages.cpp +++ b/Telegram/SourceFiles/data/components/sponsored_messages.cpp @@ -5,7 +5,7 @@ the official desktop application for the Telegram messaging service. For license and copyright information please follow this link: https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL */ -#include "data/data_sponsored_messages.h" +#include "data/components/sponsored_messages.h" #include "api/api_text_entities.h" #include "apiwrap.h" @@ -34,8 +34,8 @@ constexpr auto kRequestTimeLimit = 5 * 60 * crl::time(1000); } // namespace -SponsoredMessages::SponsoredMessages(not_null<Session*> owner) -: _session(&owner->session()) +SponsoredMessages::SponsoredMessages(not_null<Main::Session*> session) +: _session(session) , _clearTimer([=] { clearOldRequests(); }) { } diff --git a/Telegram/SourceFiles/data/data_sponsored_messages.h b/Telegram/SourceFiles/data/components/sponsored_messages.h similarity index 98% rename from Telegram/SourceFiles/data/data_sponsored_messages.h rename to Telegram/SourceFiles/data/components/sponsored_messages.h index cad8a6134..022ccd19e 100644 --- a/Telegram/SourceFiles/data/data_sponsored_messages.h +++ b/Telegram/SourceFiles/data/components/sponsored_messages.h @@ -20,8 +20,6 @@ class Session; namespace Data { -class Session; - struct SponsoredReportResult final { using Id = QByteArray; struct Option final { @@ -89,7 +87,7 @@ public: bool canReport = false; }; using RandomId = QByteArray; - explicit SponsoredMessages(not_null<Session*> owner); + explicit SponsoredMessages(not_null<Main::Session*> session); SponsoredMessages(const SponsoredMessages &other) = delete; SponsoredMessages &operator=(const SponsoredMessages &other) = delete; ~SponsoredMessages(); diff --git a/Telegram/SourceFiles/data/data_cloud_file.cpp b/Telegram/SourceFiles/data/data_cloud_file.cpp index bee90358a..526dd8904 100644 --- a/Telegram/SourceFiles/data/data_cloud_file.cpp +++ b/Telegram/SourceFiles/data/data_cloud_file.cpp @@ -22,6 +22,14 @@ CloudFile::~CloudFile() { base::take(loader); } +void CloudFile::clear() { + location = {}; + base::take(loader); + byteSize = 0; + progressivePartSize = 0; + flags = {}; +} + CloudImage::CloudImage() = default; CloudImage::CloudImage( diff --git a/Telegram/SourceFiles/data/data_cloud_file.h b/Telegram/SourceFiles/data/data_cloud_file.h index e71cbe462..b44a35c7d 100644 --- a/Telegram/SourceFiles/data/data_cloud_file.h +++ b/Telegram/SourceFiles/data/data_cloud_file.h @@ -37,6 +37,8 @@ struct CloudFile final { ~CloudFile(); + void clear(); + ImageLocation location; std::unique_ptr<FileLoader> loader; int byteSize = 0; diff --git a/Telegram/SourceFiles/data/data_document.cpp b/Telegram/SourceFiles/data/data_document.cpp index afe91b8a1..9c25a7861 100644 --- a/Telegram/SourceFiles/data/data_document.cpp +++ b/Telegram/SourceFiles/data/data_document.cpp @@ -478,6 +478,31 @@ void DocumentData::setattributes( _additional = nullptr; } + if (!_filename.isEmpty()) { + using Type = Core::NameType; + if (type == VideoDocument + || type == AnimatedDocument + || type == RoundVideoDocument + || isAnimation()) { + if (!enforceNameType(Type::Video)) { + type = FileDocument; + _additional = nullptr; + } + } + if (type == SongDocument || type == VoiceDocument || isAudioFile()) { + if (!enforceNameType(Type::Audio)) { + type = FileDocument; + _additional = nullptr; + } + } + if (!Core::NameTypeAllowsThumbnail(_nameType)) { + _inlineThumbnailBytes = {}; + _flags &= ~Flag::InlineThumbnailIsPath; + _thumbnail.clear(); + _videoThumbnail.clear(); + } + } + if (isAudioFile() || isAnimation() || isVoiceMessage() @@ -530,6 +555,10 @@ void DocumentData::updateThumbnails( const ImageWithLocation &thumbnail, const ImageWithLocation &videoThumbnail, bool isPremiumSticker) { + if (!_filename.isEmpty() + && !Core::NameTypeAllowsThumbnail(Core::DetectNameType(_filename))) { + return; + } if (!inlineThumbnail.bytes.isEmpty() && _inlineThumbnailBytes.isEmpty()) { _inlineThumbnailBytes = inlineThumbnail.bytes; @@ -919,6 +948,25 @@ void DocumentData::setFileName(const QString &remoteFileName) { for (const auto &ch : controls) { _filename = std::move(_filename).replace(ch, "_"); } + _nameType = Core::DetectNameType(_filename); +} + +bool DocumentData::enforceNameType(Core::NameType nameType) { + if (_nameType == nameType) { + return true; + } + const auto base = _filename.isEmpty() ? u"file"_q : _filename; + const auto mime = Core::MimeTypeForName(mimeString()); + const auto patterns = mime.globPatterns(); + for (const auto &pattern : mime.globPatterns()) { + const auto now = base + QString(pattern).replace('*', QString()); + if (Core::DetectNameType(now) == nameType) { + _filename = now; + _nameType = nameType; + return true; + } + } + return false; } void DocumentData::setLoadedInMediaCacheLocation() { @@ -1460,6 +1508,10 @@ QString DocumentData::filename() const { return _filename; } +Core::NameType DocumentData::nameType() const { + return _nameType; +} + QString DocumentData::mimeString() const { return _mimeString; } @@ -1527,7 +1579,10 @@ bool DocumentData::isVideoMessage() const { bool DocumentData::isAnimation() const { return (type == AnimatedDocument) || isVideoMessage() - || (hasMimeType(u"image/gif"_q) + || ((_filename.isEmpty() + || _nameType == Core::NameType::Image + || _nameType == Core::NameType::Video) + && hasMimeType(u"image/gif"_q) && !(_flags & Flag::StreamingPlaybackFailed)); } @@ -1537,9 +1592,11 @@ bool DocumentData::isGifv() const { } bool DocumentData::isTheme() const { - return hasMimeType(u"application/x-tgtheme-tdesktop"_q) - || _filename.endsWith(u".tdesktop-theme"_q, Qt::CaseInsensitive) - || _filename.endsWith(u".tdesktop-palette"_q, Qt::CaseInsensitive); + return _filename.endsWith(u".tdesktop-theme"_q, Qt::CaseInsensitive) + || _filename.endsWith(u".tdesktop-palette"_q, Qt::CaseInsensitive) + || (hasMimeType(u"application/x-tgtheme-tdesktop"_q) + && (_filename.isEmpty() + || _nameType == Core::NameType::ThemeFile)); } bool DocumentData::isSong() const { @@ -1562,6 +1619,10 @@ bool DocumentData::isAudioFile() const { return true; } return false; + } else if (!_filename.isEmpty() + && _nameType != Core::NameType::Audio + && _nameType != Core::NameType::Video) { + return false; } const auto left = _mimeString.mid(prefix.size()); const auto types = { u"x-wav"_q, u"wav"_q, u"mp4"_q }; diff --git a/Telegram/SourceFiles/data/data_document.h b/Telegram/SourceFiles/data/data_document.h index 82fcd9ba3..93297550c 100644 --- a/Telegram/SourceFiles/data/data_document.h +++ b/Telegram/SourceFiles/data/data_document.h @@ -20,6 +20,10 @@ namespace Images { class Source; } // namespace Images +namespace Core { +enum class NameType : uchar; +} // namespace Core + namespace Storage { namespace Cache { struct Key; @@ -255,6 +259,7 @@ public: void collectLocalData(not_null<DocumentData*> local); [[nodiscard]] QString filename() const; + [[nodiscard]] Core::NameType nameType() const; [[nodiscard]] QString mimeString() const; [[nodiscard]] bool hasMimeType(const QString &mime) const; void setMimeString(const QString &mime); @@ -340,6 +345,7 @@ private: void setMaybeSupportsStreaming(bool supports); void setLoadedInMediaCacheLocation(); void setFileName(const QString &remoteFileName); + bool enforceNameType(Core::NameType nameType); void finishLoad(); void handleLoaderUpdates(); @@ -373,6 +379,7 @@ private: std::unique_ptr<DocumentAdditionalData> _additional; mutable Flags _flags = kStreamingSupportedUnknown; GoodThumbnailState _goodThumbnailState = GoodThumbnailState(); + Core::NameType _nameType = Core::NameType(); std::unique_ptr<FileLoader> _loader; }; diff --git a/Telegram/SourceFiles/data/data_document_media.cpp b/Telegram/SourceFiles/data/data_document_media.cpp index a7783605c..9cb579812 100644 --- a/Telegram/SourceFiles/data/data_document_media.cpp +++ b/Telegram/SourceFiles/data/data_document_media.cpp @@ -22,6 +22,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "window/themes/window_theme_preview.h" #include "core/core_settings.h" #include "core/application.h" +#include "core/mime_type.h" #include "storage/file_download.h" #include "ui/chat/attach/attach_prepare.h" @@ -295,10 +296,12 @@ void DocumentMedia::automaticLoad( // No automatic download in this case. return; } + const auto indata = _owner->filename(); const auto filename = toCache ? QString() : DocumentFileNameForSave(_owner); - const auto shouldLoadFromCloud = !Data::IsExecutableName(filename) + const auto shouldLoadFromCloud = (indata.isEmpty() + || Core::DetectNameType(indata) != Core::NameType::Executable) && (item ? Data::AutoDownload::Should( _owner->session().settings().autoDownload(), diff --git a/Telegram/SourceFiles/data/data_document_resolver.cpp b/Telegram/SourceFiles/data/data_document_resolver.cpp index 8ab502564..575d695cf 100644 --- a/Telegram/SourceFiles/data/data_document_resolver.cpp +++ b/Telegram/SourceFiles/data/data_document_resolver.cpp @@ -28,6 +28,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "ui/chat/chat_theme.h" #include "ui/text/text_utilities.h" #include "ui/widgets/checkbox.h" +#include "ui/wrap/slide_wrap.h" #include "window/window_session_controller.h" #include "styles/style_layers.h" @@ -46,11 +47,12 @@ base::options::toggle OptionExternalVideoPlayer({ void ConfirmDontWarnBox( not_null<Ui::GenericBox*> box, rpl::producer<TextWithEntities> &&text, + rpl::producer<QString> &&check, rpl::producer<QString> &&confirm, Fn<void(bool)> callback) { auto checkbox = object_ptr<Ui::Checkbox>( box.get(), - tr::lng_launch_exe_dont_ask(), + std::move(check), false, st::defaultBoxCheckbox); const auto weak = Ui::MakeWeak(checkbox.data()); @@ -67,29 +69,43 @@ void ConfirmDontWarnBox( auto padding = st::boxPadding; padding.setTop(padding.bottom()); box->addRow(std::move(checkbox), std::move(padding)); + box->addRow(object_ptr<Ui::SlideWrap<Ui::FlatLabel>>( + box, + object_ptr<Ui::FlatLabel>( + box, + tr::lng_launch_dont_ask_settings(), + st::boxLabel) + ))->toggleOn(weak->checkedValue()); } void LaunchWithWarning( // not_null<Window::Controller*> controller, const QString &name, HistoryItem *item) { - const auto isExecutable = Data::IsExecutableName(name); - const auto isIpReveal = Data::IsIpRevealingName(name); + const auto nameType = Core::DetectNameType(name); + const auto isIpReveal = (nameType != Core::NameType::Executable) + && Core::IsIpRevealingPath(name); + const auto extension = Core::FileExtension(name).toLower(); + auto &app = Core::App(); + auto &settings = app.settings(); const auto warn = [&] { if (item && item->history()->peer->isVerified()) { return false; } - return (isExecutable && app.settings().exeLaunchWarning()) - || (isIpReveal && app.settings().ipRevealWarning()); + return (isIpReveal && settings.ipRevealWarning()) + || ((nameType == Core::NameType::Executable + || nameType == Core::NameType::Unknown) + && !settings.noWarningExtensions().contains(extension)); }(); - const auto extension = '.' + Data::FileExtension(name); - if (Platform::IsWindows() && extension == u"."_q) { + if (extension.isEmpty()) { // If you launch a file without extension, like "test", in case // there is an executable file with the same name in this folder, // like "test.bat", the executable file will be launched. // // Now we always force an Open With dialog box for such files. + // + // Let's force it for all platforms for files without extension. crl::on_main([=] { Platform::File::UnsafeShowOpenWith(name); }); @@ -98,27 +114,38 @@ void LaunchWithWarning( File::Launch(name); return; } - const auto callback = [=, &app](bool checked) { + const auto callback = [=, &app, &settings](bool checked) { if (checked) { - if (isExecutable) { - app.settings().setExeLaunchWarning(false); - } else if (isIpReveal) { - app.settings().setIpRevealWarning(false); + if (isIpReveal) { + settings.setIpRevealWarning(false); + } else { + auto copy = settings.noWarningExtensions(); + copy.emplace(extension); + settings.setNoWarningExtensions(std::move(copy)); } app.saveSettingsDelayed(); } File::Launch(name); }; - auto text = isExecutable - ? tr::lng_launch_exe_warning( - lt_extension, - rpl::single(Ui::Text::Bold(extension)), - Ui::Text::WithEntities) - : tr::lng_launch_svg_warning(Ui::Text::WithEntities); + auto text = isIpReveal + ? tr::lng_launch_svg_warning(Ui::Text::WithEntities) + : ((nameType == Core::NameType::Executable) + ? tr::lng_launch_exe_warning + : tr::lng_launch_other_warning)( + lt_extension, + rpl::single(Ui::Text::Bold('.' + extension)), + Ui::Text::WithEntities); + auto check = (isIpReveal + ? tr::lng_launch_exe_dont_ask + : tr::lng_launch_dont_ask)(); + auto confirm = ((nameType == Core::NameType::Executable) + ? tr::lng_launch_exe_sure + : tr::lng_launch_other_sure)(); Ui::show(Box( ConfirmDontWarnBox, std::move(text), - (isExecutable ? tr::lng_launch_exe_sure : tr::lng_continue)(), + std::move(check), + std::move(confirm), callback)); } @@ -126,91 +153,6 @@ void LaunchWithWarning( const char kOptionExternalVideoPlayer[] = "external-video-player"; -QString FileExtension(const QString &filepath) { - const auto reversed = ranges::views::reverse(filepath); - const auto last = ranges::find_first_of(reversed, ".\\/"); - if (last == reversed.end() || *last != '.') { - return QString(); - } - return QString(last.base(), last - reversed.begin()); -} - -#if 0 -bool IsValidMediaFile(const QString &filepath) { - static const auto kExtensions = [] { - const auto list = qsl("\ -16svx 2sf 3g2 3gp 8svx aac aaf aif aifc aiff amr amv ape asf ast au aup \ -avchd avi brstm bwf cam cdda cust dat divx drc dsh dsf dts dtshd dtsma \ -dvr-ms dwd evo f4a f4b f4p f4v fla flac flr flv gif gifv gsf gsm gym iff \ -ifo it jam la ly m1v m2p m2ts m2v m4a m4p m4v mcf mid mk3d mka mks mkv mng \ -mov mp1 mp2 mp3 mp4 minipsf mod mpc mpe mpeg mpg mpv mscz mt2 mus mxf mxl \ -niff nsf nsv off ofr ofs ogg ogv opus ots pac ps psf psf2 psflib ptb qsf \ -qt ra raw rka rm rmj rmvb roq s3m shn sib sid smi smp sol spc spx ssf svi \ -swa swf tak ts tta txm usf vgm vob voc vox vqf wav webm wma wmv wrap wtv \ -wv xm xml ym yuv").split(' '); - return base::flat_set<QString>(list.begin(), list.end()); - }(); - - return ranges::binary_search( - kExtensions, - FileExtension(filepath).toLower()); -} -#endif - -bool IsExecutableName(const QString &filepath) { - static const auto kExtensions = [] { - const auto joined = -#ifdef Q_OS_WIN - u"\ -ad ade adp app application appref-ms asp asx bas bat bin cab cdxml cer cfg \ -chi chm cmd cnt com cpl crt csh der diagcab dll drv eml exe fon fxp gadget \ -grp hlp hpj hta htt inf ini ins inx isp isu its jar jnlp job js jse key ksh \ -lnk local lua mad maf mag mam manifest maq mar mas mat mau mav maw mcf mda \ -mdb mde mdt mdw mdz mht mhtml mjs mmc mof msc msg msh msh1 msh2 msh1xml \ -msh2xml mshxml msi msp mst ops osd paf pcd phar php php3 php4 php5 php7 phps \ -php-s pht phtml pif pl plg pm pod prf prg ps1 ps2 ps1xml ps2xml psc1 psc2 \ -psd1 psm1 pssc pst py py3 pyc pyd pyi pyo pyw pywz pyz rb reg rgs scf scr \ -sct search-ms settingcontent-ms sh shb shs slk sys t tmp u3p url vb vbe vbp \ -vbs vbscript vdx vsmacros vsd vsdm vsdx vss vssm vssx vst vstm vstx vsw vsx \ -vtx website ws wsc wsf wsh xbap xll xnk xs"_q; -#elif defined Q_OS_MAC // Q_OS_MAC - u"\ -applescript action app bin command csh osx workflow terminal url caction \ -mpkg pkg scpt scptd xhtm webarchive"_q; -#else // Q_OS_WIN || Q_OS_MAC - u"bin csh deb desktop ksh out pet pkg pup rpm run sh shar \ -slp zsh"_q; -#endif // !Q_OS_WIN && !Q_OS_MAC - const auto list = joined.split(' '); - return base::flat_set<QString>(list.begin(), list.end()); - }(); - - return ranges::binary_search( - kExtensions, - FileExtension(filepath).toLower()); -} - -bool IsIpRevealingName(const QString &filepath) { - static const auto kExtensions = [] { - const auto joined = u"htm html svg m4v m3u8"_q; - const auto list = joined.split(' '); - return base::flat_set<QString>(list.begin(), list.end()); - }(); - static const auto kMimeTypes = [] { - const auto joined = u"text/html image/svg+xml"_q; - const auto list = joined.split(' '); - return base::flat_set<QString>(list.begin(), list.end()); - }(); - - return ranges::binary_search( - kExtensions, - FileExtension(filepath).toLower() - ) || ranges::binary_search( - kMimeTypes, - QMimeDatabase().mimeTypeForFile(QFileInfo(filepath)).name() - ); -} - base::binary_guard ReadBackgroundImageAsync( not_null<Data::DocumentMedia*> media, FnMut<QImage(QImage)> postprocess, diff --git a/Telegram/SourceFiles/data/data_document_resolver.h b/Telegram/SourceFiles/data/data_document_resolver.h index 9931da3e8..4988297aa 100644 --- a/Telegram/SourceFiles/data/data_document_resolver.h +++ b/Telegram/SourceFiles/data/data_document_resolver.h @@ -22,10 +22,6 @@ class DocumentMedia; extern const char kOptionExternalVideoPlayer[]; -[[nodiscard]] QString FileExtension(const QString &filepath); -// [[nodiscard]] bool IsValidMediaFile(const QString &filepath); -[[nodiscard]] bool IsExecutableName(const QString &filepath); -[[nodiscard]] bool IsIpRevealingName(const QString &filepath); base::binary_guard ReadBackgroundImageAsync( not_null<Data::DocumentMedia*> media, FnMut<QImage(QImage)> postprocess, diff --git a/Telegram/SourceFiles/data/data_histories.cpp b/Telegram/SourceFiles/data/data_histories.cpp index 8f599ff03..e9c16c32e 100644 --- a/Telegram/SourceFiles/data/data_histories.cpp +++ b/Telegram/SourceFiles/data/data_histories.cpp @@ -9,13 +9,13 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "api/api_text_entities.h" #include "data/business/data_shortcut_messages.h" +#include "data/components/scheduled_messages.h" #include "data/data_session.h" #include "data/data_channel.h" #include "data/data_chat.h" #include "data/data_folder.h" #include "data/data_forum.h" #include "data/data_forum_topic.h" -#include "data/data_scheduled_messages.h" #include "data/data_user.h" #include "base/unixtime.h" #include "base/random.h" @@ -846,11 +846,12 @@ void Histories::deleteMessages(const MessageIdsList &ids, bool revoke) { if (item->isScheduled()) { const auto wasOnServer = !item->isSending() && !item->hasFailed(); + auto &scheduled = _owner->session().scheduledMessages(); if (wasOnServer) { - scheduledIdsByPeer[history->peer].push_back(MTP_int( - _owner->scheduledMessages().lookupId(item))); + scheduledIdsByPeer[history->peer].push_back( + MTP_int(scheduled.lookupId(item))); } else { - _owner->scheduledMessages().removeSending(item); + scheduled.removeSending(item); } continue; } else if (item->isBusinessShortcut()) { diff --git a/Telegram/SourceFiles/data/data_poll.cpp b/Telegram/SourceFiles/data/data_poll.cpp index f781f95bc..800f3ee32 100644 --- a/Telegram/SourceFiles/data/data_poll.cpp +++ b/Telegram/SourceFiles/data/data_poll.cpp @@ -121,8 +121,8 @@ bool PollData::applyResults(const MTPPollResults &results) { return results.match([&](const MTPDpollResults &results) { _lastResultsUpdate = crl::now(); - const auto newTotalVoters = - results.vtotal_voters().value_or(totalVoters); + const auto newTotalVoters + = results.vtotal_voters().value_or(totalVoters); auto changed = (newTotalVoters != totalVoters); if (const auto list = results.vresults()) { for (const auto &result : list->v) { diff --git a/Telegram/SourceFiles/data/data_session.cpp b/Telegram/SourceFiles/data/data_session.cpp index e21d11a65..0301d74a2 100644 --- a/Telegram/SourceFiles/data/data_session.cpp +++ b/Telegram/SourceFiles/data/data_session.cpp @@ -40,6 +40,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "data/business/data_business_chatbots.h" #include "data/business/data_business_info.h" #include "data/business/data_shortcut_messages.h" +#include "data/components/scheduled_messages.h" #include "data/stickers/data_stickers.h" #include "data/notify/data_notify_settings.h" #include "data/data_bot_app.h" @@ -56,9 +57,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "data/data_poll.h" #include "data/data_replies_list.h" #include "data/data_chat_filters.h" -#include "data/data_scheduled_messages.h" #include "data/data_send_action.h" -#include "data/data_sponsored_messages.h" #include "data/data_message_reactions.h" #include "data/data_emoji_statuses.h" #include "data/data_forum_icons.h" @@ -278,9 +277,7 @@ Session::Session(not_null<Main::Session*> session) , _savedMessages(std::make_unique<SavedMessages>(this)) , _chatbots(std::make_unique<Chatbots>(this)) , _businessInfo(std::make_unique<BusinessInfo>(this)) -, _scheduledMessages(std::make_unique<ScheduledMessages>(this)) -, _shortcutMessages(std::make_unique<ShortcutMessages>(this)) -, _sponsoredMessages(std::make_unique<SponsoredMessages>(this)) { +, _shortcutMessages(std::make_unique<ShortcutMessages>(this)) { _cache->open(_session->local().cacheKey()); _bigFileCache->open(_session->local().cacheBigFileKey()); @@ -407,9 +404,8 @@ void Session::clear() { _sendActionManager->clear(); _histories->unloadAll(); - _scheduledMessages = nullptr; _shortcutMessages = nullptr; - _sponsoredMessages = nullptr; + _session->scheduledMessages().clear(); _dependentMessages.clear(); base::take(_messages); base::take(_nonChannelMessages); diff --git a/Telegram/SourceFiles/data/data_session.h b/Telegram/SourceFiles/data/data_session.h index 0f7df77f4..fa58d4847 100644 --- a/Telegram/SourceFiles/data/data_session.h +++ b/Telegram/SourceFiles/data/data_session.h @@ -47,10 +47,8 @@ namespace Data { class Folder; class LocationPoint; class WallPaper; -class ScheduledMessages; class ShortcutMessages; class SendActionManager; -class SponsoredMessages; class Reactions; class EmojiStatuses; class ForumIcons; @@ -104,9 +102,6 @@ public: [[nodiscard]] ChatFilters &chatsFilters() const { return *_chatsFilters; } - [[nodiscard]] ScheduledMessages &scheduledMessages() const { - return *_scheduledMessages; - } [[nodiscard]] ShortcutMessages &shortcutMessages() const { return *_shortcutMessages; } @@ -128,9 +123,6 @@ public: [[nodiscard]] Stickers &stickers() const { return *_stickers; } - [[nodiscard]] SponsoredMessages &sponsoredMessages() const { - return *_sponsoredMessages; - } [[nodiscard]] Reactions &reactions() const { return *_reactions; } @@ -1084,9 +1076,7 @@ private: const std::unique_ptr<SavedMessages> _savedMessages; const std::unique_ptr<Chatbots> _chatbots; const std::unique_ptr<BusinessInfo> _businessInfo; - std::unique_ptr<ScheduledMessages> _scheduledMessages; std::unique_ptr<ShortcutMessages> _shortcutMessages; - std::unique_ptr<SponsoredMessages> _sponsoredMessages; MsgId _nonHistoryEntryId = ShortcutMaxMsgId; diff --git a/Telegram/SourceFiles/data/data_shared_media.cpp b/Telegram/SourceFiles/data/data_shared_media.cpp index 8033fba9c..6834190bf 100644 --- a/Telegram/SourceFiles/data/data_shared_media.cpp +++ b/Telegram/SourceFiles/data/data_shared_media.cpp @@ -13,10 +13,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "storage/storage_facade.h" #include "history/history.h" #include "history/history_item.h" +#include "data/components/scheduled_messages.h" #include "data/data_document.h" #include "data/data_media_types.h" #include "data/data_photo.h" -#include "data/data_scheduled_messages.h" #include "data/data_session.h" #include "core/crash_reports.h" @@ -193,9 +193,9 @@ rpl::producer<SparseIdsMergedSlice> SharedScheduledMediaViewer( const auto history = session->data().history(key.mergedKey.peerId); return rpl::single(rpl::empty) | rpl::then( - session->data().scheduledMessages().updates(history) + session->scheduledMessages().updates(history) ) | rpl::map([=] { - const auto list = session->data().scheduledMessages().list(history); + const auto list = session->scheduledMessages().list(history); auto items = ranges::views::all( list.ids diff --git a/Telegram/SourceFiles/data/data_statistics_chart.h b/Telegram/SourceFiles/data/data_statistics_chart.h index 5a29ebef7..fba664d34 100644 --- a/Telegram/SourceFiles/data/data_statistics_chart.h +++ b/Telegram/SourceFiles/data/data_statistics_chart.h @@ -30,14 +30,15 @@ struct StatisticalChart { [[nodiscard]] int findIndex(int left, int right, float64 v) const; struct Line final { - std::vector<int> y; + std::vector<Statistic::ChartValue> y; Statistic::SegmentTree segmentTree; int id = 0; QString idString; QString name; - int maxValue = 0; - int minValue = std::numeric_limits<int>::max(); + Statistic::ChartValue maxValue = 0; + Statistic::ChartValue minValue + = std::numeric_limits<Statistic::ChartValue>::max(); QString colorKey; QColor color; QColor colorDark; @@ -55,8 +56,9 @@ struct StatisticalChart { float64 max = 0.; } defaultZoomXIndex; - int maxValue = 0; - int minValue = std::numeric_limits<int>::max(); + Statistic::ChartValue maxValue = 0; + Statistic::ChartValue minValue + = std::numeric_limits<Statistic::ChartValue>::max(); float64 oneDayPercentage = 0.; diff --git a/Telegram/SourceFiles/dialogs/dialogs_widget.cpp b/Telegram/SourceFiles/dialogs/dialogs_widget.cpp index 789226009..55839da4d 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_widget.cpp +++ b/Telegram/SourceFiles/dialogs/dialogs_widget.cpp @@ -775,8 +775,8 @@ void Widget::updateScrollUpPosition() { _scrollToTop->moveToRight( st::historyToDownPosition.x(), _scroll->height() - top); - const auto shouldBeHidden = - !_scrollToTopIsShown && !_scrollToTopShown.animating(); + const auto shouldBeHidden + = !_scrollToTopIsShown && !_scrollToTopShown.animating(); if (shouldBeHidden != _scrollToTop->isHidden()) { _scrollToTop->setVisible(!shouldBeHidden); } diff --git a/Telegram/SourceFiles/editor/photo_editor_content.cpp b/Telegram/SourceFiles/editor/photo_editor_content.cpp index 065b2a1a6..1a379b9b3 100644 --- a/Telegram/SourceFiles/editor/photo_editor_content.cpp +++ b/Telegram/SourceFiles/editor/photo_editor_content.cpp @@ -48,8 +48,8 @@ PhotoEditorContent::PhotoEditorContent( return; } const auto imageSizeF = [&] { - const auto rotatedSize = - FlipSizeByRotation(size, mods.angle); + const auto rotatedSize + = FlipSizeByRotation(size, mods.angle); const auto m = _crop->cropMargins(); const auto sizeForCrop = rotatedSize - QSize(m.left() + m.right(), m.top() + m.bottom()); diff --git a/Telegram/SourceFiles/export/export_api_wrap.cpp b/Telegram/SourceFiles/export/export_api_wrap.cpp index 6471feb82..734f347df 100644 --- a/Telegram/SourceFiles/export/export_api_wrap.cpp +++ b/Telegram/SourceFiles/export/export_api_wrap.cpp @@ -541,8 +541,8 @@ void ApiWrap::requestDialogsCount() { Expects(_startProcess != nullptr); if (_settings->onlySinglePeer()) { - _startProcess->info.dialogsCount = - (_settings->singlePeer.type() == mtpc_inputPeerChannel + _startProcess->info.dialogsCount + = (_settings->singlePeer.type() == mtpc_inputPeerChannel ? 1 : _splits.size()); sendNextStartRequest(); diff --git a/Telegram/SourceFiles/history/admin_log/history_admin_log_item.cpp b/Telegram/SourceFiles/history/admin_log/history_admin_log_item.cpp index 5899117be..53e0926e0 100644 --- a/Telegram/SourceFiles/history/admin_log/history_admin_log_item.cpp +++ b/Telegram/SourceFiles/history/admin_log/history_admin_log_item.cpp @@ -738,8 +738,8 @@ void GenerateItems( using LogPromote = MTPDchannelAdminLogEventActionParticipantToggleAdmin; using LogSticker = MTPDchannelAdminLogEventActionChangeStickerSet; using LogEmoji = MTPDchannelAdminLogEventActionChangeEmojiStickerSet; - using LogPreHistory = - MTPDchannelAdminLogEventActionTogglePreHistoryHidden; + using LogPreHistory + = MTPDchannelAdminLogEventActionTogglePreHistoryHidden; using LogPermissions = MTPDchannelAdminLogEventActionDefaultBannedRights; using LogPoll = MTPDchannelAdminLogEventActionStopPoll; using LogDiscussion = MTPDchannelAdminLogEventActionChangeLinkedChat; @@ -749,19 +749,19 @@ void GenerateItems( using LogDiscardCall = MTPDchannelAdminLogEventActionDiscardGroupCall; using LogMute = MTPDchannelAdminLogEventActionParticipantMute; using LogUnmute = MTPDchannelAdminLogEventActionParticipantUnmute; - using LogCallSetting = - MTPDchannelAdminLogEventActionToggleGroupCallSetting; - using LogJoinByInvite = - MTPDchannelAdminLogEventActionParticipantJoinByInvite; - using LogInviteDelete = - MTPDchannelAdminLogEventActionExportedInviteDelete; - using LogInviteRevoke = - MTPDchannelAdminLogEventActionExportedInviteRevoke; + using LogCallSetting + = MTPDchannelAdminLogEventActionToggleGroupCallSetting; + using LogJoinByInvite + = MTPDchannelAdminLogEventActionParticipantJoinByInvite; + using LogInviteDelete + = MTPDchannelAdminLogEventActionExportedInviteDelete; + using LogInviteRevoke + = MTPDchannelAdminLogEventActionExportedInviteRevoke; using LogInviteEdit = MTPDchannelAdminLogEventActionExportedInviteEdit; using LogVolume = MTPDchannelAdminLogEventActionParticipantVolume; using LogTTL = MTPDchannelAdminLogEventActionChangeHistoryTTL; - using LogJoinByRequest = - MTPDchannelAdminLogEventActionParticipantJoinByRequest; + using LogJoinByRequest + = MTPDchannelAdminLogEventActionParticipantJoinByRequest; using LogNoForwards = MTPDchannelAdminLogEventActionToggleNoForwards; using LogSendMessage = MTPDchannelAdminLogEventActionSendMessage; using LogChangeAvailableReactions = MTPDchannelAdminLogEventActionChangeAvailableReactions; diff --git a/Telegram/SourceFiles/history/history.cpp b/Telegram/SourceFiles/history/history.cpp index bdfa6d1d0..6eb9d43bb 100644 --- a/Telegram/SourceFiles/history/history.cpp +++ b/Telegram/SourceFiles/history/history.cpp @@ -19,6 +19,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "history/history_unread_things.h" #include "dialogs/ui/dialogs_layout.h" #include "data/business/data_shortcut_messages.h" +#include "data/components/scheduled_messages.h" +#include "data/components/sponsored_messages.h" #include "data/notify/data_notify_settings.h" #include "data/stickers/data_stickers.h" #include "data/data_drafts.h" @@ -28,8 +30,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "data/data_channel_admins.h" #include "data/data_changes.h" #include "data/data_chat_filters.h" -#include "data/data_scheduled_messages.h" -#include "data/data_sponsored_messages.h" #include "data/data_send_action.h" #include "data/data_folder.h" #include "data/data_forum.h" @@ -598,7 +598,7 @@ not_null<HistoryItem*> History::addNewItem( not_null<HistoryItem*> item, bool unread) { if (item->isScheduled()) { - owner().scheduledMessages().appendSending(item); + session().scheduledMessages().appendSending(item); return item; } else if (item->isBusinessShortcut()) { owner().shortcutMessages().appendSending(item); diff --git a/Telegram/SourceFiles/history/history.h b/Telegram/SourceFiles/history/history.h index 29620dc2e..4a4ad8ddc 100644 --- a/Telegram/SourceFiles/history/history.h +++ b/Telegram/SourceFiles/history/history.h @@ -25,10 +25,6 @@ struct HistoryMessageMarkupData; class HistoryMainElementDelegateMixin; struct LanguageId; -namespace Main { -class Session; -} // namespace Main - namespace Data { struct Draft; class Session; diff --git a/Telegram/SourceFiles/history/history_drag_area.cpp b/Telegram/SourceFiles/history/history_drag_area.cpp index 39ba5fe3c..4f99ec778 100644 --- a/Telegram/SourceFiles/history/history_drag_area.cpp +++ b/Telegram/SourceFiles/history/history_drag_area.cpp @@ -52,8 +52,8 @@ DragArea::Areas DragArea::SetupDragAreaToContainer( auto &lifetime = container->lifetime(); container->setAcceptDrops(true); - const auto attachDragDocument = - Ui::CreateChild<DragArea>(container.get()); + const auto attachDragDocument + = Ui::CreateChild<DragArea>(container.get()); const auto attachDragPhoto = Ui::CreateChild<DragArea>(container.get()); attachDragDocument->hide(); @@ -62,8 +62,8 @@ DragArea::Areas DragArea::SetupDragAreaToContainer( attachDragDocument->raise(); attachDragPhoto->raise(); - const auto attachDragState = - lifetime.make_state<DragState>(DragState::None); + const auto attachDragState + = lifetime.make_state<DragState>(DragState::None); const auto width = [=] { return container->width(); diff --git a/Telegram/SourceFiles/history/history_drag_area.h b/Telegram/SourceFiles/history/history_drag_area.h index 64e581d58..c9c075c5a 100644 --- a/Telegram/SourceFiles/history/history_drag_area.h +++ b/Telegram/SourceFiles/history/history_drag_area.h @@ -23,8 +23,8 @@ public: DragArea *photo; }; - using CallbackComputeState = - Fn<Storage::MimeDataState(const QMimeData *data)>; + using CallbackComputeState + = Fn<Storage::MimeDataState(const QMimeData *data)>; static Areas SetupDragAreaToContainer( not_null<Ui::RpWidget*> container, diff --git a/Telegram/SourceFiles/history/history_inner_widget.cpp b/Telegram/SourceFiles/history/history_inner_widget.cpp index 91dd7401a..4a91f933e 100644 --- a/Telegram/SourceFiles/history/history_inner_widget.cpp +++ b/Telegram/SourceFiles/history/history_inner_widget.cpp @@ -68,6 +68,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "api/api_who_reacted.h" #include "api/api_views.h" #include "lang/lang_keys.h" +#include "data/components/sponsored_messages.h" #include "data/data_session.h" #include "data/data_document.h" #include "data/data_channel.h" @@ -79,7 +80,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "data/data_file_click_handler.h" #include "data/data_histories.h" #include "data/data_changes.h" -#include "data/data_sponsored_messages.h" #include "dialogs/ui/dialogs_video_userpic.h" #include "styles/style_chat.h" #include "styles/style_menu_icons.h" @@ -123,7 +123,7 @@ void FillSponsoredMessagesMenu( not_null<Window::SessionController*> controller, FullMsgId itemId, not_null<Ui::PopupMenu*> menu) { - const auto &data = controller->session().data().sponsoredMessages(); + const auto &data = controller->session().sponsoredMessages(); const auto info = data.lookupDetails(itemId).info; const auto show = controller->uiShow(); if (!info.empty()) { @@ -984,7 +984,7 @@ void HistoryInner::paintEvent(QPaintEvent *e) { : yShown(top + height / 2); if (markShown) { if (isSponsored) { - session().data().sponsoredMessages().view(item->fullId()); + session().sponsoredMessages().view(item->fullId()); } else if (isUnread) { readTill = item; } diff --git a/Telegram/SourceFiles/history/history_item.cpp b/Telegram/SourceFiles/history/history_item.cpp index 7d5c966eb..4a523dc0d 100644 --- a/Telegram/SourceFiles/history/history_item.cpp +++ b/Telegram/SourceFiles/history/history_item.cpp @@ -40,11 +40,12 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "base/timer_rpl.h" #include "api/api_text_entities.h" #include "api/api_updates.h" +#include "data/components/scheduled_messages.h" +#include "data/components/sponsored_messages.h" #include "data/notify/data_notify_settings.h" #include "data/data_bot_app.h" #include "data/data_saved_messages.h" #include "data/data_saved_sublist.h" -#include "data/data_scheduled_messages.h" #include "data/data_changes.h" #include "data/data_session.h" #include "data/data_message_reactions.h" @@ -57,7 +58,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "data/data_user.h" #include "data/data_group_call.h" // Data::GroupCall::id(). #include "data/data_poll.h" // PollData::publicVotes. -#include "data/data_sponsored_messages.h" #include "data/data_stories.h" #include "data/data_web_page.h" #include "chat_helpers/stickers_gift_box_pack.h" diff --git a/Telegram/SourceFiles/history/history_item_components.cpp b/Telegram/SourceFiles/history/history_item_components.cpp index aeef37557..22b513730 100644 --- a/Telegram/SourceFiles/history/history_item_components.cpp +++ b/Telegram/SourceFiles/history/history_item_components.cpp @@ -33,6 +33,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "media/audio/media_audio.h" #include "media/player/media_player_instance.h" #include "data/business/data_shortcut_messages.h" +#include "data/components/scheduled_messages.h" #include "data/stickers/data_custom_emoji.h" #include "data/data_channel.h" #include "data/data_media_types.h" @@ -42,7 +43,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "data/data_document.h" #include "data/data_web_page.h" #include "data/data_file_click_handler.h" -#include "data/data_scheduled_messages.h" #include "data/data_session.h" #include "data/data_stories.h" #include "main/main_session.h" @@ -301,7 +301,7 @@ ReplyFields ReplyFieldsFromMTP( const auto owner = &item->history()->owner(); if (const auto id = data.vreply_to_msg_id().value_or_empty()) { result.messageId = data.is_reply_to_scheduled() - ? owner->scheduledMessages().localMessageId(id) + ? owner->session().scheduledMessages().localMessageId(id) : item->shortcutId() ? owner->shortcutMessages().localMessageId(id) : id; diff --git a/Telegram/SourceFiles/history/history_widget.cpp b/Telegram/SourceFiles/history/history_widget.cpp index ae2ba9f8a..6bf793a89 100644 --- a/Telegram/SourceFiles/history/history_widget.cpp +++ b/Telegram/SourceFiles/history/history_widget.cpp @@ -54,6 +54,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "base/unixtime.h" #include "base/call_delayed.h" #include "data/business/data_shortcut_messages.h" +#include "data/components/scheduled_messages.h" +#include "data/components/sponsored_messages.h" #include "data/notify/data_notify_settings.h" #include "data/data_changes.h" #include "data/data_drafts.h" @@ -68,8 +70,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "data/data_forum_topic.h" #include "data/data_user.h" #include "data/data_chat_filters.h" -#include "data/data_scheduled_messages.h" -#include "data/data_sponsored_messages.h" #include "data/data_file_origin.h" #include "data/data_histories.h" #include "data/data_group_call.h" @@ -319,7 +319,7 @@ HistoryWidget::HistoryWidget( ) | rpl::start_with_next([=] { if (_history && _history->loadedAtBottom() - && session().data().sponsoredMessages().append(_history)) { + && session().sponsoredMessages().append(_history)) { _scroll->contentAdded(); } }, lifetime()); @@ -2241,7 +2241,7 @@ void HistoryWidget::showHistory( return; } else { _sponsoredMessagesStateKnown = false; - session().data().sponsoredMessages().clearItems(_history); + session().sponsoredMessages().clearItems(_history); session().data().hideShownSpoilers(); _composeSearch = nullptr; } @@ -2491,20 +2491,18 @@ void HistoryWidget::showHistory( if (history != _history) { return; } - auto &sponsored = session().data().sponsoredMessages(); using State = Data::SponsoredMessages::State; - const auto state = sponsored.state(_history); + const auto state = session().sponsoredMessages().state( + _history); _sponsoredMessagesStateKnown = (state != State::None); if (state == State::AppendToEnd) { _scroll->setTrackingContent( - sponsored.canHaveFor(_history)); + session().sponsoredMessages().canHaveFor(_history)); } else if (state == State::InjectToMiddle) { injectSponsoredMessages(); } }); - session().data().sponsoredMessages().request( - _history, - checkState); + session().sponsoredMessages().request(_history, checkState); checkState(); } } else { @@ -2608,7 +2606,7 @@ void HistoryWidget::setupPreview() { } void HistoryWidget::injectSponsoredMessages() const { - session().data().sponsoredMessages().inject( + session().sponsoredMessages().inject( _history, _showAtMsgId, _scroll->height() * 2, @@ -2799,9 +2797,9 @@ void HistoryWidget::setupScheduledToggle() { controller()->activeChatValue( ) | rpl::map([=](Dialogs::Key key) -> rpl::producer<> { if (const auto history = key.history()) { - return session().data().scheduledMessages().updates(history); + return session().scheduledMessages().updates(history); } else if (const auto topic = key.topic()) { - return session().data().scheduledMessages().updates( + return session().scheduledMessages().updates( topic->owningHistory()); } return rpl::never<rpl::empty_value>(); @@ -2816,7 +2814,7 @@ void HistoryWidget::setupScheduledToggle() { void HistoryWidget::refreshScheduledToggle() { const auto has = _history && _canSendMessages - && (session().data().scheduledMessages().count(_history) > 0); + && (session().scheduledMessages().count(_history) > 0); if (!_scheduled && has) { _scheduled.create(this, st::historyScheduledToggle); _scheduled->show(); @@ -3659,7 +3657,7 @@ void HistoryWidget::loadMessagesDown() { auto from = loadMigrated ? _migrated : _history; if (from->loadedAtBottom()) { if (_sponsoredMessagesStateKnown) { - session().data().sponsoredMessages().request(_history, nullptr); + session().sponsoredMessages().request(_history, nullptr); } return; } diff --git a/Telegram/SourceFiles/history/view/controls/history_view_voice_record_bar.cpp b/Telegram/SourceFiles/history/view/controls/history_view_voice_record_bar.cpp index 3b223b166..92a1d329c 100644 --- a/Telegram/SourceFiles/history/view/controls/history_view_voice_record_bar.cpp +++ b/Telegram/SourceFiles/history/view/controls/history_view_voice_record_bar.cpp @@ -377,8 +377,8 @@ TTLButton::TTLButton( return (r.left() + r.width() > parentWidget()->width()); }) | rpl::distinct_until_changed( ) | rpl::start_with_next([=](bool toHide) { - const auto isFirstTooltip = - !Core::App().settings().ttlVoiceClickTooltipHidden(); + const auto isFirstTooltip + = !Core::App().settings().ttlVoiceClickTooltipHidden(); if (isFirstTooltip || (!isFirstTooltip && toHide)) { _tooltip->toggleAnimated(!toHide); } diff --git a/Telegram/SourceFiles/history/view/history_view_element.cpp b/Telegram/SourceFiles/history/view/history_view_element.cpp index de58b7ac9..742034bbe 100644 --- a/Telegram/SourceFiles/history/view/history_view_element.cpp +++ b/Telegram/SourceFiles/history/view/history_view_element.cpp @@ -39,10 +39,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "ui/text/text_utilities.h" #include "ui/item_text_options.h" #include "ui/painter.h" +#include "data/components/sponsored_messages.h" #include "data/data_session.h" #include "data/data_forum.h" #include "data/data_forum_topic.h" -#include "data/data_sponsored_messages.h" #include "data/data_message_reactions.h" #include "data/data_user.h" #include "lang/lang_keys.h" @@ -1125,7 +1125,7 @@ ClickHandlerPtr Element::fromLink() const { } const auto my = context.other.value<ClickHandlerContext>(); if (const auto window = ContextOrSessionWindow(my, session)) { - auto &sponsored = session->data().sponsoredMessages(); + auto &sponsored = session->sponsoredMessages(); const auto itemId = my.itemId ? my.itemId : item->fullId(); const auto details = sponsored.lookupDetails(itemId); if (!details.externalLink.isEmpty()) { diff --git a/Telegram/SourceFiles/history/view/history_view_list_widget.cpp b/Telegram/SourceFiles/history/view/history_view_list_widget.cpp index ac95a45a3..03b5466e3 100644 --- a/Telegram/SourceFiles/history/view/history_view_list_widget.cpp +++ b/Telegram/SourceFiles/history/view/history_view_list_widget.cpp @@ -56,8 +56,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "boxes/premium_preview_box.h" #include "boxes/peers/edit_participant_box.h" #include "core/crash_reports.h" +#include "data/components/sponsored_messages.h" #include "data/data_session.h" -#include "data/data_sponsored_messages.h" #include "data/data_changes.h" #include "data/data_folder.h" #include "data/data_media_types.h" @@ -2138,8 +2138,7 @@ void ListWidget::paintEvent(QPaintEvent *e) { : yShown(top + height / 2); if (markShown) { if (isSponsored) { - session->data().sponsoredMessages().view( - item->fullId()); + session->sponsoredMessages().view(item->fullId()); } else if (isUnread) { readTill = item; } @@ -3898,8 +3897,8 @@ bool ListWidget::lastMessageEditRequestNotify() const { if (it == end(list)) { return false; } else { - const auto item = - session().data().groups().findItemToEdit((*it)->data()).get(); + const auto item + = session().data().groups().findItemToEdit((*it)->data()).get(); editMessageRequestNotify(item->fullId()); return true; } diff --git a/Telegram/SourceFiles/history/view/history_view_message.cpp b/Telegram/SourceFiles/history/view/history_view_message.cpp index 06706372a..4bba62d73 100644 --- a/Telegram/SourceFiles/history/view/history_view_message.cpp +++ b/Telegram/SourceFiles/history/view/history_view_message.cpp @@ -27,12 +27,12 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "ui/round_rect.h" #include "ui/text/text_utilities.h" #include "ui/power_saving.h" +#include "data/components/sponsored_messages.h" #include "data/data_session.h" #include "data/data_user.h" #include "data/data_channel.h" #include "data/data_forum_topic.h" #include "data/data_message_reactions.h" -#include "data/data_sponsored_messages.h" #include "lang/lang_keys.h" #include "mainwidget.h" #include "main/main_session.h" @@ -440,8 +440,9 @@ Message::Message( } } if (data->isSponsored()) { - const auto &messages = data->history()->owner().sponsoredMessages(); - const auto details = messages.lookupDetails(data->fullId()); + const auto &session = data->history()->session(); + const auto details = session.sponsoredMessages().lookupDetails( + data->fullId()); if (details.canReport) { _rightAction = std::make_unique<RightAction>(); _rightAction->second = std::make_unique<SecondRightAction>(); @@ -1867,27 +1868,27 @@ void Message::clickHandlerPressedChanged( Element::clickHandlerPressedChanged(handler, pressed); if (!handler) { return; - } else if (_rightAction) { - if (_rightAction->second && (handler == _rightAction->second->link)) { - const auto rightSize = rightActionSize(); - Assert(rightSize != std::nullopt); - if (pressed) { - if (!_rightAction->second->ripple) { - // Create a ripple. - _rightAction->second->ripple = - std::make_unique<Ui::RippleAnimation>( - st::defaultRippleAnimation, - Ui::RippleAnimation::RoundRectMask( - Size(rightSize->width()), - rightSize->width() / 2), - [=] { repaint(); }); - } - _rightAction->second->ripple->add(_rightAction->lastPoint); - } else if (_rightAction->second->ripple) { - _rightAction->second->ripple->lastStop(); + } else if (_rightAction && (handler == _rightAction->link)) { + toggleRightActionRipple(pressed); + } else if (_rightAction + && _rightAction->second + && (handler == _rightAction->second->link)) { + const auto rightSize = rightActionSize(); + Assert(rightSize != std::nullopt); + if (pressed) { + if (!_rightAction->second->ripple) { + // Create a ripple. + _rightAction->second->ripple + = std::make_unique<Ui::RippleAnimation>( + st::defaultRippleAnimation, + Ui::RippleAnimation::RoundRectMask( + Size(rightSize->width()), + rightSize->width() / 2), + [=] { repaint(); }); } - } else if (handler == _rightAction->link) { - toggleRightActionRipple(pressed); + _rightAction->second->ripple->add(_rightAction->lastPoint); + } else if (_rightAction->second->ripple) { + _rightAction->second->ripple->lastStop(); } } else if (_comments && (handler == _comments->link)) { toggleCommentsButtonRipple(pressed); diff --git a/Telegram/SourceFiles/history/view/history_view_replies_section.cpp b/Telegram/SourceFiles/history/view/history_view_replies_section.cpp index 91183100a..ac2fa2efb 100644 --- a/Telegram/SourceFiles/history/view/history_view_replies_section.cpp +++ b/Telegram/SourceFiles/history/view/history_view_replies_section.cpp @@ -52,6 +52,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "core/mime_type.h" #include "main/main_session.h" #include "main/main_session_settings.h" +#include "data/components/scheduled_messages.h" #include "data/data_session.h" #include "data/data_user.h" #include "data/data_chat.h" @@ -63,7 +64,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "data/data_changes.h" #include "data/data_shared_media.h" #include "data/data_send_action.h" -#include "data/data_scheduled_messages.h" #include "data/data_premium_limits.h" #include "storage/storage_media_prepare.h" #include "storage/storage_account.h" @@ -234,10 +234,9 @@ RepliesWidget::RepliesWidget( .stickerOrEmojiChosen = controller->stickerOrEmojiChosen(), .scheduledToggleValue = _topic ? rpl::single(rpl::empty_value()) | rpl::then( - session().data().scheduledMessages().updates( - _topic->owningHistory()) + session().scheduledMessages().updates(_topic->owningHistory()) ) | rpl::map([=] { - return session().data().scheduledMessages().hasFor(_topic); + return session().scheduledMessages().hasFor(_topic); }) | rpl::type_erased() : rpl::single(false), })) diff --git a/Telegram/SourceFiles/history/view/history_view_scheduled_section.cpp b/Telegram/SourceFiles/history/view/history_view_scheduled_section.cpp index df1a88f8c..632132a13 100644 --- a/Telegram/SourceFiles/history/view/history_view_scheduled_section.cpp +++ b/Telegram/SourceFiles/history/view/history_view_scheduled_section.cpp @@ -33,11 +33,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "core/mime_type.h" #include "chat_helpers/tabbed_selector.h" #include "main/main_session.h" +#include "data/components/scheduled_messages.h" #include "data/data_forum.h" #include "data/data_forum_topic.h" #include "data/data_session.h" #include "data/data_changes.h" -#include "data/data_scheduled_messages.h" #include "data/data_user.h" #include "data/data_message_reactions.h" #include "data/data_peer_values.h" @@ -62,7 +62,7 @@ namespace HistoryView { ScheduledMemento::ScheduledMemento(not_null<History*> history) : _history(history) , _forumTopic(nullptr) { - const auto list = _history->owner().scheduledMessages().list(_history); + const auto list = _history->session().scheduledMessages().list(_history); if (!list.ids.empty()) { _list.setScrollTopState({ .item = { .fullId = list.ids.front() } }); } @@ -71,7 +71,8 @@ ScheduledMemento::ScheduledMemento(not_null<History*> history) ScheduledMemento::ScheduledMemento(not_null<Data::ForumTopic*> forumTopic) : _history(forumTopic->owningHistory()) , _forumTopic(forumTopic) { - const auto list = _history->owner().scheduledMessages().list(_forumTopic); + const auto list = _history->session().scheduledMessages().list( + _forumTopic); if (!list.ids.empty()) { _list.setScrollTopState({ .item = { .fullId = list.ids.front() } }); } @@ -1201,13 +1202,13 @@ rpl::producer<Data::MessagesSlice> ScheduledWidget::listSource( Data::MessagePosition aroundId, int limitBefore, int limitAfter) { - const auto data = &controller()->session().data(); + const auto session = &controller()->session(); return rpl::single(rpl::empty) | rpl::then( - data->scheduledMessages().updates(_history) + session->scheduledMessages().updates(_history) ) | rpl::map([=] { return _forumTopic - ? data->scheduledMessages().list(_forumTopic) - : data->scheduledMessages().list(_history); + ? session->scheduledMessages().list(_forumTopic) + : session->scheduledMessages().list(_history); }) | rpl::after_next([=](const Data::MessagesSlice &slice) { highlightSingleNewMessage(slice); }); diff --git a/Telegram/SourceFiles/history/view/history_view_send_action.cpp b/Telegram/SourceFiles/history/view/history_view_send_action.cpp index 5380ccfb5..460941e6d 100644 --- a/Telegram/SourceFiles/history/view/history_view_send_action.cpp +++ b/Telegram/SourceFiles/history/view/history_view_send_action.cpp @@ -150,8 +150,8 @@ bool SendActionPainter::paint( const auto extraAnimationWidth = _animationLeft ? animationWidth * 2 : 0; - const auto left = - (availableWidth < _animationLeft + extraAnimationWidth) + const auto left + = (availableWidth < _animationLeft + extraAnimationWidth) ? 0 : _animationLeft; _sendActionAnimation.paint( diff --git a/Telegram/SourceFiles/history/view/history_view_sponsored_click_handler.cpp b/Telegram/SourceFiles/history/view/history_view_sponsored_click_handler.cpp index 65b030476..7a6d7b685 100644 --- a/Telegram/SourceFiles/history/view/history_view_sponsored_click_handler.cpp +++ b/Telegram/SourceFiles/history/view/history_view_sponsored_click_handler.cpp @@ -10,8 +10,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "api/api_chat_invite.h" #include "core/click_handler_types.h" #include "core/file_utilities.h" +#include "data/components/sponsored_messages.h" #include "data/data_session.h" -#include "data/data_sponsored_messages.h" #include "main/main_session.h" #include "window/window_session_controller.h" @@ -37,8 +37,8 @@ ClickHandlerPtr SponsoredLink(const QString &externalLink) { if (!controller) { return; } - const auto &data = controller->session().data(); - const auto details = data.sponsoredMessages().lookupDetails( + const auto &session = controller->session(); + const auto details = session.sponsoredMessages().lookupDetails( my.itemId); if (!details.externalLink.isEmpty()) { File::OpenUrl(details.externalLink); diff --git a/Telegram/SourceFiles/history/view/media/history_view_document.cpp b/Telegram/SourceFiles/history/view/media/history_view_document.cpp index d312489f4..bb5ebf46e 100644 --- a/Telegram/SourceFiles/history/view/media/history_view_document.cpp +++ b/Telegram/SourceFiles/history/view/media/history_view_document.cpp @@ -387,12 +387,9 @@ void Document::createComponents(bool caption) { mask |= HistoryDocumentVoice::Bit(); } else { mask |= HistoryDocumentNamed::Bit(); - if (_data->hasThumbnail()) { - if (!_data->isSong() - && !Data::IsExecutableName(_data->filename())) { - _data->loadThumbnail(_realParent->fullId()); - mask |= HistoryDocumentThumbed::Bit(); - } + if (_data->hasThumbnail() && !_data->isSong()) { + _data->loadThumbnail(_realParent->fullId()); + mask |= HistoryDocumentThumbed::Bit(); } } if (caption) { diff --git a/Telegram/SourceFiles/history/view/media/history_view_web_page.cpp b/Telegram/SourceFiles/history/view/media/history_view_web_page.cpp index 8967e74ac..ef3589ad3 100644 --- a/Telegram/SourceFiles/history/view/media/history_view_web_page.cpp +++ b/Telegram/SourceFiles/history/view/media/history_view_web_page.cpp @@ -13,11 +13,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "iv/iv_instance.h" #include "core/click_handler_types.h" #include "core/ui_integration.h" +#include "data/components/sponsored_messages.h" #include "data/stickers/data_custom_emoji.h" #include "data/data_file_click_handler.h" #include "data/data_photo_media.h" #include "data/data_session.h" -#include "data/data_sponsored_messages.h" #include "data/data_web_page.h" #include "history/history.h" #include "history/history_item_components.h" @@ -231,8 +231,8 @@ WebPage::WebPage( if (!(flags & MediaWebPageFlag::Sponsored)) { return std::nullopt; } - const auto &data = _parent->data()->history()->owner(); - const auto details = data.sponsoredMessages().lookupDetails( + const auto &session = _parent->data()->history()->session(); + const auto details = session.sponsoredMessages().lookupDetails( _parent->data()->fullId()); auto result = std::make_optional<SponsoredData>(); result->buttonText = details.buttonText; @@ -500,8 +500,8 @@ QSize WebPage::countOptimalSize() { minHeight = resizeGetHeight(maxWidth); } if (_sponsoredData && _sponsoredData->canReport) { - _sponsoredData->widthBeforeHint = - st::webPageTitleStyle.font->width(siteName); + _sponsoredData->widthBeforeHint + = st::webPageTitleStyle.font->width(siteName); const auto &font = st::webPageSponsoredHintFont; _sponsoredData->hintSize = QSize( font->width(tr::lng_sponsored_message_revenue_button(tr::now)) diff --git a/Telegram/SourceFiles/info/channel_statistics/earn/earn_format.cpp b/Telegram/SourceFiles/info/channel_statistics/earn/earn_format.cpp index ea470af93..4f87fa505 100644 --- a/Telegram/SourceFiles/info/channel_statistics/earn/earn_format.cpp +++ b/Telegram/SourceFiles/info/channel_statistics/earn/earn_format.cpp @@ -48,8 +48,11 @@ QString MinorPart(EarnInt value) { QString ToUsd(EarnInt value, float64 rate) { constexpr auto kApproximately = QChar(0x2248); - const auto multiplier = EarnInt(rate * Data::kEarnMultiplier); - const auto result = (value * multiplier) / Data::kEarnMultiplier; + + const auto result = value + / float64(Data::kEarnMultiplier) + * rate + * Data::kEarnMultiplier; return QString(kApproximately) + QChar('$') + MajorPart(result) diff --git a/Telegram/SourceFiles/info/channel_statistics/earn/info_earn_inner_widget.cpp b/Telegram/SourceFiles/info/channel_statistics/earn/info_earn_inner_widget.cpp index 80e377e1e..ad1155b89 100644 --- a/Telegram/SourceFiles/info/channel_statistics/earn/info_earn_inner_widget.cpp +++ b/Telegram/SourceFiles/info/channel_statistics/earn/info_earn_inner_widget.cpp @@ -13,7 +13,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "boxes/peers/edit_peer_color_box.h" // AddLevelBadge. #include "chat_helpers/stickers_emoji_pack.h" #include "core/application.h" -#include "core/ui_integration.h" // Core::MarkedTextContext. #include "data/data_channel.h" #include "data/data_premium_limits.h" #include "data/data_session.h" @@ -31,6 +30,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "main/main_session.h" #include "statistics/chart_widget.h" #include "ui/basic_click_handlers.h" +#include "ui/widgets/label_with_custom_emoji.h" #include "ui/boxes/boost_box.h" #include "ui/controls/userpic_button.h" #include "ui/effects/animation_value_f.h" @@ -334,23 +334,21 @@ void InnerWidget::fill() { st::channelEarnLearnArrowMargins, false)); const auto addAboutWithLearn = [&](const tr::phrase<lngtag_link> &text) { - auto label = object_ptr<Ui::FlatLabel>( + auto label = Ui::CreateLabelWithCustomEmoji( container, - st::boxDividerLabel); - const auto raw = label.data(); - text( - lt_link, - tr::lng_channel_earn_about_link( - lt_emoji, - rpl::single(arrow), + text( + lt_link, + tr::lng_channel_earn_about_link( + lt_emoji, + rpl::single(arrow), + Ui::Text::RichLangValue + ) | rpl::map([](TextWithEntities text) { + return Ui::Text::Link(std::move(text), 1); + }), Ui::Text::RichLangValue - ) | rpl::map([](TextWithEntities text) { - return Ui::Text::Link(std::move(text), 1); - }), - Ui::Text::RichLangValue - ) | rpl::start_with_next([=](const TextWithEntities &text) { - raw->setMarkedText(text, makeContext(raw)); - }, label->lifetime()); + ), + { .session = session }, + st::boxDividerLabel); label->setLink(1, std::make_shared<LambdaClickHandler>([=] { _show->showBox(Box([=](not_null<Ui::GenericBox*> box) { box->setNoContentMargin(true); @@ -454,17 +452,16 @@ void InnerWidget::fill() { const auto l = box->addRow( object_ptr<Ui::CenterWrap<Ui::FlatLabel>>( content, - object_ptr<Ui::FlatLabel>( + Ui::CreateLabelWithCustomEmoji( content, + tr::lng_channel_earn_learn_coin_title( + lt_emoji, + rpl::single( + Ui::Text::Link(bigCurrencyIcon, 1)), + Ui::Text::RichLangValue + ), + { .session = session }, st::boxTitle)))->entity(); - tr::lng_channel_earn_learn_coin_title( - lt_emoji, - rpl::single( - Ui::Text::Link(bigCurrencyIcon, 1)), - Ui::Text::RichLangValue - ) | rpl::start_with_next([=](TextWithEntities t) { - l->setMarkedText(std::move(t), makeContext(l)); - }, l->lifetime()); const auto diamonds = l->lifetime().make_state<int>(0); l->setLink(1, std::make_shared<LambdaClickHandler>([=] { const auto count = (*diamonds); @@ -480,25 +477,23 @@ void InnerWidget::fill() { Ui::AddSkip(content); { const auto label = box->addRow( - object_ptr<Ui::FlatLabel>( + Ui::CreateLabelWithCustomEmoji( content, + tr::lng_channel_earn_learn_coin_about( + lt_link, + tr::lng_channel_earn_about_link( + lt_emoji, + rpl::single(arrow), + Ui::Text::RichLangValue + ) | rpl::map([](TextWithEntities text) { + return Ui::Text::Link(std::move(text), 1); + }), + Ui::Text::RichLangValue + ), + { .session = session }, st::channelEarnLearnDescription)); - tr::lng_channel_earn_learn_coin_about( - lt_link, - tr::lng_channel_earn_about_link( - lt_emoji, - rpl::single(arrow), - Ui::Text::RichLangValue - ) | rpl::map([](TextWithEntities text) { - return Ui::Text::Link(std::move(text), 1); - }), - Ui::Text::RichLangValue - ) | rpl::start_with_next([=, l = label]( - TextWithEntities t) { - l->setMarkedText(std::move(t), makeContext(l)); - l->resizeToWidth(box->width() - - rect::m::sum::h(st::boxRowPadding)); - }, label->lifetime()); + label->resizeToWidth(box->width() + - rect::m::sum::h(st::boxRowPadding)); label->setLink( 1, LearnMoreCurrencyLink( diff --git a/Telegram/SourceFiles/info/info_top_bar.cpp b/Telegram/SourceFiles/info/info_top_bar.cpp index d09652a85..6a10bde23 100644 --- a/Telegram/SourceFiles/info/info_top_bar.cpp +++ b/Telegram/SourceFiles/info/info_top_bar.cpp @@ -693,13 +693,13 @@ void TopBar::createSelectionControls() { _selectionActionRequests, _cancelSelection->lifetime()); _delete->entity()->setVisible(_canDelete); - const auto archive = - _toggleStoryPin = wrap(Ui::CreateChild<Ui::FadeWrap<Ui::IconButton>>( - this, - object_ptr<Ui::IconButton>( + const auto archive = _toggleStoryPin = wrap( + Ui::CreateChild<Ui::FadeWrap<Ui::IconButton>>( this, - _storiesArchive ? _st.storiesSave : _st.storiesArchive), - st::infoTopBarScale)); + object_ptr<Ui::IconButton>( + this, + _storiesArchive ? _st.storiesSave : _st.storiesArchive), + st::infoTopBarScale)); registerToggleControlCallback( _toggleStoryPin.data(), [this] { return selectionMode() && _canToggleStoryPin; }); diff --git a/Telegram/SourceFiles/info/media/info_media_list_widget.cpp b/Telegram/SourceFiles/info/media/info_media_list_widget.cpp index 7cc90d0c6..1ebb1d315 100644 --- a/Telegram/SourceFiles/info/media/info_media_list_widget.cpp +++ b/Telegram/SourceFiles/info/media/info_media_list_widget.cpp @@ -814,8 +814,8 @@ void ListWidget::paintEvent(QPaintEvent *e) { } if (_dateBadge->goodType && clip.intersects(_dateBadge->rect)) { - const auto scrollDateOpacity = - _dateBadge->opacity.value(_dateBadge->shown ? 1. : 0.); + const auto scrollDateOpacity + = _dateBadge->opacity.value(_dateBadge->shown ? 1. : 0.); if (scrollDateOpacity > 0.) { p.setOpacity(scrollDateOpacity); if (_dateBadge->corners.p[0].isNull()) { diff --git a/Telegram/SourceFiles/info/statistics/info_statistics_inner_widget.cpp b/Telegram/SourceFiles/info/statistics/info_statistics_inner_widget.cpp index 6f4e45fb2..6e5803114 100644 --- a/Telegram/SourceFiles/info/statistics/info_statistics_inner_widget.cpp +++ b/Telegram/SourceFiles/info/statistics/info_statistics_inner_widget.cpp @@ -349,12 +349,14 @@ void FillOverview( const auto diffText = diffAbs > kTooMuchDiff ? Lang::FormatCountToShort(std::abs(diff)).string : QString::number(diffAbs); + const auto percentage = std::abs(v.growthRatePercentage); + const auto precision = (percentage == int(percentage)) ? 0 : 1; return { (diff < 0 ? st::menuIconAttentionColor : st::settingsIconBg2)->c, QString("%1%2 (%3%)") .arg((diff < 0) ? QChar(0x2212) : QChar(0x002B)) .arg(diffText) - .arg(std::abs(std::round(v.growthRatePercentage * 10.) / 10.)) + .arg(QString::number(percentage, 'f', precision)) }; }; diff --git a/Telegram/SourceFiles/main/main_session.cpp b/Telegram/SourceFiles/main/main_session.cpp index 6705f9554..fcadbefe0 100644 --- a/Telegram/SourceFiles/main/main_session.cpp +++ b/Telegram/SourceFiles/main/main_session.cpp @@ -28,6 +28,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "storage/file_upload.h" #include "storage/storage_account.h" #include "storage/storage_facade.h" +#include "data/components/scheduled_messages.h" +#include "data/components/sponsored_messages.h" #include "data/data_session.h" #include "data/data_changes.h" #include "data/data_user.h" @@ -100,6 +102,8 @@ Session::Session( , _giftBoxStickersPacks(std::make_unique<Stickers::GiftBoxPack>(this)) , _sendAsPeers(std::make_unique<SendAsPeers>(this)) , _attachWebView(std::make_unique<InlineBots::AttachWebView>(this)) +, _scheduledMessages(std::make_unique<Data::ScheduledMessages>(this)) +, _sponsoredMessages(std::make_unique<Data::SponsoredMessages>(this)) , _supportHelper(Support::Helper::Create(this)) , _saveSettingsTimer([=] { saveSettings(); }) { Expects(_settings != nullptr); diff --git a/Telegram/SourceFiles/main/main_session.h b/Telegram/SourceFiles/main/main_session.h index d8c74e087..4249f888f 100644 --- a/Telegram/SourceFiles/main/main_session.h +++ b/Telegram/SourceFiles/main/main_session.h @@ -31,6 +31,8 @@ class Templates; namespace Data { class Session; class Changes; +class ScheduledMessages; +class SponsoredMessages; } // namespace Data namespace Storage { @@ -104,6 +106,12 @@ public: [[nodiscard]] Data::Changes &changes() const { return *_changes; } + [[nodiscard]] Data::SponsoredMessages &sponsoredMessages() const { + return *_sponsoredMessages; + } + [[nodiscard]] Data::ScheduledMessages &scheduledMessages() const { + return *_scheduledMessages; + } [[nodiscard]] Api::Updates &updates() const { return *_updates; } @@ -224,6 +232,8 @@ private: const std::unique_ptr<Stickers::GiftBoxPack> _giftBoxStickersPacks; const std::unique_ptr<SendAsPeers> _sendAsPeers; const std::unique_ptr<InlineBots::AttachWebView> _attachWebView; + const std::unique_ptr<Data::ScheduledMessages> _scheduledMessages; + const std::unique_ptr<Data::SponsoredMessages> _sponsoredMessages; const std::unique_ptr<Support::Helper> _supportHelper; diff --git a/Telegram/SourceFiles/main/main_session_settings.cpp b/Telegram/SourceFiles/main/main_session_settings.cpp index 239bc7cf6..7806dea9f 100644 --- a/Telegram/SourceFiles/main/main_session_settings.cpp +++ b/Telegram/SourceFiles/main/main_session_settings.cpp @@ -140,7 +140,7 @@ void SessionSettings::addFromSerialized(const QByteArray &serialized) { qint32 supportChatsTimeSlice = _supportChatsTimeSlice.current(); qint32 appIncludeMutedCounter = app.includeMutedCounter() ? 1 : 0; qint32 appCountUnreadMessages = app.countUnreadMessages() ? 1 : 0; - qint32 appExeLaunchWarning = app.exeLaunchWarning() ? 1 : 0; + qint32 legacyAppExeLaunchWarning = 1; QByteArray autoDownload; qint32 supportAllSearchResults = _supportAllSearchResults.current() ? 1 : 0; qint32 archiveCollapsed = _archiveCollapsed.current() ? 1 : 0; @@ -262,7 +262,7 @@ void SessionSettings::addFromSerialized(const QByteArray &serialized) { stream >> appCountUnreadMessages; } if (!stream.atEnd()) { - stream >> appExeLaunchWarning; + stream >> legacyAppExeLaunchWarning; } } if (!stream.atEnd()) { @@ -509,7 +509,6 @@ void SessionSettings::addFromSerialized(const QByteArray &serialized) { } app.setIncludeMutedCounter(appIncludeMutedCounter == 1); app.setCountUnreadMessages(appCountUnreadMessages == 1); - app.setExeLaunchWarning(appExeLaunchWarning == 1); app.setNotifyAboutPinned(appNotifyAboutPinned == 1); app.setLoopAnimatedStickers(appLoopAnimatedStickers == 1); app.setLargeEmoji(appLargeEmoji == 1); diff --git a/Telegram/SourceFiles/mainwidget.cpp b/Telegram/SourceFiles/mainwidget.cpp index 80390d239..7fdaf7202 100644 --- a/Telegram/SourceFiles/mainwidget.cpp +++ b/Telegram/SourceFiles/mainwidget.cpp @@ -9,6 +9,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "api/api_updates.h" #include "api/api_views.h" +#include "data/components/scheduled_messages.h" #include "data/data_document_media.h" #include "data/data_document_resolver.h" #include "data/data_forum_topic.h" @@ -22,7 +23,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "data/data_chat.h" #include "data/data_user.h" #include "data/data_chat_filters.h" -#include "data/data_scheduled_messages.h" #include "data/data_file_origin.h" #include "data/data_histories.h" #include "data/stickers/data_stickers.h" @@ -811,6 +811,13 @@ void MainWidget::createPlayer() { }); _player->entity()->setShowItemCallback([=]( not_null<const HistoryItem*> item) { + const auto peer = item->history()->peer; + if (const auto window = Core::App().windowFor(peer)) { + if (const auto controller = window->sessionController()) { + controller->showMessage(item); + return; + } + } _controller->showMessage(item); }); diff --git a/Telegram/SourceFiles/mainwindow.cpp b/Telegram/SourceFiles/mainwindow.cpp index 5e8724b37..93d6d3060 100644 --- a/Telegram/SourceFiles/mainwindow.cpp +++ b/Telegram/SourceFiles/mainwindow.cpp @@ -77,8 +77,8 @@ base::options::toggle AutoScrollInactiveChat({ } // namespace -const char kOptionAutoScrollInactiveChat[] = - "auto-scroll-inactive-chat"; +const char kOptionAutoScrollInactiveChat[] + = "auto-scroll-inactive-chat"; MainWindow::MainWindow(not_null<Window::Controller*> controller) : Platform::MainWindow(controller) { diff --git a/Telegram/SourceFiles/media/player/media_player_dropdown.cpp b/Telegram/SourceFiles/media/player/media_player_dropdown.cpp index 618a0becb..e52728aba 100644 --- a/Telegram/SourceFiles/media/player/media_player_dropdown.cpp +++ b/Telegram/SourceFiles/media/player/media_player_dropdown.cpp @@ -35,8 +35,8 @@ constexpr auto kSpeedDebounceTimeout = crl::time(600); return base::SafeRound(speed * 10) / 10.; } -constexpr auto kSpeedStickedValues = - std::array<std::pair<float64, float64>, 7>{{ +constexpr auto kSpeedStickedValues + = std::array<std::pair<float64, float64>, 7>{{ { 0.8, 0.05 }, { 1.0, 0.05 }, { 1.2, 0.05 }, diff --git a/Telegram/SourceFiles/media/system_media_controls_manager.cpp b/Telegram/SourceFiles/media/system_media_controls_manager.cpp index d16685860..91f016aa5 100644 --- a/Telegram/SourceFiles/media/system_media_controls_manager.cpp +++ b/Telegram/SourceFiles/media/system_media_controls_manager.cpp @@ -44,8 +44,8 @@ bool SystemMediaControlsManager::Supported() { SystemMediaControlsManager::SystemMediaControlsManager() : _controls(std::make_unique<base::Platform::SystemMediaControls>()) { - using PlaybackStatus = - base::Platform::SystemMediaControls::PlaybackStatus; + using PlaybackStatus + = base::Platform::SystemMediaControls::PlaybackStatus; using Command = base::Platform::SystemMediaControls::Command; _controls->setApplicationName(AppName.utf16()); diff --git a/Telegram/SourceFiles/menu/menu_sponsored.cpp b/Telegram/SourceFiles/menu/menu_sponsored.cpp index bfa8427f1..e917c3f07 100644 --- a/Telegram/SourceFiles/menu/menu_sponsored.cpp +++ b/Telegram/SourceFiles/menu/menu_sponsored.cpp @@ -9,10 +9,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "boxes/premium_preview_box.h" #include "chat_helpers/compose/compose_show.h" -#include "core/ui_integration.h" // Core::MarkedTextContext. +#include "data/components/sponsored_messages.h" #include "data/data_premium_limits.h" #include "data/data_session.h" -#include "data/data_sponsored_messages.h" #include "data/stickers/data_custom_emoji.h" #include "history/history.h" #include "lang/lang_keys.h" @@ -25,6 +24,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "ui/vertical_list.h" #include "ui/widgets/buttons.h" #include "ui/widgets/popup_menu.h" +#include "ui/widgets/label_with_custom_emoji.h" #include "styles/style_channel_earn.h" #include "styles/style_chat.h" #include "styles/style_layers.h" @@ -169,31 +169,23 @@ void AboutBox( st::topicButtonArrow, st::channelEarnLearnArrowMargins, false)); - const auto label = box->addRow( - object_ptr<Ui::FlatLabel>( + const auto available = box->width() + - rect::m::sum::h(st::boxRowPadding); + box->addRow( + Ui::CreateLabelWithCustomEmoji( content, - st::channelEarnLearnDescription)); - tr::lng_sponsored_revenued_footer_description( - lt_link, - tr::lng_channel_earn_about_link( - lt_emoji, - rpl::single(arrow), - Ui::Text::RichLangValue - ) | rpl::map([=](TextWithEntities text) { - return Ui::Text::Link(std::move(text), kUrl.utf16()); - }), - Ui::Text::RichLangValue - ) | rpl::start_with_next([=, l = label]( - TextWithEntities t) { - l->setMarkedText( - std::move(t), - Core::MarkedTextContext{ - .session = session, - .customEmojiRepaint = [=] { l->update(); }, - }); - l->resizeToWidth(box->width() - - rect::m::sum::h(st::boxRowPadding)); - }, label->lifetime()); + tr::lng_sponsored_revenued_footer_description( + lt_link, + tr::lng_channel_earn_about_link( + lt_emoji, + rpl::single(arrow), + Ui::Text::RichLangValue + ) | rpl::map([=](TextWithEntities text) { + return Ui::Text::Link(std::move(text), kUrl.utf16()); + }), + Ui::Text::RichLangValue), + { .session = session }, + st::channelEarnLearnDescription))->resizeToWidth(available); } Ui::AddSkip(content); Ui::AddSkip(content); @@ -217,7 +209,7 @@ void ShowReportSponsoredBox( std::shared_ptr<ChatHelpers::Show> show, not_null<HistoryItem*> item) { const auto peer = item->history()->peer; - auto &sponsoredMessages = peer->session().data().sponsoredMessages(); + auto &sponsoredMessages = peer->session().sponsoredMessages(); const auto fullId = item->fullId(); const auto report = sponsoredMessages.createReportCallback(fullId); const auto guideLink = Ui::Text::Link( diff --git a/Telegram/SourceFiles/overview/overview_layout.cpp b/Telegram/SourceFiles/overview/overview_layout.cpp index 69fc9f292..b742a6436 100644 --- a/Telegram/SourceFiles/overview/overview_layout.cpp +++ b/Telegram/SourceFiles/overview/overview_layout.cpp @@ -1514,9 +1514,7 @@ bool Document::iconAnimated() const { } bool Document::withThumb() const { - return !songLayout() - && _data->hasThumbnail() - && !Data::IsExecutableName(_data->filename()); + return !songLayout() && _data->hasThumbnail(); } bool Document::updateStatusText() { diff --git a/Telegram/SourceFiles/passport/passport_form_controller.cpp b/Telegram/SourceFiles/passport/passport_form_controller.cpp index 980888ffb..b0ad0fcdf 100644 --- a/Telegram/SourceFiles/passport/passport_form_controller.cpp +++ b/Telegram/SourceFiles/passport/passport_form_controller.cpp @@ -2686,8 +2686,8 @@ bool FormController::applyPassword(const MTPDaccount_password &result) { settings.notEmptyPassport = result.is_has_secure_values(); settings.request = Core::ParseCloudPasswordCheckRequest(result); settings.unknownAlgo = result.vcurrent_algo() && !settings.request; - settings.unconfirmedPattern = - qs(result.vemail_unconfirmed_pattern().value_or_empty()); + settings.unconfirmedPattern = qs( + result.vemail_unconfirmed_pattern().value_or_empty()); settings.newAlgo = Core::ValidateNewCloudPasswordAlgo( Core::ParseCloudPasswordAlgo(result.vnew_algo())); settings.newSecureAlgo = Core::ValidateNewSecureSecretAlgo( diff --git a/Telegram/SourceFiles/passport/passport_panel_controller.h b/Telegram/SourceFiles/passport/passport_panel_controller.h index 94cd418c8..5c3d296b4 100644 --- a/Telegram/SourceFiles/passport/passport_panel_controller.h +++ b/Telegram/SourceFiles/passport/passport_panel_controller.h @@ -26,8 +26,8 @@ struct EditContactScheme; enum class ReadScanError; -using preferredLangCallback = - Fn<rpl::producer<EditDocumentCountry>(const QString &)>; +using preferredLangCallback + = Fn<rpl::producer<EditDocumentCountry>(const QString &)>; EditDocumentScheme GetDocumentScheme( Scope::Type type, std::optional<Value::Type> scansType, diff --git a/Telegram/SourceFiles/payments/payments_checkout_process.cpp b/Telegram/SourceFiles/payments/payments_checkout_process.cpp index b9e1b631d..ad7299664 100644 --- a/Telegram/SourceFiles/payments/payments_checkout_process.cpp +++ b/Telegram/SourceFiles/payments/payments_checkout_process.cpp @@ -766,12 +766,12 @@ void CheckoutProcess::requestPassword() { (index < list.size()) ? list[index].title : QString()); fields.customSubmitButton = tr::lng_payments_password_submit(); fields.customCheckCallback = [=]( - const Core::CloudPasswordResult &result) { + const Core::CloudPasswordResult &result, + QPointer<PasscodeBox> box) { + _enterPasswordBox = box; _form->submit(result); }; - auto owned = Box<PasscodeBox>(_session, fields); - _enterPasswordBox = owned.data(); - _panel->showBox(std::move(owned)); + _panel->showBox(Box<PasscodeBox>(_session, fields)); }); } diff --git a/Telegram/SourceFiles/platform/linux/main_window_linux.cpp b/Telegram/SourceFiles/platform/linux/main_window_linux.cpp index ae7fb1e99..9a0d91c4d 100644 --- a/Telegram/SourceFiles/platform/linux/main_window_linux.cpp +++ b/Telegram/SourceFiles/platform/linux/main_window_linux.cpp @@ -99,42 +99,6 @@ void XCBSkipTaskbar(QWindow *window, bool skip) { | XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY, reinterpret_cast<const char*>(&xev)); } - -void XCBSetDesktopFileName(QWindow *window) { - const auto connection = base::Platform::XCB::GetConnectionFromQt(); - if (!connection) { - return; - } - - const auto utf8Atom = base::Platform::XCB::GetAtom( - connection, - "UTF8_STRING"); - - if (!utf8Atom.has_value()) { - return; - } - - const auto filenameAtoms = { - base::Platform::XCB::GetAtom(connection, "_GTK_APPLICATION_ID"), - base::Platform::XCB::GetAtom(connection, "_KDE_NET_WM_DESKTOP_FILE"), - }; - - const auto filename = QGuiApplication::desktopFileName().toUtf8(); - - for (const auto atom : filenameAtoms) { - if (atom.has_value()) { - xcb_change_property( - connection, - XCB_PROP_MODE_REPLACE, - window->winId(), - *atom, - *utf8Atom, - 8, - filename.size(), - filename.data()); - } - } -} #endif // !DESKTOP_APP_DISABLE_X11_INTEGRATION void SkipTaskbar(QWindow *window, bool skip) { @@ -206,10 +170,6 @@ void MainWindow::initHook() { } return base::EventFilterResult::Continue; }); - -#ifndef DESKTOP_APP_DISABLE_X11_INTEGRATION - XCBSetDesktopFileName(windowHandle()); -#endif // !DESKTOP_APP_DISABLE_X11_INTEGRATION } void MainWindow::workmodeUpdated(Core::Settings::WorkMode mode) { diff --git a/Telegram/SourceFiles/platform/linux/notifications_manager_linux.cpp b/Telegram/SourceFiles/platform/linux/notifications_manager_linux.cpp index 0ea48a7de..747e4c2fa 100644 --- a/Telegram/SourceFiles/platform/linux/notifications_manager_linux.cpp +++ b/Telegram/SourceFiles/platform/linux/notifications_manager_linux.cpp @@ -315,19 +315,19 @@ bool NotificationData::init( _actions.push_back("inline-reply"); _actions.push_back(tr::lng_notification_reply(tr::now).toStdString()); - _notificationRepliedSignalId = - _interface.signal_notification_replied().connect([=]( - XdgNotifications::Notifications, - uint id, - std::string text) { - Core::Sandbox::Instance().customEnterFromEventLoop([&] { - if (id == _notificationId) { - _manager->notificationReplied( - _id, - { QString::fromStdString(text), {} }); - } + _notificationRepliedSignalId + = _interface.signal_notification_replied().connect([=]( + XdgNotifications::Notifications, + uint id, + std::string text) { + Core::Sandbox::Instance().customEnterFromEventLoop([&] { + if (id == _notificationId) { + _manager->notificationReplied( + _id, + { QString::fromStdString(text), {} }); + } + }); }); - }); } _actionInvokedSignalId = _interface.signal_action_invoked().connect([=]( diff --git a/Telegram/SourceFiles/platform/mac/touchbar/items/mac_pinned_chats_item.mm b/Telegram/SourceFiles/platform/mac/touchbar/items/mac_pinned_chats_item.mm index 477075719..ca4f88dad 100644 --- a/Telegram/SourceFiles/platform/mac/touchbar/items/mac_pinned_chats_item.mm +++ b/Telegram/SourceFiles/platform/mac/touchbar/items/mac_pinned_chats_item.mm @@ -551,13 +551,11 @@ NSRect PeerRectByIndex(int index) { const auto processOnline = [=](const auto &pin) { // TODO: this should be replaced // with the global application timer for online statuses. - const auto onlineChanges = - peerChangedLifetime->make_state<rpl::event_stream<PeerData*>>(); + const auto onlineChanges + = peerChangedLifetime->make_state<rpl::event_stream<PeerData*>>(); const auto peer = pin->peer; - const auto onlineTimer = - peerChangedLifetime->make_state<base::Timer>([=] { - onlineChanges->fire_copy({ peer }); - }); + const auto onlineTimer = peerChangedLifetime->make_state<base::Timer>( + [=] { onlineChanges->fire_copy({ peer }); }); const auto callTimer = [=](const auto &pin) { onlineTimer->cancel(); diff --git a/Telegram/SourceFiles/platform/mac/touchbar/mac_touchbar_manager.mm b/Telegram/SourceFiles/platform/mac/touchbar/mac_touchbar_manager.mm index f9c24a5a5..5f314e4b5 100644 --- a/Telegram/SourceFiles/platform/mac/touchbar/mac_touchbar_manager.mm +++ b/Telegram/SourceFiles/platform/mac/touchbar/mac_touchbar_manager.mm @@ -135,8 +135,8 @@ const auto kAudioItemIdentifier = @"touchbarAudio"; if (isEqual(kMainItemIdentifier)) { auto *item = [[GroupTouchBarItem alloc] initWithIdentifier:itemId]; - item.groupTouchBar = - [[[TouchBarMain alloc] + item.groupTouchBar + = [[[TouchBarMain alloc] init:_controller touchBarSwitches:_touchBarSwitches.events()] autorelease]; rpl::combine( diff --git a/Telegram/SourceFiles/settings/settings_business.cpp b/Telegram/SourceFiles/settings/settings_business.cpp index feee8e87c..163716819 100644 --- a/Telegram/SourceFiles/settings/settings_business.cpp +++ b/Telegram/SourceFiles/settings/settings_business.cpp @@ -605,8 +605,8 @@ QPointer<Ui::RpWidget> Business::createPinnedToBottom( }); { const auto callback = [=](int value) { - const auto options = - _controller->session().api().premium().subscriptionOptions(); + auto &api = _controller->session().api(); + const auto options = api.premium().subscriptionOptions(); if (options.empty()) { return; } diff --git a/Telegram/SourceFiles/settings/settings_premium.cpp b/Telegram/SourceFiles/settings/settings_premium.cpp index a7eeeec80..902cae550 100644 --- a/Telegram/SourceFiles/settings/settings_premium.cpp +++ b/Telegram/SourceFiles/settings/settings_premium.cpp @@ -1221,8 +1221,8 @@ QPointer<Ui::RpWidget> Premium::createPinnedToBottom( #endif { const auto callback = [=](int value) { - const auto options = - _controller->session().api().premium().subscriptionOptions(); + auto &api = _controller->session().api(); + const auto options = api.premium().subscriptionOptions(); if (options.empty()) { return; } diff --git a/Telegram/SourceFiles/settings/settings_privacy_security.cpp b/Telegram/SourceFiles/settings/settings_privacy_security.cpp index 045457819..4849719ff 100644 --- a/Telegram/SourceFiles/settings/settings_privacy_security.cpp +++ b/Telegram/SourceFiles/settings/settings_privacy_security.cpp @@ -36,6 +36,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "ui/toast/toast.h" #include "ui/wrap/slide_wrap.h" #include "ui/wrap/fade_wrap.h" +#include "ui/widgets/fields/input_field.h" #include "ui/widgets/shadow.h" #include "ui/widgets/checkbox.h" #include "ui/vertical_list.h" @@ -114,6 +115,56 @@ void AddPremiumStar( }, badge->lifetime()); } +void OpenFileConfirmationsBox(not_null<Ui::GenericBox*> box) { + box->setTitle(tr::lng_settings_file_confirmations()); + + const auto settings = &Core::App().settings(); + const auto &list = settings->noWarningExtensions(); + const auto text = QStringList(begin(list), end(list)).join(' '); + const auto layout = box->verticalLayout(); + const auto extensions = box->addRow( + object_ptr<Ui::InputField>( + box, + st::defaultInputField, + Ui::InputField::Mode::MultiLine, + tr::lng_settings_edit_extensions(), + TextWithTags{ text }), + st::boxRowPadding + QMargins(0, 0, 0, st::settingsPrivacySkip)); + Ui::AddDividerText(layout, tr::lng_settings_edit_extensions_about()); + Ui::AddSkip(layout); + const auto ip = layout->add(object_ptr<Ui::SettingsButton>( + box, + tr::lng_settings_edit_ip_confirm(), + st::settingsButtonNoIcon + ))->toggleOn(rpl::single(settings->ipRevealWarning())); + Ui::AddSkip(layout); + Ui::AddDividerText(layout, tr::lng_settings_edit_ip_confirm_about()); + + box->setFocusCallback([=] { + extensions->setFocusFast(); + }); + + box->addButton(tr::lng_settings_save(), [=] { + const auto extensionsList = extensions->getLastText() + .mid(0, 10240) + .split(' ', Qt::SkipEmptyParts) + .mid(0, 1024); + auto extensions = base::flat_set<QString>( + extensionsList.begin(), + extensionsList.end()); + const auto ipRevealWarning = ip->toggled(); + if (extensions != settings->noWarningExtensions() + || ipRevealWarning != settings->ipRevealWarning()) { + settings->setNoWarningExtensions(std::move(extensions)); + settings->setIpRevealWarning(ipRevealWarning); + Core::App().saveSettingsDelayed(); + } + box->closeBox(); + + }); + box->addButton(tr::lng_cancel(), [=] { box->closeBox(); }); +} + QString PrivacyBase(Privacy::Key key, const Privacy::Rule &rule) { using Key = Privacy::Key; using Option = Privacy::Option; @@ -645,6 +696,30 @@ void SetupBotsAndWebsites( }); Ui::AddSkip(container); + Ui::AddDivider(container); +} + +void SetupConfirmationExtensions( + not_null<Window::SessionController*> controller, + not_null<Ui::VerticalLayout*> container) { + if (Core::App().settings().noWarningExtensions().empty() + && Core::App().settings().ipRevealWarning()) { + return; + } + + Ui::AddSkip(container); + Ui::AddSubsectionTitle(container, tr::lng_settings_file_confirmations()); + + container->add(object_ptr<Button>( + container, + tr::lng_settings_edit_extensions(), + st::settingsButtonNoIcon + ))->addClickHandler([=] { + controller->show(Box(OpenFileConfirmationsBox)); + }); + + Ui::AddSkip(container); + Ui::AddDividerText(container, tr::lng_settings_edit_extensions_about()); } void SetupBlockedList( @@ -996,8 +1071,8 @@ void PrivacySecurity::setupContent( AddDivider(content); #endif // !OS_MAC_STORE && !OS_WIN_STORE SetupArchiveAndMute(controller, content); + SetupConfirmationExtensions(controller, content); SetupBotsAndWebsites(controller, content); - AddDivider(content); SetupSelfDestruction(controller, content, trigger()); Ui::ResizeFitChild(this, content); diff --git a/Telegram/SourceFiles/statistics/chart_rulers_data.cpp b/Telegram/SourceFiles/statistics/chart_rulers_data.cpp index 1b4e9c33a..4f9471c8c 100644 --- a/Telegram/SourceFiles/statistics/chart_rulers_data.cpp +++ b/Telegram/SourceFiles/statistics/chart_rulers_data.cpp @@ -12,17 +12,17 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL namespace Statistic { namespace { -constexpr auto kMinLines = int(2); -constexpr auto kMaxLines = int(6); +constexpr auto kMinLines = ChartValue(2); +constexpr auto kMaxLines = ChartValue(6); constexpr auto kStep = 5.; -[[nodiscard]] int Round(int maxValue) { - const auto k = int(maxValue / kStep); +[[nodiscard]] ChartValue Round(ChartValue maxValue) { + const auto k = ChartValue(maxValue / kStep); return (k % 10 == 0) ? maxValue : ((maxValue / 10 + 1) * 10); } -[[nodiscard]] QString Format(int absoluteValue) { - constexpr auto kTooMuch = int(10'000); +[[nodiscard]] QString Format(ChartValue absoluteValue) { + constexpr auto kTooMuch = ChartValue(10'000); return (absoluteValue >= kTooMuch) ? Lang::FormatCountToShort(absoluteValue).string : QString::number(absoluteValue); @@ -31,8 +31,8 @@ constexpr auto kStep = 5.; } // namespace ChartRulersData::ChartRulersData( - int newMaxHeight, - int newMinHeight, + ChartValue newMaxHeight, + ChartValue newMinHeight, bool useMinHeight, float64 rightRatio, Fn<QString(float64)> leftCustomCaption, @@ -42,11 +42,13 @@ ChartRulersData::ChartRulersData( ? Round(newMaxHeight) : newMaxHeight; - const auto step = std::max(1, int(std::ceil(v / kStep))); + const auto step = std::max( + ChartValue(1), + ChartValue(std::ceil(v / kStep))); auto n = kMaxLines; if (v < kMaxLines) { - n = std::max(2, v + 1); + n = std::max(2, int(v + 1)); } else if (v / 2 < kMaxLines) { n = v / 2 + 1; if (v % 2 != 0) { @@ -87,11 +89,11 @@ ChartRulersData::ChartRulersData( } lines.resize(n); - const auto diffAbsoluteValue = int((n - 1) * step); + const auto diffAbsoluteValue = ChartValue((n - 1) * step); const auto skipFloatValues = (step / rightRatio) < 1; for (auto i = 0; i < n; i++) { auto &line = lines[i]; - const auto value = int(i * step); + const auto value = ChartValue(i * step); line.absoluteValue = newMinHeight + value; line.relativeValue = 1. - value / float64(diffAbsoluteValue); line.caption = leftCustomCaption @@ -103,7 +105,7 @@ ChartRulersData::ChartRulersData( ? rightCustomCaption(line.absoluteValue) : (!skipFloatValues) ? Format(v) - : ((v - int(v)) < 0.01) + : ((v - ChartValue(v)) < 0.01) ? Format(v) : QString(); } @@ -112,8 +114,8 @@ ChartRulersData::ChartRulersData( } void ChartRulersData::computeRelative( - int newMaxHeight, - int newMinHeight) { + ChartValue newMaxHeight, + ChartValue newMinHeight) { for (auto &line : lines) { line.relativeValue = 1. - ((line.absoluteValue - newMinHeight) @@ -121,10 +123,10 @@ void ChartRulersData::computeRelative( } } -int ChartRulersData::LookupHeight(int maxValue) { +ChartValue ChartRulersData::LookupHeight(ChartValue maxValue) { const auto v = (maxValue > 100) ? Round(maxValue) : maxValue; - const auto step = int(std::ceil(v / kStep)); + const auto step = ChartValue(std::ceil(v / kStep)); return step * kStep; } diff --git a/Telegram/SourceFiles/statistics/chart_rulers_data.h b/Telegram/SourceFiles/statistics/chart_rulers_data.h index 4b5d63202..fef960c35 100644 --- a/Telegram/SourceFiles/statistics/chart_rulers_data.h +++ b/Telegram/SourceFiles/statistics/chart_rulers_data.h @@ -7,23 +7,25 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL */ #pragma once +#include "statistics/statistics_types.h" + namespace Statistic { struct ChartRulersData final { public: ChartRulersData( - int newMaxHeight, - int newMinHeight, + ChartValue newMaxHeight, + ChartValue newMinHeight, bool useMinHeight, float64 rightRatio, Fn<QString(float64)> leftCustomCaption = nullptr, Fn<QString(float64)> rightCustomCaption = nullptr); void computeRelative( - int newMaxHeight, - int newMinHeight); + ChartValue newMaxHeight, + ChartValue newMinHeight); - [[nodiscard]] static int LookupHeight(int maxValue); + [[nodiscard]] static ChartValue LookupHeight(ChartValue maxValue); struct Line final { float64 absoluteValue = 0.; diff --git a/Telegram/SourceFiles/statistics/chart_widget.cpp b/Telegram/SourceFiles/statistics/chart_widget.cpp index 93d225c70..823481e6b 100644 --- a/Telegram/SourceFiles/statistics/chart_widget.cpp +++ b/Telegram/SourceFiles/statistics/chart_widget.cpp @@ -1157,7 +1157,7 @@ void ChartWidget::setupDetails() { return; } const auto maxAbsoluteValue = [&] { - auto maxValue = 0; + auto maxValue = ChartValue(0); for (const auto &l : _chartData.lines) { maxValue = std::max(l.maxValue, maxValue); } diff --git a/Telegram/SourceFiles/statistics/segment_tree.cpp b/Telegram/SourceFiles/statistics/segment_tree.cpp index f19f8b8d6..51c2082ed 100644 --- a/Telegram/SourceFiles/statistics/segment_tree.cpp +++ b/Telegram/SourceFiles/statistics/segment_tree.cpp @@ -14,7 +14,7 @@ constexpr auto kMinArraySize = size_t(30); } // namespace -SegmentTree::SegmentTree(std::vector<int> array) +SegmentTree::SegmentTree(std::vector<ChartValue> array) : _array(std::move(array)) { if (_array.size() < kMinArraySize) { return; @@ -28,7 +28,7 @@ SegmentTree::SegmentTree(std::vector<int> array) build(1, 0, _array.size()); } -void SegmentTree::build(int v, int from, int size) { +void SegmentTree::build(ChartValue v, int from, int size) { _heap[v].from = from; _heap[v].to = (from + size - 1); @@ -48,9 +48,9 @@ void SegmentTree::build(int v, int from, int size) { } } -int SegmentTree::rMaxQ(int from, int to) { +ChartValue SegmentTree::rMaxQ(int from, int to) { if (_array.size() < kMinArraySize) { - auto max = 0; + auto max = ChartValue(0); from = std::max(from, 0); to = std::min(to, int(_array.size() - 1)); for (auto i = from; i <= to; i++) { @@ -61,7 +61,7 @@ int SegmentTree::rMaxQ(int from, int to) { return rMaxQ(1, from, to); } -int SegmentTree::rMaxQ(int v, int from, int to) { +ChartValue SegmentTree::rMaxQ(ChartValue v, int from, int to) { const auto &n = _heap[v]; // If you did a range update that contained this node, // you can infer the Min value without going down the tree. @@ -84,9 +84,9 @@ int SegmentTree::rMaxQ(int v, int from, int to) { return 0; } -int SegmentTree::rMinQ(int from, int to) { +ChartValue SegmentTree::rMinQ(int from, int to) { if (_array.size() < kMinArraySize) { - auto min = std::numeric_limits<int>::max(); + auto min = std::numeric_limits<ChartValue>::max(); from = std::max(from, 0); to = std::min(to, int(_array.size() - 1)); for (auto i = from; i <= to; i++) { @@ -97,7 +97,7 @@ int SegmentTree::rMinQ(int from, int to) { return rMinQ(1, from, to); } -int SegmentTree::rMinQ(int v, int from, int to) { +ChartValue SegmentTree::rMinQ(ChartValue v, int from, int to) { const auto &n = _heap[v]; // If you did a range update that contained this node, // you can infer the Min value without going down the tree. @@ -117,10 +117,10 @@ int SegmentTree::rMinQ(int v, int from, int to) { return std::min(leftMin, rightMin); } - return std::numeric_limits<int>::max(); + return std::numeric_limits<ChartValue>::max(); } -void SegmentTree::propagate(int v) { +void SegmentTree::propagate(ChartValue v) { auto &n = _heap[v]; if (n.pendingVal) { @@ -131,7 +131,7 @@ void SegmentTree::propagate(int v) { } } -void SegmentTree::change(SegmentTree::Node &n, int value) { +void SegmentTree::change(SegmentTree::Node &n, ChartValue value) { n.pendingVal = { value, true }; n.sum = n.size() * value; n.max = value; diff --git a/Telegram/SourceFiles/statistics/segment_tree.h b/Telegram/SourceFiles/statistics/segment_tree.h index e67adc76a..f83b16dd4 100644 --- a/Telegram/SourceFiles/statistics/segment_tree.h +++ b/Telegram/SourceFiles/statistics/segment_tree.h @@ -7,12 +7,14 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL */ #pragma once +#include "statistics/statistics_types.h" + namespace Statistic { class SegmentTree final { public: SegmentTree() = default; - SegmentTree(std::vector<int> array); + SegmentTree(std::vector<ChartValue> array); [[nodiscard]] bool empty() const { return _array.empty(); @@ -21,20 +23,20 @@ public: return !empty(); } - [[nodiscard]] int rMaxQ(int from, int to); - [[nodiscard]] int rMinQ(int from, int to); + [[nodiscard]] ChartValue rMaxQ(int from, int to); + [[nodiscard]] ChartValue rMinQ(int from, int to); private: struct Node final { - int sum = 0; - int max = 0; - int min = 0; + ChartValue sum = 0; + ChartValue max = 0; + ChartValue min = 0; struct PendingVal { [[nodiscard]] explicit operator bool() const { return available; } - int value = 0; + ChartValue value = 0; bool available = false; }; PendingVal pendingVal; @@ -47,12 +49,12 @@ private: } }; - void build(int v, int from, int size); - void propagate(int v); - void change(Node &n, int value); + void build(ChartValue v, int from, int size); + void propagate(ChartValue v); + void change(Node &n, ChartValue value); - [[nodiscard]] int rMaxQ(int v, int from, int to); - [[nodiscard]] int rMinQ(int v, int from, int to); + [[nodiscard]] ChartValue rMaxQ(ChartValue v, int from, int to); + [[nodiscard]] ChartValue rMinQ(ChartValue v, int from, int to); [[nodiscard]] bool contains(int from1, int to1, int from2, int to2) const; [[nodiscard]] bool intersects( @@ -61,7 +63,7 @@ private: int from2, int to2) const; - std::vector<int> _array; + std::vector<ChartValue> _array; std::vector<Node> _heap; }; diff --git a/Telegram/SourceFiles/statistics/statistics_data_deserialize.cpp b/Telegram/SourceFiles/statistics/statistics_data_deserialize.cpp index ac649cf13..7f47a396a 100644 --- a/Telegram/SourceFiles/statistics/statistics_data_deserialize.cpp +++ b/Telegram/SourceFiles/statistics/statistics_data_deserialize.cpp @@ -9,6 +9,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "base/debug_log.h" #include "data/data_statistics_chart.h" +#include "statistics/statistics_types.h" #include <QtCore/QJsonArray> #include <QtCore/QJsonDocument> @@ -61,7 +62,7 @@ Data::StatisticalChart StatisticalChartFromJSON(const QByteArray &json) { line.isHiddenOnStart = ranges::contains(hiddenLines, columnId); line.y.resize(length); for (auto i = 0; i < length; i++) { - const auto value = int(base::SafeRound( + const auto value = ChartValue(base::SafeRound( array.at(i + 1).toDouble())); line.y[i] = value; if (value > line.maxValue) { diff --git a/Telegram/SourceFiles/statistics/statistics_types.h b/Telegram/SourceFiles/statistics/statistics_types.h new file mode 100644 index 000000000..5d04d3442 --- /dev/null +++ b/Telegram/SourceFiles/statistics/statistics_types.h @@ -0,0 +1,14 @@ +/* +This file is part of Telegram Desktop, +the official desktop application for the Telegram messaging service. + +For license and copyright information please follow this link: +https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL +*/ +#pragma once + +namespace Statistic { + +using ChartValue = int64; + +} // namespace Statistic diff --git a/Telegram/SourceFiles/statistics/view/abstract_chart_view.cpp b/Telegram/SourceFiles/statistics/view/abstract_chart_view.cpp index d2c8e6bae..4b5f2929a 100644 --- a/Telegram/SourceFiles/statistics/view/abstract_chart_view.cpp +++ b/Telegram/SourceFiles/statistics/view/abstract_chart_view.cpp @@ -10,6 +10,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "data/data_statistics_chart.h" #include "statistics/chart_lines_filter_controller.h" +#include "statistics/statistics_types.h" namespace Statistic { @@ -71,11 +72,11 @@ AbstractChartView::HeightLimits DefaultHeightLimits( const std::shared_ptr<LinesFilterController> &linesFilter, Data::StatisticalChart &chartData, Limits xIndices) { - auto minValue = std::numeric_limits<int>::max(); - auto maxValue = 0; + auto minValue = std::numeric_limits<ChartValue>::max(); + auto maxValue = ChartValue(0); - auto minValueFull = std::numeric_limits<int>::max(); - auto maxValueFull = 0; + auto minValueFull = std::numeric_limits<ChartValue>::max(); + auto maxValueFull = ChartValue(0); for (auto &l : chartData.lines) { if (!linesFilter->isEnabled(l.id)) { continue; @@ -83,11 +84,11 @@ AbstractChartView::HeightLimits DefaultHeightLimits( const auto r = ratios.ratio(l.id); const auto lineMax = l.segmentTree.rMaxQ(xIndices.min, xIndices.max); const auto lineMin = l.segmentTree.rMinQ(xIndices.min, xIndices.max); - maxValue = std::max(int(lineMax * r), maxValue); - minValue = std::min(int(lineMin * r), minValue); + maxValue = std::max(ChartValue(lineMax * r), maxValue); + minValue = std::min(ChartValue(lineMin * r), minValue); - maxValueFull = std::max(int(l.maxValue * r), maxValueFull); - minValueFull = std::min(int(l.minValue * r), minValueFull); + maxValueFull = std::max(ChartValue(l.maxValue * r), maxValueFull); + minValueFull = std::min(ChartValue(l.minValue * r), minValueFull); } if (maxValue == minValue) { maxValue = chartData.maxValue; diff --git a/Telegram/SourceFiles/statistics/view/bar_chart_view.cpp b/Telegram/SourceFiles/statistics/view/bar_chart_view.cpp index 8beeaa509..f796e0294 100644 --- a/Telegram/SourceFiles/statistics/view/bar_chart_view.cpp +++ b/Telegram/SourceFiles/statistics/view/bar_chart_view.cpp @@ -256,9 +256,9 @@ AbstractChartView::HeightLimits BarChartView::heightLimits( if (_cachedHeightLimits.ySum.empty()) { _cachedHeightLimits.ySum.reserve(chartData.x.size()); - auto maxValueFull = 0; + auto maxValueFull = ChartValue(0); for (auto i = 0; i < chartData.x.size(); i++) { - auto sum = 0; + auto sum = ChartValue(0); for (const auto &line : chartData.lines) { if (linesFilterController()->isEnabled(line.id)) { sum += line.y[i]; @@ -276,7 +276,7 @@ AbstractChartView::HeightLimits BarChartView::heightLimits( _cachedHeightLimits.ySumSegmentTree.rMaxQ( xIndices.min, xIndices.max), - 1); + ChartValue(1)); return { .full = _cachedHeightLimits.full, .ranged = { 0., float64(max) }, diff --git a/Telegram/SourceFiles/statistics/view/bar_chart_view.h b/Telegram/SourceFiles/statistics/view/bar_chart_view.h index 44c1a7a6e..3105e0dae 100644 --- a/Telegram/SourceFiles/statistics/view/bar_chart_view.h +++ b/Telegram/SourceFiles/statistics/view/bar_chart_view.h @@ -9,6 +9,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "statistics/segment_tree.h" #include "statistics/statistics_common.h" +#include "statistics/statistics_types.h" #include "statistics/view/abstract_chart_view.h" #include "ui/effects/animation_value.h" @@ -48,7 +49,7 @@ private: struct { Limits full; - std::vector<int> ySum; + std::vector<ChartValue> ySum; SegmentTree ySumSegmentTree; } _cachedHeightLimits; diff --git a/Telegram/SourceFiles/statistics/view/stack_linear_chart_common.cpp b/Telegram/SourceFiles/statistics/view/stack_linear_chart_common.cpp index a2ca3ff01..b7727bd71 100644 --- a/Telegram/SourceFiles/statistics/view/stack_linear_chart_common.cpp +++ b/Telegram/SourceFiles/statistics/view/stack_linear_chart_common.cpp @@ -81,7 +81,7 @@ PiePartData PiePartsPercentageByIndices( sums.reserve(chartData.lines.size()); auto totalSum = 0.; for (const auto &line : chartData.lines) { - auto sum = 0; + auto sum = ChartValue(0); for (auto i = xIndices.min; i <= xIndices.max; i++) { sum += line.y[i]; } diff --git a/Telegram/SourceFiles/statistics/view/stack_linear_chart_view.cpp b/Telegram/SourceFiles/statistics/view/stack_linear_chart_view.cpp index dc3e00d04..a4e4a7c87 100644 --- a/Telegram/SourceFiles/statistics/view/stack_linear_chart_view.cpp +++ b/Telegram/SourceFiles/statistics/view/stack_linear_chart_view.cpp @@ -165,8 +165,8 @@ void StackLinearChartView::prepareZoom( _transition.zoomedOutXIndices = c.xIndices; _transition.zoomedOutXPercentage = c.xPercentageLimits; } else if (step == TransitionStep::PrepareToZoomIn) { - const auto &[zoomedStart, zoomedEnd] = - _transition.zoomedOutXIndices; + const auto &[zoomedStart, zoomedEnd] + = _transition.zoomedOutXIndices; _transition.lines = std::vector<Transition::TransitionLine>( c.chartData.lines.size(), Transition::TransitionLine()); @@ -624,7 +624,7 @@ void StackLinearChartView::paintZoomed(QPainter &p, const PaintContext &c) { if (selectedLineIndex >= 0) { const auto &line = c.chartData.lines[selectedLineIndex]; - auto sum = 0; + auto sum = ChartValue(0); for (auto i = zoomedStart; i <= zoomedEnd; i++) { sum += line.y[i]; } @@ -669,8 +669,8 @@ void StackLinearChartView::paintZoomedFooter( 0); const auto next = std::clamp(i + offset, zoomedStart, zoomedEnd); - const auto xPointPercentage = - (xPercentage[next] - xPercentage[zoomedStart]) + const auto xPointPercentage + = (xPercentage[next] - xPercentage[zoomedStart]) / (xPercentage[zoomedEnd] - xPercentage[zoomedStart]); const auto xPoint = leftStart + width * xPointPercentage; diff --git a/Telegram/SourceFiles/storage/storage_account.cpp b/Telegram/SourceFiles/storage/storage_account.cpp index ca04135e8..e3c2e69c4 100644 --- a/Telegram/SourceFiles/storage/storage_account.cpp +++ b/Telegram/SourceFiles/storage/storage_account.cpp @@ -1991,8 +1991,8 @@ void Account::readStickerSets( if (datesCount != scnt) { return failed(); } - const auto fillDates = - ((set->id == Data::Stickers::CloudRecentSetId) + const auto fillDates + = ((set->id == Data::Stickers::CloudRecentSetId) || (set->id == Data::Stickers::CloudRecentAttachedSetId)) && (set->stickers.size() == datesCount); if (fillDates) { diff --git a/Telegram/SourceFiles/ui/boxes/choose_date_time.cpp b/Telegram/SourceFiles/ui/boxes/choose_date_time.cpp index e4d8092a5..8651b5b01 100644 --- a/Telegram/SourceFiles/ui/boxes/choose_date_time.cpp +++ b/Telegram/SourceFiles/ui/boxes/choose_date_time.cpp @@ -146,8 +146,8 @@ ChooseDateTimeBoxDescriptor ChooseDateTimeBox( width); }, content->lifetime()); - const auto calendar = - content->lifetime().make_state<QPointer<CalendarBox>>(); + const auto calendar + = content->lifetime().make_state<QPointer<CalendarBox>>(); const auto calendarStyle = args.style.calendarStyle; state->day->focusedChanges( ) | rpl::start_with_next([=](bool focused) { diff --git a/Telegram/SourceFiles/ui/chat/chat_theme.cpp b/Telegram/SourceFiles/ui/chat/chat_theme.cpp index 1022f8e56..4979e5c4a 100644 --- a/Telegram/SourceFiles/ui/chat/chat_theme.cpp +++ b/Telegram/SourceFiles/ui/chat/chat_theme.cpp @@ -909,12 +909,17 @@ QImage PrepareImageForTiled(const QImage &prepared) { const QString &path, const QByteArray &content, bool gzipSvg) { - return Images::Read({ + auto result = Images::Read({ .path = path, .content = content, .maxSize = QSize(kMaxSize, kMaxSize), .gzipSvg = gzipSvg, }).image; + if (result.isNull()) { + result = QImage(1, 1, QImage::Format_ARGB32_Premultiplied); + result.fill(Qt::black); + } + return result; } QImage GenerateBackgroundImage( diff --git a/Telegram/SourceFiles/ui/controls/call_mute_button.cpp b/Telegram/SourceFiles/ui/controls/call_mute_button.cpp index 2c57087c0..f9d1024e5 100644 --- a/Telegram/SourceFiles/ui/controls/call_mute_button.cpp +++ b/Telegram/SourceFiles/ui/controls/call_mute_button.cpp @@ -414,8 +414,8 @@ void BlobsWidget::init(int diameter) { } // Main circle. - const auto circleProgress = - Clamp(_switchConnectingProgress - kBlobPartAnimation) + const auto circleProgress + = Clamp(_switchConnectingProgress - kBlobPartAnimation) / kFillCirclePartAnimation; const auto skipColoredCircle = (circleProgress == 1.); @@ -744,8 +744,8 @@ void CallMuteButton::init() { }, lifetime()); // State type. - const auto previousType = - lifetime().make_state<CallMuteButtonType>(_state.current().type); + const auto previousType + = lifetime().make_state<CallMuteButtonType>(_state.current().type); setHandleMouseState(HandleMouseState::Disabled); refreshGradients(); diff --git a/Telegram/SourceFiles/ui/menu_icons.style b/Telegram/SourceFiles/ui/menu_icons.style index 862caf79d..4ec165b62 100644 --- a/Telegram/SourceFiles/ui/menu_icons.style +++ b/Telegram/SourceFiles/ui/menu_icons.style @@ -151,6 +151,7 @@ menuIconAsTopics: icon {{ "menu/mode_topics", menuIconColor }}; menuIconAsMessages: icon {{ "menu/mode_messages", menuIconColor }}; menuIconTagFilter: icon{{ "menu/tag_filter", menuIconColor }}; menuIconTagRename: icon{{ "menu/tag_rename", menuIconColor }}; +menuIconGroupsHide: icon {{ "menu/hide_members", menuIconColor }}; menuIconTTLAny: icon {{ "menu/auto_delete_plain", menuIconColor }}; menuIconTTLAnyTextPosition: point(11px, 22px); diff --git a/Telegram/SourceFiles/ui/widgets/label_with_custom_emoji.cpp b/Telegram/SourceFiles/ui/widgets/label_with_custom_emoji.cpp new file mode 100644 index 000000000..4502d6553 --- /dev/null +++ b/Telegram/SourceFiles/ui/widgets/label_with_custom_emoji.cpp @@ -0,0 +1,32 @@ +/* +This file is part of Telegram Desktop, +the official desktop application for the Telegram messaging service. + +For license and copyright information please follow this link: +https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL +*/ +#include "ui/widgets/label_with_custom_emoji.h" + +#include "core/ui_integration.h" +#include "ui/widgets/labels.h" +#include "styles/style_widgets.h" + +namespace Ui { + +object_ptr<Ui::FlatLabel> CreateLabelWithCustomEmoji( + QWidget *parent, + rpl::producer<TextWithEntities> &&text, + Core::MarkedTextContext context, + const style::FlatLabel &st) { + auto label = object_ptr<Ui::FlatLabel>(parent, st); + const auto raw = label.data(); + if (!context.customEmojiRepaint) { + context.customEmojiRepaint = [=] { raw->update(); }; + } + std::move(text) | rpl::start_with_next([=](const TextWithEntities &text) { + raw->setMarkedText(text, context); + }, label->lifetime()); + return label; +} + +} // namespace Ui diff --git a/Telegram/SourceFiles/ui/widgets/label_with_custom_emoji.h b/Telegram/SourceFiles/ui/widgets/label_with_custom_emoji.h new file mode 100644 index 000000000..f22e4e801 --- /dev/null +++ b/Telegram/SourceFiles/ui/widgets/label_with_custom_emoji.h @@ -0,0 +1,35 @@ +/* +This file is part of Telegram Desktop, +the official desktop application for the Telegram messaging service. + +For license and copyright information please follow this link: +https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL +*/ +#pragma once + +#include "core/ui_integration.h" // Core::MarkedTextContext. + +template <typename Object> +class object_ptr; + +namespace Main { +class Session; +} // namespace Main + +namespace style { +struct FlatLabel; +} // namespace style + +namespace Ui { +class FlatLabel; +} // namespace Ui + +namespace Ui { + +[[nodiscard]] object_ptr<Ui::FlatLabel> CreateLabelWithCustomEmoji( + QWidget *parent, + rpl::producer<TextWithEntities> &&text, + Core::MarkedTextContext context, + const style::FlatLabel &st); + +} // namespace Ui diff --git a/Telegram/SourceFiles/ui/widgets/level_meter.cpp b/Telegram/SourceFiles/ui/widgets/level_meter.cpp index 15acd28ab..7a94b8c46 100644 --- a/Telegram/SourceFiles/ui/widgets/level_meter.cpp +++ b/Telegram/SourceFiles/ui/widgets/level_meter.cpp @@ -24,7 +24,7 @@ void LevelMeter::setValue(float value) { void LevelMeter::paintEvent(QPaintEvent* event) { auto p = QPainter(this); - PainterHighQualityEnabler hq(p); + auto hq = PainterHighQualityEnabler(p); p.setPen(Qt::NoPen); @@ -34,7 +34,7 @@ void LevelMeter::paintEvent(QPaintEvent* event) { const auto rect = QRect(0, 0, _st.lineWidth, height()); p.setBrush(activeFg); for (auto i = 0; i < _st.lineCount; ++i) { - const auto valueAtLine = (float)(i + 1) / _st.lineCount; + const auto valueAtLine = (float64)(i + 1) / _st.lineCount; if (valueAtLine > _value) { p.setBrush(inactiveFg); } diff --git a/Telegram/SourceFiles/window/window_main_menu_helpers.cpp b/Telegram/SourceFiles/window/window_main_menu_helpers.cpp index c10a3e41a..ba42403d4 100644 --- a/Telegram/SourceFiles/window/window_main_menu_helpers.cpp +++ b/Telegram/SourceFiles/window/window_main_menu_helpers.cpp @@ -27,10 +27,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "ui/rect.h" #include "ui/widgets/popup_menu.h" #include "ui/widgets/tooltip.h" +#include "ui/wrap/slide_wrap.h" #include "window/window_controller.h" #include "window/window_session_controller.h" -#include "styles/style_chat.h" // popupMenuExpandedSeparator -#include "styles/style_info.h" // infoTopBarMenu +#include "styles/style_chat.h" +#include "styles/style_info.h" #include "styles/style_menu_icons.h" #include "styles/style_window.h" @@ -177,7 +178,9 @@ not_null<Ui::SettingsButton*> AddMyChannelsBox( const auto count = c ? c->membersCount() : g->count; _status.setText( st::defaultTextStyle, - !p->username().isEmpty() + (g && !g->amIn()) + ? tr::lng_chat_status_unaccessible(tr::now) + : !p->username().isEmpty() ? ('@' + p->username()) : (count > 0) ? ((c && !c->isMegagroup()) @@ -219,10 +222,11 @@ not_null<Ui::SettingsButton*> AddMyChannelsBox( }; - const auto add = [&](not_null<PeerData*> peer) { - const auto row = box->addRow( - object_ptr<Button>(box, rpl::single(QString())), - {}); + const auto add = [&]( + not_null<PeerData*> peer, + not_null<Ui::VerticalLayout*> container) { + const auto row = container->add( + object_ptr<Button>(container, rpl::single(QString()))); row->setPeer(peer); row->setClickedCallback([=] { controller->showPeerHistory(peer); @@ -233,8 +237,16 @@ not_null<Ui::SettingsButton*> AddMyChannelsBox( userpic->setAttribute(Qt::WA_TransparentForMouseEvents); }; + const auto inaccessibleWrap = box->verticalLayout()->add( + object_ptr<Ui::SlideWrap<Ui::VerticalLayout>>( + box->verticalLayout(), + object_ptr<Ui::VerticalLayout>(box->verticalLayout()))); + inaccessibleWrap->toggle(false, anim::type::instant); + const auto &data = controller->session().data(); auto ids = std::vector<PeerId>(); + auto inaccessibleIds = std::vector<PeerId>(); + if (chats) { data.enumerateGroups([&](not_null<PeerData*> peer) { peer = peer->migrateToOrMe(); @@ -244,8 +256,13 @@ not_null<Ui::SettingsButton*> AddMyChannelsBox( const auto c = peer->asChannel(); const auto g = peer->asChat(); if ((c && c->amCreator()) || (g && g->amCreator())) { + if (g && !g->amIn()) { + inaccessibleIds.push_back(peer->id); + add(peer, inaccessibleWrap->entity()); + } else { + add(peer, box->verticalLayout()); + } ids.push_back(peer->id); - add(peer); } }); } else { @@ -253,13 +270,29 @@ not_null<Ui::SettingsButton*> AddMyChannelsBox( if (channel->amCreator() && !ranges::contains(ids, channel->id)) { ids.push_back(channel->id); - add(channel); + add(channel, box->verticalLayout()); } }); } if (ids.empty()) { addIcon(box); } + if (!inaccessibleIds.empty()) { + const auto icon = [=] { + return !inaccessibleWrap->toggled() + ? &st::menuIconGroups + : &st::menuIconGroupsHide; + }; + auto button = object_ptr<Ui::IconButton>(box, st::backgroundSwitchToDark); + button->setClickedCallback([=, raw = button.data()] { + inaccessibleWrap->toggle( + !inaccessibleWrap->toggled(), + anim::type::normal); + raw->setIconOverride(icon(), icon()); + }); + button->setIconOverride(icon(), icon()); + box->addTopButton(std::move(button)); + } }; using Menu = base::unique_qptr<Ui::PopupMenu>; diff --git a/Telegram/SourceFiles/window/window_peer_menu.cpp b/Telegram/SourceFiles/window/window_peer_menu.cpp index c3c0950c2..510902a15 100644 --- a/Telegram/SourceFiles/window/window_peer_menu.cpp +++ b/Telegram/SourceFiles/window/window_peer_menu.cpp @@ -68,6 +68,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "info/profile/info_profile_values.h" #include "info/statistics/info_statistics_widget.h" #include "info/stories/info_stories_widget.h" +#include "data/components/scheduled_messages.h" #include "data/notify/data_notify_settings.h" #include "data/data_changes.h" #include "data/data_session.h" @@ -79,7 +80,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "data/data_forum_topic.h" #include "data/data_user.h" #include "data/data_saved_sublist.h" -#include "data/data_scheduled_messages.h" #include "data/data_histories.h" #include "data/data_chat_filters.h" #include "dialogs/dialogs_key.h" @@ -143,8 +143,8 @@ void ShareBotGame( } // namespace -const char kOptionViewProfileInChatsListContextMenu[] = - "view-profile-in-chats-list-context-menu"; +const char kOptionViewProfileInChatsListContextMenu[] + = "view-profile-in-chats-list-context-menu"; namespace { @@ -2255,8 +2255,8 @@ QPointer<Ui::BoxContent> ShowSendNowMessagesBox( auto ids = QVector<MTPint>(); for (const auto item : session->data().idsToItems(list)) { if (item->allowsSendNow()) { - ids.push_back(MTP_int( - session->data().scheduledMessages().lookupId(item))); + ids.push_back( + MTP_int(session->scheduledMessages().lookupId(item))); } } session->api().request(MTPmessages_SendScheduledMessages( diff --git a/Telegram/SourceFiles/window/window_session_controller.cpp b/Telegram/SourceFiles/window/window_session_controller.cpp index 2472bb39e..042397297 100644 --- a/Telegram/SourceFiles/window/window_session_controller.cpp +++ b/Telegram/SourceFiles/window/window_session_controller.cpp @@ -2023,10 +2023,10 @@ void SessionController::resizeForThirdSection() { auto &settings = Core::App().settings(); auto layout = computeColumnLayout(); - auto tabbedSelectorSectionEnabled = - settings.tabbedSelectorSectionEnabled(); - auto thirdSectionInfoEnabled = - settings.thirdSectionInfoEnabled(); + auto tabbedSelectorSectionEnabled + = settings.tabbedSelectorSectionEnabled(); + auto thirdSectionInfoEnabled + = settings.thirdSectionInfoEnabled(); settings.setTabbedSelectorSectionEnabled(false); settings.setThirdSectionInfoEnabled(false); diff --git a/Telegram/ThirdParty/libprisma b/Telegram/ThirdParty/libprisma index adf35ba88..23b0d70f9 160000 --- a/Telegram/ThirdParty/libprisma +++ b/Telegram/ThirdParty/libprisma @@ -1 +1 @@ -Subproject commit adf35ba88160777ce5b8d122630852394c58279f +Subproject commit 23b0d70f9709da9b38561d5706891a134d18df76 diff --git a/Telegram/build/docker/centos_env/Dockerfile b/Telegram/build/docker/centos_env/Dockerfile index 92cd7bf31..964684ab8 100644 --- a/Telegram/build/docker/centos_env/Dockerfile +++ b/Telegram/build/docker/centos_env/Dockerfile @@ -90,10 +90,11 @@ RUN git clone -b v21.9 --depth=1 --recursive {{ GIT }}/protocolbuffers/protobuf. -Dprotobuf_BUILD_TESTS=OFF \ -Dprotobuf_BUILD_PROTOBUF_BINARIES=ON \ -Dprotobuf_BUILD_LIBPROTOC=ON \ - -Dprotobuf_WITH_ZLIB_DEFAULT=OFF \ - -Dprotobuf_DEBUG_POSTFIX="" \ + -Dprotobuf_WITH_ZLIB=OFF \ && cmake --build build --parallel \ - && rm -rf .git + && DESTDIR="{{ LibrariesPath }}/protobuf-cache" cmake --install build \ + && cd .. \ + && rm -rf protobuf FROM builder AS lcms2 RUN git clone -b lcms2.15 --depth=1 {{ GIT }}/mm2/Little-CMS.git \ @@ -262,7 +263,7 @@ COPY --link --from=lcms2 {{ LibrariesPath }}/lcms2-cache / COPY --link --from=brotli {{ LibrariesPath }}/brotli-cache / COPY --link --from=highway {{ LibrariesPath }}/highway-cache / -RUN git clone -b v0.8.2 --depth=1 {{ GIT }}/libjxl/libjxl.git \ +RUN git clone -b v0.10.2 --depth=1 {{ GIT }}/libjxl/libjxl.git \ && cd libjxl \ && cmake -GNinja -B build . \ -DCMAKE_BUILD_TYPE=None \ @@ -800,7 +801,7 @@ RUN cmake --build out --config Debug --parallel \ FROM builder-base COPY --link --from=zlib {{ LibrariesPath }}/zlib-cache / COPY --link --from=xz {{ LibrariesPath }}/xz-cache / -COPY --link --from=protobuf {{ LibrariesPath }}/protobuf protobuf +COPY --link --from=protobuf {{ LibrariesPath }}/protobuf-cache / COPY --link --from=lcms2 {{ LibrariesPath }}/lcms2-cache / COPY --link --from=brotli {{ LibrariesPath }}/brotli-cache / COPY --link --from=highway {{ LibrariesPath }}/highway-cache / diff --git a/Telegram/build/version b/Telegram/build/version index 700c4cc2a..2b788edea 100644 --- a/Telegram/build/version +++ b/Telegram/build/version @@ -1,7 +1,7 @@ -AppVersion 4016006 +AppVersion 4016008 AppVersionStrMajor 4.16 -AppVersionStrSmall 4.16.6 -AppVersionStr 4.16.6 +AppVersionStrSmall 4.16.8 +AppVersionStr 4.16.8 BetaChannel 0 AlphaVersion 0 -AppVersionOriginal 4.16.6 +AppVersionOriginal 4.16.8 diff --git a/Telegram/cmake/td_ui.cmake b/Telegram/cmake/td_ui.cmake index 12a984556..9eb06eef8 100644 --- a/Telegram/cmake/td_ui.cmake +++ b/Telegram/cmake/td_ui.cmake @@ -208,6 +208,7 @@ PRIVATE statistics/statistics_data_deserialize.h statistics/statistics_format_values.cpp statistics/statistics_format_values.h + statistics/statistics_types.h statistics/view/abstract_chart_view.cpp statistics/view/abstract_chart_view.h statistics/view/bar_chart_view.cpp @@ -385,6 +386,8 @@ PRIVATE ui/widgets/discrete_sliders.h ui/widgets/gradient_round_button.cpp ui/widgets/gradient_round_button.h + ui/widgets/level_meter.cpp + ui/widgets/level_meter.h ui/widgets/multi_select.cpp ui/widgets/multi_select.h ui/widgets/sent_code_field.cpp diff --git a/changelog.txt b/changelog.txt index 0b1319a36..d6905d010 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,3 +1,13 @@ +4.16.8 (16.04.24) + +- Fix in-app playing of some video and audio files. +- Fix crash on Linux opening chats with custom backgrounds. +- Fix crash on quit after using scheduled messages. + +4.16.7 (15.04.24) + +- Reimplement file open confirmations. + 4.16.6 (09.04.24) - Show custom emoji preview on long press. diff --git a/cmake b/cmake index f921cb6ab..4ec493812 160000 --- a/cmake +++ b/cmake @@ -1 +1 @@ -Subproject commit f921cb6aba9ada6099b3f9c8c237986ecda238f5 +Subproject commit 4ec493812d25de1eccfedccc49a23c15d032b118