diff --git a/Telegram/Resources/langs/lang.strings b/Telegram/Resources/langs/lang.strings index b686d20d0..f01ab6da4 100644 --- a/Telegram/Resources/langs/lang.strings +++ b/Telegram/Resources/langs/lang.strings @@ -1655,6 +1655,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL "lng_rights_slowmode_interval_minutes#one" = "every {count} minute"; "lng_rights_slowmode_interval_minutes#other" = "every {count} minutes"; +"lng_slowmode_enabled"= "Slowmode is enabled. You can send your next message in {left}."; +"lng_slowmode_no_many" = "Slowmode is enabled. You can't send more than one message at once."; + "lng_rights_channel_info" = "Change channel info"; "lng_rights_channel_post" = "Post messages"; "lng_rights_channel_edit" = "Edit messages of others"; diff --git a/Telegram/SourceFiles/apiwrap.cpp b/Telegram/SourceFiles/apiwrap.cpp index b17b93b24..704633ec2 100644 --- a/Telegram/SourceFiles/apiwrap.cpp +++ b/Telegram/SourceFiles/apiwrap.cpp @@ -548,7 +548,9 @@ void ApiWrap::toggleHistoryArchived( // }).send(); //} -void ApiWrap::sendMessageFail(const RPCError &error) { +void ApiWrap::sendMessageFail( + not_null peer, + const RPCError &error) { if (error.type() == qstr("PEER_FLOOD")) { Ui::show(Box( PeerFloodErrorText(PeerFloodType::Send))); @@ -560,6 +562,14 @@ void ApiWrap::sendMessageFail(const RPCError &error) { tr::now, lt_more_info, link))); + } else if (error.type().startsWith(qstr("SLOWMODE_WAIT_"))) { + const auto chop = qstr("SLOWMODE_WAIT_").size(); + const auto left = error.type().mid(chop).toInt(); + if (const auto channel = peer->asChannel()) { + const auto seconds = channel->slowmodeSeconds(); + channel->growSlowmodeLastMessage( + base::unixtime::now() - (left - seconds)); + } } } @@ -4828,9 +4838,10 @@ void ApiWrap::editUploadedFile( return; } + const auto peer = item->history()->peer; request(MTPmessages_EditMessage( MTP_flags(flagsEditMsg), - item->history()->peer->input, + peer->input, MTP_int(item->id), MTP_string(item->originalText().text), *media, @@ -4853,7 +4864,7 @@ void ApiWrap::editUploadedFile( Box(tr::lng_edit_media_invalid_file(tr::now)), LayerOption::KeepOther); } else { - sendMessageFail(error); + sendMessageFail(peer, error); } }).send(); } @@ -4986,7 +4997,7 @@ void ApiWrap::sendMessage(MessageToSend &&message) { if (error.type() == qstr("MESSAGE_EMPTY")) { lastMessage->destroy(); } else { - sendMessageFail(error); + sendMessageFail(peer, error); } history->clearSentDraftText(QString()); }).afterRequest(history->sendRequestId @@ -5099,7 +5110,7 @@ void ApiWrap::sendInlineResult( applyUpdates(result, randomId); history->clearSentDraftText(QString()); }).fail([=](const RPCError &error) { - sendMessageFail(error); + sendMessageFail(peer, error); history->clearSentDraftText(QString()); }).afterRequest(history->sendRequestId ).send(); @@ -5200,12 +5211,12 @@ void ApiWrap::sendExistingDocument( if (document->fileReference() != usedFileReference) { performRequest(); } else { - sendMessageFail(error); + sendMessageFail(peer, error); } }; refreshFileReference(origin, std::move(refreshed)); } else { - sendMessageFail(error); + sendMessageFail(peer, error); } }; performRequest(); @@ -5329,9 +5340,10 @@ void ApiWrap::sendMediaWithRandomId( ? MTPmessages_SendMedia::Flag::f_entities : MTPmessages_SendMedia::Flag(0)); + const auto peer = history->peer; history->sendRequestId = request(MTPmessages_SendMedia( MTP_flags(flags), - history->peer->input, + peer->input, MTP_int(replyTo), media, MTP_string(caption.text), @@ -5339,7 +5351,7 @@ void ApiWrap::sendMediaWithRandomId( MTPReplyMarkup(), sentEntities )).done([=](const MTPUpdates &result) { applyUpdates(result); - }).fail([=](const RPCError &error) { sendMessageFail(error); + }).fail([=](const RPCError &error) { sendMessageFail(peer, error); }).afterRequest(history->sendRequestId ).send(); } @@ -5416,9 +5428,10 @@ void ApiWrap::sendAlbumIfReady(not_null album) { | (IsSilentPost(sample, album->silent) ? MTPmessages_SendMultiMedia::Flag::f_silent : MTPmessages_SendMultiMedia::Flag(0)); + const auto peer = history->peer; history->sendRequestId = request(MTPmessages_SendMultiMedia( MTP_flags(flags), - history->peer->input, + peer->input, MTP_int(replyTo), MTP_vector(medias) )).done([=](const MTPUpdates &result) { @@ -5426,7 +5439,7 @@ void ApiWrap::sendAlbumIfReady(not_null album) { applyUpdates(result); }).fail([=](const RPCError &error) { _sendingAlbums.remove(groupId); - sendMessageFail(error); + sendMessageFail(peer, error); }).afterRequest(history->sendRequestId ).send(); } diff --git a/Telegram/SourceFiles/apiwrap.h b/Telegram/SourceFiles/apiwrap.h index a846a3190..b72ec4232 100644 --- a/Telegram/SourceFiles/apiwrap.h +++ b/Telegram/SourceFiles/apiwrap.h @@ -662,7 +662,9 @@ private: not_null channel, not_null from); - void sendMessageFail(const RPCError &error); + void sendMessageFail( + not_null peer, + const RPCError &error); void uploadAlbumMedia( not_null item, const MessageGroupId &groupId, diff --git a/Telegram/SourceFiles/boxes/send_files_box.cpp b/Telegram/SourceFiles/boxes/send_files_box.cpp index df0fda85f..b0946a52a 100644 --- a/Telegram/SourceFiles/boxes/send_files_box.cpp +++ b/Telegram/SourceFiles/boxes/send_files_box.cpp @@ -1365,11 +1365,13 @@ SendFilesBox::SendFilesBox( not_null controller, Storage::PreparedList &&list, const TextWithTags &caption, - CompressConfirm compressed) + CompressConfirm compressed, + SendLimit limit) : _controller(controller) , _list(std::move(list)) , _compressConfirmInitial(compressed) , _compressConfirm(compressed) +, _sendLimit(limit) , _caption( this, st::confirmCaptionArea, @@ -1514,9 +1516,24 @@ void SendFilesBox::initSendWay() { } void SendFilesBox::updateCaptionPlaceholder() { - if (_caption) { - const auto sendWay = _sendWay->value(); + if (!_caption) { + return; + } + const auto sendWay = _sendWay->value(); + const auto isAlbum = (sendWay == SendFilesWay::Album); + const auto compressImages = (sendWay != SendFilesWay::Files); + if (!_list.canAddCaption(isAlbum, compressImages) + && _sendLimit == SendLimit::One) { + _caption->hide(); + if (_emojiToggle) { + _emojiToggle->hide(); + } + } else { _caption->setPlaceholder(FieldPlaceholder(_list, sendWay)); + _caption->show(); + if (_emojiToggle) { + _emojiToggle->show(); + } } } @@ -1640,6 +1657,8 @@ void SendFilesBox::setupCaption() { } void SendFilesBox::setupEmojiPanel() { + Expects(_caption != nullptr); + const auto container = getDelegate()->outerContainer(); _emojiPanel = base::make_unique_q( container, @@ -1663,6 +1682,7 @@ void SendFilesBox::setupEmojiPanel() { [=](not_null event) { return emojiFilter(event); })); _emojiToggle.create(this, st::boxAttachEmoji); + _emojiToggle->setVisible(!_caption->isHidden()); _emojiToggle->installEventFilter(_emojiPanel); _emojiToggle->addClickHandler([=] { _emojiPanel->toggleAnimated(); @@ -1905,7 +1925,7 @@ void SendFilesBox::send(bool ctrlShiftEnter) { applyAlbumOrder(); _confirmed = true; if (_confirmedCallback) { - auto caption = _caption + auto caption = (_caption && !_caption->isHidden()) ? _caption->getTextWithAppliedMarkdown() : TextWithTags(); _confirmedCallback( diff --git a/Telegram/SourceFiles/boxes/send_files_box.h b/Telegram/SourceFiles/boxes/send_files_box.h index 8395e12c1..5446ecb13 100644 --- a/Telegram/SourceFiles/boxes/send_files_box.h +++ b/Telegram/SourceFiles/boxes/send_files_box.h @@ -43,12 +43,17 @@ enum class SendFilesWay { class SendFilesBox : public BoxContent { public: + enum class SendLimit { + One, + Many + }; SendFilesBox( QWidget*, not_null controller, Storage::PreparedList &&list, const TextWithTags &caption, - CompressConfirm compressed); + CompressConfirm compressed, + SendLimit limit); void setConfirmedCallback( Fn(archived), LayerOption::KeepOther); diff --git a/Telegram/SourceFiles/data/data_channel.h b/Telegram/SourceFiles/data/data_channel.h index 03fe60115..b1633d023 100644 --- a/Telegram/SourceFiles/data/data_channel.h +++ b/Telegram/SourceFiles/data/data_channel.h @@ -95,7 +95,8 @@ public: | MTPDchannel::Flag::f_megagroup | MTPDchannel::Flag::f_restricted | MTPDchannel::Flag::f_signatures - | MTPDchannel::Flag::f_username; + | MTPDchannel::Flag::f_username + | MTPDchannel::Flag::f_slowmode_enabled; using Flags = Data::Flags< MTPDchannel::Flags, kEssentialFlags>; diff --git a/Telegram/SourceFiles/data/data_peer.cpp b/Telegram/SourceFiles/data/data_peer.cpp index fc65245d8..3285a9e55 100644 --- a/Telegram/SourceFiles/data/data_peer.cpp +++ b/Telegram/SourceFiles/data/data_peer.cpp @@ -13,6 +13,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "data/data_photo.h" #include "data/data_folder.h" #include "data/data_session.h" +#include "base/unixtime.h" #include "lang/lang_keys.h" #include "observer_peer.h" #include "apiwrap.h" @@ -701,6 +702,26 @@ bool PeerData::canRevokeFullHistory() const { && (Global::RevokePrivateTimeLimit() == 0x7FFFFFFF); } +bool PeerData::slowmodeApplied() const { + if (const auto channel = asChannel()) { + return !channel->amCreator() + && !channel->hasAdminRights() + && (channel->flags() & MTPDchannel::Flag::f_slowmode_enabled); + } + return false; +} + +int PeerData::slowmodeSecondsLeft() const { + if (const auto channel = asChannel()) { + if (const auto last = channel->slowmodeLastMessage()) { + const auto seconds = channel->slowmodeSeconds(); + const auto now = base::unixtime::now(); + return std::max(seconds - (now - last), 0); + } + } + return 0; +} + namespace Data { std::vector ListOfRestrictions() { diff --git a/Telegram/SourceFiles/data/data_peer.h b/Telegram/SourceFiles/data/data_peer.h index fa609225a..ee003dd23 100644 --- a/Telegram/SourceFiles/data/data_peer.h +++ b/Telegram/SourceFiles/data/data_peer.h @@ -177,6 +177,8 @@ public: [[nodiscard]] Data::RestrictionCheckResult amRestricted( ChatRestriction right) const; [[nodiscard]] bool canRevokeFullHistory() const; + [[nodiscard]] bool slowmodeApplied() const; + [[nodiscard]] int slowmodeSecondsLeft() const; [[nodiscard]] UserData *asUser(); [[nodiscard]] const UserData *asUser() const; diff --git a/Telegram/SourceFiles/history/history.style b/Telegram/SourceFiles/history/history.style index ed7d7a754..a9f347209 100644 --- a/Telegram/SourceFiles/history/history.style +++ b/Telegram/SourceFiles/history/history.style @@ -580,3 +580,5 @@ historyAudioInDownload: icon {{ "history_audio_download", historyFileInIconFg }} historyAudioInDownloadSelected: icon {{ "history_audio_download", historyFileInIconFgSelected }}; historyAudioOutDownload: icon {{ "history_audio_download", historyFileOutIconFg }}; historyAudioOutDownloadSelected: icon {{ "history_audio_download", historyFileOutIconFgSelected }}; + +historySlowmodeCounterMargins: margins(0px, 0px, 10px, 0px); diff --git a/Telegram/SourceFiles/history/history_widget.cpp b/Telegram/SourceFiles/history/history_widget.cpp index 85bb8a409..86a183f84 100644 --- a/Telegram/SourceFiles/history/history_widget.cpp +++ b/Telegram/SourceFiles/history/history_widget.cpp @@ -236,6 +236,21 @@ object_ptr SetupDiscussButton( return result; } +void ShowSlowmodeToast(const QString &text) { + auto config = Ui::Toast::Config(); + config.multiline = true; + config.minWidth = st::msgMinWidth; + config.text = text; + Ui::Toast::Show(config); +} + +void ShowSlowmodeToast(int seconds) { + ShowSlowmodeToast(tr::lng_slowmode_enabled( + tr::now, + lt_left, + formatDurationWords(seconds))); +} + } // namespace HistoryWidget::HistoryWidget( @@ -2800,11 +2815,14 @@ void HistoryWidget::hideSelectorControlsAnimated() { } void HistoryWidget::send(Qt::KeyboardModifiers modifiers) { - if (!_history) return; - - if (_editMsgId) { + if (!_history) { + return; + } else if (_editMsgId) { saveEditMsg(); return; + } else if (const auto left = _peer->slowmodeSecondsLeft()) { + ShowSlowmodeToast(left); + return; } const auto webPageId = _previewCancelled @@ -2818,6 +2836,17 @@ void HistoryWidget::send(Qt::KeyboardModifiers modifiers) { message.replyTo = replyToId(); message.webPageId = webPageId; message.handleSupportSwitch = Support::HandleSwitch(modifiers); + + if (_peer->slowmodeApplied()) { + if (_toForward.size() > 1 + || (!_toForward.empty() + && !message.textWithTags.text.isEmpty()) + || (message.textWithTags.text.size() > MaxMessageSize)) { + ShowSlowmodeToast(tr::lng_slowmode_no_many(tr::now)); + return; + } + } + session().api().sendMessage(std::move(message)); clearFieldText(); @@ -3016,13 +3045,23 @@ void HistoryWidget::chooseAttach() { } else if (const auto error = Data::RestrictionError( _peer, ChatRestriction::f_send_media)) { - Ui::show(Box(*error)); + Ui::Toast::Show(*error); + return; + } else if (const auto left = _peer->slowmodeSecondsLeft()) { + ShowSlowmodeToast(left); return; } - auto filter = FileDialog::AllFilesFilter() + qsl(";;Image files (*") + cImgExtensions().join(qsl(" *")) + qsl(")"); + const auto filter = FileDialog::AllFilesFilter() + + qsl(";;Image files (*") + + cImgExtensions().join(qsl(" *")) + + qsl(")"); - FileDialog::GetOpenPaths(this, tr::lng_choose_files(tr::now), filter, crl::guard(this, [this](FileDialog::OpenResult &&result) { + const auto method = _peer->slowmodeApplied() + ? &FileDialog::GetOpenPath + : &FileDialog::GetOpenPaths; + method(this, tr::lng_choose_files(tr::now), filter, crl::guard(this, [=]( + FileDialog::OpenResult &&result) { if (result.paths.isEmpty() && result.remoteContent.isEmpty()) { return; } @@ -3052,14 +3091,12 @@ void HistoryWidget::chooseAttach() { confirmSendingFiles(std::move(list), CompressConfirm::No); } } - })); + }), nullptr); } void HistoryWidget::sendButtonClicked() { const auto type = _send->type(); - if (type == Ui::SendButton::Type::Slowmode) { - return; - } else if (type == Ui::SendButton::Type::Cancel) { + if (type == Ui::SendButton::Type::Cancel) { onInlineBotCancel(); } else if (type != Ui::SendButton::Type::Record) { send(); @@ -3539,17 +3576,9 @@ void HistoryWidget::updateSendButtonType() { _send->setType(type); const auto delay = [&] { - if (type == Type::Cancel || type == Type::Save) { - return 0; - } - const auto channel = _peer ? _peer->asChannel() : nullptr; - const auto last = channel ? channel->slowmodeLastMessage() : 0; - if (!last) { - return 0; - } - const auto seconds = channel->slowmodeSeconds(); - const auto now = base::unixtime::now(); - return std::max(seconds - (now - last), 0); + return (type != Type::Cancel && type != Type::Save && _peer) + ? _peer->slowmodeSecondsLeft() + : 0; }(); _send->setSlowmodeDelay(delay); @@ -3963,6 +3992,14 @@ bool HistoryWidget::showSendingFilesError( } else if (!canWriteMessage()) { return tr::lng_forward_send_files_cant(tr::now); } + if (list.files.size() > 1 && _peer->slowmodeApplied()) { + return tr::lng_slowmode_no_many(tr::now); + } else if (const auto left = _peer->slowmodeSecondsLeft()) { + return tr::lng_slowmode_enabled( + tr::now, + lt_left, + formatDurationWords(left)); + } using Error = Storage::PreparedList::Error; switch (list.error) { case Error::None: return QString(); @@ -3983,7 +4020,7 @@ bool HistoryWidget::showSendingFilesError( return false; } - Ui::show(Box(text)); + ShowSlowmodeToast(text); return true; } @@ -4024,11 +4061,13 @@ bool HistoryWidget::confirmSendingFiles( const auto position = cursor.position(); const auto anchor = cursor.anchor(); const auto text = _field->getTextWithTags(); + using SendLimit = SendFilesBox::SendLimit; auto box = Box( controller(), std::move(list), text, - boxCompressConfirm); + boxCompressConfirm, + _peer->slowmodeApplied() ? SendLimit::One : SendLimit::Many); _field->setTextWithTags({}); box->setConfirmedCallback(crl::guard(this, [=]( Storage::PreparedList &&list, @@ -4172,6 +4211,17 @@ void HistoryWidget::uploadFilesAfterConfirmation( std::shared_ptr album) { Assert(canWriteMessage()); + const auto isAlbum = (album != nullptr); + const auto compressImages = (type == SendMediaType::Photo); + if (_peer->slowmodeApplied() + && (list.files.size() > 1 + || (!list.files.empty() + && !caption.text.isEmpty() + && !list.canAddCaption(isAlbum, compressImages)))) { + ShowSlowmodeToast(tr::lng_slowmode_no_many(tr::now)); + return; + } + auto options = ApiWrap::SendOptions(_history); options.replyTo = replyTo; session().api().sendFiles( @@ -5292,6 +5342,9 @@ void HistoryWidget::sendInlineResult( not_null bot) { if (!_peer || !_peer->canWrite()) { return; + } else if (const auto left = _peer->slowmodeSecondsLeft()) { + ShowSlowmodeToast(left); + return; } auto errorText = result->getErrorOnSend(_history); @@ -5445,6 +5498,9 @@ bool HistoryWidget::sendExistingDocument( return false; } else if (!_peer || !_peer->canWrite()) { return false; + } else if (const auto left = _peer->slowmodeSecondsLeft()) { + ShowSlowmodeToast(left); + return false; } const auto origin = document->stickerOrGifOrigin(); @@ -5480,6 +5536,9 @@ bool HistoryWidget::sendExistingPhoto( return false; } else if (!_peer || !_peer->canWrite()) { return false; + } else if (const auto left = _peer->slowmodeSecondsLeft()) { + ShowSlowmodeToast(left); + return false; } auto options = ApiWrap::SendOptions(_history); diff --git a/Telegram/SourceFiles/ui/special_buttons.cpp b/Telegram/SourceFiles/ui/special_buttons.cpp index d68ddf229..3b860bc53 100644 --- a/Telegram/SourceFiles/ui/special_buttons.cpp +++ b/Telegram/SourceFiles/ui/special_buttons.cpp @@ -420,7 +420,10 @@ void SendButton::paintSend(Painter &p, bool over) { void SendButton::paintSlowmode(Painter &p) { p.setFont(st::normalFont); p.setPen(st::windowSubTextFg); - p.drawText(rect(), _slowmodeDelayText, style::al_center); + p.drawText( + rect().marginsRemoved(st::historySlowmodeCounterMargins), + _slowmodeDelayText, + style::al_center); } void SendButton::onStateChanged(State was, StateChangeSource source) { diff --git a/Telegram/SourceFiles/ui/toast/toast.h b/Telegram/SourceFiles/ui/toast/toast.h index 0d485aab0..6274c9ab5 100644 --- a/Telegram/SourceFiles/ui/toast/toast.h +++ b/Telegram/SourceFiles/ui/toast/toast.h @@ -13,16 +13,19 @@ namespace Ui { namespace Toast { namespace internal { - class Manager; - class Widget; +class Manager; +class Widget; } // namespace internal static constexpr const int DefaultDuration = 1500; struct Config { QString text; - int durationMs = DefaultDuration; - int maxWidth = 0; QMargins padding; + int durationMs = DefaultDuration; + int minWidth = 0; + int maxWidth = 0; + int maxLines = 16; + bool multiline = false; }; void Show(QWidget *parent, const Config &config); void Show(const Config &config); diff --git a/Telegram/SourceFiles/ui/toast/toast_widget.cpp b/Telegram/SourceFiles/ui/toast/toast_widget.cpp index e1c51f99c..42b8124bc 100644 --- a/Telegram/SourceFiles/ui/toast/toast_widget.cpp +++ b/Telegram/SourceFiles/ui/toast/toast_widget.cpp @@ -12,23 +12,25 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL namespace Ui { namespace Toast { namespace internal { -namespace { - -constexpr auto kToastMaxLines = 16; - -} // namespace Widget::Widget(QWidget *parent, const Config &config) : TWidget(parent) -, _multiline(config.maxWidth > 0) +, _multiline(config.multiline) , _maxWidth((config.maxWidth > 0) ? config.maxWidth : st::toastMaxWidth) , _padding((config.padding.left() > 0) ? config.padding : st::toastPadding) , _maxTextWidth(_maxWidth - _padding.left() - _padding.right()) -, _text(_multiline ? _maxTextWidth : QFIXED_MAX) { - TextParseOptions toastOptions = { 0, _maxTextWidth, st::toastTextStyle.font->height, Qt::LayoutDirectionAuto }; - if (_multiline) { - toastOptions.maxh *= kToastMaxLines; - } - _text.setText(st::toastTextStyle, _multiline ? config.text : TextUtilities::SingleLine(config.text), toastOptions); +, _maxTextHeight( + st::toastTextStyle.font->height * (_multiline ? config.maxLines : 1)) +, _text(_multiline ? config.minWidth : QFIXED_MAX) { + const auto toastOptions = TextParseOptions{ + 0, + _maxTextWidth, + _maxTextHeight, + Qt::LayoutDirectionAuto + }; + _text.setText( + st::toastTextStyle, + _multiline ? config.text : TextUtilities::SingleLine(config.text), + toastOptions); setAttribute(Qt::WA_TransparentForMouseEvents); @@ -41,9 +43,10 @@ void Widget::onParentResized() { accumulate_min(newWidth, _padding.left() + _text.maxWidth() + _padding.right()); accumulate_min(newWidth, parentWidget()->width() - 2 * st::toastMinMargin); _textWidth = newWidth - _padding.left() - _padding.right(); - auto maxHeight = kToastMaxLines * st::toastTextStyle.font->height; - auto textHeight = _multiline ? qMin(_text.countHeight(_textWidth), maxHeight) : _text.minHeight(); - auto newHeight = _padding.top() + textHeight + _padding.bottom(); + const auto textHeight = _multiline + ? qMin(_text.countHeight(_textWidth), _maxTextHeight) + : _text.minHeight(); + const auto newHeight = _padding.top() + textHeight + _padding.bottom(); setGeometry((parentWidget()->width() - newWidth) / 2, (parentWidget()->height() - newHeight) / 2, newWidth, newHeight); } @@ -58,7 +61,7 @@ void Widget::paintEvent(QPaintEvent *e) { p.setOpacity(_shownLevel); App::roundRect(p, rect(), st::toastBg, ImageRoundRadius::Large); - auto lines = _multiline ? kToastMaxLines : 1; + const auto lines = _maxTextHeight / st::toastTextStyle.font->height; p.setPen(st::toastFg); _text.drawElided(p, _padding.left(), _padding.top(), _textWidth + 1, lines); } diff --git a/Telegram/SourceFiles/ui/toast/toast_widget.h b/Telegram/SourceFiles/ui/toast/toast_widget.h index bc13db400..17804ef07 100644 --- a/Telegram/SourceFiles/ui/toast/toast_widget.h +++ b/Telegram/SourceFiles/ui/toast/toast_widget.h @@ -34,6 +34,7 @@ private: QMargins _padding; int _maxTextWidth = 0; + int _maxTextHeight = 0; int _textWidth = 0; Text::String _text; diff --git a/Telegram/SourceFiles/window/window_peer_menu.cpp b/Telegram/SourceFiles/window/window_peer_menu.cpp index 7e687014b..12ffd3929 100644 --- a/Telegram/SourceFiles/window/window_peer_menu.cpp +++ b/Telegram/SourceFiles/window/window_peer_menu.cpp @@ -575,9 +575,10 @@ void FolderFiller::addTogglesForArchive() { }); _addAction(tr::lng_context_archive_to_menu(tr::now), [=] { - Ui::Toast::Config toast; + auto toast = Ui::Toast::Config(); toast.text = tr::lng_context_archive_to_menu_info(tr::now); - toast.maxWidth = st::boxWideWidth; + toast.minWidth = toast.maxWidth = st::boxWideWidth; + toast.multiline = true; toast.durationMs = kArchivedToastDuration; Ui::Toast::Show(toast); @@ -896,11 +897,12 @@ void PeerMenuAddMuteAction( // void ToggleHistoryArchived(not_null history, bool archived) { const auto callback = [=] { - Ui::Toast::Config toast; + auto toast = Ui::Toast::Config(); toast.text = archived ? tr::lng_archived_added(tr::now) : tr::lng_archived_removed(tr::now); - toast.maxWidth = st::boxWideWidth; + toast.minWidth = toast.maxWidth = st::boxWideWidth; + toast.multiline = true; if (archived) { toast.durationMs = kArchivedToastDuration; }