diff --git a/Telegram/SourceFiles/data/data_channel.cpp b/Telegram/SourceFiles/data/data_channel.cpp index 0919a12d5..c93ee8af3 100644 --- a/Telegram/SourceFiles/data/data_channel.cpp +++ b/Telegram/SourceFiles/data/data_channel.cpp @@ -597,12 +597,11 @@ TimeId ChannelData::slowmodeLastMessage() const { return (hasAdminRights() || amCreator()) ? 0 : _slowmodeLastMessage; } -void ChannelData::setSlowmodeLastMessage(TimeId when) { - const auto time = when ? when : base::unixtime::now(); - if (_slowmodeLastMessage == time) { +void ChannelData::growSlowmodeLastMessage(TimeId when) { + if (_slowmodeLastMessage >= when) { return; } - _slowmodeLastMessage = time; + _slowmodeLastMessage = when; Notify::peerUpdatedDelayed(this, UpdateFlag::ChannelSlowmode); } diff --git a/Telegram/SourceFiles/data/data_channel.h b/Telegram/SourceFiles/data/data_channel.h index 8ac00face..03fe60115 100644 --- a/Telegram/SourceFiles/data/data_channel.h +++ b/Telegram/SourceFiles/data/data_channel.h @@ -392,7 +392,7 @@ public: [[nodiscard]] int slowmodeSeconds() const; void setSlowmodeSeconds(int seconds); [[nodiscard]] TimeId slowmodeLastMessage() const; - void setSlowmodeLastMessage(TimeId when = 0); + void growSlowmodeLastMessage(TimeId when); // Still public data members. uint64 access = 0; diff --git a/Telegram/SourceFiles/data/data_session.cpp b/Telegram/SourceFiles/data/data_session.cpp index a3ec11843..e7e5d2ed5 100644 --- a/Telegram/SourceFiles/data/data_session.cpp +++ b/Telegram/SourceFiles/data/data_session.cpp @@ -1636,6 +1636,11 @@ bool Session::checkEntitiesAndViewsUpdate(const MTPDmessage &data) { existing->updateForwardedInfo(data.vfwd_from()); existing->setViewsCount(data.vviews().value_or(-1)); existing->indexAsNewItem(); + if (const auto channel = existing->history()->peer->asChannel()) { + if (existing->out()) { + channel->growSlowmodeLastMessage(data.vdate().v); + } + } requestItemTextRefresh(existing); if (existing->mainView()) { App::checkSavedGif(existing); diff --git a/Telegram/SourceFiles/history/history.cpp b/Telegram/SourceFiles/history/history.cpp index 26b34ae42..6b22c5a18 100644 --- a/Telegram/SourceFiles/history/history.cpp +++ b/Telegram/SourceFiles/history/history.cpp @@ -1235,6 +1235,11 @@ void History::newItemAdded(not_null item) { if (!item->unread()) { outboxRead(item); } + if (const auto channel = peer->asChannel()) { + if (IsServerMsgId(item->id)) { + channel->growSlowmodeLastMessage(item->date()); + } + } } else if (item->unread()) { if (!isChannel() || peer->asChannel()->amIn()) { _notifications.push_back(item); diff --git a/Telegram/SourceFiles/history/history_widget.cpp b/Telegram/SourceFiles/history/history_widget.cpp index bdb7165e7..85bb8a409 100644 --- a/Telegram/SourceFiles/history/history_widget.cpp +++ b/Telegram/SourceFiles/history/history_widget.cpp @@ -110,6 +110,7 @@ constexpr auto kSaveDraftTimeout = 1000; constexpr auto kSaveDraftAnywayTimeout = 5000; constexpr auto kSaveCloudDraftIdleTimeout = 14000; constexpr auto kRecordingUpdateDelta = crl::time(100); +constexpr auto kRefreshSlowmodeLabelTimeout = crl::time(200); ApiWrap::RequestMessageDataCallback replyEditMessageDataCallback() { return [](ChannelData *channel, MsgId msgId) { @@ -3055,8 +3056,10 @@ void HistoryWidget::chooseAttach() { } void HistoryWidget::sendButtonClicked() { - auto type = _send->type(); - if (type == Ui::SendButton::Type::Cancel) { + const auto type = _send->type(); + if (type == Ui::SendButton::Type::Slowmode) { + return; + } else if (type == Ui::SendButton::Type::Cancel) { onInlineBotCancel(); } else if (type != Ui::SendButton::Type::Record) { send(); @@ -3522,8 +3525,8 @@ bool HistoryWidget::showInlineBotCancel() const { } void HistoryWidget::updateSendButtonType() { - auto type = [this] { - using Type = Ui::SendButton::Type; + using Type = Ui::SendButton::Type; + const auto type = [&] { if (_editMsgId) { return Type::Save; } else if (_isInlineBot) { @@ -3532,8 +3535,30 @@ void HistoryWidget::updateSendButtonType() { return Type::Record; } return Type::Send; - }; - _send->setType(type()); + }(); + _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); + }(); + _send->setSlowmodeDelay(delay); + + if (delay != 0) { + App::CallDelayed( + kRefreshSlowmodeLabelTimeout, + this, + [=] { updateSendButtonType(); }); + } } bool HistoryWidget::updateCmdStartShown() { diff --git a/Telegram/SourceFiles/mainwidget.cpp b/Telegram/SourceFiles/mainwidget.cpp index d68fada72..b0647b7e9 100644 --- a/Telegram/SourceFiles/mainwidget.cpp +++ b/Telegram/SourceFiles/mainwidget.cpp @@ -3826,6 +3826,9 @@ void MainWidget::feedUpdates(const MTPUpdates &updates, uint64 randomId) { TextUtilities::EntitiesFromMTP(list.value_or_empty()) }); item->updateSentMedia(d.vmedia()); + if (const auto channel = item->history()->peer->asChannel()) { + channel->growSlowmodeLastMessage(d.vdate().v); + } if (!wasAlready) { item->indexAsNewItem(); }