mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-05 22:54:01 +02:00
Support slowmode restrictions in Replies section.
This commit is contained in:
parent
719bed6e85
commit
94c2969f8b
11 changed files with 174 additions and 27 deletions
|
@ -836,6 +836,31 @@ bool PeerData::slowmodeApplied() const {
|
|||
return false;
|
||||
}
|
||||
|
||||
rpl::producer<bool> PeerData::slowmodeAppliedValue() const {
|
||||
using namespace rpl::mappers;
|
||||
const auto channel = asChannel();
|
||||
if (!channel) {
|
||||
return rpl::single(false);
|
||||
}
|
||||
|
||||
auto hasAdminRights = channel->adminRightsValue(
|
||||
) | rpl::map([=] {
|
||||
return channel->hasAdminRights();
|
||||
}) | rpl::distinct_until_changed();
|
||||
|
||||
auto slowmodeEnabled = channel->flagsValue(
|
||||
) | rpl::filter([=](const ChannelData::Flags::Change &change) {
|
||||
return (change.diff & MTPDchannel::Flag::f_slowmode_enabled) != 0;
|
||||
}) | rpl::map([=](const ChannelData::Flags::Change &change) {
|
||||
return (change.value & MTPDchannel::Flag::f_slowmode_enabled) != 0;
|
||||
}) | rpl::distinct_until_changed();
|
||||
|
||||
return rpl::combine(
|
||||
std::move(hasAdminRights),
|
||||
std::move(slowmodeEnabled),
|
||||
!_1 && _2);
|
||||
}
|
||||
|
||||
int PeerData::slowmodeSecondsLeft() const {
|
||||
if (const auto channel = asChannel()) {
|
||||
if (const auto seconds = channel->slowmodeSeconds()) {
|
||||
|
|
|
@ -199,6 +199,7 @@ public:
|
|||
[[nodiscard]] bool amAnonymous() const;
|
||||
[[nodiscard]] bool canRevokeFullHistory() const;
|
||||
[[nodiscard]] bool slowmodeApplied() const;
|
||||
[[nodiscard]] rpl::producer<bool> slowmodeAppliedValue() const;
|
||||
[[nodiscard]] int slowmodeSecondsLeft() const;
|
||||
[[nodiscard]] bool canSendPolls() const;
|
||||
|
||||
|
|
|
@ -3675,15 +3675,18 @@ void HistoryWidget::updateSendButtonType() {
|
|||
const auto type = computeSendButtonType();
|
||||
_send->setType(type);
|
||||
|
||||
// This logic is duplicated in RepliesWidget.
|
||||
const auto disabledBySlowmode = _peer
|
||||
&& _peer->slowmodeApplied()
|
||||
&& (_history->latestSendingMessage() != nullptr);
|
||||
|
||||
const auto delay = [&] {
|
||||
return (type != Type::Cancel && type != Type::Save && _peer)
|
||||
? _peer->slowmodeSecondsLeft()
|
||||
: 0;
|
||||
}();
|
||||
_send->setSlowmodeDelay(delay);
|
||||
_send->setDisabled(_peer
|
||||
&& _peer->slowmodeApplied()
|
||||
&& (_history->latestSendingMessage() != nullptr)
|
||||
_send->setDisabled(disabledBySlowmode
|
||||
&& (type == Type::Send || type == Type::Record));
|
||||
|
||||
if (delay != 0) {
|
||||
|
|
|
@ -528,7 +528,13 @@ Main::Session &ComposeControls::session() const {
|
|||
return _window->session();
|
||||
}
|
||||
|
||||
void ComposeControls::setHistory(History *history) {
|
||||
void ComposeControls::setHistory(SetHistoryArgs &&args) {
|
||||
_showSlowmodeError = std::move(args.showSlowmodeError);
|
||||
_slowmodeSecondsLeft = rpl::single(0)
|
||||
| rpl::then(std::move(args.slowmodeSecondsLeft));
|
||||
_sendDisabledBySlowmode = rpl::single(false)
|
||||
| rpl::then(std::move(args.sendDisabledBySlowmode));
|
||||
const auto history = *args.history;
|
||||
if (_history == history) {
|
||||
return;
|
||||
}
|
||||
|
@ -878,8 +884,8 @@ void ComposeControls::recordStartCallback() {
|
|||
if (error) {
|
||||
Ui::show(Box<InformBox>(*error));
|
||||
return;
|
||||
//} else if (showSlowmodeError()) { // #TODO slowmode
|
||||
// return;
|
||||
} else if (_showSlowmodeError && _showSlowmodeError()) {
|
||||
return;
|
||||
} else if (!::Media::Capture::instance()->available()) {
|
||||
return;
|
||||
}
|
||||
|
@ -1034,7 +1040,13 @@ void ComposeControls::initTabbedSelector() {
|
|||
}
|
||||
|
||||
void ComposeControls::initSendButton() {
|
||||
updateSendButtonType();
|
||||
rpl::combine(
|
||||
_slowmodeSecondsLeft.value(),
|
||||
_sendDisabledBySlowmode.value()
|
||||
) | rpl::start_with_next([=] {
|
||||
updateSendButtonType();
|
||||
}, _send->lifetime());
|
||||
|
||||
_send->finishAnimating();
|
||||
}
|
||||
|
||||
|
@ -1053,22 +1065,13 @@ void ComposeControls::updateSendButtonType() {
|
|||
_send->setType(type);
|
||||
|
||||
const auto delay = [&] {
|
||||
return /*(type != Type::Cancel && type != Type::Save && _peer)
|
||||
? _peer->slowmodeSecondsLeft()
|
||||
: */0;
|
||||
return (type != Type::Cancel && type != Type::Save)
|
||||
? _slowmodeSecondsLeft.current()
|
||||
: 0;
|
||||
}();
|
||||
_send->setSlowmodeDelay(delay);
|
||||
//_send->setDisabled(_peer
|
||||
// && _peer->slowmodeApplied()
|
||||
// && (_history->latestSendingMessage() != nullptr)
|
||||
// && (type == Type::Send || type == Type::Record));
|
||||
|
||||
//if (delay != 0) {
|
||||
// base::call_delayed(
|
||||
// kRefreshSlowmodeLabelTimeout,
|
||||
// this,
|
||||
// [=] { updateSendButtonType(); });
|
||||
//}
|
||||
_send->setDisabled(_sendDisabledBySlowmode.current()
|
||||
&& (type == Type::Send || type == Type::Record));
|
||||
|
||||
_send->setRecordStartCallback([=] { recordStartCallback(); });
|
||||
_send->setRecordStopCallback([=](bool active) { recordStopCallback(active); });
|
||||
|
@ -1076,6 +1079,11 @@ void ComposeControls::updateSendButtonType() {
|
|||
_send->setRecordAnimationCallback([=] { _wrap->update(); });
|
||||
}
|
||||
|
||||
void ComposeControls::finishAnimating() {
|
||||
_send->finishAnimating();
|
||||
_recordingAnimation.stop();
|
||||
}
|
||||
|
||||
void ComposeControls::updateControlsGeometry(QSize size) {
|
||||
// _attachToggle -- _inlineResults ------ _tabbedPanel -- _fieldBarCancel
|
||||
// (_attachDocument|_attachPhoto) _field _tabbedSelectorToggle _send
|
||||
|
|
|
@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
*/
|
||||
#pragma once
|
||||
|
||||
#include "base/required.h"
|
||||
#include "api/api_common.h"
|
||||
#include "base/unique_qptr.h"
|
||||
#include "ui/rp_widget.h"
|
||||
|
@ -88,7 +89,14 @@ public:
|
|||
|
||||
[[nodiscard]] Main::Session &session() const;
|
||||
|
||||
void setHistory(History *history);
|
||||
struct SetHistoryArgs {
|
||||
required<History*> history;
|
||||
Fn<bool()> showSlowmodeError;
|
||||
rpl::producer<int> slowmodeSecondsLeft;
|
||||
rpl::producer<bool> sendDisabledBySlowmode;
|
||||
};
|
||||
void setHistory(SetHistoryArgs &&args);
|
||||
void finishAnimating();
|
||||
|
||||
void move(int x, int y);
|
||||
void resizeToWidth(int width);
|
||||
|
@ -184,6 +192,9 @@ private:
|
|||
const not_null<QWidget*> _parent;
|
||||
const not_null<Window::SessionController*> _window;
|
||||
History *_history = nullptr;
|
||||
Fn<bool()> _showSlowmodeError;
|
||||
rpl::variable<int> _slowmodeSecondsLeft;
|
||||
rpl::variable<bool> _sendDisabledBySlowmode;
|
||||
Mode _mode = Mode::Normal;
|
||||
|
||||
const std::unique_ptr<Ui::RpWidget> _wrap;
|
||||
|
|
|
@ -746,6 +746,8 @@ void Message::paintCommentsButton(
|
|||
QImage::Format_ARGB32_Premultiplied);
|
||||
}
|
||||
_comments->cachedUserpics.fill(Qt::transparent);
|
||||
_comments->cachedUserpics.setDevicePixelRatio(cRetinaFactor());
|
||||
|
||||
auto q = Painter(&_comments->cachedUserpics);
|
||||
auto hq = PainterHighQualityEnabler(q);
|
||||
auto pen = QPen(Qt::transparent);
|
||||
|
|
|
@ -22,9 +22,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "ui/layers/generic_box.h"
|
||||
#include "ui/text_options.h"
|
||||
#include "ui/toast/toast.h"
|
||||
#include "ui/text/format_values.h"
|
||||
#include "ui/special_buttons.h"
|
||||
#include "ui/ui_utility.h"
|
||||
#include "ui/toasts/common_toasts.h"
|
||||
#include "base/timer_rpl.h"
|
||||
#include "api/api_common.h"
|
||||
#include "api/api_editing.h"
|
||||
#include "api/api_sending.h"
|
||||
|
@ -62,6 +64,7 @@ namespace HistoryView {
|
|||
namespace {
|
||||
|
||||
constexpr auto kReadRequestTimeout = 3 * crl::time(1000);
|
||||
constexpr auto kRefreshSlowmodeLabelTimeout = crl::time(200);
|
||||
|
||||
bool CanSendFiles(not_null<const QMimeData*> data) {
|
||||
if (data->hasImage()) {
|
||||
|
@ -135,6 +138,8 @@ RepliesWidget::RepliesWidget(
|
|||
setupRoot();
|
||||
setupRootView();
|
||||
|
||||
session().api().requestFullPeer(_history->peer);
|
||||
|
||||
_topBar->setActiveChat(
|
||||
_history,
|
||||
TopBarWidget::Section::Replies,
|
||||
|
@ -396,7 +401,51 @@ bool RepliesWidget::computeAreComments() const {
|
|||
}
|
||||
|
||||
void RepliesWidget::setupComposeControls() {
|
||||
_composeControls->setHistory(_history);
|
||||
auto slowmodeSecondsLeft = session().changes().peerFlagsValue(
|
||||
_history->peer,
|
||||
Data::PeerUpdate::Flag::Slowmode
|
||||
) | rpl::map([=] {
|
||||
return _history->peer->slowmodeSecondsLeft();
|
||||
}) | rpl::map([=](int delay) -> rpl::producer<int> {
|
||||
auto start = rpl::single(delay);
|
||||
if (!delay) {
|
||||
return start;
|
||||
}
|
||||
return std::move(
|
||||
start
|
||||
) | rpl::then(base::timer_each(
|
||||
kRefreshSlowmodeLabelTimeout
|
||||
) | rpl::map([=] {
|
||||
return _history->peer->slowmodeSecondsLeft();
|
||||
}) | rpl::take_while([=](int delay) {
|
||||
return delay > 0;
|
||||
})) | rpl::then(rpl::single(0));
|
||||
}) | rpl::flatten_latest();
|
||||
|
||||
const auto channel = _history->peer->asChannel();
|
||||
Assert(channel != nullptr);
|
||||
|
||||
auto hasSendingMessage = session().changes().historyFlagsValue(
|
||||
_history,
|
||||
Data::HistoryUpdate::Flag::LocalMessages
|
||||
) | rpl::map([=] {
|
||||
return _history->latestSendingMessage() != nullptr;
|
||||
}) | rpl::distinct_until_changed();
|
||||
|
||||
using namespace rpl::mappers;
|
||||
auto sendDisabledBySlowmode = (!channel || channel->amCreator())
|
||||
? (rpl::single(false) | rpl::type_erased())
|
||||
: rpl::combine(
|
||||
channel->slowmodeAppliedValue(),
|
||||
std::move(hasSendingMessage),
|
||||
_1 && _2);
|
||||
|
||||
_composeControls->setHistory({
|
||||
.history = _history.get(),
|
||||
.showSlowmodeError = [=] { return showSlowmodeError(); },
|
||||
.slowmodeSecondsLeft = std::move(slowmodeSecondsLeft),
|
||||
.sendDisabledBySlowmode = std::move(sendDisabledBySlowmode),
|
||||
});
|
||||
|
||||
_composeControls->height(
|
||||
) | rpl::start_with_next([=] {
|
||||
|
@ -497,6 +546,8 @@ void RepliesWidget::setupComposeControls() {
|
|||
}
|
||||
Unexpected("action in MimeData hook.");
|
||||
});
|
||||
|
||||
_composeControls->finishAnimating();
|
||||
}
|
||||
|
||||
void RepliesWidget::chooseAttach() {
|
||||
|
@ -507,6 +558,8 @@ void RepliesWidget::chooseAttach() {
|
|||
.text = { *error },
|
||||
});
|
||||
return;
|
||||
} else if (showSlowmodeError()) {
|
||||
return;
|
||||
}
|
||||
|
||||
const auto filter = FileDialog::AllFilesFilter()
|
||||
|
@ -684,6 +737,30 @@ bool RepliesWidget::confirmSendingFiles(
|
|||
insertTextOnCancel);
|
||||
}
|
||||
|
||||
bool RepliesWidget::showSlowmodeError() {
|
||||
const auto text = [&] {
|
||||
if (const auto left = _history->peer->slowmodeSecondsLeft()) {
|
||||
return tr::lng_slowmode_enabled(
|
||||
tr::now,
|
||||
lt_left,
|
||||
Ui::FormatDurationWords(left));
|
||||
} else if (_history->peer->slowmodeApplied()) {
|
||||
if (const auto item = _history->latestSendingMessage()) {
|
||||
showAtPositionNow(item->position(), nullptr);
|
||||
return tr::lng_slowmode_no_many(tr::now);
|
||||
}
|
||||
}
|
||||
return QString();
|
||||
}();
|
||||
if (text.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
Ui::ShowMultilineToast({
|
||||
.text = { text },
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
void RepliesWidget::uploadFilesAfterConfirmation(
|
||||
Storage::PreparedList &&list,
|
||||
SendMediaType type,
|
||||
|
@ -783,6 +860,16 @@ bool RepliesWidget::showSendingFilesError(
|
|||
if (error) {
|
||||
return *error;
|
||||
}
|
||||
if (list.files.size() > 1
|
||||
&& _history->peer->slowmodeApplied()
|
||||
&& !list.albumIsPossible) {
|
||||
return tr::lng_slowmode_no_many(tr::now);
|
||||
} else if (const auto left = _history->peer->slowmodeSecondsLeft()) {
|
||||
return tr::lng_slowmode_enabled(
|
||||
tr::now,
|
||||
lt_left,
|
||||
Ui::FormatDurationWords(left));
|
||||
}
|
||||
using Error = Storage::PreparedList::Error;
|
||||
switch (list.error) {
|
||||
case Error::None: return QString();
|
||||
|
@ -831,6 +918,10 @@ void RepliesWidget::sendVoice(
|
|||
}
|
||||
|
||||
void RepliesWidget::send(Api::SendOptions options) {
|
||||
if (!options.scheduled && showSlowmodeError()) {
|
||||
return;
|
||||
}
|
||||
|
||||
const auto webPageId = _composeControls->webPageId();/* _previewCancelled
|
||||
? CancelledWebPageId
|
||||
: ((_previewData && _previewData->pendingTill >= 0)
|
||||
|
@ -964,6 +1055,8 @@ bool RepliesWidget::sendExistingDocument(
|
|||
if (error) {
|
||||
Ui::show(Box<InformBox>(*error), Ui::LayerOption::KeepOther);
|
||||
return false;
|
||||
} else if (showSlowmodeError()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto message = Api::MessageToSend(_history);
|
||||
|
@ -1004,6 +1097,8 @@ bool RepliesWidget::sendExistingPhoto(
|
|||
if (error) {
|
||||
Ui::show(Box<InformBox>(*error), Ui::LayerOption::KeepOther);
|
||||
return false;
|
||||
} else if (showSlowmodeError()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto message = Api::MessageToSend(_history);
|
||||
|
|
|
@ -152,7 +152,7 @@ ScheduledWidget::ScheduledWidget(
|
|||
ScheduledWidget::~ScheduledWidget() = default;
|
||||
|
||||
void ScheduledWidget::setupComposeControls() {
|
||||
_composeControls->setHistory(_history);
|
||||
_composeControls->setHistory({ .history = _history });
|
||||
|
||||
_composeControls->height(
|
||||
) | rpl::start_with_next([=] {
|
||||
|
|
|
@ -234,7 +234,6 @@ void SessionNavigation::showPeerByLinkResolved(
|
|||
showPeerHistory(peer->id, params, msgId);
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void SessionNavigation::showRepliesForMessage(
|
||||
|
@ -246,6 +245,9 @@ void SessionNavigation::showRepliesForMessage(
|
|||
&& _showingRepliesHistory == history.get()
|
||||
&& _showingRepliesRootId == rootId) {
|
||||
return;
|
||||
} else if (!history->peer->asChannel()) {
|
||||
// HistoryView::RepliesWidget right now handles only channels.
|
||||
return;
|
||||
}
|
||||
_session->api().request(base::take(_showingRepliesRequestId)).cancel();
|
||||
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit c28f55ab25c9ee7aee7e960c6a4127b008742bdd
|
||||
Subproject commit 4f03dbd9a0c3dce0268fa208bf1e3ffff4c95c72
|
|
@ -1 +1 @@
|
|||
Subproject commit e654c5ee98199b47a426aaaf6a1f7331aca0ebcd
|
||||
Subproject commit 86b9b80fae7a41e7c6ad85f14659883533ab84e8
|
Loading…
Add table
Reference in a new issue